Login
Back to forumReply to this topicGo to last reply

Posted By

Sirhadisen
on 2024-05-30
17:38:17
 raster IRQs returning dynamically to RAM or RAM under ROM

Hi folks!

I wonder if there is a way to interrupt code that is either located in the "RAM" or the "RAM under ROM" dynamically. How do I set up the IRQ-handler to notice whether to return to the right program pointer with the right banking configuration, if it can interrupt code after sta $FF3E OR sta $FF3F?
Would be happy about any references or advice.

Cheers!


I have prepared a minmial crashing example:

.IRQvectorToggle. - toggles vector at $0314-$0315 between default and myIRQ
lda #$0e
eor #$50
eor $0314
sta $0314
lda #$ce
eor #$03
eor $0315
sta $0315
rts

.myIRQ.
lda $ff3e - save ROM status
pha
sta $ff3f
jsr $a660 - execute some simple screen/modifying code in the RAM under the ROM
sta $ff3e
asl $ff09 - acknowledge IRQ
jsr $cfbf - clock
jsr $cecd - sound
jsr $db11 - scnkey
pla
beq $.skipROMswitching.
sta $ff3f
.skipROMswitching.
pla - restore registers
tay
pla
tax
pla
rti

.mainProgram.
sei - toggle vector to enable myIRQ
jsr $.IRQvectorToggle.
cli
.mainLoop.
sei - !!! if I replace this sei-cli-embedding with nop, the code crashes, possibly, because the rti does not return to the correct program pointer in the dynamic RAM / RAM under the ROM!
sta $ff3f
.idler.
cmp $ff1d - idler to spent a significant amount of time with RAM under ROM enabled
bne $.idler.
sta $ff3e
cli
ldx $0527 - dummy statement (incomplete part of detection of stop-key-strokes)
cpx #$03
bne $.mainLoop.
sei - toggle vector to disable myIRQ and exit to BASIC (must-have!)
jsr $.IRQvectorToggle.
cli
rts - return to execution of BASIC code


Posted By

Csabo
on 2024-05-30
23:00:07
 Re: raster IRQs returning dynamically to RAM or RAM under ROM

I'm not 100% sure what your end goal is here. What does JSR $A660 supposed to do? I'm not familiar with that one. If I comment that out, the code appears to work fine.

Also... well, I went ahead and verified it, it does work, but to be honest I've never seen reading from $FF3E/$FF3F... That looks odd to me.

Posted By

Sirhadisen
on 2024-06-02
07:06:52
 Re: raster IRQs returning dynamically to RAM or RAM under ROM

Hi Csabo,

Thank you for your response! jsr $a660 jumps to an arbitrary code under the ROM that I wrote myself and which is not included in the example, sorry for the confusion. It is a piece of my animation player code:
.clearVideoBuffer.
.a660 ldy #$00
.a662 lda #$20
.emptyVideoBufferLoop.
.a664 sta $7c00,y
.a667 sta $7d00,y
.a66a sta $7e00,y
.a66d sta $7f00,y
.a670 dey
.a671 bne $.emptyVideoBufferLoop.
.a673 rts
The code crashes when one replaces the marked sei and cli in my main with nop, which allows the interrupts to occur after a sta $ff3f!

I noticed that (at least in plus4emu Debugmode), $ff3e and $ff3f hold the value #$ff right after a sta $ff3f statement has enabled the ram and that they hold the value #$00 after a sta $ff3e statement has disabled it, so my idea was to use it to test whether the IRQ interrupted the execution of a subroutine that is located in the RAM under the ROM (>$8000), or the main that is located below (<$8000). In my IRQ-handler, I would then do a conditional sta $ff3e before the rti to return to the correct bank.
Does that make sense, or how else can I test the complete banking configuration / ROM status? $fb does not seem to contain this information.


Posted By

Csabo
on 2024-06-03
08:31:18
 Re: raster IRQs returning dynamically to RAM or RAM under ROM

OK, so reading from $FF3E/$FF3F does seem reliable, but, if you want to be absolutely sure, you could simply use a separate external variable to keep track of the state.

E.g. let's say zero page $FB. When switching to RAM: LDA #$00 / STA $FB / STA $FF3E. When switching to ROM: LDA #$FF / STA $FB / STA $FF3F. Then you can confidently read from $FB, BEQ for RAM, BNE for ROM.

