Using xa65 assembler to create Commodore 64 .prg
Asked Answered
B

3

12

I am trying to learn 6510 assembly and since I am running Debian xa65 is the assembler I want to use.

I have so far written a piece of code that looks like so:

*=$0801
.byte $0c, $08, $0a, $00, $9e, $20
.byte $34, $30, $39, $36, $00, $00
.byte $00

*=$1000
INC 53280
INC 53281
JMP $1000

Now, the first .byte section are suposed to "autostart" the program once loaded. This is something I found from a tutorial and as far as I can understand it will only run SYS 4096 making the CPU start executing the code at address $1000

The rest of the code should simply start flickering the outer and inner border of the C64 and repeat forever.

When assembling this I simply run the following:

xa test.s -o test.prg

and then I try to load test.prg into VICE to test it. with LOAD "TEST.PRG",8,1: and even if the file loads it does not autostart, nothing happens if i type RUN: and the same if I type LIST: - the only result is the famous READY. and the cursor flashing very happily like usual.

I tried to remove the autostart stuff and assembled only the code starting from *=$1000 but I got the same results. Trying to start with SYS 4096 also results in READY and nothing more.

I am sure I am not using the xa assembler right, but I can't figure out how I do create a proper PRG file for the C64 to use. What am I doing wrong?

Bannock answered 31/1, 2015 at 10:37 Comment(1)
FWIW the sequence $34, $30, $39, $36 is simply the ASCII (PETSCII) encoding for 4096 If you want to load your machine code somewhere else, you can just change that. The $9E is the Basic token for SYS. The $0a $00 is the line number (10). The $0c, $08 is the address of the start of the next line.Venusian
T
9

I was trying to figure out how to make xa65 pad its output when I came across your question and have since learned how it works. Here's what I've found.

As jester said, your code won't be at $1000 since setting the PC doesn't perform any padding. Padding is supported in xa65 using the .dsb directive, but a number of bytes must be specified for the directive rather than just an address like some assemblers' .org directive allows. Since the assembler allows for simple arithmetic, the number of bytes is given by <desired address> - PC.

Adding the missing .prg address header and changing your second PC change to a padding directive results in output that behaves as expected. However, this still doesn't make it autostart. LOAD "TEST.PRG",8,1: and RUN does work, though.

.byte $01, $08 ; Load this .prg into $0801

*=$0801
.byte $0c, $08, $0a, $00, $9e, $20
.byte $34, $30, $39, $36, $00, $00
.byte $00

.dsb $1000 - * ; Pad with zeroes from PC to $1000

INC 53280
INC 53281
JMP $1000

FWIW, how to use the padding method wasn't immediately obvious in xa65's documentation (to me, at least).

Tandy answered 2/7, 2015 at 19:41 Comment(1)
Thanks a lot - this made my day (or night rather)Bannock
P
6

As far as I remember, $0801 was the start address of basic programs and that doesn't autostart anything. To autostart, you had to play tricks.

Just assemble for $1000 and start your program using sys 4096. A frequently used area for assembly helpers was $c000 (sys 49152) as that doesn't interfere with normal basic programs.


I am not familiar with xa65 but according to my tests it does not pad the file if you assign to *. As such, the code you expect to be at $1000 isn't going to be there, in fact it's just after the previous block. Also, c64 prg format expects a start address on the first two bytes which xa64 doesn't seem to fill in either. I have managed to get this to work:

*=$0FFE
.byte $00, $10
INC 53280
INC 53281
JMP $1000

Start with sys 4096.

PS: VICE has built-in monitor (machine level debugger).

Purse answered 31/1, 2015 at 12:12 Comment(2)
I edited my question to also include that I DID in fact try to start with SYS 4096. And yes, the data after $0801 is supposed to be a basic program that execytes SYS 4096 ;)Bannock
Ah yeah, I see it's a byte encoded version of sys 4096. It won't autostart but run should start it.Purse
A
1

Personally I use CA65 from CC65 package, and have found a suitable macro for this.

If you're wondering "why is this so hard", one of the issues is, that you need to convert the address (where the machine code starts) to base-10 petscii string.

Here you can see similar solution for VIC-20, which actually tells what those mystery .byte's are: http://techtinkering.com/2013/05/10/adding-a-basic-stub-to-a-vic-20-assembly-language-program/

(I assume it's the same on C64)

Personally I use following macro to create the basic stub in CA65:

.macro Address address, digits
.ifblank digits
    dig=5
.else
    dig=digits
.endif
.if dig>4
    .byte <(((address / 1000) .mod 10) + $30)
.endif
.byte <(((address / 100 ) .mod 10) + $30)
.byte <(((address / 10  ) .mod 10) + $30)
.byte <(((address) .mod 10) + $30)

.endmacro

With digits arg, you can set the amount of digits to 4, otherwise you will get code like SYS 04096 (no big deal, but wanted to avoid wasting that extra byte in 1k intro :-) )

As for .byte $01, $08 - does xa65 support .word type, that will insert 16bit value in "least significant byte first" format?

Annunciate answered 7/8, 2015 at 12:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.