| Post Your Message | |
| |
| Previous Messages | Posted By
Sirhadisen on 2024-06-30 06:07:40
| Re: raster IRQs returning dynamically to RAM or RAM under ROM
Cool, thank you. That will make it easier to master the plus4 eventually
|
|
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!
|
|
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
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
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-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
|
|
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
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
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
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-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-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
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
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-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-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
|
|
| |
Copyright © Plus/4 World Team, 2001-2024. Support Plus/4 World on Patreon |