128k paging BASIC loader

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

128k paging BASIC loader

Post by R-Tape »

This is the scenario:

Stack below 24064, main code fills 24064 up to the top, including vector table at 65024 in main (=bank 0?) filled with db 253, JPs to interrupt routine at 32768.

Interrupt routine will page in bank 1, call AY music there, then page bank 0 back in.

I'm struggling to get the code loaded into bank 1, and make it all work.

This is the loader.

10 CLEAR 24063:LOAD"MAIN"CODE ;regular code into main memory with bank 0 at the top
20 IF PEEK 23388 THEN OUT 32765,17:LOAD"AYMUSIC"CODE:OUT 32765,16 ;AY music loaded into bank 1
30 RANDOMIZE USR 24064

I'm getting crashes, it's possible it's because of the return to BASIC within the editor. Should the above strategy work?

I hate coding for the 128k.
User avatar
bob_fossil
Manic Miner
Posts: 654
Joined: Mon Nov 13, 2017 6:09 pm

Re: 128k paging BASIC loader

Post by bob_fossil »

Had a look at some old 128 .tap conversions I did from years ago and I was doing the following to page from BASIC:

Code: Select all

POKE VAL "23388", a: OUT VAL "32765",a
with a being the page, e,g. 16.

This seemed to work without problems.

Bob Fossil
User avatar
Seven.FFF
Manic Miner
Posts: 735
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: 128k paging BASIC loader

Post by Seven.FFF »

I would compress the part that’s overwriting basic, and load that at a higher address or in another bank. Have the entry point be high, and make it decompress the low chunk before starting.

I hate loaders that return to basic. I’m trying to figure out the same process for Pentagon loaders, which involves making TR-DOS m/c calls from the loader too. Ugh.

Zeus has a really nice integrated 128K scatterloader. It uses the Halls of The Things loader that displays the loading screen in line order. Even if you don’t want to use Zeus for main dev, you could call the command line version of Zeus as part of your build process. It would just need to import all your binary chunks (which it can do all at once because it maps each page to a virtual 32-bit address) and export the tap and tax.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
User avatar
Seven.FFF
Manic Miner
Posts: 735
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: 128k paging BASIC loader

Post by Seven.FFF »

This is how simple a zeus paging loader is:

Code: Select all

  TapeMode equ 3
  BorderOptions equ $00002353
  output_tzx "..\bin\Tumult-Uncompressed.tzx", "Tumult", "(c) Robin Verhagen-Guest 2017", Page52Start32, Page52Size, TapeMode , EntryPoint, BorderOptions 
  output_tzx_block "..\bin\Tumult-Uncompressed.tzx", Page0Start32, Page0Size
  output_tzx_block "..\bin\Tumult-Uncompressed.tzx", Page1Start32, Page1Size
  output_tzx_block "..\bin\Tumult-Uncompressed.tzx", Page3Start32, Page3Size
  output_tzx_block "..\bin\Tumult-Uncompressed.tzx", Page4Start32, Page4Size
  output_tzx_block "..\bin\Tumult-Uncompressed.tzx", Page6Start32, Page6Size
  output_tzx_block "..\bin\Tumult-Uncompressed.tzx", Page7Start32, Page7Size
Exactly the same for taps except the command is output_tap.

In that example Page52Start32 = $6000 and Page52Size = $6000 (i.e. from $6000-$BFFF). This overwrites basic, but it doesn't matter because the loader never returns to basic.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: 128k paging BASIC loader

Post by Ast A. Moore »

For starters, returning to BASIC will change the top bank to bank 7. It will also automatically select ROM 0 for you, so no need to set bit 4. Most importantly, you need to disable interrupts and keep the system variable at 23388 updated with the value you send to the port.

I recommend you write a small MC loader and stick it into BASIC. Then run the whole thing with RANDOMIZE USR (PEEK 23635+256*PEEK 23636+5).
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
Woodster
Drutt
Posts: 47
Joined: Mon Nov 13, 2017 12:17 pm

Re: 128k paging BASIC loader

Post by Woodster »

