My ROM Works!
-
- Posts: 952
- Joined: Fri Mar 19, 2021 9:06 pm
My ROM Works!
Is it just me, or is finding good samples of ca65 syntax really difficult?
But I have, after a few hours, figured out how to write a 65c02 hello world application that uses JSRFAR to call the kernal, assembled it as a ROM image, appended it to the "stock roms", and poked a 7 byte stub at $0400, and used SYS 1024 to run my "ROM". Yay!
Now to do something "useful" with this...
-
- Posts: 913
- Joined: Tue Apr 28, 2020 2:45 am
My ROM Works!
I just yesterday created a new macro to simplify JSRFAR on ca65:
Quote
JSRFAR_kernal_addr = $FF6E
.macro JSRFAR far_sr_addr, bank
jsr JSRFAR_kernal_addr
.addr far_sr_addr
.byte bank
.endmacro
Then you can just call JSRFAR like a function in your code, where $ABCD is the subroutine address and it sits in bank 42:
Quote
JSRFAR $ABCD, 42
My ROM Works!
31 minutes ago, SlithyMatt said:
JSRFAR_kernal_addr = $FF6E
.macro JSRFAR far_sr_addr, bank
jsr JSRFAR_kernal_addr
.addr far_sr_addr
.byte bank
.endmacro
I've seen this kind of construct go by in several people's code lately. Just want to make sure my understanding of what's going on is correct:
Normally, jsr pushes the PC onto the stack - which would be PC-> .addr far_sr_addr - but the code in JSRFAR (or any routine doing this trick) will at some point pull the PC off of the stack, use that as the address to read some arguments from, bump this value up by however many bytes of arguments were read (in this case, 3) and then push the new value back on the stack as if it were the original value pushed by JSR. This way, whenever the routine called by JSRFAR executes RTS, it doesn't come back and try to execute the .addr far_sr_addr as a command.
Essentially, this is a "pass by value" way to pass parameters to a function - it's "by value" because the values are copied to a new location and those copies are used. In this case, the new location happens to be right in the middle of the code, and the values are a pointer (to a function) and an unsigned char.
Is that about right?
-
- Posts: 913
- Joined: Tue Apr 28, 2020 2:45 am
My ROM Works!
2 minutes ago, ZeroByte said:
Is that about right?
Yes, that's correct. It's a bit of stack manipulation in the kernal JSRFAR subroutine -- so don't try to do additional stack manipulation unless you know what you're doing!
-
- Posts: 952
- Joined: Fri Mar 19, 2021 9:06 pm
My ROM Works!
2 hours ago, SlithyMatt said:
I just yesterday created a new macro to simplify JSRFAR on ca65:
Then you can just call JSRFAR like a function in your code, where $ABCD is the subroutine address and it sits in bank 42:
Since my code is executing out of a ROM, I can't JSRFAR into the kernal (I don't think) directly, so I copied the bjsrfar stub from the BASIC ROM so that I had my own entry point in my own ROM space.
Really, most of my time was spent puzzling out how to get the right ca65 syntax for segments and configuration file. I have years of experience with assembly language on 6502 & x86, just not ca65.
I do look forward to utilizing the macro features Real Soon Now(TM).
-
- Posts: 913
- Joined: Tue Apr 28, 2020 2:45 am
My ROM Works!
2 minutes ago, Scott Robison said:
I can't JSRFAR into the kernal (I don't think) directly
Correct, JSRFAR only works with the RAM banks. My repo here shows you how to do some other config magic, and it's going to be the subject of my next vlog coming out Thursday.
-
- Posts: 952
- Joined: Fri Mar 19, 2021 9:06 pm
My ROM Works!
1 minute ago, SlithyMatt said:
Correct, JSRFAR only works with the RAM banks. My repo here shows you how to do some other config magic, and it's going to be the subject of my next vlog coming out Thursday.
JSRFAR seems like it works for ROM, there is just a chicken and egg problem. JSRFAR is a kernal routine at $FF6E (which I have memorized for the moment after typing it in multiple times over the last 12 hours). Kernal is in ROM bank 0. My Hello World ROM is in ROM bank 7. I can't change the ROM bank while my code is executing in ROM without bad things happening, so I need a little helper function in my own ROM to get to the RAM entry point. My (almost completely worthless) code is below:
.pc02
.code
ldx #0
loop: lda message,x
bne print
rts
print: jsr xjsrfar
.word $FFD2
.byte 0
inx
bra loop
; -----------------------------------------------------------------------------
; code borrowed from BASIC ROM to support jsrfar to kernal
ram_bank = 0
rom_bank = 1
.include "c:/dev/x16/x16-rom/inc/banks.inc"
.export xjsrfar
xjsrfar:
.include "c:/dev/x16/x16-rom/inc/jsrfar.inc"
; -----------------------------------------------------------------------------
.rodata
message: .asciiz "HELLO WORLD"
-
- Posts: 952
- Joined: Fri Mar 19, 2021 9:06 pm
My ROM Works!
2 hours ago, evlthecat said:
Congrats on the success!
Thanks! I'm debating several project ideas.
1. An "advanced" (for some concept of advanced) BASIC-like interpreter that supports a more structured language than Commodore BASIC
2. An emulator of some other computer. I feel like basic emulation of some 40 year old computers should be possible with 2+ MB of RAM and 16 KB of ROM
My ROM Works!
You get the inception award if you can emulate a VIC-II + SID and C64 Kernal+BASIC on an X16, especially if it correctly runs any demoscene demos.