Unusual custom turbo loaders - with sources

edited August 2014 in Development
I have always been fascinated by turbo loaders; my games all feature a TZX version with one of such schemes implemented, and I have been experimenting with several of them.

I reverse engineered the loading routines of four 'exotic' loaders and recorded data with ZX Spin as WAV files, later converted as TZX images with WAV2TZX, in order to discover the timings. Normal loading speed chunks of data can be altered in Tapir with those timings, in order to 're-save' them as turbo speed data.

UPDATE: A fifth loader, found in Erbe Software's re-release of Cobra, has been added (see below).

UPDATE 2: A sixth loader from Alternative has been added.

The results are here for anyone interested to enjoy.

1) Biturbo (both I and II variants)

First programmed by Giovanni "G.B. Max" Zanetti in 1985, the Biturbo loading scheme is fast and very reliable, since it was used for recording software on the Spectrum cassette side of the infamous Italian SIPE tape magazines featuring hacked games with changed names and badly translated into Italian, and such tapes weren't exactly of high quality to begin with.

The first variant was used until about April 1987 to be replaced with the second one, which has exactly the same timings except for the pilot tone, but a 'scrambled' appearance instead of the orderly one associated with Biturbo I. The pilot tone colors of Biturbo I also seem to vary randomly between these combinations: black-green; red-yellow; magenta-white.

Biturbo II was the object of my first attempt at reverse engineering of a custom loader but at the time my knowledge of Spectrum machine code was too scarce to 'isolate' the loading routine. Only recently I was able to extract it from an actual TZX file and reuse it effectively.

Biturbo II is being used as the custom loader for the TZX files of my forthcoming game Cousin Horace.
; Biturbo 1 loading routine
; by Giovanni "G.B. Max" Zanetti
; Used 1985-1987 ca.
; Readapted by Alessandro Grussu, April 2014
; ------------------
; Standard timings:
; ------------------
; Pilot pulse : 2165
; Pilot length: 8350
; Sync 1 pulse:  714
; Sync 2 pulse:  714
; Zero pulse  :  486
; One pulse   :  833

	ORG 65355

	LD A,255
	SCF
	INC D
	EX AF,AF'
	DEC D
	DI
	IN A,(254)
	RRA
	AND 032
	OR 002
	LD C,A
	CP A
	RET NZ
	CALL 65485
	JR NC,65371
	LD HL,01045
	DJNZ 65380
	DEC HL
	LD A,H
	OR L
	JR NZ,65380
	CALL 65481
	JR NC,65371
	LD B,156
	CALL 65481
	JR NC,65371
	LD A,198
	CP B
	JR NC,65372
	INC H
	JR NZ,65392
	LD B,201
	CALL 65485
	JR NC,65371
	LD A,B
	CP 212
	JR NC,65407
	CALL 65485
	RET NC
	LD A,C
	XOR 003
	LD C,A
	LD H,000
	LD B,208
	JR 65457
	EX AF,AF'
	JR NZ,65441
	LD (IX+000),L
	JR 65451
	RL C
	XOR L
	RET NZ
	LD A,C
	RRA
	LD C,A
	INC DE
	JR 65453
	INC IX
	DEC DE
	EX AF,AF'
	LD B,210
	LD L,001
	CALL 65481
	RET NC
	LD A,220
	CP B
	RL L
	LD B,208
	JP NC,65459
	LD A,H
	XOR L
	LD H,A
	LD A,D
	OR E
	JR NZ,65433
	RET
	CALL 65485
	RET NC
	LD A,013
	DEC A
	JR NZ,65487
	AND A
	INC B
	RET Z
	LD A,127
	IN A,(254)
	RRA
	XOR C
	AND 032
	JR Z,65491
	LD A,C
	CPL
	LD C,A
	LD A,R
	AND 007
	OR 008
	OUT (254),A
	SCF
	RET