R-Tape wrote: Fri Dec 08, 2017 12:47 pm 10 CLEAR 24063:LOAD"MAIN"CODE ;regular code into main memory with bank 0 at the top
20 IF PEEK 23388 THEN OUT 32765,17:LOAD"AYMUSIC"CODE:OUT 32765,16 ;AY music loaded into bank 1
30 RANDOMIZE USR 24064
Try:
20 POKE 23388,17: PAUSE 1: LOAD"AYMUSIC" CODE: POKE 23388,16: PAUSE 1 ;AY music loaded into bank 1
User avatar
Seven.FFF
Manic Miner
Posts: 735
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: 128k paging BASIC loader

Post by Seven.FFF »

Ast A. Moore wrote: Fri Dec 08, 2017 1:21 pmFor starters, returning to BASIC will change the top bank to bank 7.
Woodster wrote: Fri Dec 08, 2017 2:50 pm20 POKE 23388,17: PAUSE 1: LOAD"AYMUSIC" CODE: POKE 23388,16: PAUSE 1 ;AY music loaded into bank 1
Does Woody's technique stop BASIC changing the top bank back to bank 7, then?
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
User avatar
Spud
Manic Miner
Posts: 372
Joined: Sun Nov 12, 2017 8:50 pm
Contact:

Re: 128k paging BASIC loader

Post by Spud »

Can you compress as much as possible, load it in to whatever standard banks are paged in by default and then splurge it all over the other banks once you're in your program? That's what I did. I recognise if all your data you're loading in won't fit at once then it won't work.
Hikaru
Microbot
Posts: 100
Joined: Mon Nov 13, 2017 1:42 pm
Location: Russia
Contact:

Re: 128k paging BASIC loader

Post by Hikaru »

USR0 it with fire!
Inactive account
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: 128k paging BASIC loader

Post by Ast A. Moore »

Seven.FFF wrote: Fri Dec 08, 2017 3:18 pm Does Woody's technique stop BASIC changing the top bank back to bank 7, then?
Well, kind of. Until the machine resets. ;)
However, if you OUT 32765,17: POKE 23388,17, it’ll page in bank 1 and reset into 48K BASIC, and the bank will stick.
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
Seven.FFF
Manic Miner
Posts: 735
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: 128k paging BASIC loader

Post by Seven.FFF »

Ast A. Moore wrote: Fri Dec 08, 2017 6:37 pm However, if you OUT 32765,17: POKE 23388,17, it’ll page in bank 1 and reset into 48K BASIC, and the bank will stick.
So it does!

Is there a magic way to:
  • be in 128K basic
  • run a program
  • call m/c from the program
  • in that machine code, do the m/c equivalent of OUT 32765,17: POKE 23388,17
  • Frig the sysvars and stack (somehow) to...
  • return to 48K basic, with your program still running, without resetting?
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
User avatar
Woodster
Drutt
Posts: 47
Joined: Mon Nov 13, 2017 12:17 pm

Re: 128k paging BASIC loader

Post by Woodster »

Seven.FFF wrote: Fri Dec 08, 2017 3:18 pm Does Woody's technique stop BASIC changing the top bank back to bank 7, then?
Works fine with the stack in a safe place for paging.

Check out Amaurote's BASIC loader (128K version obviously!) :)

Edit: The bank won't stick if you return to the 128 editor. My original post in this thread was really a suggestion for line 20 of that specific program :)
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: 128k paging BASIC loader

Post by Ast A. Moore »

Seven.FFF wrote: Fri Dec 08, 2017 6:46 pm Is there a magic way to:
  • be in 128K basic
  • run a program
  • call m/c from the program
  • in that machine code, do the m/c equivalent of OUT 32765,17: POKE 23388,17
  • Frig the sysvars and stack (somehow) to...
  • return to 48K basic, with your program still running, without resetting?
That’s a tall order, brother!

Okay, so let’s doodle a bit:

