Bank switching issue

The place for codemasters or beginners to talk about programming any language for the Spectrum.
User avatar
Prototron
Drutt
Posts: 11
Joined: Thu Mar 07, 2024 2:10 pm
Location: Glasgow, Scotland

Re: Bank switching issue

Post by Prototron »

deanysoft wrote: Tue Apr 09, 2024 5:04 pm OK, I can't quite visualise how that works but you say it does so that's good. I would've thought if graphics data is banked in at $c000 then your screen, in another bank at $c000, is not available. So copying from one to another means you're having to copy bytes to a temp buffer first or hold your bytes in registers, swap bank then copy to screen. Both don't seem very fast methods.

I'm probably just not quite understanding your process here. So long as it works, that's the main thing.
It works but it's maybe not ideal. I was just happy that it was doing what it should. I'll need to try and organise a little better and only use banking for certain things.

I'm trying to reclaim the RAM from $5B00 - $8000 as it's got system stuff in it that I'm not ever going to use, but so far I can only use $6000-$8000 without any issues.

The adventure continues!
"For the money, for the glory, and for the fun! Mostly for the money."
~ Bo "Bandit" Darville
User avatar
ketmar
Manic Miner
Posts: 719
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Bank switching issue

Post by ketmar »

if you want to use system vars for your code, you will need your own interrupt handler. ROM handler expects IY to point to sysvars area, and hopes to find some sysvars there (FRAMES, keyboard state). also, if you are using RST #10 for printing, you will need sysvars too (and some other ROM routines like PLOT wants sysvars).

