DEV Community

Amir Mullagaliev
Amir Mullagaliev

Posted on

SPO600: First Lab

Introduction

This blog post dedicated to the very first lab in the SPO600 course. It includes solutions for all of the tasks, screenshots, and the thoughts that I have regarding whole process.

Throughout week number two we were learning basics of 6502 CPU, and 6502 Assembly. It is interesting and invaluable experience. Moreover, couple of years ago I wanted to learn assembly language, for the reason, that I'd been learning C++ where you have to manually allocate dynamic memory.

6502 CPU is an 8 bit microprocessor that has an address bus with width of 16 bit. Therefore, 16-bit address comprised with two 8-bit bytes.

Lab Description

Since we don't have a physical 6502 CPU chip, we work using an online emulator. I ain't going to dive very deep into 6502's theory because I still don't feel very comfortable with it, and I don't want to mislead people that are reading it.

For the first lab we have initial code that we have to analyze and manipulate in different ways. This is how it looks:

        lda #$00    
        sta $40     
        lda #$02    
        sta $41     
        lda #$07    
        ldy #$00    
 loop:  sta ($40),y 
        iny     
        bne loop    
        inc $41     
        ldx $41     
        cpx #$06    
        bne loop    
Enter fullscreen mode Exit fullscreen mode

At first it looks horrifying. However, when you know how everything works, you will find out that is pretty logical sequence of instructions.

This code fills the bitmap with yellow colour on every page. Where every page is 256 bytes. Here's the output:

Image description

As you can see, it filled the bitmap entirely (all 4 pages).

First Task

Calculate how long it takes for the code to execute, assuming a 1 MHz clock speed.

One of the sources provided by professor in the lab is documentation that helps to understand how many cycles and memory usage of each instruction.

I have created the spreadsheet that helped me to count, as professor presented us during the lab session.

Image description

I broke down the code in the first column, number of cycles in the second, and the number of iterations in the third. Obviously, you will ask what alt-cycles and alt-count mean. These are alternative number of cycles and iterations.

Why alternative?

As per documentation we can see that some of instructions under certain conditions are adding number of cycles for an instruction.

In the provided code BNE is the only instruction that has this unique ability.

Image description

It is screenshot from the documentation for BNE instruction. If you take a closer look the number of cycles is 2 + t + p, where p added if page is crossed, and t if branch is taken. It is tricky part, but since we know the size of each page, and it the bitmap four of these pages, we can calculate everything.

To calculate time, we need to understand that clock speed is 1MHz (million cycles per second). Therefore, one cycle takes 0.000001s, therefore, 11326 cycles takes 11326 * 0.000001s which results in 0.011326s or 11.326mS or 11326uS.

Second Task

Calculate the total memory usage for the program code plus any pointers or variables.

This task wasn't hard, I included my calculations to the spreadsheet. However, it wasn't necessary because this emulator provides the number of bytes to the console:

Image description

Third Task

Find one or more ways to decrease the time taken to fill the screen with a solid colour. Calculate the execution time of the fastest version of this program that you can create. Challenge: the fastest version is nearly twice as fast as the original version shown above!

It is really challenging part, especially with the language that you barely know. As per professor's words, the best solution in terms of performance is the most stupid one, so I started digging.

First of all, I looked at documentation of STA instruction because it has different parameters that we can pass, and it affects the number of cycles that instruction takes.

Image description

Unfortunately, it didn't help at all, and I realized that it wouldn't even help to cut-off half of the cycles. However, It pushed me to find other way, and I realized that each page can iterate independently, the only thing that changes is the Y that iterates.

Here's the code that I came up with:

; load accumulator with yellow color
lda #$07
; set y to 00
ldy #$00
loop:
; store y, in each page on each position
; within the pages
sta $0200, y
sta $0300, y
sta $0400, y
sta $0500, y
; increment y
iny
; loops until y isn't 0
bne loop
Enter fullscreen mode Exit fullscreen mode

Hopefully, all the comments clear and explain the principles of code. This solution cuts almost half of the operations:

Image description

Using the same technique, this spreadsheet shows that the number of cycles now is 6403. 11324 / 6403 ≈ 1.8. Therefore, this code 1.8 times faster, than initial version. I think that my solution perfectly fits requirements!

Forth Task

Change the code to fill the display with light blue instead of yellow.

For this task we will need a table of colour codes:

Image description

This task is simple as changing just one line of code, in my case it is first line, where we load accumulator with 7 or lda #$07, and change it to lda #$e. Code:

; load accumulator with yellow color
lda #$e
; set y to 00
ldy #$00
loop:
; store y, in each page on each position
; within the pages
sta $0200, y
sta $0300, y
sta $0400, y
sta $0500, y
; increment y
iny
; loops until y isn't 0
bne loop
Enter fullscreen mode Exit fullscreen mode

Bitmap Display:

Image description

Fifth Task

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

To solve this task, I decided to use initial code, where I can change colour every time page crossed. I was surprised that I found the solution fast.

The key point of this solution to understand that we are able to load accumulator with the value that matches page number – lda $41.

Solution:

; load accumulator with low-byte #$00
lda #$00
; store at address $40
sta $40
; load accumulator with high-byte #$02
lda #$02
; store at address $41
sta $41
; load Y register with #$00, to iterate further
ldy #$00
; load accumulator with color light-blue(#$0e)
lda #$0e
loop:
; store accumulator with value from
; address $40 + y
sta ($40), y
; increment y
iny
; iterate while y isn't 0
bne loop
; load accumulator with colors
; (#$02, #$03, #$04, #$05)
lda $41
; increment value at address $41
inc $41
; load x with value at address $41
ldx $41
; compare x with 6
cpx #$6
bne loop
Enter fullscreen mode Exit fullscreen mode

Bitmap Display:

Image description

Sixth Task

Make each pixel a random colour.

This is going to be the last task considered in this blog post, but we will continue in the next one. We will take a look at experiments and challenges professor proposed.

Let's get back to the task.

As per documentation, if we use lda $fe it generates one-byte pseudo-random number. Doesn't take much effort to execute, also using initial code. I added inside of the loop this instruction, so it gives every pixel a random colour.

Code:

; load accumulator with low-byte #$00
lda #$00
; store at address $40
sta $40
; load accumulator with high-byte #$02
lda #$02
; store at address $41
sta $41
; load Y register with #$00, to iterate further
ldy #$00
loop:
; store accumulator with value from
; address $40 + y
sta ($40), y
; load random color to accumulator
lda $fe
; increment y
iny
; iterate while y isn't 0
bne loop
; increment value at address $41
inc $41
; load x with value at address $41
ldx $41
; compare x with 6
cpx #$6
bne loo
Enter fullscreen mode Exit fullscreen mode

Bitmap Display:

Image description

Conclusion

It is really interesting experience to learn assembly. Epecially, when you start from simple versions like 6502. It is not easy to me, it requires a lot of reading, you cannot just dive into the code without theory. Moreover, assembly requires knowledge how hardware works. I will continue in my next blog with the rest of the lab experiments and the challenges!

Top comments (0)