I would say give this a shot - but TBH my suspicion is that if your code crashes somewhere, it's NOT because of this.

Posted By

gerliczer
on 2024-06-03
10:33:43
 Re: raster IRQs returning dynamically to RAM or RAM under ROM

I may mix it up with something completely different, but I seem to remember that there is one TED register that mirrors the ROM paging state in one of its bits...

I did a quick check here in the Encyclopedia and I found $FF13, bit 0. So, first, there is no need to waste memory on that and second, luckily, my memory didn't trick me this time.

Posted By

Sirhadisen
on 2024-06-09
18:22:12
 Re: raster IRQs returning dynamically to RAM or RAM under ROM

Thanks Csabo and gerliczer!

Csabo, you were right: I had a conflict of a routine called in the IRQ and one called in main using the same user variables $D4, $D5, $E2, $E3 and $E8. Therefore, I had to save&restore them too in the RAM-IRQ-handler. It looks like this now:

-- I. Enter IRQ
--- save registers (standard)
pha
txa
pha
tya
pha
--- save user variables that are shared by routines of the IRQ and routines that are called from main and therefore might be interrupted by the IRQ
lda $d4
pha
lda $d5
pha
lda $e2
pha
lda $e3
pha
lda $e8
pha
--- activate BASIC module configuration and jump to software-IRQ-vector (also standard; mind that this does not affect the RAM/ROM status!)
sta $ffd0
jmp ($0314)
-- II. Exit IRQ
--- restore module configuration (standard)
ldx $fb
sta $fdd0,x
--- restore user variables
pla
sta $e8
pla
sta $e3
pla
sta $e2
pla
sta $d5
pla
sta $d4
--- restore registers
pla
tay
pla
tax
pla
rti

The test for the RAM-status stays in the IRQ-code itself, because it either returns to the standard-handler if it had been called while RAM was active, or the cutomized one otherwise:

