SPO600: Lab01 Experiments
Introduction If you didn't read my last post, I would suggest to read it before proceeding to this one. However, if for some reasons you don't want or cannot do it, I will quickly explain what is going on. Currently, I'm working on lab01 for Software Portability and Optimization course where we learn 6502 Assembly. In the previous post, I had some tasks regarding optimization of the code that had been provided by professor, and as result I provided code, solution and explanations. In this blog, I write about some experiments and challenges, also provided by professor which are part of the lab. They are really interesting and worth your attention. Let's begin with experiments. Experiments Before I start all the experiments, I would like to share initial code we have that fills the bitmap entirely. I will not share the code in the experiments, only results and explanations, as the instructions are clear. 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 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 First Experiment Add this instruction after the loop: label and before the STA ($40),Y instruction: TYA First thing first, I check what does TYA instruction mean in the documentation: What I understand from the description is that every time we loop, the accumulator will receive value of Index Y, every page has 256 bits. As we know 6502 assembly uses hex-decimal values, from 00 to ff(255 decimal.) We could assume that there is going to be a mess of pixels, but not. For the reason, that we have 32 bits on each row, and hex-decimal number of index Y changes colour non-repetitively only 16 times since index Y changes it's lower bit value in a such sequence: 00 -> 01 -> ... -> 0e -> 0f -> 10 You may notice that the lowest byte becomes zero again, and this one determines colour. Therefore, the highest byte doesn't play role in dyeing bits. Eventually, we will get 32 columns of coloured bits where colour repeats once every 16 bits! Result: Second Experiment Add this instruction after the TYA: LSR I take the same path and read the documentation regarding LSR instruction: This description helps me a lot to come up with the result. If you didn't understand, I will help you. By shifting to the right, it produces devision by 2, so we divide index Y by 2. We will get following sequence: Y = 0 to 1 => A = 0 .. Y = 2 to 3 => A = 1 .. Y = 3 to 4 => A = 2 and so on Eventually, we get 16 columns and 2 pixels wide of non-repetitively coloured bits. Result: Third Experiment Repeat the above tests with two, three, four, and five LSR instructions in a row. Describe and explain the effect in each case. Two LSRs If we take a look at previous experiment, we can come up with an answer really quick. For the reason, that using two LSRs will result in A = Y/2^2 => A = Y/4, so we will have in each row 8 columns of non-repetitive colours, and the colour set will be repeating itself every 2 rows. Result: Three LSRs A = Y/2^3 => A = Y/8, therefore, we will get 4 colours 8 bits wide in each row, colour set will repeat every 4 rows. Result: Four LSRs A = Y/2^4 => A = Y/16`, therefore, we will get 2 colours 16 bits wide in each row, colour set will repeat every 8 rows. Result: Five LSRs A = Y/2^5 => A = Y/32, therefore, we will get 1 colour 32 bits wide in each row, colour set will repeat every 16 rows. Result: Fourth Experiment Repeat the tests using ASL instructions instead of LSR instructions. Describe and explain the effect in each case. Lets take a look at the description of the ASL instruction: If we shift left, it should be opposite to shift right, so my assumption is that we will get formula: A = Y * 2^(number of ASLs) Single ASL Following formula withdrawn above A = Y * 2, so we will have 32 columns where colour set repeats every 8 bits, therefore there are 8 colors. Result: Two ASLs Knowing the formula, its easy to understand what's going to happen. A = Y * 2^2 => A = Y * 4, therefore, we get 32 columns where colour set of 4 colours repeats every 4 bits. Result: Three ASLs A = Y * 2^3 => A = Y * 8, therefore, we get 32 columns where colour set of 2 colours repeats every 2 bits. Result: Four ASLs A = Y * 2^4 => A = Y * 16, therefore, we get bitmap filled with only one colour, and it's black. For the reason, that we only have 16 colours, and accumulator picks only 0 as the lowest byte. Result:
Introduction
If you didn't read my last post, I would suggest to read it before proceeding to this one. However, if for some reasons you don't want or cannot do it, I will quickly explain what is going on.
Currently, I'm working on lab01
for Software Portability and Optimization
course where we learn 6502 Assembly
. In the previous post, I had some tasks regarding optimization of the code that had been provided by professor, and as result I provided code, solution and explanations.
In this blog, I write about some experiments and challenges, also provided by professor which are part of the lab. They are really interesting and worth your attention. Let's begin with experiments.
Experiments
Before I start all the experiments, I would like to share initial code we have that fills the bitmap entirely. I will not share the code in the experiments, only results and explanations, as the instructions are clear.
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
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
First Experiment
Add this instruction after the
loop:
label and before theSTA ($40),Y
instruction:TYA
First thing first, I check what does TYA
instruction mean in the documentation:
What I understand from the description is that every time we loop, the accumulator will receive value of Index Y
, every page has 256 bits. As we know 6502 assembly
uses hex-decimal
values, from 00 to ff(255 decimal.)
We could assume that there is going to be a mess of pixels, but not. For the reason, that we have 32 bits on each row, and hex-decimal number of index Y
changes colour non-repetitively only 16 times since index Y
changes it's lower bit value in a such sequence:
00 -> 01 -> ... -> 0e -> 0f -> 10
You may notice that the lowest byte becomes zero again, and this one determines colour. Therefore, the highest byte doesn't play role in dyeing bits.
Eventually, we will get 32 columns of coloured bits where colour repeats once every 16 bits!
Result:
Second Experiment
Add this instruction after the
TYA
:LSR
I take the same path and read the documentation regarding LSR
instruction:
This description helps me a lot to come up with the result. If you didn't understand, I will help you. By shifting to the right, it produces devision by 2, so we divide index Y
by 2.
We will get following sequence:
Y = 0 to 1 => A = 0 .. Y = 2 to 3 => A = 1 .. Y = 3 to 4 => A = 2 and so on
Eventually, we get 16 columns and 2 pixels wide of non-repetitively coloured bits.
Result:
Third Experiment
Repeat the above tests with two, three, four, and five
LSR
instructions in a row. Describe and explain the effect in each case.
Two LSRs
If we take a look at previous experiment, we can come up with an answer really quick. For the reason, that using two LSRs
will result in A = Y/2^2 => A = Y/4
, so we will have in each row 8 columns of non-repetitive colours, and the colour set will be repeating itself every 2 rows.
Result:
Three LSRs
A = Y/2^3 => A = Y/8
, therefore, we will get 4 colours 8 bits wide in each row, colour set will repeat every 4 rows.
Result:
Four LSRs
A = Y/2^4
=> A = Y/16`, therefore, we will get 2 colours 16 bits wide in each row, colour set will repeat every 8 rows.
Result:
Five LSRs
A = Y/2^5 => A = Y/32
, therefore, we will get 1 colour 32 bits wide in each row, colour set will repeat every 16 rows.
Result:
Fourth Experiment
Repeat the tests using
ASL
instructions instead ofLSR
instructions. Describe and explain the effect in each case.
Lets take a look at the description of the ASL
instruction:
If we shift left, it should be opposite to shift right, so my assumption is that we will get formula:
A = Y * 2^(number of ASLs)
Single ASL
Following formula withdrawn above A = Y * 2
, so we will have 32 columns where colour set repeats every 8 bits, therefore there are 8 colors.
Result:
Two ASLs
Knowing the formula, its easy to understand what's going to happen.
A = Y * 2^2 => A = Y * 4
, therefore, we get 32 columns where colour set of 4 colours repeats every 4 bits.
Result:
Three ASLs
A = Y * 2^3 => A = Y * 8
, therefore, we get 32 columns where colour set of 2 colours repeats every 2 bits.
Result:
Four ASLs
A = Y * 2^4 => A = Y * 16
, therefore, we get bitmap filled with only one colour, and it's black. For the reason, that we only have 16 colours, and accumulator picks only 0 as the lowest byte.
Result:
Five ASLs
I don't know if this makes sense to provide a result of multiplication of Y by 32, but I will do it. The same answer because accumulator still picks up only the lowest byte 0 exclusively!
Result:
Fifth Experiment
The original code includes one
INY
instruction. Test with one to five consecutiveINY
instructions. Describe and explain the effect in each case.
Following the documentation we know that INY
instruction means Increment Index Register Y by One
.
We know what happens with one incrementation of Index Y
, so we will skip it, and move into two incrementations.
Two INYs
It is pretty logical, my assumption is that we will have two colors on the screen: yellow and black. For the reason, that we skip every second column, and the accumulator simply doesn't fill them and leaves it empty.
Result:
Three INYs
Now it is getting interesting. You may assume that the gap between lines is going to be bigger, however not. When Index Y
increments by 3, it skips 00
condition twice.
First time it follows this pattern: Y = 00, 03, 06, 09, 0c... etc.
. However, once it reaches FF
, during next iteration, it jumps to 02
, and fill everything starting from Y = 02, 05, 08, 0b... etc.
Therefore, it doesn't take a branch twice, but after the third iteration, it moves onto next page. Eventually, filling the entire bitmap. It looks beautiful! Try code provided, but don't forget to add two more INY
instructions in emulator, it will look really satisfying. I promise!
Result:
Four INYs
This time it takes the branch every time, for the reason, that 256/4 will produce the whole number. Eventually, we get 4 bits gap between yellow coloured bits!
Result:
Five INYs
With incrementation by 5, we will see the same result as with incrementation by 3. The process looks satisfying, but as the result you get fully filled bitmap.
Result:
Conclusion
To walk through the experiments was fun, and understanding the results of experiments was interesting. It is one of the best ways to learn. When you test something yourself, and then digging by adding breaks to understand what just happened is the brilliant teaching strategy by our professor! I want to thank him for it because I have a clear understanding of what I've just done!
Although, I wanted include to this blog the Challenges
part, but Experiments
took most of it. However, I decided to write the third post dedicated to Lab01
which is essentially good because blogs help me understand concepts better. As one of my school teachers said:
If you want to make sure that you learned something, try to explain!
The third post will come out shortly! Will catch y'all later :)
What's Your Reaction?