Help with SetoLOAD

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
User avatar
blueowl0708
Berk
Posts: 28
Joined: Fri Oct 26, 2018 8:55 am

Help with SetoLOAD

Post by blueowl0708 » Fri Aug 09, 2019 10:36 pm

Hi @Alessandro

Sorry to bother but I wonder if you could help with this? I would like to use your SetoLOAD function in my game, but I'm not really sure how to go about implementing this. I've seen the english page on your site and downloaded the source but all the comments are in Italian so I'm a bit lost :)

I suppose I just need to assemble one of the sources (depending on required colours), then load and execute it before loading in the rest of the blocks on my tape? If so, how do I make the blocks I already have 'faster' (for want of a better word!).

Thanks!
0 x

User avatar
Ast A. Moore
Dynamite Dan
Posts: 1194
Joined: Mon Nov 13, 2017 3:16 pm

Re: Help with SetoLOAD

Post by Ast A. Moore » Fri Aug 09, 2019 10:51 pm

You’ll either need to use an assembler in which you can define arbitrary zero/one pulse lengths in a TAP/TZX block (zasm allows you to do that), or manually change them using an application such as Tapir.

Turbo loaders aren’t particularly difficult to write, though. The vast majority are based on the standard ROM loader with a few time constants changed. Of course, the ROM loader can be optimized and improved even further. It’s a lot of fun; I highly recommend it as an exercise.
0 x
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
Alessandro
Manic Miner
Posts: 491
Joined: Wed Nov 15, 2017 11:10 am
Location: Messina, Italy
Contact:

Re: Help with SetoLOAD

Post by Alessandro » Sat Aug 10, 2019 12:50 pm

Hi @blueowl0708,

thank you for your interest in SetoLOAD :D There are essentially two ways to include a fast loading scheme like SetoLOAD in your programs. I have employed both. All of them require a basic knowledge of Z80 Assembly and of the Spectrum ROM loading routine. Nothing out of this world however, as you will soon see.

This is due to the fact that you will usually need to load more than a piece of data at a time, e.g. a loading screen and one or more blocks of code, therefore you will need to insert your loading routine inside another Assembly program, which will recall the custom loading one changing the necessary references - loading address and length of the data - as needed, from block to block.

What you should always remember, anyway, is:
  • any custom loader routine must be assembled in the non-contended RAM space, i.e. from address 32768 on, otherwise the loading routine's timings will go astray and loading will fail;
  • for turbo blocks, timings (Pilot pulse etc.), must be set through a block editor routine. ZX-Blockeditor allows you to insert them once, then copy and paste turbo data and attach it to each block. Timings for SetoLOAD can be found in the source code.
The simplest method is to load from a BASIC program the loading routine comprehensive of the custom loading scheme. This is especially useful when you must load pieces of code into different memory banks for 128K RAM models. In this case, each block is loaded at address 49152.

In this example we load a screen image and a block of code, assembling the code to an address that must be higher than the main block end, i.e. if the main block starts at 32000 and is 18000 bytes long, then our loading program must be assembled higher than 32000+18000 = 50000. For simplicity's sake, we will also assume that none of the blocks are compressed, in that case you must also add a decompression code to the program to decompress data after loading it.

Code: Select all

  ORG 64000

  ; The following four rows are optional. They obscure the screen so that the 
  ; loading screen can be only seen at the end, when attributes are loaded.

  LD A,0           ; (64 for BRIGHT 1)
  LD (23693),A     ; PAPER 0, INK 0, BRIGHT 0
  LD (23624),A     ; last two rows have INK and PAPER 0
  CALL 3503        ; CLS

  ; Load the screen

  LD IX,16384      ; code loading address
  LD DE,6912       ; code block length in bytes
  
  CALL SETOLOAD

  ; Load the code block

  LD IX,32000      ; code loading address
  LD DE,18000      ; code block length in bytes

  CALL SETOLOAD

  JP 32000         ; jump to the start of the loaded program

SETOLOAD:

  [here goes the SetoLOAD routine]
This program is assembled to a tape file with an assembler (I use Pasmo 0.54 beta), and loaded through a simple BASIC program like:

10 CLEAR 31999: LOAD "" CODE : RANDOMIZE USR 64000

Another way is to load the routine directly as if it was a BASIC program. This method was used by G.B. Max (Giovanni Zanetti) for his great Biturbo/Biturbo II loading schemes, which were the first I managed to "reverse engineer". An example of this loader in action can be seen in my Cousin Horace, the last game I made before creating SetoLOAD.