Code: Select all

	ld a,(23388)	;fetch current value
	and %11111000	;clear bits 0–2 (bank #)
	or 1		;select new bank
	ld bc,32765	;our port
	di		;condom on
	ld (23388),a	;write new value back to sys. var
	out (c),a	;and to port
	ei		;condom off
	ret		;we should be back in BASIC now
This ought to cover everything except
Seven.FFF wrote: Fri Dec 08, 2017 6:46 pm
  • return to 48K basic, with your program still running, without resetting?
Then again, I’m not sure why you’d want to do that. If you wanted to prevent further bank switching, you could simply set bit 5, but I presume you’re after something else.

Oh, yeah, and as Mark says, mind the ga— I mean, the stack.
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: 128k paging BASIC loader

Post by R-Tape »

Just wanted to say thanks all, I'll get the content finished and see if I can use this advice over the weekend.

I'd also like to prove I have tried! I have old notes, and today I added one:

Image

BTW - The main file is too big compressed and spills over 49152, so a simple one load is out. Though I did learn today that zx7 compresses more than just screens!
AndyC
Dynamite Dan
Posts: 1386
Joined: Mon Nov 13, 2017 5:12 am

Re: 128k paging BASIC loader

Post by AndyC »

R-Tape wrote: Fri Dec 08, 2017 12:47 pm This is the scenario:

Stack below 24064, main code fills 24064 up to the top, including vector table at 65024 in main (=bank 0?) filled with db 253, JPs to interrupt routine at 32768.

Interrupt routine will page in bank 1, call AY music there, then page bank 0 back in.
If you're using an original 128 or +2 that can crash the machine as I will be pointing at contended RAM in the upper 16K, which triggers a hardware bug.
andydansby
Microbot
Posts: 147
Joined: Fri Nov 24, 2017 5:09 pm
Location: Syracuse, NY, USA
Contact:

Re: 128k paging BASIC loader

Post by andydansby »

The Mojon Twins have a 128k loader that I use in Xelda.

Code: Select all

; Relocator by Benway

org 25000
memory_to_change defb 0
org 25002

ld a, (memory_to_change)
ld b, a

ld A, (#5B5C)   ; in 5B5C is the current memory page
and #F8
or b
ld (#5B5C), A   ; you have to preserve it, or the BASIC goes crazy

ld BC, #7FFD
out (C), A

ld hl, 32768
ld de, 49152
ld bc, 16384   
ldir      ; we copy 16k from 32768 to 49152 (on the correct page)

; here you go back to 0


ld A, (#5B5C)
and #F8
ld (#5B5C), A

ld BC, #7FFD
out (C), A

ret

Code: Select all

10 BORDER NOT PI:PAPER NOT PI:INK NOT PI:CLEAR VAL "24199": LET D=VAL"25000":LET E=D+2:LOAD""SCREEN$:POKE VAL"23739",CODE"o":LOAD""CODE:LOAD""CODE:POKE D,VAL"1":RANDOMIZE USR E:LOAD""CODE:POKE D,VAL"3":RANDOMIZE USR E:LOAD""CODE:POKE D,VAL"4":RANDOMIZE USR E:LOAD""CODE:POKE D,VAL"6":RANDOMIZE USR E:LOAD""CODE:POKE D,VAL"7":RANDOMIZE USR E:LOAD""CODE:RANDOMIZE USR VAL"24200"
The first assembly part is loaded in after the screen$, followed by the game data in 16k blocks for each of the RAM banks, finally switching in the main RAM loading in 36k

Andy Dansby
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: 128k paging BASIC loader

Post by R-Tape »

Hikaru, you have a PM!
User avatar
Seven.FFF
Manic Miner
Posts: 735
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: 128k paging BASIC loader

Post by Seven.FFF »

Thanks Andy. I’m playing around with your Mojon loader adapting it to TR-Dos.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: 128k paging BASIC loader

Post by Ast A. Moore »

Seven.FFF wrote: Sun Dec 10, 2017 3:55 pm Thanks Andy. I’m playing around with your Mojon loader adapting it to TR-Dos.
Seems a little convoluted to me, switching back and forth between BASIC and custom machine code. Like I said earlier,
Ast A. Moore wrote: Fri Dec 08, 2017 1:21 pm I recommend you write a small MC loader and stick it into BASIC. Then run the whole thing with RANDOMIZE USR (PEEK 23635+256*PEEK 23636+5).
NOTE: This is important, because TR-DOS reserves 112 bytes for its variables before the beginning of the BASIC program, so you need to fetch the start address from the PROG system variable (as it won’t be 23755). It’s generally good advice, because some other peripherals might change that value as well.
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
Seven.FFF
Manic Miner
Posts: 735
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: 128k paging BASIC loader

Post by Seven.FFF »

Ast A. Moore wrote: Sun Dec 10, 2017 7:04 pmSeems a little convoluted to me, switching back and forth between BASIC and custom machine code.
Ast A. Moore wrote: Sun Dec 10, 2017 7:04 pm NOTE: This is important, because TR-DOS reserves 112 bytes for its variables before the beginning of the BASIC program, so you need to fetch the start address from the PROG system variable (as it won’t be 23755). It’s generally good advice, because some other peripherals might change that value as well.
You could well be right - I;m still fiddling with everything. Cheers for the tip :)
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
XoRRoX
Manic Miner
Posts: 231
Joined: Wed Jul 11, 2018 6:34 am

Re: 128k paging BASIC loader

Post by XoRRoX »

And... it is alive! :) ;)

Sorry for reviving this old thread but as it's so related to its contents, it seemed more appropriate than creating a new one.

As a novice in 128 banks, it took me quite a while to understand that Bank 0 is the default one (with ROM1) activated by poke 23388,16(?).

Now, in several places I've seen this method used to switch banks in BASIC:

Code: Select all

POKE 23388,17: OUT 32765,17

but it seems to also work without the OUT. This code with only using the POKE seems to work:

Code: Select all

10 CLEAR 49151
20 POKE 49152,255
30 PRINT PEEK 49152
40 POKE 23388,17
50 PRINT PEEK 49152
60 POKE 23388,16
70 PRINT PEEK 49152
and outputs:

Code: Select all

255
0
255
Is there a reason for also using the OUT?
Nienn Heskil
Microbot
Posts: 132
Joined: Tue Jun 09, 2020 6:14 am
Contact:

Re: 128k paging BASIC loader

Post by Nienn Heskil »

This sort of POKE relies on the 128K BASIC ROM to do the paging OUTs, and that might not be enabled at all times. For instance, there's such a thing as the 'USR0 mode', i.e. resetting to BASIC 48 while leaving the 128K paging port active. In that case, this method will not work. 'USR0 mode' is sometimes set by default by TR-DOS 'boot' launcher programs among other things (perhaps some peripherals as well) since it's more compatible. So, I think it's a good idea to keep the OUTs to make sure.
XoRRoX
Manic Miner
Posts: 231
Joined: Wed Jul 11, 2018 6:34 am

Re: 128k paging BASIC loader

Post by XoRRoX »

[mention]Nienn Heskil[/mention]

Thanks for the explanation. So it's to keep it wider compatible.
USR0 is also used by all divMMC devices.

Thanks again :)
AndyC
Dynamite Dan
Posts: 1386
Joined: Mon Nov 13, 2017 5:12 am

Re: 128k paging BASIC loader

Post by AndyC »

Technically the POKE doesn't do anything. If BASIC runs fast enough, the next instruction will access unpaged memory (though that is unlikely given the speed of Sinclair BASIC). The OUT actually pages the memory, but there is a caveat. The ROM will cut in at various points and rearrange memory as the system requires it.

The system variables that get POKEd are where the OS keeps track of what the memory should be restored to (in essence the "current" memory paging). So if you just did the OUT without the POKE, the chances are something will come along and reset the paging back to how it was "supposed" to be.
User avatar
Seven.FFF
Manic Miner
Posts: 735
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: 128k paging BASIC loader

Post by Seven.FFF »

And it's like this because you can't read back the current page with IN on any Spectrum model. In fact on some models, even trying to read it crashes the machine. So the last OUTed value has to be shadowed in RAM so the ROM can do its "change page/do stuff/restore page" activities.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
Post Reply