; Biturbo 2 loading routine
; by Giovanni "G.B. Max" Zanetti
; Used 1987-1990 ca.
; Readapted by Alessandro Grussu, September 2013
; ------------------
; Standard timings:
; ------------------
; Pilot pulse : 2165
; Pilot length: 3190
; Sync 1 pulse:  714
; Sync 2 pulse:  714
; Zero pulse  :  486
; One pulse   :  833

	ORG 65355

	LD A, 255
	SCF
	INC D
	EX AF, AF'
	DEC D
	DI
	IN A, (254)
	RRA
	AND 32
	OR 2
	LD C, A
	CP A
	RET NZ
	CALL 65485
	JR NC, 65371
	LD HL, 1045
	DJNZ 65380
	DEC HL
	LD A, H
	OR L
	JR NZ, 65380
	CALL 65481
	JR NC, 65371
	LD B, 156
	CALL 65481
	JR NC, 65371
	LD A, 198
	CP B
	JR NC, 65372
	INC H
	JR NZ, 65392
	LD B, 201
	CALL 65485
	JR NC, 65371
	LD A, B
	CP 212
	JR NC, 65407
	CALL 65485
	RET NC
	LD A, C
	XOR 3
	LD C, A
	LD H, 0
	LD B, 208
	JR 65457
	EX AF, AF'
	JR NZ, 65441
	LD (IX+0), L
	JR 65451
	RL C
	XOR L
	RET NZ
	LD A, C
	RRA
	LD C, A
	INC DE
	JR 65453
	INC IX
	DEC DE
	EX AF, AF'
	LD B, 210
	LD L, 1
	CALL 65481
	RET NC
	LD A, 220
	CP B
	RL L
	LD B, 208
	JP NC, 65459
	LD A, H
	XOR L
	LD H, A
	LD A, D
	OR E
	JR NZ, 65433
	RET
	CALL 65485
	RET NC
	LD A, 13
	DEC A
	JR NZ, 65487
	AND A
	INC B
	RET Z
	LD A, 127
	IN A, (254)
	RRA
	XOR C
	AND 32
	JR Z, 65491
	LD A, C
	CPL
	LD C, A
	LD A, B
	NOP
	AND 7
	OR 8
	OUT (254), A
	SCF
	RET

Example files
Post edited by Alessandro Grussu on

