Lions remember very little about C64 development. load "$",8 loads a directory listing into the program space. PRG files are programs. SEQ files are data. Assembly language programs tended to be stored in SEQ files. There was 1 PRG file for starting. load with ,8,1 was required for assembly language. The mane wrinkle was the many addressing modes enabled by the X Y index registers. You'd load 8 bit offsets into those & use LDA STA variants which add those to the address. There are no 16 bit registers, which lions tend to confuse with the 68HC11 which had a 16 bit X Y & accumulator.
Assembly language arguments in ca65 are:
$01 dereference a value in a hex address
1234 dereference a value in a decimal address
#$34 a literal in hex format
#%01010101 a literal in binary
#123 a literal in decimal format
< provides the low byte of a literal
> provides the high byte of a literal
Enclosing the agrument in various parenthesis POINTER,X (POINTER) (POINTER),Y (POINTER,X) invokes different addressing modes described in http://www.emulator101.com/6502-addressing-modes.html.
POINTER,X Add X to pointer to get POINTER2. Dereference the value in POINTER2. POINTER is a 16 bit or 8 bit address. There are different opcodes for the 16 bit & 8 bit variant. The 8 bit variant wraps at 256 (zero page memory). This works with X or Y.
(POINTER) Read the address stored in POINTER to get POINTER2. Dereference the value in POINTER2. POINTER is a 16 bit address. This only works with GOTO.
(POINTER,X) add X to POINTER to get POINTER2. Dereference the address in POINTER2. POINTER is limited to zero page memory. This works with X only.
(POINTER),Y Dereference the address stored in POINTER to get POINTER2. Add Y to POINTER2 to get POINTER3. Dereference the address in POINTER3. POINTER is limited to zero page memory. This works with Y only.
Double & triple pointers were the key to accessing large amounts of memory with 8 bit registers. They had special instructions for accessing the 1st 256 bytes of memory (zero page). You'd ideally have all your variables in that space. 16 bit POINTER,X was the only indexing mode lions could understand 40 years ago.
A starting point is to call into the C library to print something.
.autoimport on ; imports _cprintf, pushax .forceimport __STARTUP__ ; imports STARTUP, INIT, ONCE .export _main ; expose mane to the C library .segment "RODATA" _Text: ; PETSCII text to print .byte $C8,$45,$4C,$4C,$4F,$20,$57,$4F,$52,$4C,$44,$21,$00 .segment "CODE" .proc _main: near lda #<(_Text) ; low byte function argument ldx #>(_Text) ; high byte function argument jsr pushax ; put function arguments on stack ldy #$02 ; size of function arguments (2 bytes) jsr _cprintf ; C library function .endproc
The trick with this is it uses PETSCII instead of ASCII.
The pushax function is a beast in libsrc/runtime/pushax.s
There's a command to assemble it.
ca65 -t c64 hello.s
Then link it with the standard C library.
ld65 -t c64 hello.o -o hello c64.lib
The executable doesn't end in .prg but is a PRG file anyway. It's an utterly gigantic 2108 bytes for what it does, probably because cprintf has to parse formatting codes. There is a simpler _puts function.
lda #<(string)
ldx #>(string)
jsr _puts
The trick with the C library is compiling C programs to figure out the function arguments. Cc65 generates a .s file with the assembly language function calls. The mane C function of note is cprintf.
For fast development on the emulator, the journey begins by creating a disk image
c1541 -format "disk,00" d64 disk.d64
Store the program in the disk image.
c1541 -attach disk.d64 -write hello hello,p
Then the emulator can automatically run the 1st program on the disk image.
x64 -VICIIdsize -ntsc -warp -autostart disk.d64
The C library puts it into lowercase mode. Left CTRL + SHIFT toggles the case. Left CTRL is the commodore key.
There's a command for listing the directory so you don't have to fight the emulator.
c1541 -attach disk.d64 -list
The only way to get it to load a file other than the 1st one is to make a script.
The emulator has always randomly dropped keypresses in addition to crashing some games. It may be that these games always crashed.
The trick with the emulator is even without the bugs, audio can never be synchronized with video as it was. Modern sound drivers are all based on buffers while the SID was a direct analog synthesizer tied to registers.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.