Login
Back to forumReply to this topicGo to last reply

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?

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
16:45:19
 Re: Cartridge and raster interrupts

I have no good reason. happy

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

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

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

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

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

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

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

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

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

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

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-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-08
05:42:27
 Re: Cartridge and raster interrupts

Just having a quick look during my break. Yeah the code is readable happy


jmp $fcbe looks like something I didn't do.

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

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

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

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

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

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-20
16:59:44
 Re: Cartridge and raster interrupts

I hope so because that's what I'm doing happy



Back to topReply to this topic


Copyright © Plus/4 World Team, 2001-2024. Support Plus/4 World on Patreon