Comments

  • edited May 2014
    2) Multi-Load (by Simon Owen)

    First published in Your Sinclair (February 1989 issue) as a type-in, this loading routine was used within a program for 'fancy' screen loading. It comes in four speeds: Normal (same as ROM loading), Medium (not very fast), Fast (very fast) and Aaargh! (too fast, unpractical for real use). Colour schemes are Normal, Multicolor and Masked (no stripes, just a black border).

    The code was originally located at 64000. After some trial and error I managed to relocate it as high as 65200; at higher addresses the code does not work properly, although there is still room left until the top of RAM.

    Here follow the sources for Multicolor Medium and Fast settings.
    ; Multi-Load loading routine
    ; by Simon Owen, 1989
    ; Readapted by Alessandro Grussu, April 2014
    ; -------------------------------
    ; Multicolor/Medium speed version
    ; -------------------------------
    ; Standard timings
    ; Pilot pulse : 2178
    ; Pilot length: 3220
    ; Sync 1 pulse:  714
    ; Sync 2 pulse:  714
    ; Zero pulse  :  625
    ; One pulse   : 1249
    
      ORG 65200
      
      LD A,255
      SCF
      INC D
      EX AF,AF'
      DEC D
      DI
      LD A,008
      OUT (254),A
      LD HL,01343
      PUSH HL
      IN A,(254)
      RRA
      AND 032
      OR 002
      LD C,A
      CP A
      RET NZ
      CALL 65332
      JR NC,65224
      LD H,100
      LD B,000
      CALL 65328
      LD B,156
      CALL 65328
      JR NC,65224
      LD A,198
      CP B
      JR NC,65225
      DEC H
      JR NZ,65237
      LD B,201
      CALL 65332
      JR NC,65224
      LD A,B
      CP 212
      JR NC,65252
      CALL 65332
      RET NC
      LD A,C
      XOR 003
      LD C,A
      LD H,000
      LD B,202
      JR 65302
      EX AF,AF'
      JR NZ,65286
      LD (IX+000),L
      JR 65296
      RL C
      XOR L
      RET NZ
      LD A,C
      RRA
      LD C,A
      INC DE
      JR 65298
      INC IX
      DEC DE
      EX AF,AF'
      LD B,204
      LD L,001
      CALL 65328
      RET NC
      LD A,221
      CP B
      RL L
      LD B,207
      JR NC,65304
      LD A,H
      XOR L
      LD H,A
      LD A,D
      OR E
      JR NZ,65278
      LD A,H
      CP 001
      RET
      CALL 65332
      RET NC
      LD A,016
      DEC A
      JR NZ,65334
      AND A
      INC B
      RET Z
      LD A,127
      IN A,(254)
      RRA
      RET NC
      XOR C
      AND 032
      JR Z,65338
      LD A,C
      CPL
      LD C,A
      XOR L
      NOP
      AND 007
      OR 008
      OUT (254),A
      SCF
      PUSH AF
      PUSH HL
      LD A,(65391)
      AND A
      JR Z,65386
      LD A,(65389)
      LD HL,(65390)
      LD (HL),A
      XOR A
      LD (65391),A
      LD IX,65389
      POP HL
      POP AF
      RET
    
    ; Multi-Load loading routine
    ; by Simon Owen, 1989
    ; Readapted by Alessandro Grussu, April 2014
    ; -----------------------------
    ; Multicolor/Fast speed version
    ; -----------------------------
    ; Standard timings
    ; Pilot pulse : 2178
    ; Pilot length: 3220
    ; Sync 1 pulse:  714
    ; Sync 2 pulse:  714
    ; Zero pulse  :  399
    ; One pulse   :  798
    
      ORG 65200
    
      LD A,255
      SCF
      INC D
      EX AF,AF'
      DEC D
      DI
      LD A,008
      OUT (254),A
      LD HL,01343
      PUSH HL
      IN A,(254)
      RRA
      AND 032
      OR 002
      LD C,A
      CP A
      RET NZ
      CALL 65332
      JR NC,65224
      LD H,100
      LD B,000
      CALL 65328
      LD B,156
      CALL 65328
      JR NC,65224
      LD A,198
      CP B
      JR NC,65225
      DEC H
      JR NZ,65237
      LD B,201
      CALL 65332
      JR NC,65224
      LD A,B
      CP 212
      JR NC,65252
      CALL 65332
      RET NC
      LD A,C
      XOR 003
      LD C,A
      LD H,000
      LD B,228
      JR 65302
      EX AF,AF'
      JR NZ,65286
      LD (IX+000),L
      JR 65296
      RL C
      XOR L
      RET NZ
      LD A,C
      RRA
      LD C,A
      INC DE
      JR 65298
      INC IX
      DEC DE
      EX AF,AF'
      LD B,230
      LD L,001
      CALL 65328
      RET NC
      LD A,239
      CP B
      RL L
      LD B,228
      JR NC,65304
      LD A,H
      XOR L
      LD H,A
      LD A,D
      OR E
      JR NZ,65278
      LD A,H
      CP 001
      RET
      CALL 65332
      RET NC
      LD A,005
      DEC A
      JR NZ,65334
      AND A
      INC B
      RET Z
      LD A,127
      IN A,(254)
      RRA
      RET NC
      XOR C
      AND 032
      JR Z,65338
      LD A,C
      CPL
      LD C,A
      XOR L
      NOP
      AND 007
      OR 008
      OUT (254),A
      SCF
      PUSH AF
      PUSH HL
      LD A,(65391)
      AND A
      JR Z,65386
      LD A,(65389)
      LD HL,(65390)
      LD (HL),A
      XOR A
      LD (65391),A
      LD IX,65389
      POP HL
      POP AF
      RET
    

    Example file
  • edited May 2014
    3) SG (Special Games)

    This loading scheme was used between 1987 and 1989 in the Special Games tape magazines published by Edigamma, the second force - after SIPE - of the Italian market of hacked games with false names sold with magazines in newsagents.

    It is a strange loader, with a peculiar frequency, unusual color scheme and a long pilot tone. It is not very fast - loads a headerless screen data file in about 28 seconds against the 21 of Biturbo II. The author is unknown.
    ; Special Games turbo loading routine
    ; Author unknown
    ; Used ca. 1987-1989
    ; Readapted by Alessandro Grussu in April 2014
    ; 
    ; Standard timings:
    ;
    ; Pilot pulse : 2165
    ; Pilot length: 8100
    ; Sync 1 pulse:  714
    ; Sync 2 pulse:  714
    ; Zero pulse  :  500
    ; One pulse   : 1250
    
      ORG 65354
    
      LD A,255
      SCF
      INC D
      EX AF,AF'
      DEC D
      DI
      LD A,015
      OUT (254),A
      LD HL,01343
      PUSH HL
      IN A,(254)
      RRA
      AND 032
      OR 002
      LD C,A
      CP A
      RET NZ
      CALL 65502
      JR NC,65378
      LD HL,01045
      DJNZ 65387
      DEC HL
      LD A,H
      OR L
      JR NZ,65387
      CALL 65498
      JR NC,65378
      LD B,156
      CALL 65498
      JR NC,65378
      LD A,198
      CP B
      JR NC,65379
      INC H
      JR NZ,65399
      LD B,201
      CALL 65502
      JR NC,65378
      LD A,B
      CP 212
      JR NC,65414
      CALL 65502
      RET NC
      LD A,C
      XOR 003
      LD C,A
      LD H,000
      LD B,210
      JR 65471
      EX AF,AF'
      JR NZ,65450
      JR NC,65460
      LD (IX+000),L
      JR 65465
      RL C
      XOR L
      RET NZ
      LD A,C
      RRA
      LD C,A
      INC DE
      JR 65467
      LD A,(IX+000)
      XOR L
      RET NZ
      INC IX
      DEC DE
      EX AF,AF'
      LD B,212
      LD L,001
      CALL 65498
      RET NC
      LD A,225
      CP B
      RL L
      LD B,210
      JP NC,65473
      LD A,H
      XOR L
      LD H,A
      LD A,D
      OR E
      JR NZ,65440
      LD A,H
      CP 001
      RET
      CALL 65502
      RET NC
      LD A,015
      DEC A
      JR NZ,65504
      AND A
      INC B
      RET Z
      LD A,127
      IN A,(254)
      RRA
      RET NC
      XOR C
      AND 032
      JR Z,65508
      LD A,C
      CPL
      LD C,A
      PUSH AF
      AND B
      AND 007
      OR 008
      OUT (254),A
      POP AF
      SCF
      RET
    

    Example file
  • edited May 2014
    4) Kobrahsoft Advanced Super Speedloader 3

    A flexible (six speeds available) and reliable loader that I have used for Cronopios y Famas, Kobrahsoft's SL3 comes with no less than 13 different combination of colors. Although I employed speed 4 at first (CYF's TZX files are 'recorded' at it), I think speed 3 would be a safer bet although I did not experience any problem whatsoever with the faster option when tested on real hardware. Hence, as an example, follow the sources for the multicolor and magenta-green/black-white loading routines both at speed 3, which is still very fast.
    ; Kobrahsoft Advanced Super Speedloader 3
    ; Multicolor/Speed 3 version
    ; Readapted by Alessandro Grussu, April 2014
    ; --------------------
    ; Timings for speed 3:
    ; Pilot pulse	2178
    ; Pilot length	3221
    ; Sync 1 pulse	 635
    ; Sync 2 pulse	 714
    ; Zero pulse	 396
    ; One pulse		 791
    
      ORG 65356
    
      SCF
      LD A,255
      INC D
      EX AF,AF'
      DEC D
      DI
      LD A,015
      OUT (254),A
      LD HL,01343
      PUSH HL
      IN A,(254)
      RRA
      AND 032
      OR 002
      LD C,A
      CP A
      RET NZ
      CALL 65504
      JR NC,65380
      LD HL,01045
      DJNZ 65389
      DEC HL
      LD A,H
      OR L
      JR NZ,65389
      CALL 65500
      JR NC,65380
      LD B,156
      CALL 65500
      JR NC,65380
      LD A,198
      CP B
      JR NC,65381
      INC H
      JR NZ,65401
      LD B,201
      CALL 65504
      JR NC,65380
      LD A,B
      CP 212
      JR NC,65416
      CALL 65504
      RET NC
      LD A,C
      XOR 003
      LD C,A
      LD H,000
      LD B,176
      JR 65473
      EX AF,AF'
      JR NZ,65452
      JR NC,65462
      LD (IX+000),L
      JR 65467
      RL C
      XOR L
      RET NZ
      LD A,C
      RRA
      LD C,A
      INC DE
      JR 65469
      LD A,(IX+000)
      XOR L
      RET NZ
      INC IX
      DEC DE
      EX AF,AF'
      LD B,178
      LD L,001
      CALL 65500
      RET NC
      LD A,187
      CP B
      RL L
      LD B,176
      JP NC,65475
      LD A,H
      XOR L
      LD H,A
      LD A,D
      OR E
      JR NZ,65442
      LD A,H
      CP 001
      RET
      CALL 65504
      RET NC
      LD A,009
      DEC A
      JR NZ,65506
      AND A
      INC B
      RET Z
      LD A,127
      IN A,(254)
      RRA
      RET NC
      XOR C
      AND 032
      JR Z,65510
      LD A,C
      CPL
      LD C,A
      LD A,R
      AND 007
      OR 008
      OUT (254),A
      SCF
      RET
    
    ; Kobrahsoft Advanced Super Speedloader 3
    ; Magenta-green/Black-white/Speed 3 version
    ; Readapted by Alessandro Grussu, April 2014
    ; --------------------
    ; Timings for speed 3:
    ; Pilot pulse	2178
    ; Pilot length	3221
    ; Sync 1 pulse	 635
    ; Sync 2 pulse	 714
    ; Zero pulse	 396
    ; One pulse		 791
    
      ORG 65356
    
      SCF
      LD A,255
      INC D
      EX AF,AF'
      DEC D
      DI
      LD A,015
      OUT (254),A
      LD HL,01343
      PUSH HL
      IN A,(254)
      RRA
      AND 032
      OR 003
      LD C,A
      CP A
      RET NZ
      CALL 65504
      JR NC,65380
      LD HL,01045
      DJNZ 65389
      DEC HL
      LD A,H
      OR L
      JR NZ,65389
      CALL 65500
      JR NC,65380
      LD B,156
      CALL 65500
      JR NC,65380
      LD A,198
      CP B
      JR NC,65381
      INC H
      JR NZ,65401
      LD B,201
      CALL 65504
      JR NC,65380
      LD A,B
      CP 212
      JR NC,65416
      CALL 65504
      RET NC
      LD A,C
      XOR 003
      LD C,A
      LD H,000
      LD B,176
      JR 65473
      EX AF,AF'
      JR NZ,65452
      JR NC,65462
      LD (IX+000),L
      JR 65467
      RL C
      XOR L
      RET NZ
      LD A,C
      RRA
      LD C,A
      INC DE
      JR 65469
      LD A,(IX+000)
      XOR L
      RET NZ
      INC IX
      DEC DE
      EX AF,AF'
      LD B,178
      LD L,001
      CALL 65500
      RET NC
      LD A,187
      CP B
      RL L
      LD B,176
      JP NC,65475
      LD A,H
      XOR L
      LD H,A
      LD A,D
      OR E
      JR NZ,65442
      LD A,H
      CP 001
      RET
      CALL 65504
      RET NC
      LD A,009
      DEC A
      JR NZ,65506
      AND A
      INC B
      RET Z
      LD A,127
      IN A,(254)
      RRA
      RET NC
      XOR C
      AND 032
      JR Z,65510
      LD A,C
      CPL
      LD C,A
      EX DE,HL
      EX DE,HL
      AND 007
      OR 008
      OUT (254),A
      SCF
      RET
    

    Example file
  • edited May 2014
    5) Erbe Software

    Another loading scheme I just isolated, taken from the Erbe re-release of Cobra. I don't know if it was used with other titles, but presumably it was.

    Speed seems to be pretty much the same as Biturbo I/II.
    ; Erbe Software loading scheme
    ; Readapted by Alessandro Grussu, May 2014
    ; ------------------
    ; Standard timings :
    ; ------------------
    ; Pilot pulse : 2113
    ; Pilot length: 4832
    ; Sync 1 pulse:  833
    ; Sync 2 pulse:  833
    ; Zero pulse  :  425
    ; One pulse   :  850
    
      ORG 65356
    
      LD A,255
      SCF
      INC D
      EX AF,AF'
      DEC D
      DI
      LD A,015
      OUT (254),A
      LD HL,01343
      PUSH HL
      IN A,(254)
      RRA
      AND 032
      OR 002
      LD C,A
      CP A
      CALL 65503
      JR NC,65380
      LD HL,01389
      DJNZ 65388
      DEC HL
      LD A,H
      OR L
      JR NZ,65388
      CALL 65499
      JR NC,65380
      LD B,142
      CALL 65499
      JR NC,65380
      LD A,195
      CP B
      JR NC,65380
      INC H
      JR NZ,65400
      LD B,190
      CALL 65503
      JR NC,65380
      LD A,B
      CP 212
      JR NC,65415
      CALL 65503
      RET NC
      LD A,C
      XOR 003
      LD C,A
      LD H,000
      LD B,224
      JR 65472
      EX AF,AF'
      JR NZ,65451
      JR NC,65461
      LD (IX+000),L
      JR 65466
      RL C
      XOR L
      RET NZ
      LD A,C
      RRA
      LD C,A
      INC DE
      JR 65468
      LD A,(IX+000)
      XOR L
      RET NZ
      INC IX
      DEC DE
      EX AF,AF'
      LD B,226
      LD L,001
      CALL 65499
      RET NC
      LD A,235
      CP B
      RL L
      LD B,224
      JP NC,65474
      LD A,H
      XOR L
      LD H,A
      LD A,D
      OR E
      JR NZ,65441
      LD A,H
      CP 001
      RET
      CALL 65503
      RET NC
      LD A,012
      DEC A
      JR NZ,65505
      AND A
      INC B
      RET Z
      LD A,127
      IN A,(254)
      RRA
      NOP
      XOR C
      AND 032
      JR Z,65509
      LD A,C
      CPL
      LD C,A
      LD A,R
      AND 007
      OR 008
      OUT (254),A
      SCF
      RET
    

    Example file
  • edited May 2014
    Nice, I do like a turbo loader... look forward to fiddling with these :)
    The comp.sys.sinclair crap games competition 2015
    "Let's not be childish. Let's play Spectrum games."
  • edited May 2014
    leespoons wrote: »
    Nice, I do like a turbo loader... look forward to fiddling with these :)

    Thank you leespoons; actually, there is more to come, because I just found this.

    6) Alternative Software

    Used in this release from the software house; I don't remember it being present in other Alternative titles right now.

    Border pattern looks very similar to Biturbo I, although as a loader it is noticeably slower - will load a headerless screen data file in about 25 seconds. Still faster than SG, though.
    ; Alternative Software loading scheme
    ; Readapted by Alessandro Grussu, May 2014
    ; ------------------
    ; Standard timings :
    ; ------------------
    ; Pilot pulse : 2168
    ; Pilot length: 3220
    ; Sync 1 pulse:  667
    ; Sync 2 pulse:  735
    ; Zero pulse  :  550
    ; One pulse   : 1100
    
      ORG 65351
    
      LD A,255
      SCF
      INC D
      EX AF,AF'
      DEC D
      DI
      LD A,015
      OUT (254),A
      LD HL,01343
      PUSH HL
      IN A,(254)
      RRA
      AND 032
      OR 002
      LD C,A
      CP A
      RET NZ
      CALL 65499
      JR NC,65375
      LD HL,01045
      DJNZ 65384
      DEC HL
      LD A,H
      OR L
      JR NZ,65384
      CALL 65495
      JR NC,65375
      LD B,156
      CALL 65495
      JR NC,65375
      LD A,198
      CP B
      JR NC,65376
      INC H
      JR NZ,65396
      LD B,201
      CALL 65499
      JR NC,65375
      LD A,B
      CP 212
      JR NC,65411
      CALL 65499
      LD A,C
      RET NC
      XOR 003
      LD C,A
      LD H,000
      LD B,176
      JR 65468
      EX AF,AF'
      JR NZ,65447
      JR NC,65457
      LD (IX+000),L
      JR 65462
      RL C
      XOR L
      RET NZ
      LD A,C
      RRA
      LD C,A
      INC DE
      JR 65464
      LD A,(IX+000)
      XOR L
      RET NZ
      INC IX
      DEC DE
      EX AF,AF'
      LD B,178
      LD L,001
      CALL 65495
      RET NC
      LD A,189
      CP B
      RL L
      LD B,176
      JP NC,65470
      LD A,H
      XOR L
      LD H,A
      LD A,D
      OR E
      JR NZ,65437
      LD A,H
      CP 001
      RET
      CALL 65499
      RET NC
      LD A,022
      DEC A
      JR NZ,65501
      AND A
      INC B
      RET Z
      LD A,127
      IN A,(254)
      RRA
      XOR C
      AND 032
      JR Z,65505
      LD A,C
      CPL
      LD C,A
      LD A,(65535)
      INC A
      LD (65535),A
      AND 007
      OR 008
      OUT (254),A
      SCF
      RET
    

    Example file
  • edited May 2014
    i love a good loader, so maybe i'm a little too excited and off topic. but i'm sure i heard a rumour once about a speccy loader that used the full screen and not just the border.

    not sure if that would even count as a turbo loader?

    anyway, please delete this post if its not relevant, and i'll ask elsewhere
  • edited May 2014
    i love a good loader, so maybe i'm a little too excited and off topic. but i'm sure i heard a rumour once about a speccy loader that used the full screen and not just the border.

    There is one, but for technical reasons it only works in 128k mode. Can't remember what it's called offhand though but I think it came out of the demo scene - I'll post a link if I remember.

    edit:
    Song in Lines 5 and MDA Demo both by Busysoft.

    Also Lyra II Megademo which was on a SU cover tape in 1991.

    And finally Removal Deluxe which performs the neat trick of loading the loader itself as a short BASIC program then switching straight to full screen mode with no leader in between (I've always wondered if this was possible) - can't get the game to work though :(
    The comp.sys.sinclair crap games competition 2015
    "Let's not be childish. Let's play Spectrum games."
  • edited May 2014
    Thanks for such a valuable collection there Alessandro!!!... Now just have to figure out how to use Tapir to create the data for them... Never realised there were so many variations... Ideally, it would be great if there was an easy to use cross development tool (perhaps Java) with options to auto generate .TZX files using these schemes... Perhaps something that could take data in, and spit it out according to these loaders...

    Nice work - its definitely going into my ZX library of useful assembly files!.. :)
  • edited May 2014
    kgmcneil wrote: »
    Thanks for such a valuable collection there Alessandro!!!... Now just have to figure out how to use Tapir to create the data for them... Never realised there were so many variations... Ideally, it would be great if there was an easy to use cross development tool (perhaps Java) with options to auto generate .TZX files using these schemes... Perhaps something that could take data in, and spit it out according to these loaders...

    Nice work - its definitely going into my ZX library of useful assembly files!.. :)

    Thanks! As for the Tapir bit, it's dead easy. Just open in it the file with the data you need to convert, then select the desired block and from the drop-down menu in the lower part of the Tapir window select Turbo speed. The timings will now be editable. Just change the six values in accordance with the loading scheme you are using and click on the 'Commit' button (lower right). Et voila - you now have your turbo block ready.

    Examine the example files I provided here in Tapir to see how values change from one scheme to another.
  • edited May 2014
    Thank you Timmy!

    Here is another practical demonstration of some of these loaders put to work. The Loader-examples.zip archive contains the following:
    • Pieces Of Eight (Vadim's repacked version with initial screen restored), reassembled with Special Games loader;
    • Slowglass (128K), transferred from the DSK file, packed and reassembled with Multi-Load at Fast speed;
    • Thanatos (128K fixed version with full compatibility), packed and reassembled with Kobrahsoft SL3 - Multicolor, Speed 3;
    • Xecutor (bug-fixed by Einar Saukas), packed and reassembled with Erbe loader.
    [URL="http://http://www.alessandrogrussu.it/zx/Loader-examples.zip"]Download[/URL]
  • edited August 2014
    Some more turbo versions of recent games. Tested on real hardware as well as under emulation.

    Azzurro 8-bit Jam (Multi-Load fast setting), 2'01" [previously 4'12"]

    Box Reloaded (Kobrahsoft SL3 speed 3), 1'29" [4'44"]

    El Stompo (Multi-Load fast setting), 1'07" [4'26"]

    Isotopia (Kobrahsoft SL3 speed 3), 4'44" [9'33"]

    Knightmare ZX (Kobrahsoft SL3 speed 3), 3'40" [7'05"]

    Sunbucket (Multi-Load fast setting), 1'04" [4'16"]
  • edited August 2014
    More turbo versions.

    Dingo (Multi-Load fast setting), 2'09" [previously 4'31"]

    The Speccies (Multi-Load fast setting), 2'06" [4'30"]

    Speccy Bros. (Multi-Load fast setting), 1'39" [3'32"]
  • I've been messing with a 'turbo' loader these last few days working with ROM loader timings (plus one extra large pulse!) and changing the encoding method to speed things up.

    I have 855T pulses to store a copy of the 'current' tape bit value, 1710T to invert the current bit value and store, and the huge 2327T (only on the first byte pulse) which indicates that the byte is a copy of the previously loaded byte.

    It's not brilliant. Except after CLS!
  • Save_Bytes        proc
                      ld    hl,#053f
                      push  hl
    
                      ld    hl,#0c98
    
    l04d0:            ex    af,af'             ; flag byte to A'
    
                      ld    a,(ix+0)
                      inc   a
                      ld    (LDSV_lastbyte),a ; ensure mismatch in last byte check in first saved byte
    
                      inc   de
                      dec   ix
                      di
                      ld    a,#02
                      ld    b,a
    l04d8:            djnz  l04d8
    
                      out   (#fe),a
                      xor   #0f
                      ld    b,#a4
                      dec   l
                      jr    nz,l04d8
    
                      dec   b
                      dec   h
                      jp    p,l04d8
    
                      ld    b,#2f
    l04ea:            djnz  l04ea
    
                      out   (#fe),a
                      ld    a,#0d
                      ld    b,#37
    l04f2:            djnz  l04f2
    
                      out   (#fe),a
                      ld    b,#3b
                      xor   a           ; set initial last bit saved flag
                      ex    af,af'      ; and move to A'
                      ld    l,a         ; flag byte to L
                      jp    l0507       ; branch to save the flag byte (which will not be a repeating byte) and initialise parity
    
    
                      ; pulses at 855t  for normal byte save
                      ;           1710t for repeating bit save
                      ;           2327t for repeating last byte saved
    
    save_byte:        ld    a,d
                      or    e
                      jp    z,save_parity           ; 18
    
                      ld    l,(ix+#00)
                      ld    a,(LDSV_lastbyte)
                      cp    l
                      jp    nz,sv_new_last_byte     ; +43 = 61
    
                      ; 2327t
    tpulse1           defl  (2327-61-37)/13
    tpulse2           defl  2327/13
                      ld    bc,+(tpulse1 shl 8) or tpulse2
                      call  save_edge_bc
                      jp    sv_next_byte            ; Note: we skip updating parity for repeating bytes
    
    sv_new_last_byte: ld    a,l
                      ld    (LDSV_lastbyte),a       ; +14 = 75
    
                      ; 855t
    tpulse1           defl  (855-75-37)/13
    tpulse2           defl  855/13
    sv_normal:        ld    bc,+(tpulse1 shl 8) or tpulse2
                      call  save_edge_bc
                      jp    save_byte_entry
    
                      ; 855t
    tpulse1           defl  (855-18-31)/13
    tpulse2           defl  855/13
    save_parity:      ld    l,h
                      ld    bc,+(tpulse1 shl 8) or tpulse2
                      call  save_edge_bc
    
    
    save_byte_entry:  ld    b,#31-2
                      ld    a,h
                      xor   l
    l0507:            ld    h,a
                      ld    a,#01
                      scf
                      jp    l0525
    
    l0511:            ld    a,#0e
                      bit   7,b
    
    l0514:            djnz l0514
    
                      ex    af,af'
                      jr    nc,l051c
    
                      ld    b,#42
    l051a:            djnz  l051a
    
    l051c:            ex    af,af'
                      out  (#fe),a
    
                      ld    b,#3e
                      jr    nz,l0511
    
                      ld    a,l
                      or    a
                      rl    a
                      jr    z,sv_next_byte
    
                      ld    b,#3b
                      xor   a
                      inc   a           ; A = 1 for border/mic, clear Carry to rotate into L
    
    l0525:            ex    af,af'
                      xor   l           ; look for bit transition in bit 7
                      rla               ; Carry set for bit transitions
                      ld    a,l         ; take a copy of L before rotating
                      ex    af,af'
                      ld    b,#39
    
                      rl    l
                      jp    nz,l0514
    
    
    sv_next_byte:     dec   de
                      inc   ix
                      ld    b,#31
                      ld    a,#7f
                      in    a,(#fe)
                      rra
                      ret   nc
    
                      ld    a,d
                      inc   a
                      jp    nz,save_byte
    
                      ld    b,#3b
    l053c:            djnz  l053c
                      ret
    
    save_edge_bc:     djnz  save_edge_bc
                      ld    a,1
                      out  (#fe),a
    
                      ld    b,c
    .sv_pulse_len2:   djnz  .sv_pulse_len2
                      ld    a,#0e
                      out  (#fe),a
                      ret
    
                      endp
    
    Load_Bytes        proc
    
                      inc   d
                      ex    af,af'
                      dec   d
                      di
                      ld    a,#0f
                      out   (#fe),a
                      ld    hl,#053f
                      push  hl
                      in    a,(#fe)
                      rra
                      and   #20
                      or    #02
                      ld    c,a
                      cp    a
    l056b:            ret   nz
    
    l056c:            call  l05e7
                      jr    nc,l056b
    
                      ld    hl,#0415
    l0574:            djnz  l0574
    
                      dec   hl
                      ld    a,h
                      or    l
                      jr    nz,l0574
    
                      call  l05e3
                      jr    nc,l056b
    
    l0580:            ld    b,#9c
                      call  l05e3
                      jr    nc,l056b
    
                      ld    a,#c6
                      cp    b
                      jr    nc,l056c
    
                      inc   h
                      jr    nz,l0580
    
    l058f:            ld    b,#c9
                      call  l05e7
                      jr    nc,l056b
    
                      ld    a,b
                      cp    #d4
                      jr    nc,l058f
    
                      call  l05e7
                      ret   nc
    
                      ld    a,c
                      xor   #03
                      ld    c,a
                      ld    h,#00
                      ld    b,#b0
    
                      ld    l,#01
                      res   7,c               ; initialise last bit loaded state
                      jr    .wait_pulse       ; first (flag) byte will not be a repeating byte
    
    l05a9:            ex    af,af'
                      jr    nz,l05b3
    
                      jr    nc,l05bd
    
                      ld    (ix+#00),l
                      ld    a,l
                      ld    (LDSV_lastbyte),a
                      jr    l05c2
    
    l05b3:            push  bc
                      rl    c
                      xor   l
    
                      ld    a,c
                      pop   bc
                      ret   nz
                      rra
    
                      ex    af,af'
                      ld    b,#b1
                      jr    l05c8
    
    l05bd:            ld    a,(ix+#00)
                      xor   l
                      ret   nz
    
    l05c2:            inc   ix
    l05c4:            dec   de
    
    l05c5:            ex    af,af'
                      ld    b,#b2
    l05c8:            ld    l,#01
    
    ; bd = 189
    ; da = 218
    ; f3 = 243
    ; cp #cb = 203
    ; cp #e6 = 230
    
                      ; pulses at 855t  for store current bit
                      ;           1710t for toggle and store current bit
                      ;           2327t for repeating last byte loaded (first byte pulse only)
    
                      call  l05e3
                      ret   nc
    
                      ld    a,b               ; testing first pulse for long pulse length
                      cp    #e6
                      jp    nc,.ld_repeat_byte
    
                      ld    b,#b2
    .wait_pulse:      call  l05e3
                      ret   nc
    
                      ld    a,#cb
                      cp    b
                      jr    nc,.set_load_bit
    
                      ld    a,c
                      xor   128
                      ld    c,a
    
    .set_load_bit:    ld    a,c
                      rla
    
                      rl    l
                      ld    b,#b0-1
                      jp    nc,.wait_pulse
    
    .loaded_byte:     ld    a,h
                      xor   l
                      ld    h,a
    
    .rep_byte_load:   ld    a,d
                      or    e
                      jr    nz,l05a9
    
                      ld    a,h
                      cp    #01
                      ret
    
    l05e3:            call  l05e7
                      ret   nc
    
    l05e7:            ld    a,#16
    l05e9:            dec   a
                      jr    nz,l05e9
    
                      and   a
    l05ed:            inc   b
                      ret   z
    
                      ld    a,#7f
                      in    a,(#fe)
                      rra
                      ret   nc
    
                      xor   c
                      and   #20
                      jr    z,l05ed
    
                      ld    a,c
                      xor   %00100111
                      ld    c,a
                      and   #07
                      or    #08
                      out   (#fe),a
                      scf
                      ret
    
    .ld_repeat_byte:  ld   a,(LDSV_lastbyte)
                      ld   l,a
                      jp   .rep_byte_load           ; we won't update parity with repeating bytes
    
                      endp
    
  • ROM loader + Exomizer or equivalent for even more turbo out of the box ... amazing isn't it
  • Hikaru wrote: »
    ROM loader + Exomizer or equivalent for even more turbo out of the box ... amazing isn't it

    Yes, but my idea is for something a bit quicker than the ROM loader but using timings as reliable for loading data after compression!
  • Hikaru wrote: »
    ROM loader + Exomizer or equivalent for even more turbo out of the box ... amazing isn't it
    No.
    I wanna tell you a story 'bout a woman I know...
  • Three loading screens using the turbo version of my new loader:


    500T for store current bit, 1000T for invert current bit and store, 1500T to repeat last loaded byte.
Sign In or Register to comment.