-- memorize current ROM status ($FF3E = #$FF means RAM is enabled, $FF3E = #$00 means ROM is enabled) with which the IRQ was entered to make code under the ROM interruptable and return to the correct banking configuration
lda $ff3e
pha
(...)
-- recall ROM status to exit the IRQ with the same banking configuration as it was entered
pla
beq $.skipRAMenabling.
sta $ff3f rom -> ram
.skipRAMenabling.
jmp $fcbe

It took me quite a while to get this working, but you pointed me in the right direction! Thanks for testing.

gerliczer: I might try the $FF13 0-Bit as an alternative. However, "pla, bne" would save one and-statement compared to "pla and #$01 beq". Thank you for pointing it out anyways!

Posted By

gerliczer
on 2024-06-10
02:05:51
 Re: raster IRQs returning dynamically to RAM or RAM under ROM

-- memorize current ROM status ($FF3E = #$FF means RAM is enabled, $FF3E = #$00 means ROM is enabled) with which the IRQ was entered to make code under the ROM interruptable and return to the correct banking configuration
How does that work? I have an idea, but is it really a safe hack to depend on values read from a phantom register?

However, "pla, bne" would save one and-statement compared to "pla and #$01 beq".
That looks nonsensical to me. Could you elaborate, please? BTW, you do not need AND #$01. It could go something like this: LDA $FF13, LSR (or ROR, whichever you prefer), BCS or BCC (depending on what fits the code path better).

Posted By

Sirhadisen
on 2024-06-10
04:09:02
 Re: raster IRQs returning dynamically to RAM or RAM under ROM

Hi gerliczer,

Well, it might be unsafe for the real machine for reasons I do not know, but with plus4emu it works quite well.

And you are right, LSR BCS would also work. In my code there wasn't even room for another byte, but I decided to rearrange things. I am still working with the MONITOR of the emulator. There are more efficient ways, I know :-/

Posted By

Crown
on 2024-06-10
10:52:05
 Re: raster IRQs returning dynamically to RAM or RAM under ROM

You are most likely reading RAM/ROM at $ff3e-$ff3f and RAM is not guaranteed to be initialised as #$ff. Use $ff13.

Verify on a real C16 with 16K RAM, switch in RAM then write #$aa into $3f3e, and check what your read back at $ff3e. If is is not #$aa, then I would verify whether it works as unconnected read, in that case the value read would be the value on the data bus in the previous system cycle. (This needs some explicit timing to put a known value read on the bus like a RAM refresh cycle, before the last cycle of the LDA $ff3e instruction)

Posted By

gerliczer
on 2024-06-11
00:32:53
 Re: raster IRQs returning dynamically to RAM or RAM under ROM

.. might be unsafe for the real machine ... but with plus4emu it works quite well.
That sounds to me like a recipe for disaster.

There are more efficient ways, I know :-/
Are you doing it to challenge yourself?

Posted By

Sirhadisen
on 2024-06-12
07:29:47
 Re: raster IRQs returning dynamically to RAM or RAM under ROM

Mainly for nostalgic reasons, and to test whether my memory is still intact.. soon, I will get to know an IDE.

And no worries, I rearranged it, use $FF13 now and will also test the code on my Plus4 before publishing anything wink

Posted By

seff
on 2024-06-18
11:14:09
 Re: raster IRQs returning dynamically to RAM or RAM under ROM

@Sirhadisen

Take a look at the ROM listing:

1. The $FFFC and $FFFE vectors are copied both to ROM and RAM (see comment, line 8620)
2. Kernal/Basic is paged in (puls)
3. Service IRQ is called (puls1)

And the keyword here is curbnk ;-).

Memory $FC00-$FCFF is non-pagable and is reserved for banking routines.


8156 ;*******************************
8157 ;
8158 ; irq / break service routine
8159 ;
8160 ;*******************************
8161
CE00 8162 krnirq ;enter from 'puls' in non-banking rom
CE00 BA 8163 tsx
CE01 BD 0104 8164 lda $104,x ;get old status
CE04 29 10 8165 and #$10 ;test if irq or break
CE06 D0 03 8166 bne puls1 ;branch if break
CE08 6C 0314 8167 jmp (cinv) ;usually goes to srvirq
CE0B 8168 puls1
CE0B 6C 0316 8169 jmp (cbinv) ;usually goes to monitor
8170
8171
8172
CE0E 8173 srvirq
CE0E AD FF09 8174 lda tedirq
CE11 29 02 8175 and #%00000010 ;is this a raster interrupt?
CE13 F0 03 8176 beq srv010 ;no, go test for acia
CE15 20 CE60 8177 jsr srvspl ;service split screen
8178
CE18 8179 srv010 ;test the acia
CE18 2C 07D8 8180 bit apres ;see if acia is present
CE1B 10 0E 8181 bpl srv020 ;no, don't poll
CE1D AD FD01 8182 lda acia+1
CE20 8D 07D4 8183 sta astat ;read sensitive device
CE23 10 06 8184 bpl srv020 ;no acia interrupt
CE25 20 EA95 8185 jsr ain ;did we get a char?
CE28 20 EA5B 8186 jsr aout ;can we send a char?
8187
CE2B 8188 srv020
CE2B 20 E3E4 8189 jsr dtimeo ;see if cass interrupt
CE2E AD FF09 8190 lda tedirq
CE31 29 02 8191 and #%00000010 ;is this a raster interrupt?
CE33 F0 28 8192 beq srv080 ;nope
8193
CE35 8D FF09 8194 sta tedirq ;turn off interrupt
CE38 2C FF0B 8195 bit ted+11 ;line 20 or end of screen?
CE3B A9 CC 8196 lda #$cc ;assume line 20
CE3D 50 1B 8197 bvc srv070 ;it was line 20! just reload raster compare reg.
8198
CE3F 6C 0312 8199 jmp (itime)
CE42 8200 ntime
CE42 20 CFBF 8201 jsr judt2 ;update jiffy clock +++
CE45 20 CECD 8202 jsr domus ;service sound generators
8203
8204 ; *** 01/16/84 fix: remove function key handler from irq
8205 ; (let screen editor do it all)
8206
CE48 A5 FB 8207 lda curbnk ;save old bank configuration,
CE4A 48 8208 pha
CE4B A9 00 8209 lda #0
CE4D 85 FB 8210 sta curbnk ;make kernal (temporarily) the new configuration,
CE4F 08 8211 php
CE50 58 8212 cli ;key scan must be interruptable
CE51 20 DB11 8213 jsr scnkey ;scan keyboard
CE54 28 8214 plp ;protect our retreat
CE55 68 8215 pla ;get old 'current bank'
CE56 85 FB 8216 sta curbnk
CE58 8217 srv060
CE58 A9 A1 8218 lda #$a1 ;set up to load raster compare reg for line 20
CE5A 8219 srv070
CE5A 8D FF0B 8220 sta ted+11
CE5D 8221 srv080
CE5D 4C FCBE 8222 jmp irqret ;restore registers, exit from irq
8223
8224 ;end
8225
8226 .include split


8094 ;***********************************************************************
8095 ;
8096 ; long irq routine.
8097 ; called by a bank which has received an interrupt, and wishes to have
8098 ; the system roms (kernal/basic) service the interrupt.
8099 ;
8100 ; the users irq vector should point to the following routine in his rom:
8101 ;
8102 ; pha ;save accum.
8103 ; txa
8104 ; pha ;save x reg
8105 ; tya
8106 ; pha ;save y reg
8107 ; .
8108 ; .
8109 ; determine if this is an interrupt to be serviced by the kernal.
8110 ; if so....
8111 ; jmp lngirq
8112 ;
8113 ; *note* before calling this routine, curbank must contain your bank #
8114 ;
8115 ;***********************************************************************
8116
FCB3 8117 puls ;entry for normal irq's
FCB3 48 8118 pha
FCB4 8A 8119 txa
FCB5 48 8120 pha
FCB6 98 8121 tya
FCB7 48 8122 pha
8123
FCB8 8124 lngirq ;entry for irq's passed from banking cartridges
FCB8 8D FDD0 8125 sta bnksel ;select system roms
FCBB 4C CE00 8126 jmp krnirq ;kernal irq routine
8127
FCBE 8128 irqret
FCBE A6 FB 8129 ldx curbnk ;restore previous bank
FCC0 9D FDD0 8130 sta bnksel,x
FCC3 68 8131 pla
FCC4 A8 8132 tay
FCC5 68 8133 pla
FCC6 AA 8134 tax
FCC7 68 8135 pla
FCC8 40 8136 rti
FCC9 8138 gobvec
FCC9 A6 FB 8139 ldx curbnk
FCCB 9D FDD0 8140 sta $fdd0,x
FCCE 6C 02FE 8141 jmp (bnkvec)
8142
=FCF1 8143 *=$fcf1 ;jump table for banking routines
FCF1 4C FCC9 8144 jmp gobvec
FCF4 4C FC59 8145 jmp phenix
FCF7 4C FC7F 8146 jmp fetchl
FCFA 4C FC89 8147 jmp long
FCFD 4C FCB8 8148 jmp lngirq
8149
8150 ;end


8620 ; the following code is necessary to prevent the problem where
8621 ; the reset button is pressed while the rom is banked out. since
8622 ; the ted chip has no reset pin, the processor will attempt to
8623 ; fetch the reset vectors without banking in rom, and will get
8624 ; garbage. this code is copied into ram behind the reset vectors,
8625 ; and will switch the rom back on before transferring execution
8626 ; to the reset routine.
8627
FFF6 8628 gostrt
FFF6 8D FF3E 8629 sta romon
FFF9 4C F2A4 8630 jmp start
FFFC FFF6 8631 .wor gostrt ;initialization code
FFFE FCB3 8632 .wor puls ;interrupt handler
8633
8634 ;end


Posted By

Sirhadisen
on 2024-06-20
15:47:23
 Re: raster IRQs returning dynamically to RAM or RAM under ROM

Thank you all for your advice. I am happy with my code now and it uses FF13.
Interestingly, the vice emulator cannot return to basic when I toggle the IRQ back to $CE0E, I assume it is an emulator-specific hick up, but will test it on my real hardware just to be sure.

@seff, that looks like a neat ROM listing. Is a complete version available somewhere on this forum? I am still struggeling with a German pdf version that uses odd decimal numbers for addresses :-/

Posted By

Lavina
on 2024-06-20
15:47:06
 Re: raster IRQs returning dynamically to RAM or RAM under ROM

Never ever use VICE for plus4 stuff

Posted By

seff
on 2024-06-21
02:06:02
 Re: raster IRQs returning dynamically to RAM or RAM under ROM

@Sirhadisen

Here is the source code: c264 source code

I don't remember, where I got it from though. I have uploaded it to Plus4World and let Csabo/Luca decide what to do with it.
Enjoy!



Back to topReply to this topic


Copyright © Plus/4 World Team, 2001-2024