it is usualy easier to leave sysvars where they are (and don't use IY).
User avatar
Prototron
Drutt
Posts: 11
Joined: Thu Mar 07, 2024 2:10 pm
Location: Glasgow, Scotland

Re: Bank switching issue

Post by Prototron »

ketmar wrote: Fri Apr 12, 2024 1:15 pm if you want to use system vars for your code, you will need your own interrupt handler. ROM handler expects IY to point to sysvars area, and hopes to find some sysvars there (FRAMES, keyboard state). also, if you are using RST #10 for printing, you will need sysvars too (and some other ROM routines like PLOT wants sysvars).

it is usualy easier to leave sysvars where they are (and don't use IY).
I have an IM 2 handler set up, but it's not doing much yet. Got a table at $8000 filled so it'll jump to my handler routine held $8181, and the stack is between them.

There's nothing actually in the handler just yet as I'm not really sure what to put in there.
"For the money, for the glory, and for the fun! Mostly for the money."
~ Bo "Bandit" Darville
User avatar
ketmar
Manic Miner
Posts: 719
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Bank switching issue

Post by ketmar »

also note that by destroying sysvars you won't be able to use +3DOS. you need to call ROM interrupt handler to eventually turn drive motor off, and it uses some other sysvars too.

tbh, i never bothered to get rid of sysvars, and i don't think you need to. ;-) hey, you wasted 257 bytes on interrupt table, you definitely have plenty of unused RAM! ;-)

for IM2 trick: you don't actually need 257 bytes for the table which is already in ROM. let me quote one of my sources:

Code: Select all

  ;; this is using an old trick:
  ;; 48K ROM has a lot of #FF (more than 256),
  ;; so we can use it as interrupt table.
  ;; this way, the interrupt will jump at #FFFF.
  ;; this is not that useful... but we can put "JR"
  ;; opcode there, and it will jump to #FFF4
  ;; (due to first ROM byte being DI opcode aka #F3).
  ;; and we can put a real jump to our interrupt
  ;; routine at #FFF4.
  ;; so we cannot use last UDG, but meh... not a big deal.
  \ di
  ld    a, # $3B  ;; ROM contains a lot of #FF there
  ;; I register points to area filled with #FF here
  ld    i, a
  ;; write JR opcode to #FFFF
  ld    a, # $18
  ld    $FFFF (), a   ;; jr
  ;; write JP opcode to #FFF4
  ld    a, # $C3      ;; jp
  ld    $FFF4 (), a
  ;; write interrupt handler address to #FFF5
  ld    hl, # .IntrHandler
  ld    $FFF5 (), hl
  ;; switch to second interrupt mode
  im    # 2
many commercial games used this trick, so i consider it as "reliable and stable". ;-)
User avatar
goodboy
Microbot
Posts: 142
Joined: Tue Jul 23, 2019 8:22 am
Location: Russia

Re: Bank switching issue

Post by goodboy »

on the 128k machine you can use im1 for your code subroutine
User avatar
ketmar
Manic Miner
Posts: 719
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Bank switching issue

Post by ketmar »

goodboy wrote: Sun Apr 14, 2024 10:51 am on the 128k machine you can use im1 for your code subroutine
but only if you have 128K ROM paged in, otherwise SWAP is not called.
AndyC
Dynamite Dan
Posts: 1412
Joined: Mon Nov 13, 2017 5:12 am

Re: Bank switching issue

Post by AndyC »

ketmar wrote: Sun Apr 14, 2024 12:53 am also note that by destroying sysvars you won't be able to use +3DOS. you need to call ROM interrupt handler to eventually turn drive motor off, and it uses some other sysvars too.

tbh, i never bothered to get rid of sysvars, and i don't think you need to. ;-) hey, you wasted 257 bytes on interrupt table, you definitely have plenty of unused RAM! ;-)

for IM2 trick: you don't actually need 257 bytes for the table which is already in ROM. let me quote one of my sources:

Code: Select all

  ;; this is using an old trick:
  ;; 48K ROM has a lot of #FF (more than 256),
  ;; so we can use it as interrupt table.
  ;; this way, the interrupt will jump at #FFFF.
  ;; this is not that useful... but we can put "JR"
  ;; opcode there, and it will jump to #FFF4
  ;; (due to first ROM byte being DI opcode aka #F3).
  ;; and we can put a real jump to our interrupt
  ;; routine at #FFF4.
  ;; so we cannot use last UDG, but meh... not a big deal.
  \ di
  ld    a, # $3B  ;; ROM contains a lot of #FF there
  ;; I register points to area filled with #FF here
  ld    i, a
  ;; write JR opcode to #FFFF
  ld    a, # $18
  ld    $FFFF (), a   ;; jr
  ;; write JP opcode to #FFF4
  ld    a, # $C3      ;; jp
  ld    $FFF4 (), a
  ;; write interrupt handler address to #FFF5
  ld    hl, # .IntrHandler
  ld    $FFF5 (), hl
  ;; switch to second interrupt mode
  im    # 2
many commercial games used this trick, so i consider it as "reliable and stable". ;-)
Will that still work if the +3DOS ROM is paged in? Is there actually a guaranteed 257 byte ramp containing FFh at the same addresses in every ROM? And, of course, you'd have to replicate the interrupt handler in every banked page.

Seems a lot easier just to use your own table, tbh.
User avatar
ketmar
Manic Miner
Posts: 719
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Bank switching issue

Post by ketmar »

AndyC wrote: Sun Apr 14, 2024 11:15 am Will that still work if the +3DOS ROM is paged in?
i am cheating by switching to IM1 when calling +3DOS. not that you can do much while +3DOS does its business anyway.
AndyC wrote: Sun Apr 14, 2024 11:15 am Is there actually a guaranteed 257 byte ramp containing FFh at the same addresses in every ROM?
it is still there in 48K BASIC, which i page in at the start of all my code. and i am guilty of forgetting to tell about this. ;-)
AndyC wrote: Sun Apr 14, 2024 11:15 am And, of course, you'd have to replicate the interrupt handler in every banked page.
yes, but only those 4 bytes to perform the jump.
AndyC wrote: Sun Apr 14, 2024 11:15 am Seems a lot easier just to use your own table, tbh.
it highly depends of the memory map of your program, and if you want to waste 257 bytes of fast memory for the table. a matter of taste, i guess, but i prefer to not waste fast memory for that, and (usually) to have my interrupt handler in slow memory, and waste fast memory for some other tables, or code for fast screen blitting.

anyway, it's not the only method, of course. altering SWAP routine on 128K/3+ is another good way (but limited to 128K ;-).
Post Reply