Lab 01 - 6502 Assembly Language Lab


Bitmap Code

We will discover the basics of 6502 Assembly Language by running and analyzing a program given on a web based simulator here.  The comments in each line of code explains what they do.

	lda #$00	; set a pointer in memory location $40 to point to $0200
 	sta $40		; ... low byte ($00) goes in address $40
 	lda #$02	
 	sta $41		; ... high byte ($02) goes into address $41
 	lda #$07	; colour number
 	ldy #$00	; set index to 0
 loop:	sta ($40),y	; set pixel colour at the address (pointer)+Y
 	iny		; increment index
 	bne loop	; continue until done the page (256 pixels)
 	inc $41		; increment the page
 	ldx $41		; get the current page number
 	cpx #$06	; compare with 6
 	bne loop	; continue until done all pages

When we assemble and run the code, the emulator's bitmapped result is filled with the colour yellow. There are no error messages displayed so we can dissect the code.  This code uses 25 bytes of memory.


Calculate Performance 

Assuming the CPU is running at 1MHz (Megahertz) clock speed, the execution time, memory usage and pointers and variables will be calculated with the help of a reference 6502 Instruction Set.


Program time = 3353 cycles x 1 MHz = 3353 uS = 3353 uS / 1,000,000 = 0.003353 S 

Calculate Memory Usage

Sum up the size of all the instructions along with the size of each pointer and variable used. The size of each instruction uses can be found using 6502 documentation for reference. 




Memory usage (instructions)  = 26 bytes 

Memory locations $40 and $41 are used for pointers and variables using 1 byte each

Total memory usage = 26 + 2 = 28 bytes 

Optimize Performance 

To make the program faster we can minimize the number of instructions executed during each iteration and reduce redundant operations. 

Loops consume the most cycles. The code has nested loop where the first one filled in one quarter of the display with pixel colours and the sesta ($30), ycond loop checks if that was the last display. If that is not the case, the first loop would be repeated filling the subsequent screen until all 4 screens were filled. I found that filling all 4 screens in the same loop would be better since it would need to run once.

LDA #$00
                STA $40
                STA $30
                STA $20
                STA $10
                LDA #$02
                STA $41
                LDA #$03
                STA $31
                LDA #$04
                STA $21
                LDA #$05
                STA $11
                LDA #$07
                LDY #$00
LOOP: STA ($40),Y
                STA($30), Y
                STA($20), Y
                STA($10), Y
                INY
                BNE LOOP
Calculate memory usage and performance for optimized code


Our first code runs at 0.003353 seconds, whereas our second code runs at 0.013606 seconds. We were able to reduce the time by 0.010253 (an improvement in performance of 30.58%.

Modifying the code

1. Change the code to fill the display with light blue instead of yellow. (Tip: you can find the colour codes on the 6502 Emulator page).

    Change the colour code from yellow to blue.

	Change LDA #$07; to LDA #$06

    The result is 



2. Change the code to fill the display with a different colour on each page (each “page” will be one-quarter of the bitmapped display).

    Change the accumulator by adding after each loop. Each loop fill one display, the following loop have different colour value.

	lda #$00	; set a pointer in memory location $40 to point to $0200
 	sta $40		; ... low byte ($00) goes in address $40
 	lda #$02	
 	sta $41		; ... high byte ($02) goes into address $41
 	lda #$07	; colour number
 	ldy #$00	; set index to 0
 loop:	sta ($40),y	; set pixel colour at the address (pointer)+Y
 	iny		; increment index
 	bne loop	; continue until done the page (256 pixels)
        adc #$02        ; adding to accumulator 
 	inc $41		; increment the page
 	ldx $41		; get the current page number
 	cpx #$06	; compare with 6
 	bne loop	; continue until done all pages

   The result is 




3. Make each pixel a random colour. (Hint: use the psudo-random number generator mentioned on the 6502 Emulator page)

    Change the value of the accumulator inside the fist loop so in each iteration of the loop a different color would be loaded to the display. Below has the modified code. 

	lda #$00	; set a pointer in memory location $40 to point to $0200
 	sta $40		; ... low byte ($00) goes in address $40
 	lda #$02	
 	sta $41		; ... high byte ($02) goes into address $41
 	lda #$07	; colour number
 	ldy #$00	; set index to 0
 loop:	sta ($40),y	; set pixel colour at the address (pointer)+Y
        LDA $FE
 	iny		; increment index
 	bne loop	; continue until done the page (256 pixels)
 	inc $41		; increment the page
 	ldx $41		; get the current page number
 	cpx #$06	; compare with 6
 	bne loop	; continue until done all pages
    The result is 
                                                        
Experiments 

  1. Add this instruction after the loop: label and before the sta ($40),y instruction: tya
                                                        

 16 colours filling the display with 32 bits wide each repeating once. The color codes on the 6502 Emulator start with black, which is $0. In our loop, the TYA instruction transfers the Y register value to the accumulator, which starts at 0. As the loop runs, Y is incremented, so the accumulator will load new values, like $1 for white, and use them to change the screen color. The loop continues until $F, which is light gray. After 15 iterations, Y resets to 0, bringing the color back to black, and the cycle repeats.
                                                        
       3. Add this instruction after the tyalsr

        
This instruction shifts the bits of the A register one position to the right. The screen will have fewer unique colours, so every other colour will appear. 


5. Repeat the above tests with two, three, four, and five lsr instructions in a row. Describe and explain the effect in each case. 


.   

When increasing the lsr instructions in a row, the colours will continue to be less distinct, and the screen will show fewer and fewer colours, creating a blockier or more uniform visual pattern.

6. Repeat the tests using asl instructions instead of lsr instructions. Describe and explain the effect in each case.
.     
This will increase the values in A, causing a "zoom-in" effect on the color palette.

7. Revert to the original code.

8. The original code includes one iny instruction. Test with one to five consecutive iny instructions. Describe and explain the effect in each case. Note: it is helpful to place the Speed slider is on its lowest setting (left) for these experiments.

.     

      

The index value (Y) is used to reference the memory location, and changing the Y value will move through different positions in the memory or the bitmap.The visual effect will result in a faster "fill" of the screen, skipping certain pixels, and creating a sparser pattern with gaps between the filled pixels.

9.Revert to the original code.


Challenge:

1. Set all of the display pixels to the same colour, except for the middle four pixels, which will be drawn in another colour

LDA #$07 LDX #$00 LOOP: STA $0200, X STA $0300, X STA $0400, X STA $0500, X INX BNE LOOP LDA #$08 STA $03EF STA $03F0 STA $040F STA $0410
2. Write a program which draws lines around the edge of the display:
    • A red line across the top
    • A green line across the bottom
    • A blue line across the right side.
    • A purple line across the left size.



LDY #$04 LDX #$00 PURPLE_LOOP: TYA STA $0200, X STA $0300, X STA $0400, X STA $0500, X TXA ADC #$20 TAX CPX #$00 CLC BNE PURPLE_LOOP LDY #$06 LDX #$1F BLUE_LOOP: TYA STA $0200, X STA $0300, X STA $0400, X STA $0500, X TXA ADC #$20 TAX CPX #$1F CLC BNE BLUE_LOOP LDA #$05 LDX #$00 GREEN_LOOP: STA $05E0, X INX CPX #$20 BNE GREEN_LOOP LDA #$02 LDX #$00 RED_LOOP: STA $0200, X INX CPX #$20 BNE RED_LOOP

Comments

Popular posts from this blog

Project Stage 1

Lab05 - x86_64

Lab 03 - 6502 Program Lab (Revised)