This will require the program to be assembled as a .BIN file and then to a BASIC file with BIN2DATA.EXE, an utility which assembles a machine code program into a BASIC file. A batch file I created for this purpose is CAR.BAT:

Code: Select all

@echo off
pasmo --bin %1.asm %1.bin
bin2data -org [assembly address] -rem %1.bin %1.tap
del %1.bin
If for example your program is saved as LOADING.ASM and begins at address 25000, [assembly address] must be 25000 in fact. Just type CAR LOADING at the PC command prompt and a LOADING.TAP file will be created, which can be loaded by simply entering LOAD "" on the Spectrum.

Also, the SetoLOAD code must be copied in non-contended memory to work, and must have been assembled at the required address first. So if you want SetoLOAD to stay at address 65000, first assemble it at that address as a .BIN file, otherwise it won't work.

So here is another example:

Code: Select all

  SETOLOAD EQU 65000 ; we want SetoLOAD at this address

  ORG 25000

  ; The following four rows are optional etc.

  LD A,0           ; (64 for BRIGHT 1)
  LD (23693),A     ; PAPER 0, INK 0, BRIGHT 0
  LD (23624),A     ; last two rows have INK and PAPER 0
  CALL 3503        ; CLS

  LD HL,SL         ; We want the SetoLOAD routine copied from this address...
  LD DE,SETOLOAD   ; ...to this.
  LD BC,178        ; length in bytes of the "SetoLOAD.bin" file
  LDIR             ; copy the routine

  LD IX,16384      ; load screen
  LD DE,6912
  
  CALL SETOLOAD

  LD IX,32000      ; load code
  LD DE,18000

  CALL SETOLOAD

  JP 32000         ; jump to the start of the loaded program

SL: INCBINE "SetoLOAD.bin"
That's how it works basically, feel free to ask if you want to know more.
1 x

User avatar
Alessandro
Manic Miner
Posts: 491
Joined: Wed Nov 15, 2017 11:10 am
Location: Messina, Italy
Contact:

Re: Help with SetoLOAD

Post by Alessandro » Sat Aug 10, 2019 3:12 pm

Erratum. The last line of the last piece of code should read:

SL: INCBIN "SetoLOAD.bin"
0 x

User avatar
blueowl0708
Berk
Posts: 28
Joined: Fri Oct 26, 2018 8:55 am

Re: Help with SetoLOAD

Post by blueowl0708 » Thu Aug 15, 2019 9:56 am

Thanks for this @Alessandro so it looks like you essentially implement the entire loader in asm and change the timings of the blocks in the tape image.
All of them require a basic knowledge of Z80 Assembly
I can assemble things, but just with spin at the moment. Not had time to set up a proper environment
and of the Spectrum ROM loading routine.
pass, but I think I can muddle through this.

@Ast A. Moore - maybe one day. I am very much a beginner with this!
0 x

User avatar
blueowl0708
Berk
Posts: 28
Joined: Fri Oct 26, 2018 8:55 am

Re: Help with SetoLOAD

Post by blueowl0708 » Wed Aug 21, 2019 4:54 pm

So... after a bit of messing that worked really well :D, 5:10 becomes 2:44 - thanks @Alessandro!

Image

One thing you didn't mention is that the code blocks need to be headerless when following your approach and loader example, but that was an easy fix once I realised what the problem was.

Not related to your instructions but I found ZX-Block editor a bit cumbersome to use - I couldn't find a way to paste a turbo block onto an existing data block so I had to manually add it to each block and type in the required values.
1 x

User avatar
Alessandro
Manic Miner
Posts: 491
Joined: Wed Nov 15, 2017 11:10 am
Location: Messina, Italy
Contact:

Re: Help with SetoLOAD

Post by Alessandro » Sun Aug 25, 2019 1:48 pm

Hi @blueowl0708, glad you made use of my custom loader :D

I didn't mention the headerless block thing because turbo blocks are, with some very rare exceptions, always "recorded" that way. As for ZX-Blockeditor:
  • to copy turbo data, you must click the right mouse button while on the turbo block data line (i.e. "Turbo data addition"), then click the left mouse button on "Turbo data..." and then on "Copy turbo data to clipboard";
  • to paste turbo data, click with the right mouse button on the line right under the block you want to convert, then click the left mouse button on "Turbo data..." and then on "Paste turbo data from clipboard".
You may also convert blocks with Tapir - as I did myself in my first forays into the turbo loaders territory - but you will have to insert the values each time for every single block, and that rapidly becomes a chore when you have multiple blocks to convert to turbo.
0 x

Post Reply