ZX Spectrum - a procedure for fast multiloader with music.

Never Mind #01
multiloader


.sti^mlt


 Cool thing multiloader, but damn slow!!!
 Today I will talk here about the fast muleloader...


 Well, let's start with the fact that what about this crap?
works...
 The hedgehog understands that it will not be possible to simply taxi #3d13, but in
In general, who needs #3d13 let him suck without music (ay-rulez!!!).
 Since we abandoned #3d13, we will have to use VG without
anyone or anything. Well, this is not a problem - the Spectrumists have the brains
not for nothing for nothing!!!


 The entry point to the DOS ROM is #3d2f. Since there are a lot of dos, then
Let's talk about using some procedures like in a,(#1f) and
etc.: guys, do it better 'through the ass', i.e. like ours
grandfathers, for the reason that if in your dos, for example, at the address
#1000 is, for example, the same in a,(#1f) this is not at all
means your neighbor has the same thing!!!


   And so, we have:


 #3d2f, disk reading point #2090 (we are using it, because
it is standard).
 If you look at the DOS ROM, we will notice that at this address
is located di :(, but it doesn’t matter, who’s stopping us from taxiing right away
on 2091???
 This procedure reads one sector to the HL address, from the DE address,
which is what we need.


 The trick is that you don't have to wait until it's counting
this sector from the disk, but simply enter it into the table
uncounted sectors, and count them in the second pass along the same
algorithm, and so onthen depending on how many sectors to read ;)


   Here is a listing of a working loader:


       ORG #C000
+ INCBIN "muzon

MUSIC EQU #C000
PLAY EQU #C006

       ORG #6000
       CALL im2 ;turn on im
       EXX
       LD HL,table;addresses of uncounted sectors
       LD C,#00 ;number of uncounted sectors
       EXX
       LD HL,#4000 ;to which address to read
       LD DE,#0B02 ;sector/track
       LD C,#1B ;how many sectors
       CALL LOADER
       CALL STP ;exit from interrupts
       RET ;I don’t remember ;)
 im2 CALL MUSIC
       D.I.
       LD HL,#5E00
       LD DE,#5E01
       LD B,E
       LD C,L
       LD(HL),H
       LD A,H
       LDIR
       LD I,A
       LD A,#C3
       LD (#5E5E),A
       IM #02
       LD HL,MULT
       LD (#5E5F),HL
       EI
       RET

LOADER EI
       PUSH BC
       CALL posit ; positioning
       CALL read_s ; I may be wrong, but it's faster this way
       CALL read_s ; reads than with one (?)
       OR A
       JR Z,rulez ;if counted, to the next sector
       PUSH DE
       LD A,H
       EXX
       POP DE
       LD(HL),E ; write the sector number in the table
       INC HL
       LD(HL),D ; write down the track number
       INC HLLD(HL),A ; address in memory too, so as not to count
       INC HL
       INC C ;increase the number of uncounted sectors
       EXX
rulez INC H; transition procedure
       INC E ; to the next sector
       BIT #04,E ;  (stolen somewhere)
       JR Z,cool ;
       INC D ;
       LD E,#00 ;
cool POP BC
       DEC C; reduce the number of remaining sec
       JR NZ,LOADER+#01
       EXX ;reading is done here in two passes,
                         ;one to the table, and the second to complete
                         ;reading
       CALL from ;take the first unread sector
loader EI
       PUSH BC
read CALL posit
       CALL read_s
       CALL read_s
       OR A
       JR NZ,read;read until it is completely read
       CALL from ;take the next one
       POP B.C.
       DEC C ;reduce the number of unread sectors
       JR NZ,loader+#01
       RET
from LD DE,(table)
       LD HL,(from+#02)
       INC HL
       INC HL
       INC HL
       LD (from+#02),HL
       DEC HL
       LD H,(HL)
       LD L,#00
       RET

posit LD A,E
       INC A
       LD C,#5F
       CALL dos
       LD A,D
       SRL A
       LD C,#7F
       CALL dos
       LD A,#3CBIT     #00,D
       JR      Z,side
       LD      A,#2C
side   LD      C,#FF
       CALL    dos
       LD      A,#18
       LD      C,#1F
dos    LD      IX,#2A53
dos_   PUSH    IX
       JP      #3D2F

MULT   PUSH    AF
       PUSH    DE
       PUSH    HL
       PUSH    BC
       PUSH    IX
       PUSH    IY
       EXX
       PUSH    HL
       PUSH    DE
       PUSH    BC
       EX      AF,AF'
       PUSH    AF
       LD      A,#10      ; то, что и
       LD      BC,#7FFD   ; будет выполняться
       OUT     (C),A      ; во время
       CALL    PLAY       ;      прерывания
bann   LD      A,#13      ;
       LD      BC,#7FFD   ;
       OUT     (C),A      ;
       POP     AF
       EX      AF,AF'
       POP     BC
       POP     DE
       POP     HL
       EXX
       POP     IY
       POP     IX
       POP     BC
       POP     HL
       POP     DE
       POP     AF
       EI
end    JP      #3D2F
STP    DI
       PUSH    AF
       PUSH    DE
       PUSH    BC
       XOR     A
       LD      D,#0C
STOP1  LD      BC,#FFFD
       OUT     (C),D
       LD      B,#BF
       OUT     (C),A
       DEC     D
       JP      P,STOP1
       LD      A,#3F
       LD      I,A
       IM      #01
       POP     BC
       POP     DE
       POP     AF
       EI
       RET

read_s PUSH    BC
       PUSH    DE
       PUSH    HL
       XOR     A
       LD      (#5CD6),A
       CALL    dosaLD A,(#5CD6)
       POP HL
       POP DE
       POP B.C.
       RET
dosa EXX
       LD DE,gandonk
       LD A,#01
       LD(DE),A
       PUSH DE
       EXX
       LD BC,#2091
       PUSH BC
       LD BC,#017F
       JP #3D2F

gandonk
       DEFB #01 ;that's right
table ;the length of this table depends on the length of the load block

Share your thoughts about the article