Preface

This is 3rd post dedicated to the Lab #1 for Software Portability and Optimization course. I highly suggest to read last two blogs from this series to understand what's going on here

TL;DR

In the last two posts I've been going through Lab#1 and it's experiments in 6502 assembly language. Everything has been solved and explained, it was really interesting!

Introduction

In this post I discuss all the optional challenges provided, I decided to walk through them to gain some more knowledge, and probably learn new concepts. However, it is not a huge post since we only have two challenges provided.

To refresh your memory I will once again provide and explain you the initial code for this lab:

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

This code using the loop fulfills the bitmap with a single colour, all four pages.
Result:

I explained how it works in one of the previous blogs.

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.

After reading this challenge description, first thing that comes in mind, I have to learn what addresses belong to those middle four pixels. Fortunately, professor provided us the table representing every single pixel with it's corresponding address:

6502 Emulator Bitmapped Screen Memory Map - Google Sheets

favicon

docs.google.com

It helps us to understand that we need following addresses to be filled after the whole screen has been filled with one colour: $$03Ef $03F0 $040f $0410.

Eventually, I came up with this 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 #$04    ; 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

  lda #$03
  sta $03Ef
  sta $03F0
  sta $040f
  sta $0410

I decided to use the easiest solution possible, just by filling these four pixels after the initial loop.

Result:

Challenge #2

Write a program which draws lines around the edge of the display:A red line across the topA green line across the bottomA blue line across the right side.A purple line across the left size.

This challenge is the hardest, I had to make a huge research on how to execute it, but here's the code and the result.

Code:

; Red line across the top ($0200-$021F)
    lda #$02        ; red color
    ldx #$00
top:
    sta $0200,x     ; write to first row
    inx
    cpx #$20        ; done 32 pixels?
    bne top

    ; Green line across bottom ($05E0-$05FF)
    lda #$05        ; green color
    ldx #$00
bottom:
    sta $05E0,x     ; write to last row
    inx
    cpx #$20        ; done 32 pixels?
    bne bottom

    ; Purple line on left side
    lda #$04        ; purple color
    lda #$00        ; start with low byte
    sta $40
    lda #$02        ; start with page 2
    sta $41
left:
    ldy #$00        ; left column
    lda #$04        ; purple color
    sta ($40),y
    clc             ; add 32 to address
    lda $40
    adc #$20
    sta $40
    bcc skip1       ; handle carry
    inc $41
skip1:
    lda $41
    cmp #$06        ; check if done
    bne left

    ; Blue line on right side
    lda #$00
    sta $40
    lda #$02
    sta $41
right:
    ldy #$1F        ; right column
    lda #$06        ; blue color
    sta ($40),y
    clc             ; add 32 to address
    lda $40
    adc #$20
    sta $40
    bcc skip2       ; handle carry
    inc $41
skip2:
    lda $41
    cmp #$06        ; check if done
    bne right

Result:

Main code changes are:

  • I used direct approach to draw top and bottom lines because it requires adding 32 to our address($20) , and indirect to draw right and left sides because we need to fill consecutive pixels in memory
  • I had to properly handle page transition with carry checks
  • To draw vertical lines I had to properly carry to the high byte

Conclusion

In conclusion, I want to say that this lab gave me a lot of knowledge of 6502 assembly, and helped me to concrete them. Overall, I enjoy learning new concepts that will help me in the future to understand how machines work in the low-level!

Author Of article : Amir Mullagaliev Read full article