Skip to content

Instantly share code, notes, and snippets.

@cellularmitosis
Last active December 12, 2021 17:17
Show Gist options
  • Save cellularmitosis/6f8e835efd856710f3019aec22ce3247 to your computer and use it in GitHub Desktop.
Save cellularmitosis/6f8e835efd856710f3019aec22ce3247 to your computer and use it in GitHub Desktop.
Some Easy6502 katas and solutions

Blog 2021/6/5

<- previous | index | next ->

Some Easy6502 katas and solutions

When it comes to learning a new language / platform / concept / etc in programming, being forced to solve problems (that is, being engaged) is far more effective than passively reading docs or watching tutorials.

Some good examples of this approach:

Another name for this learning approach is the code kata.

Here are some katas I've come up with for learning 6502 assembly, using the Easy6502 simulator. Paste in each solution, then click "Assemble", then click "Run".

The Easy6502 virtual machine

The Easy6502 machine comes with these notes:

Notes:

Memory location $fe contains a new random byte on every instruction.
Memory location $ff contains the ascii code of the last key pressed.

Memory locations $200 to $5ff map to the screen pixels. Different values will
draw different colour pixels. The colours are:

$0: Black
$1: White
$2: Red
$3: Cyan
$4: Purple
$5: Green
$6: Blue
$7: Yellow
$8: Orange
$9: Brown
$a: Light red
$b: Dark grey
$c: Grey
$d: Light green
$e: Light blue
$f: Light grey

Some additional 6502 resources:

Write a white pixel to the upper left corner of the screen (0,0)

 LDA #1     ; load an immediate (decimal 1) into the accumulator.
 STA $0200  ; store the accumlator to memory location 0x0200.
 BRK        ; done.

Write a cyan pixel to the lower right corner of the screen (31,31)

 LDA #3     ; load an immediate (decimal 3) into the accumulator.
 STA $05ff  ; store the accumlator to memory location 0x05FF.
 BRK        ; done.

Write all 16 colors in a line of pixels at the top of the screen

The linear approach, using decimal values:

 LDA #0   ; black
 STA 512  ; pixel (0,0)
 LDA #1   ; white
 STA 513  ; pixel (0,1)
 LDA #2   ; red
 STA 514  ; pixel (0,2)
 LDA #3
 STA 516
 LDA #4
 STA 517
 LDA #5
 STA 518
 LDA #6
 STA 519
 LDA #7
 STA 520
 LDA #8
 STA 521
 LDA #9
 STA 522
 LDA #10
 STA 523
 LDA #11
 STA 524
 LDA #12
 STA 525
 LDA #13
 STA 526
 LDA #14
 STA 527
 LDA #15
 STA 528
 BRK

The linear approach, using hex values:

 LDA #$0    ; black
 STA $0200  ; pixel (0,0)
 LDA #$1    ; white
 STA $0201  ; pixel (0,1)
 LDA #$2    ; red
 STA $0202  ; pixel (0,2)
 LDA #$3
 STA $0203
 LDA #$4
 STA $0204
 LDA #$5
 STA $0205
 LDA #$6
 STA $0206
 LDA #$7
 STA $0207
 LDA #$8
 STA $0208
 LDA #$9
 STA $0209
 LDA #$A
 STA $020A
 LDA #$B
 STA $020B
 LDA #$C
 STA $020C
 LDA #$D
 STA $020D
 LDA #$E
 STA $020E
 LDA #$F
 STA $020F
 BRK

Using a loop:

 LDA #0       ; use the accumulator to store the color.
 LDX #0       ; use X to store the pixel index.
 STA $0200,X  ; write the first pixel at (0,0).
loop:
 ADC #1       ; increment the color.
 INX          ; increment the pixel index.
 STA $0200,X  ; write the pixel
 CPX #15      ; if X != 15, loop.
 BNE loop
 BRK          ; else, done.

Fill the top line with red pixels

 LDA #2       ; red
 LDX #0       ; pixel offset
 STA $0200,X
loop:
 INX
 STA $0200,X
 CPX #31      ; if X != 31, loop.
 BNE loop
 BRK          ; else, done.

Fill the first eight lines with purple pixels

Because pixel index wraps to the next line automatically, we can reuse the previous solution but count up to 255 instead of 31:

 LDA #4
 LDX #0
 STA $0200,X
loop:
 INX
 STA $0200,X
 CPX #255
 BNE loop
 BRK

Fill the screen with green pixels

This is a bit trickier because we need to write 1024 pixels, but the registers can only count up to 255.

Our first approach might be to simply use four copies of the previous solution, with each one starting on a different "page" of memory:

 LDA #5       ; green

; fill pixels 0x0200 through 0x02FF
 LDX #0
 STA $0200,X
loop1:
 INX
 STA $0200,X
 CPX #$FF
 BNE loop1

; fill pixels 0x0300 through 0x03FF
 LDX #0
 STA $0300,X
loop2:
 INX
 STA $0300,X
 CPX #$FF
 BNE loop2

; fill pixels 0x0400 through 0x04FF
 LDX #0
 STA $0400,X
loop3:
 INX
 STA $0400,X
 CPX #$FF
 BNE loop3

; fill pixels 0x0500 through 0x05FF
 LDX #0
 STA $0500,X
loop4:
 INX
 STA $0500,X
 CPX #$FF
 BNE loop4

 BRK

If we use indirect indexed addressing, we can store the page number in memory and repeat the inner loop four times:

 LDA #5      ; green

; store the value 0x0200 starting at address 0x0000. 
 LDX #$00
 STX $0
 LDX #$02
 STX $1

; the inner loop: write 8 lines of pixels.
 LDY #0
 STA ($0),Y
loop:
 INY
 STA ($0),Y
 CPY #$FF
 BNE loop

; the outer loop: increment the pixel page and restart the inner loop.
 LDX $1
 INX
 STX $1
 CPX #6    ; repeat the inner loop for pages 3, 4, and 5.
 BNE loop

 BRK
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment