Previous Messages |
Posted By
Stinaris on 2023-12-20 16:59:44
| Re: Cartridge and raster interrupts
I hope so because that's what I'm doing
|
|
Posted By
SVS on 2023-12-20 12:07:24
| Re: Cartridge and raster interrupts
Really I realize that the argument is not well explained in the Ultimate Map. I thank you all for clarifying it. So I have prepared this table (will be available in the next release). Pls let me know if it is correct as it is. Thanks.
|
|
Posted By
Stinaris on 2023-12-19 15:04:30
| Re: Cartridge and raster interrupts
Thanks Gerliczer. Completely got the wrong end of the stick with the memory locations. The problem with having my son in the same room playing online with his mates. It's quite noisy and distracting.
|
|
Posted By
gerliczer on 2023-12-19 06:44:31
| Re: Cartridge and raster interrupts
I find it a bit baffling that you couldn't get any books that has a good explanation on ROM banking. However, here's how it goes. There are four ROM banks: BASIC/KERNAL, internal ROM expansion which is not available in C16 and contains 3-Plus-1 in an unmodified Plus/4, Cartridge1 ROM and Cartridge2 ROM. The lower and upper halves of those banks can be paged independently. So, we have four options for low ROM and four options for High ROM. Four by four is sixteen. What else is sixteen? The length of the $FDDX range in the I/O area. I guess you realised now where this goes. We have four bits (16 possibilities) used as a selection "register" and that is mapped to the above address range. Bottom two bits select low ROM, top two bits select high ROM. And values corresponding to the banks are what you would infer from the enumeration order I listed the banks in. Therefore, what you are doing in your code is obviously take whatever ROM is paged into the low area and force the KERNAL for the high area. Which is exactly what's written in the comment.
|
|
Posted By
Stinaris on 2023-12-19 05:52:08
| Re: Cartridge and raster interrupts
Finally got back to the C16. Wow what a busy year.
Anyway. I got my raster interrupts working by moving the interrupt routine to RAM. So thank you everyone for your help. I have the Plus/4 Programmers Reference Manual and I've got to say it's a bit disappointing compared to the VIC and C64 versions. Which leads me onto the next bit
While having a little play with carts I opened up my ScriptPlus cart and it as 2 ROMs. Playing with YAPE you can set ROM C1 Low/ROM C1 High i.e. $8000-$bfff/$c000-$fcff. It looks like you can have 2 16K Roms located at the positions above.
Using the code below I can access the lower of these and autostart my cartridge.
start sei lda $fb ; Get current ROM bank (to provide runnability in any slots) and #$03 ; Use our ROM in low bank only and KERNAL in high tax sta $fdd0,x ; Do bank selection
With my cartridge installed $fb contains 1 which looks like it relates to Bank1 but only Low.
I can't find any information that describes how, if at all possible, I can bank in the Hi/Lo regions at the same time. I suspect it's something to do with $fddx but nothing i try banks anything in, only out :-/
|
|
Posted By
BSZ on 2021-06-15 07:39:16
| Re: Cartridge and raster interrupts
In the machine, always shows the KERNAL ROM in the range $FC00..$FCFF. This does not paged out. The routines in this area are those related to ROM paging. It would be unfortunate if they disappeared during their run.
|
|
Posted By
Luca on 2021-06-12 10:43:05
| Re: Cartridge and raster interrupts
Have to relive this old thread to compare our experiences.
I'm burning a couple of eeproms with some personal compilations of games in order to test the whole process, the objective is: merge 4 16kB LO ROMs and 4 16kB HI ROMs to be used in a Sukkopera's OpenCard (which allows the selection of 4 16kB banks into any of the hi/lo 64kB eeproms, have to add this hardware heretoo...), and have overall up to 128kB of games in one single card. While composing the first hi/lo couple, had a surprise: I guessed I can use the memory $8000-$FCFF, but that's not the truth, because the operations necessary to transfer in RAM probably touch into $FCxx, so the real available ROM on a C16 seem to actually be 31kB $8000-$FBFF.
Does this match your experience with it too?
|
|
Posted By
Stinaris on 2020-12-09 10:52:23
| Re: Cartridge and raster interrupts
Hey Mad,
It's all interesting. Discussing always helps iron out these things. I've not had time to check the code because Christmas. But I finish work Friday lunchtime and can't wait to get cracking on this.
I was hoping to stick to 16K machines but expand the available space using a cartridge. Yeah I know, I'm weird.
|
|
Posted By
Mad on 2020-12-08 07:22:06
| Re: Cartridge and raster interrupts
siz, Stinaris cool that you brought up this example.. I was completely on the wrong track.. I thought you want to use RAM above $8000, too (mainloop would access it, not an irq).. sta $ff3f would break siz example code, or? But you are mostly a C16 16K coder as far as I know, so sorry for that strange assumption! The others are completely right.. Thanks to siz for the example code.. Sorry again..
|
|
Posted By
Stinaris on 2020-12-08 05:42:27
| Re: Cartridge and raster interrupts
Just having a quick look during my break. Yeah the code is readable
jmp $fcbe looks like something I didn't do.
|
|
Posted By
siz on 2020-12-07 15:57:01
| Re: Cartridge and raster interrupts
Here is an example (made with 64TAss but probably the code is readable anyway):
*= $8000
vidinit = $ff81 ioinit = $ff84 ramtest = $ff87 restorio = $ff8a
texty = 12
jmp start jmp start .byte 1 ; Marker that ROM should be autostarted .text "cbm" ; Marker that this is an expansion ROM
start sei lda $fb ; Get current ROM bank (to provide runnability in any slots) and #$03 ; Use our ROM in low bank only and KERNAL in high tax sta $fdd0,x ; Do bank selection
jsr ioinit ; Do standard initialization instead of KERNAL reset jsr restorio jsr vidinit ldx #irqend-irq ; Copy IRq routing to RAM at $2000 - lda irq,x sta $2000,x dex bpl -
lda #2 ; Enable raster interrupt only sta $ff0a lda #96 ; Raster interrupt at line 96 sta $ff0b lda #<$2000 ; Set IRq vector to $2000 ldx #>$2000 sta $0314 stx $0315 cli lda #$d4 ; Switch to lower case charset sta $ff13 ldx #txtend-txt-1 ; Copy text to screen - lda txt,x sta $0c00+texty*40,x lda #$71 ; Set text color to white sta $0800+texty*40,x dex bpl -
jmp * ; Infinite loop: main routine has nothing to do
irq lda #$32 ; Load color red into register A ldx #180
- cpx $ff1e ; Wait for rasterline end bcs -
sta $ff19 ; Set border color sta $ff15 ; Set background color lda #0 ; Load color black into register A ldx #231 ; Wait a bit - dex ; (this could have been to separate interrupts to allow bne - ; main thread to use the time but this is an example only) sta $ff19 ; Set border color sta $ff15 ; Set background color
lda $ff09 ; Clear interrupt request sta $ff09 jmp $fcbe ; Use ROM interrupt handler to restore ROM bank and registers and return from the interrupt irqend
.enc screen txt .text "Cartridge ROM Raster IRq example by Siz/Absence" txtend
; Fill to 16k boundary .fill $c000-*, $ff
|
|
Posted By
Stinaris on 2020-12-07 13:03:31
| Re: Cartridge and raster interrupts
Sorry guys.
I am completely lost now with all the different threads.
All the different corrections I've made make no difference. I still can't get both raster (in ram) and cartridge working together.
|
|
Posted By
siz on 2020-12-04 04:01:13
| Re: Cartridge and raster interrupts
Hi crock, I think I wrote the same: in order to use your interrupt handler in a cartridge you have to copy your routine to RAM and point $0314/$0315 there. After that you can either use the code snippet you poster or just jump to the end of the original interrupt handler (I have no emulator/ROM listing at hand but I think it's around $fcfa or something like that)
|
|
Posted By
crock on 2020-12-03 17:00:28
| Re: Cartridge and raster interrupts
I read this thread a couple of times, and maybe I misunderstood, but the conclusion appears to be that if you are running from a cartridge, you cannot insert your own interrupt handler without bypassing the ROM completely by banking out ROM with $ff3f. Is this correct?
If so, the conclusion in wrong, because I do it in the cart version of Diag264 to test all the interrupt sources. As said, you can only do this via the $0314 vector, and your handler must be copied to RAM, because as mad points out, the kernal handler banks in BASIC and KERNAL via a write to FDD0.
Assuming you didn't need to jump back into the kernal interrupt handler, you need to finish your handler by banking the cartridge back in with a write to $FDD2 or $FDDA, and pulling the registers off the stack.
sta $fdd2 pla tay pla tax pla rti
|
|
Posted By
Stinaris on 2020-12-03 13:38:56
| Re: Cartridge and raster interrupts
$0314/$0315 definitely doesn't work in ROM I know I tried it a lot.
The only way I could get the interrupt to work at all was by setting $fffe/$ffff to an interrupt routine in RAM which I had to copy. However the minute you switch on RAM, to make this happen, you switch out the cartridge ROM. Which is a bit of a conundrum.
I think I need to disassemble Jack Attack to see how it deals with it.
|
|
Posted By
siz on 2020-12-02 13:46:59
| Re: Cartridge and raster interrupts
Sorry guys I haven't checked the KERNAL ROM before. The STA $FD00 in the interrupt handler selects the default ROM bank (BASIC+KERNAL) so yes, that means that vector $0314/$0315 won't work in a cartridge ROM you must put your interrupt handler in RAM.
|
|
Posted By
Mad on 2020-12-02 13:00:23
| Re: Cartridge and raster interrupts
Ok here is what I have now "found", lol (strange that I had to look for that):
if you do a sta $ff3f you have to write a valid interrupt pointer at $fffe/$ffff before. Else it crashes. The initial value of $fffe/$ffff in ram in plus4emu is $f700. $f700 is really called (tested it) and crashes if you do sta $ff3f without setting a fresh interrupt vector.
The Rom $fffe/$ffff points to FCB3
FCB3 48 PHA FCB4 8A TXA FCB5 48 PHA FCB6 98 TYA FCB7 48 PHA FCB8 8D D0 FD STA $FDD0 FCBB 4C 00 CE JMP $CE00
CE00 BA TSX CE01 BD 04 01 LDA $0104, X CE04 29 10 AND #$10 CE06 D0 03 BNE $CE0B CE08 6C 14 03 JMP ($0314) CE0B 6C 16 03 JMP ($0316)
All should work if you put an little routine like this in ram:
myRamIrq PHA TXA PHA TYA PHA ; STA $FDD0 ; dunno not checked JMP ($0314)
And put somewhere in code a (stas write to ram all the time)
lda #myRamIrq & 255 sta $fffe lda #myRamIrq / 256 sta $ffff
so you can do a sta $ff3e and a sta $ff3f whilst $0314 vector is called in both cases (RAM/ROM)..
What I don't know if your own rom too exchanges $fffe/$ffff.. I understood from siz that $fffe/$ffff is not connected to roms but to kernel, that's why this strange $fcb3 stuff. But on C64 it is connected to roms as far as I know.. Then this FCB3 stuff would be obsolete.. (You just would need 2 interrupt routines then, one for rom and one for ram + one $fffe/$ffff in rom and one $fffe/$ffff in ram)
Hope that helps.. If Stinaris just wanted to do all entirely in rom this post here is of course senseless..
|
|
Posted By
siz on 2020-12-02 08:42:54
| Re: Cartridge and raster interrupts
DO NOT copy $fc00-$ffff area as $fd00-$ff3f is unmappable I/O area. All these routines reside from $fc00-$fcff. There is a copy of the reset routine at $fff6 and the reset and interrupt vectors at $fffc/$fffd and $fffe/$ffff. (These are initialized by KERNAL) The KERNAL interrupt handler just saves the registers, checks if the interrupt source was external or a BRK instruction and does an appropriate indirect jumps to ($0314/$0315) or ($0316/$0317). The default interrupt handler vector value at $0314/$0315 is $ce0e If you do this yourself you don't need to use the KERNAL routines. If you want to run your interrupts from your cartridge ROM you have to: - set $0314/$0315 - set an interrupt source (for example raster interrupt) - make sure $fb contains your ROM bank number
|
|
Posted By
Stinaris on 2020-12-02 08:04:16
| Re: Cartridge and raster interrupts
I'll try copying just $fffe/$ffff first. Then the whole region from $fcff - $ffff.
|
|
Posted By
Mad on 2020-12-01 16:37:31
| Re: Cartridge and raster interrupts
I remember vaguely that $fffe/$ffff of kernal jumps to an address somwhere in the $fcff to $ffff region? If so, does that mean, that you have to copy the whole $fcff - $ffff region to ram if using sta $ff3f? To ensure $0314/$0315 is called rightly?
|
|
Posted By
siz on 2020-12-01 15:53:33
| Re: Cartridge and raster interrupts
There is a special logic in the PLA that always maps in KERNAL ROM above $fc00. So yes, $fffe/$ffff comes from ROM but you cannot change it.
edit: the above sentences are only valid if ROM is enabled. of course it comes from RAM when it's not ($ff3f written)
|
|
Posted By
Mad on 2020-12-01 16:31:11
| Re: Cartridge and raster interrupts
if you do a sta $ff3f and use $0314/$0315 you have to copy $fffe/$ffff also from rom to ram. The $fffe/$ffff value jumps(calls) somehow to $0314/$0315 by default. So this may be broken with uninitialized $fffe/$ffff and an sta $ff3f. Perhaps that is the problem.. (siz also said that)..
Seems I was wrong in thinking $fffe/$ffff may be also part of a cartridge rom.. Kernel != Cartridge! :) Thanks siz..
Edit: Maybe you need to copy more than $fffe/$ffff to ram to ensure $0314/$0315 is called rightly? Perhaps you need a small code snippet as wrapper which emulates a $0314/$0315 Kernel call.. Maybe siz has a clue..
|
|
Posted By
Stinaris on 2020-12-01 11:02:17
| Re: Cartridge and raster interrupts
Hi Siz,
As far as I'm aware $0314/$0315 are used for banking routines and it causes a massive issue if I use them. Hence using $fffe/$ffff.
If I could utilise $0314/$0315 then that would likely solve my issues, but as yet I've not found a way to do so.
BTW switch ROMs off and utilising $fffe/$ffff is not my problem as this works (irq is copied and run from RAM).
|
|
Posted By
siz on 2020-12-01 07:57:34
| Re: Cartridge and raster interrupts
In a cartridge ROM you *have to* use $0314/$0315 for interrupt as (because of ROM mapped in) is the only entry point you can change. Unless you copy your whole stuff from ROM to RAM and run it from there. Be aware that writing $ff3f will switch off *all* ROMs including KERNAL so in that case you have to ensure that $fffe/$ffff interrupt vectors are initialized properly or interrupts are disabled.
|
|
Posted By
Stinaris on 2020-12-01 09:49:40
| Re: Cartridge and raster interrupts
Thanks Mad,
I spent sometime just seeing what was causing the issue. Now I suspect, although not being an expert I am probably wrong.
So I have a bit of code in the cartridge that writes a little message. This works fine. As well as that I try to set up a raster interrupt. Part of setting the vectors is doing an sta $ff3f Which I think will tell the system not to look at the ROM version of the interrupt and look in RAM. What I suspect is when I do this it's switching to the RAM under $8000 (which doesn't exist on the C16). However if I remove this line the program runs senza raster.
I'll try moving the raster code into ram and trying again. But for now I have to work.
------------------------------------------------------------------------------------------------------------------------------------------
Ok so during my lunch break I had a quick play.
I copied the raster interrupt code to colourmap at $0800. Set the raster interrupt to point to this. Kept the cartridge code simple the following was observed.
With the "sta $ff3f" included, the raster interrupt to change the border colour works but the Cartridge code is never started. Removing the "sta $ff3f" the cartridge code is run but the raster interrupt is never run.
It seems moving between RAM and ROM code is quite tricky. So I got my cartridge code to run then at the end of the cartridge code I placed a "STA $ff3f" and the interrupt started albeit not consistently.It takes a few resets for it to settle. However the cartridge code no longer executes, because I presume there is no code where the PC currently references. More investigation this evening.
|
|
Posted By
Mad on 2020-11-30 20:28:54
| Re: Cartridge and raster interrupts
did you set $ff0a right (ora #$02 for rasterinterrupt) and ff0a rasterline highbit ff0b rasterline low 8 bits. then you need an lda $ff09 and sta $ff09 at end of the interrupt.. It's also good to use lda $ff09 sta $ff09 after setting $fffe/$fffe in the main programm before the cli.
A typical interrupt setup would look like:
irqsetup: sei lda #myirq & 255 sta $fffe lda #myirq / 256 sta $ffff lda #64 sta $ff0b lda #$02 sta $ff0a lda $ff09 sta $ff09 cli rts
and myirq would look like:
myirq: pha inc $ff19 lda $ff09 sta $ff09 pla rti
I didn't try it but this should keep changing the border color in rasterline 64.. If you want a rasterline above 256 (only pal) ff0a would need a lda #$03 instead of lda #$02..
Some people use inc $ff09 or dec $ff09 but this gave problems with nested interrupts for me (whyever that was), so I don't use it anymore.
This has nothing to do with the normal way interrupts occur in basic and so on. It's just you taking the total control of the interrupt execution, so that only your routine is handled and nothing basic or kernel related. So for instance the basic split screen functionality and so on is not usable anymore afterwards most probably command prompt keyboard access (+currently typed in character screen printing) is also disabled then.. Most probably everything is frozen of the kernal/basic stuff..
|
|
Posted By
Stinaris on 2020-11-30 16:45:19
| Re: Cartridge and raster interrupts
I have no good reason.
I'll give it a go.
Hmm. The reason I use 0314/0315 is because the examples in the PRM all use this.
It doesn't crash anymore but the interrupt doesn't occur.
|
|
Posted By
Mad on 2020-11-30 15:10:16
| Re: Cartridge and raster interrupts
No clue about cartridge and interrupts here. But, you have a good reason of not using $fffe/$ffff? I never use 314/315 since it's only a fffe/ffff wrapper with some unneeded kernel code.. Seems I didn't understand.. Perhaps some other people may help.
Hope you get it running..
Edit: Ram Expansions overdub fffe/ffff so maybe that is your reason (with a Cartridge), too.. So sorry for asking..
|
|
Posted By
Stinaris on 2020-11-30 14:25:17
| Cartridge and raster interrupts
Well I managed to get code running from a cartridge. So I'd thought I'd make it a bit more complex and that's where it all went to s#it. The issue is with the irq.
... lda #$F1; irq -> banking routines sta $0314 lda #$FC sta $0315 ...
If I modify this I get some bad mess. If I want to use IRQ's I guess I need to copy the code into RAM and jump to the code or somehow include the banking in my own interrupt. Or am I way off base?
|
|