SPO600 Software Portability & Optimization Lab01
Hello viewer and welcome to my blog on SPO600 - Software Portability and Optimization Lab01. My name is Victor and I am a student at Seneca College Newnham, this blog is to document my learning and findings I have for my labs.
In lab 01, we are working with 6502 Processor developed by MOS technology. the 6502 was a cheap solution to a problem introduced due to overpriced micro processors. During this lab I will be performing some experiments and documenting the results with code on the 6502 processor using assembly language.
We will be following data provided by Masswork for the clock cycles of the 6502 instruction set. The 6502 has 56 instructions in total, each taking different cycles based on the 13 different addressing modes available, the clock cycle information can be found here.
We are asked to put this code into the 6502 emulator:
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
Here is a more layman description and breakdown of what is happening:
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
LDA is the Load Accumulator instruction, it will take the value and based on the addressing mode put that value into the accumulator. here we are using the # symbol, indicating we want to store the immediate value of 00. We also use this again later to store other values into the accumulator with their immediate values.
Since the 6502 has a 16-bit address bus, we require two bytes of memory to express an address. There is also the low byte and the high byte of an address, and since the 6502 processor uses little endian, we need to store the least significant digit first, and the most significant digit last for a memory address. Here we are loading the accumulator with the immediate value of #$00, which is denoted by the # symbol, and then storing the accumulator at memory location $40. We then load the accumulator with the high byte of #$02 and storing that into the memory location of $41, We then load the accumulator with the immediate value of #$07 which is the color code for yellow, and load the y register with the immediate value of #$00. This is telling our Y register to start at 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
Here we are defining a loop, that will use the indirect addressing mode for the STA instruction, this line will tell our program to store the value in accumulator(07) at the address pointing at memory location $40, since the address pointing to $40 is 0020 in little endian it will be storing the value at $0200, the y is the value being added to that address, so if Y is 0, we store 07 at $0200, if y is 5, we store the 07 at $0205. We then increment the Y value and loop through. Since we use a BNE(Branch if not equal) we run through the loop until Y overflows, going back to 0 and setting the Z flag to 1.
After breaking out of the loop we increment the value at $41, which is our page index, load that into the X register, and compare it with the immediate value of #$06. Since the bitmap portion of the display starts at $0200 and ends at $05FF, we have 4 pages of 256 bytes each page. What we are doing with the compare instruction is while the value at memory location $41 is not 6, we will branch back to the loop, and since we increased the value in $41, we will be on the next page, which after the first increment $41 will be 03. So now our loop continues, and starts coloring 256 pixels starting from the $0300 address. We continue this loop until all the values from $0200 - $05FF are fill and stop the program.
We are then asked to calculate the performance of the program. Here is a spreadsheet with the calculation:
Based on the information about cycle times provided in the link above, we can see than this program takes 11308 cycles to perform, which equates to 0.01 seconds to execute.
While this is fast in itself, we are tasked with a challenge to make the program faster. After days of experimenting, giving up, and re-trying, I have managed to get it to be 44% faster with the following instructions:
We are then asked to change the color from yellow to a light blue. We therefore change the LDA #$07 instruction to be LDA #$0E. A list of colors can be found here.
We are then asked to change each pages color to a different color, I achieved this by setting the color in the accumulator in the loop before each STA operation.
This concludes the lab but there are optional experiments we could attempt:
Experiments
Adding TYA to the program:
This effect occurs because TYA transfers the Y value to the Accumulator, hence the LDA #$07 instruction we have at the start is useless. There are now 16 colors repeated twice on the screen. This is because we only have values from 0-f (0-15) for colors but have 32 bytes across.
There are now 15 different color possibilities on the screen as when it gets to F (Light Grey) it overflows back to 0 (Black).
Adding LSR to the program:
This effect occurs because LSR Shifts one bit right, which im not entirely sure but my assumption is that it is now storing the value of the accumulator into a 16 bit location rather than the 8 bit location, which would make sense because of the memory output:
Notice how the values span 2 bytes rather than 1.
Challenges
Set all of the display pixels to the same colour, except for the middle four pixels, which will be drawn in another colour.
Thanks to the excel provided with the already mapped screen provided here, we can figure out what address specifically need to be a different color and color them in after the loop.
Overall I found this first lab difficult as I have never worked with assembly language previously and it took me a while to complete due to me trying to learn the topic fresh. I chose SPO600 to learn assembly language to get into game modding but that might be quite a while away from my skills.
Comments
Post a Comment