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