My ROM Works!

Chat about anything CX16 related that doesn't fit elsewhere
Scott Robison
Posts: 952
Joined: Fri Mar 19, 2021 9:06 pm

My ROM Works!

Post by Scott Robison »


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...

evlthecat
Posts: 37
Joined: Mon Apr 05, 2021 10:47 am

My ROM Works!

Post by evlthecat »


Congrats on the success!

SlithyMatt
Posts: 913
Joined: Tue Apr 28, 2020 2:45 am

My ROM Works!

Post by SlithyMatt »


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



 

ZeroByte
Posts: 714
Joined: Wed Feb 10, 2021 2:40 pm

My ROM Works!

Post by ZeroByte »



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?

SlithyMatt
Posts: 913
Joined: Tue Apr 28, 2020 2:45 am

My ROM Works!

Post by SlithyMatt »



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!

Scott Robison
Posts: 952
Joined: Fri Mar 19, 2021 9:06 pm

My ROM Works!

Post by Scott Robison »



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).

SlithyMatt
Posts: 913
Joined: Tue Apr 28, 2020 2:45 am

My ROM Works!

Post by SlithyMatt »



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.

Scott Robison
Posts: 952
Joined: Fri Mar 19, 2021 9:06 pm

My ROM Works!

Post by Scott Robison »



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"

Scott Robison
Posts: 952
Joined: Fri Mar 19, 2021 9:06 pm

My ROM Works!

Post by Scott Robison »



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

ZeroByte
Posts: 714
Joined: Wed Feb 10, 2021 2:40 pm

My ROM Works!

Post by ZeroByte »


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.

Post Reply