Programming - ZX-STANDARD FOR AUTO-RUNNING CDs v1.0

Since whoever stood up first gets the slippers, then:

               ZX-STANDARD FOR AUTO-RUNNING CDs
                              v1.0

On autorun CD (CDFS / ISO 9660 / ECMA-119 format) in
the root directory should contain the file AUTORUN.ZX (behind
capital letters don't worry, Nero capitalizes names
files automatically) no longer than #8000 bytes. It loads by
address #6000 (port value #7ffd is #10) and starts at
address #6000 with IM1 interrupts disabled, while the current
The CD drive is initialized and is the current device, except
In addition, an attempt was made to switch it to low speed.

Registers in this case:
SP=#6000 
IY=23610 
A=#A0 (master) or #B0 (slave) [may be thrown out because 
 1. on ZX the situation CD-ROM=slave has already been established; 2. for games,
 most likely you won't need to switch to others
 devices]
B=computer type: 0=PENTAGON, 1=ATM, 2=SCORPION, 3=PROFI, 
 4=SPRINTER
C=IDE controller type: 0=NEMO, 1=ATM, 2=SMUC, 3=PROFI, 
 4=SPRINTER
D=language: 0=ENGLISH, 1=RUSSIAN 
E=COVOX address: #FB=ATM/PENTAGON, #DD=SCORP, ..., #FF=absent 
HL=available video modes (overlaid by OR): 
 ;1=512x192 BW VMG
 ;2=384x304 ZX AC
 ;4=256x192 15 AC
 ;8=320x200 16 ATM
The remaining values and bits are reserved for now.

                        END OF STANDARD

The included bootloader is not very stable yet,
Advice for improvement is acceptedstability of its work
(later we will flash it into ROM). Limitations of this
bootloader:
- no more than 30 sessions on disk (information is taken from the last one); 
- no more than #8000 bytes distance from the beginning of the root directory to 
end of AUTORUN.ZX descriptor; 
- IY, IM1 and #7ffd are assumed to be already installed. 

;loader of the file "AUTORUN.ZX" from CD at #6000
device=#B0
comptype=1
idetype=1
language=1
COVPORT=#FB
videomodes=8

;===============only NEMO,SMUC,ATM are supported below============
        IFO comptype-1
atm=1
        ELSE
atm=0
        ENDIF
        IFO idetype-2
smuc=1|atm
        ELSE
smuc=atm
        ENDIF
       IFN smuc
      IFN atm
;ATM scheme:
hddstat=#FEEF
hddcmd=#FEEF
hddhead=#FECF
hddcylhi=#FEAF
hddcyllo=#FE8F
hddsec=#FEbF
hddcount=#FEХF
hdderr=#FE2F
hdddatlo=#FEOF
hdddathi=#FFOF
 hddupr=#FEBE ;with b7 FFBA installed
 hdduprON=#FFBA
 hddupr1=#F7
 hdduprO=#77
      ELSE
;SMUC scheme:
hddstat=#FFBE
hddcmd=#FFBE
hddhead=#FEBE
hddcylhi=#FDBE
hddcyllo=#FCBE
hddsec=#FBBE
hddcount=#FABE
hdderr=#F9BE
hddddatlo=#F8BE
hdddathi=#D8BE
 hddupr=#FEBE ;with b7 FFBA installed
 hdduprON=#FFBA
 hddupr1=#F7
 hdduprO=#77
      ENDIF
       ELSE
;Nemo scheme:
hddstat=#F0
hddcmd=#F0
hddhead=#D0
hddcylhi=#B0
hddcyllo=#90
hddsec=#70
hddcount=#50
hdderr=#30
hddddatlo=#10
hdddathi=#11
 hddupr=#C8
 hdduprON=0
       ENDIF

SECBUF=#6000
        ORG #E800
begin
GO
        LDSP,#6000
        LD (IY+1),#CC
        EI
        HALT
        XOR A
        OUT (-2),A
        LD DE,#5801
        LD H,D,L,A
        LD BC,767
        LD(HL),L
        LDIR

       IFN atm
        CALL #3D46 ;calling a "check" point in (v)TR-DOS
        OR A ;if not 0, there is no vTR-DOS and the ROM cannot be replaced
        CALL Z,#3C98 ;calling the TRD/vTRD ROM substitution trigger
       ENDIF

