On that note, I would very much love to get good enough at this to engage in reverse engineering and "source code archaeology" of some of my favorite C64 games to better understand how they work. That's entirely aspariational, right now I'm struggling with "Hello World."
I found a working example of "Hello World" for the C64 and decided to change it and "make it my own." After struggling with several possible assemblers starting with ca65 I eventually settled on 64tass, though ACME was a very close second.
I started by taking that GitHub snippet and determining to understand every part of every line of code. So far, I've done fairly well. After consulting a C64 memory map, I replaced some raw values with human friendly constant names and made sure the character position code could be easily incremented; originally it just skipped a location in lieu of encoding a space character.
With all of that said, here are my questions:
- How do I get tass to simulate a loop for sta VICSCN+n until I run out of characters in "Hello World" using my current code as a starting point?
- In this version of the code, why am I (confusingly) stuck with using screen codes instead of PETSCII character codes? That fact really threw me for a bit.
- When I set *=$0810 my code "just works." A lot of example code I see online uses *=$1000 instead which never seems to work as intended when assembled with tass. Why might that be? I'll test again, but I'm 99% sure I changed the SYS call to the correct memory location when I attempted to move the *= (program counter?) to 1000.
Code: Select all
; 64TASS
; hello.asm
KERNAL_CLEAR_SCREEN = $e544 ; KERNAL ROM routine.
VICSCN = $0400 ; VIC-II Screen Video Matrix, 1024 (int).
; BASIC loader.
*=$0801 ; The two byte load address at the start of the .PRG file.
.byte $0b, $08 ; Linked list pointer to next line of BASIC.
.byte $d9, $07 ; 2009 (int) line number (LO, HI).
.byte $9e ; BASIC SYS token.
.text "2064" ; Memory address (int) to start of ASM: $0810
; ASM code.
*=$0810 ; The start of ASM execution.
jsr KERNAL_CLEAR_SCREEN
; Enter HELLO WORLD into screen memory ($0400-$07e7) (1024-2023).
lda #8 ; 'H' Screen Code
sta VICSCN + 0 ; 'H' in $0400 screen memory
lda #5 ; 'E' Screen Code
sta VICSCN + 1 ; 'E' in $0400+1 screen memory
lda #12 ; 'L' Screen Code
sta VICSCN + 2 ; 'L' in $0400+2 screen memory
lda #12 ; 'L' Screen Code
sta VICSCN + 3 ; 'L' in $0400+3 screen memory
lda #15 ; 'O' Screen Code
sta VICSCN + 4 ; 'O' in $0400+4 screen memory
lda #32 ; ' ' Screen Code
sta VICSCN + 5 ; ' ' in $0400+5 screen memory
lda #23 ; 'W' Screen Code
sta VICSCN + 6 ; 'W' in $0400+6 screen memory
lda #15 ; 'O' Screen Code
sta VICSCN + 7 ; 'O' in $0400+7 screen memory
lda #18 ; 'R' Screen Code
sta VICSCN + 8 ; 'R' in $0400+8 screen memory
lda #12 ; 'L' Screen Code
sta VICSCN + 9 ; 'L' in $0400+9 screen memory
lda #4 ; 'D' Screen Code
sta VICSCN + 10; 'D' in $0400+10 screen memory
rts ; All programs must end with Return To Subroutine (RTS).