For people born in the seventies, 6502 is a magic number. It was the name of one of the most used processors in electronic devices of the eighties such as the Apple 2, the commodore 64, the nintendo NES e.t.c.

For me everything started there. I did not write any assembly codes for years but at the beginning of my career, this was still something you write on a résumé.

Writing 6502 codes in the old days was a nightmare. Some assembler tools like MERLIN helped a lot but it has nothing in common with the modern technology we are using nowadays.

Limitations include:

  • This is a 8 bits processor, so it can only add numbers between 0 and 255. Overflows must be checked manually to handle additions that result in a number bigger than 255.
  • There was no memory protection. It was possible to write anywhere in the memory. It was even possible to change the instructions of your own software dynamically.
  • The stack was limited to 256 bytes.
  • The main memory of this kind of machines most often don’t exceed 64 KB including the video memory.
  • The regular clock speed of the 6502 was 1Mhz

Even with all these limitations, it was possible to write incredible software by using tricks that did not make the code easily maintainable but make it efficient.

While I was browsing on the internet, I ended up on a site that has a wonderful javascript emulator of the 6502. I definitively advice to read it and play with it, as it makes a wonderful introduction to assembly language. At the end, you will find a fully playable snake game using less than 700 bytes of code.

So I will add a small example of how to create  a FillRect subroutine using this processor. Note that the emulator uses a low resolution graphic mode that starts at memory $200, is 0x20 pixels large and has 20 lines. So the third pixel of line 2 is at address 200+20+2 => $222.

The following program will draw three rectangles using page zero to pass parameters to the subroutines.

 ; FIRST RECT
 LDA #$0A ; WIDTH
 STA $10
 LDA #$0F ; HEIGHT
 STA $11
 LDA #$24 ; UPPER RIGHT CORNER ADDRESS in memory LOWER BYTE
 STA $12
 LDA #$02 ; LOWER RIGHT CORNER ADDRESS in memory LOWER BYTE
 STA $13
 LDA #$0F ; COLOR
 STA $14
 JSR fillrect

; SECOND RECT
 LDA #$14 ; WIDTH
 STA $10
 LDA #$04 ; HEIGHT
 STA $11
 LDA #$07 ; UPPER RIGHT CORNER ADDRESS in memory LOWER BYTE
 STA $12
 LDA #$03 ; LOWER RIGHT CORNER ADDRESS in memory LOWER BYTE
 STA $13
 LDA #$02 ; COLOR
 STA $14
 JSR fillrect

; THIRD RECT
 LDA #$7 ; WIDTH
 STA $10
 LDA #$0F ; HEIGHT
 STA $11
 LDA #$12 ; UPPER RIGHT CORNER ADDRESS in memory LOWER BYTE
 STA $12
 LDA #$04 ; LOWER RIGHT CORNER ADDRESS in memory LOWER BYTE
 STA $13
 LDA #$03 ; COLOR
 STA $14
 JSR fillrect

BRK

;============ DRAW LINE
 ; COLOR IS STORED at ADDRESS $14
 ; WIDTH of the line at ADDRESS $10
 ; START POINT at ADDRESS $12 (Indirect 2 bytes)
 ;============ DRAW LINE

drawline:
 LDA $14 ; LOAD THE COLOR IN A
 LDY $10 ; LOAD WIDTH IN Y
 drawlineloop:
 STA ($12),Y ; STORE A AT ADDRESS (POINTED BY $12)+Y
 DEY ; DECREMENT Y
 CPY #$00 ; IS THE LINE FINISHED
 BNE drawlineloop
 RTS

;============ FILL RECT
 ; COLOR IS STORED at ADDRESS $14
 ; WIDTH of the rect at ADDRESS $10
 ; HEIGHT of the rect at ADDRESS $11
 ; START POINT at ADDRESS $12 (Indirect 2 bytes)
 ;============ FILL RECT

fillrect:
 LDX $11 ; HEIGHT
 fillrectloop:
 JSR drawline
 DEX ; DECREMENT HEIGHT
 LDA $12 ; LOWER BYTE OF START POINT
 CLC ; CLEAR CARRY
 ADC #$20 ; MOVE TO THE NEXT LINE
 BCC nocarry ; BRANCH IF NO CARRY
 INC $13 ; IF CARRY THEN ADD 1 TO THE HIGHER BYTE
 nocarry:
 STA $12 ; STORE THE LOWER BYTE
 CPX #$00 ; IS IT THE LAST LINE ?
 BNE fillrectloop
 RTS

Simply copy the code in the source in one of the emulators available here.You should end up after pushing the “assemble” and then the “run” button with the nice picture below.

Screen Shot 2017-08-25 at 18.30.32

Note that the full code is 104 bytes long but that the two routines (Fill rect and drawline) only use 33 bytes ! There are other ways to write the same code and it is probably not the most efficient one, but at least it is readable.

For old geeks note that Jordan Mechner, developper of eighties games such as Karateka and Prince of Persia, open sourced the Apple 2 code of Prince of Persia, which definitively pushed the Apple 2 to its limits.

Happy coding 🙂