;initialization
        LD A,device ;#B0=slave
        LD BC,hddhead
        CALL OUT_A
        CALL NO_BSY
    ;LD A,#FE
    ;IN A,(-2)
    ;RRA
    ;JNC SKIPINI
      ;LD A,#10 ;
      ;CALL HDSC ;ZET9 for HDD
        LD A,#08 ;
        CALL HDSC ;SMT for CD (reset for ATAPI)
      ;RET C ;ATAPI only
        LD A,device ;#B0=slave ;
        LD BC,hddhead ;BUDDER
        CALL OUT_A ;otherwise if the CD is not spun
                                 ;will not issue EB14!!!
        LD A,#EC ;identify
        CALL HDSC
      ;RET C ;for CD it will generate an error (VEGA)

        LD B,30
        HALT
        DJNZ$-1

        CALL LEN_TO_HL
        LD BC,#EB14
        OR A
        SBC HL,BC
       JP NZ,0 ;HDD
       ;LD A,1
       ;OUT (-2),A

        LD HL,AP_1x
        CALL SEND_ATAPI
        LD B,30
        HALT
        DJNZ$-1
SKIPINI
        D.I.

       ;LD A,2
       ;OUT (-2),A

      ;now sector number=0,0,0,0
        CALL READCDSECBUF ;otherwise it doesn't workREADTOC
        LD HL,AP_READTOC
        CALL SEND_ATAPI
      ;RET C
        CALL NO_BSY
      ;RET C
        CALL WAIT_DRQ
      ;RET C
        CALL LEN_TO_HL
        LD B,H,C,L
        LD HL,SECBUF
        CALL TRANS_IN
        CALL NO_BSY

       ;LD A,3
       ;OUT (-2),A

     ;take the last session (pre-post record)
        LD HL,SECBUF+1
        LD A,(HL)
        ADD A,-10
        LD L,A
        LD D,#87
       ;CY=1
        CALL LOADER ;load the beginning of the session (#8800 bytes)

        LD BC,#80A2
        ADD HL,BC
       ;CY=0
        CALL LOADER ;load the root directory
       ;HL=SECBUF

       ;LD A,4
       ;OUT (-2),A

FNDIDLOOP
       PUSH HL
        LD C,33
        ADD HL,BC
        LD DE,autorunname
        LD C,autorunnamesz
FNDIDO LD A,(DE)
        CPI
       JNZ FNDIDN
        INC DE
        JP PE,FNDIDO
       POP HL
        LD C,6
        ADD HL,BC
       ;CY=0

       ;LD A,5
       ;OUT (-2),A

        CALL LOADER; loading autorun.zx
       PUSH HL
        LD A,device ;#B0=slave
        LD BC,comptype*256+idetype ;1=ATM,1=ATM
        LD DE,language*256+COVPORT ;1=RUS,#FB
        LD HL,videomodes ;8=ATM
       RET
FNDIDN
       POP HL
        LD C,(HL)
        INC HL
        LD B,(HL)
        DEC HL
       LD A,B
       OR C
       JNZ NOPADDING
        INC H
        LD L,A
NOPADDING
        ADD HL,BC
        LD A,H
        CP 64
       JNC FNDIDLOOP
        RST 0LOADER
;грузим файл
;HL указывает на поле координат файла в motorola порядке
;CY=1: размер в DE
;CY=0: размер в (HL+4)
       PUSH DE
        LD DE,SECTOR
        LD BC,4
        LDIR
       POP DE
        JC $+5
         LD E,(HL)
         INC HL
         LD D,(HL)
        EXD
        SCF
        LD DE,2048
        INC B
        SBC HL,DE
        JNC $-3
        LD HL,SECBUF
       PUSH HL
LOADERO PUSH BC
        CALL READCD
        PUSH HL
        LD HL,SECTOR+3
        INC (HL)
        DEC HL
        JZ $-2
        POP HL
        POP BC
        DJNZ LOADERO
       POP HL
        RET

;**********************************************************************
OUT_A
       IFN smuc
      IFN atm
        PUSH AF,BC
        CALL OPENPORTS
        POP BC,AF
        OUT (C),A
        JR CLOSEPORTS
OPENPORTS
        LD A,%10101011
        LD BC,#2A53
        PUSH BC
        LD BC,#4177
        JP #3D2F
      ELSE
        LD IX,#ЗFFO
        PUSH IX
        JP #3D2F
      ENDIF
       ELSE ;nemo
        OUT (C),A
        RET
       ENDIF

IN_HDDSTAT
        LD BC,hddstat
IN_A
       IFN smuc
      IFN atm
        PUSH BC
        CALL OPENPORTS
        POP BC
        IN A,(C)
CLOSEPORTS
        PUSH AF,BC
        LD A,%10101011
        LD BC,#FF77
        OUT (C),A
        POP BC,AF
        RET
      ELSE
        LD IX,#ЗFFЗ
        PUSH IX
        JP #3D2F
      ENDIF
       ELSE
        INA,(C)
        RET
       ENDIF

;SEND COMMAND TO THE SCREW
HDSC
        LD BC,hddcmd
        CALL OUT_A
;WAITING FOR THE DEVICE TO BE RELEASED
NO_BSY
        CALL IN_HDDSTAT
        RLCA
       RET NC
        JR NO_BSY
;WAITING FOR READY TO TRANSFER DATA
WAIT_DRQ
        CALL IN_HDDSTAT
        BIT 3,A
       RET NZ
        JR WAIT_DRQ

;READING A NUMBER FROM THE CYLINDER REGISTER
LEN_TO_HL
        LD BC,hddcyllo
        CALL IN_A
        LD L,A
        LD BC,hddcylhi
        CALL IN_A
        LD H,A
        RET

;IN:HL-ADDRESS OF DATA RECEIVING
;   BC-NUMBER OF BYTES
TRANS_IN
        PUSH BC
        CALL NO_BSY
       ;POP BC
      ;RET C
       ;PUSH BC
        CALL WAIT_DRQ
        POP B.C.
      ;RET C
        INC B.C.
        SRL B
        RR C
TR_INO PUSH BC
        LD BC,hdddatlo
        CALL IN_A
        LD(HL),A
        INC HL
        LD BC,hdddathi
        CALL IN_A
        LD(HL),A
        POP B.C.
        CPI
        JP PE,TR_INO
        RET

;TRANSMITTING ATAPI PACKET
SEND_ATAPI
      ;LD A,device ;#B0=slave
      ;LD BC,hddhead
      ;CALL OUT_A
        LD BC,hddcyllo
        XOR A
        CALL OUT_A
        LD BC,hddcylhi
        LD A,'2048
        CALL OUT_A
        LD A,#A0
        CALL HDSC
      ;RET C
        LD B,6
TR_OUTO PUSH BC
        INC HL
        LD A,(HL)
        LD BC,hdddathi
        CALL OUT_A
        DEC HL
        LD A,(HL)
        LD BC,hdddatlo
        CALL OUT_AINC HL,HL
        POP B.C.
        DJNZ TR_OUTO
        RET
READCDSECBUF
        LD HL,SECBUF
READCD
;READ SECTOR
lOAD_SECTOR
       PUSH HL
        LD HL,AP_READ
        CALL SEND_ATAPI
       POP HL
      ;RET C
;there may be a situation where CHECK CONDITION (status D0) = 0,
;and at the same time DRQ is not issued!
       ;CALL IN_HDDSTAT
       ;RRA
      ;RET C
        CALL NO_BSY ;otherwise it hangs when initiating CD
      ;RET C
       ;CALL WAIT_DRQ ;hangs here if you initiate too early
      ;RET C ;after exiting, it accelerates, waits for the button and reads
     ;waiting for DRQ for Budder's recipe
        LD DE,0
RDCDDRQ CALL IN_HDDSTAT
        BIT 3,A
       JNZ READ_P2
        INC DE
        BIT 2,D ;4,D
        JZ RDCDDRQ
        PUSH HL
        LD HL,AP_00
        CALL SEND_ATAPI
        POP HL
        JR lOAD_SECTOR
READ_P2
        LD BC,2048
        CALL TRANS_IN
        JP NO_BSY

autorunname
        DB "AUTORUN.ZX"
autorunnamesz=$-autorunname

;ATAPI-PACKAGE "Dummy"
AP_00
        DW 0
        DS 10

;ATAPI PACKAGE "SPEED 1x"
AP_1x
        DW #BB
        DB 0
        DB 176 ;1x=176k/s
        DS 8

;ATAPI PACKAGE "READING"
AP_READ
       IFN 0
        DW #BE ;"READ CD"
SECTOR DB 0,0,0,0
        DB 0
        DB 0.1 ;=1 sector
        DB #10 ;read only data
        DB 0.0
       ELSE
        DW #28 ;"READ(10)"
SECTOR DB 0,0,0,0
        DB 0
        DB 0.1 ;=1 sector
        DB 0DB 0.0
       ENDIF
AP_READTOC
        DW #43 ;SCMSF=0, i.e. sectors, not MSF
        DB 0 ;FORMAT=0:all sessions
        DS 3
        DB 0 ;from 1st session
        DB '2048 ;table length
        DB 2048
        DB #00 ;FUNC
        DS 2

end
       DISPLAY end-begin
        ORG #SCDD
        DB "boot B
        INCLUDE "mrip*",#C0

Share your thoughts about the article