Sdw Posted July 8, 2013 Share Posted July 8, 2013 I am trying to write some code that should run on a 130XE (and best case, other models with >=128kb RAM). I want full access to as much RAM as possible, so I run with PORTB ($d301) set to $F2 normally, that is BASIC off, OS off etc. That works fine, I can access all RAM except for $d000-$d7ff Now I am incorporating bankswitching as well, to gain access to the extra 64kb on the 130XE. The really strange thing is, I can't get the bankswitching to work without setting the lowest bit of PORTB, that is switching in OS stuff that eat up $c000-$ffff essentially. It makes no sense to me, in my test program I run with interrupts disabled (SEI) so there is no way that the CPU can be running code "without my knowledge", yet it still seems like it needs to have access to the OS for the bankswitching to work. WTF? What am I doing wrong? For example, this does NOT work, the second write to $4000 just overwrites the first. .pc = $3000 "Code" sei lda #$a2+0*4 sta PORTB lda #$55 sta $4000 lda #$a2+1*4 sta PORTB lda #$77 sta $4000 However the following works: .pc = $3000 "Code" sei lda #$a3+0*4 sta PORTB lda #$55 sta $4000 lda #$a3+1*4 sta PORTB lda #$77 sta $4000 ??? Quote Link to comment Share on other sites More sharing options...
Rybags Posted July 8, 2013 Share Posted July 8, 2013 (edited) It should work, OS in or out makes no difference to low memory Ram banking, it only affects Self-Test, ie if OS is out Self-Test Rom also gets swapped out. Also it's a good idea to leave bit 6 set to it's default state of 1, some Ram expansions >128K use it for bank selection. Additionally NMIs can still fire off while you have the OS switched out, a good idea is to either disable via NMIEN or have a check to ensure one isn't about to occur. The only reason I can see for your code failing is that the Assembler you're using might be doing the maths for your bank number in a way you don't expect. Some assemblers simply process the maths from left to right without giving precedence to the types of operations. e.g. with Atari's Asm/Ed cart: LDA # 4+1*5 will generate decimal 25, not 9 as you'd otherwise expect. Edited July 8, 2013 by Rybags Quote Link to comment Share on other sites More sharing options...
Sdw Posted July 9, 2013 Author Share Posted July 9, 2013 Thanks. NMIs were the culprit. Adding a lda #$00 sta NMIEN solved the problem! Quote Link to comment Share on other sites More sharing options...
bugbiter Posted September 11, 2014 Share Posted September 11, 2014 I'm trying the same thing, using the RAM in C000 to $FFFF where the OS ROM sits. I've disabled NMIs including keyboard interrupt. Is there a Way to access the keyboard keys despite that 'by hand?' Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 11, 2014 Share Posted September 11, 2014 Various ways - you could provide a replacement IRQ. Or you could just read keys manually from the Pokey registers. The keycode register retains the previous keypress so on it's own isn't the full solution. SKSTAT has the key-down status bit which you should take as prompt to read the keycode. Debounce can be an issue (one keypress registering 2-3 times) - generally you'd do what the OS does, ie remember previous keypress and maintain a 3 frame timer when keyup occurs. Then ignore any keydown that is the same as the previous for that period. 1 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted September 11, 2014 Share Posted September 11, 2014 You could use a wrapper so the IRQ and NMI still use the OS - something like this: .proc NMIHand bit nmist bpl NotDLI jmp (vdslst) NotDLI pha txa pha lda #> [ExitInt.NMI] pha lda #< [ExitInt.NMI] pha tsx lda $0105,x ; get pushed flags pha cld pha txa pha tya pha inc portb ; enable OS sta nmires jmp (vvblki) .endp .proc IRQHand pha lda #> [ExitInt.IRQ] pha lda #< [ExitInt.IRQ] pha php inc portb ; enable OS jmp (vimirq) .endp .proc ExitInt NMI pla tax IRQ dec portb rti .endp .proc Ciov inc portb ; re-enable OS jsr $e456 php ; save flags dec portb ; disable OS again plp rts .endp .proc Initialize lda #0 sta nmien ; turn off NMI sei ; and IRQ lda $d301 and #$fe ; switch out ROM sta $d301 lda #< IntHand sta $fffa lda #> IntHand sta $fffb lda #< IRQHand sta $fffe lda #> IRQHand sta $ffff lda #96 ; re-enable interrupts sta nmien cli rts .endp Obviously you need to manually re-enable the OS when calling it (as does the CIOV routine). The above method is exactly how Turbo Basic XL works. Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 11, 2014 Share Posted September 11, 2014 You also need the OS VBlank, Stage 2 especially, for the key processing to function properly. Without it, pressing the same key twice in a row won't work - the VBlank takes care of repeat and debounce - the timer method I mentioned earlier is used and the default IRQ uses it's value to decide if a keypress should be ignored. I'd agree with the wrapper method - just point the IRQ+NMIs to your routine in low memory, but you need to do VBlank as well as IRQ. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted September 11, 2014 Share Posted September 11, 2014 Note above routine handles both. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.