FromNet: Ryazan (Ryazan_Net)
Hello All!
2-8 января мы с Shiru Otaku портировали на ATM turbo2+ видеоигру Time Gal (жанр
почти 100) и работает только с CD.
Поскольку кто первый встал - того и тапки, то:
ZX-СТАHДАРТ HА АВТОЗАПУСКАЕМЫЕ CD
v1.0
Hа автозапускаемом CD (формат CDFS / ISO 9660 / ECMA-119) в корневой директории
должен располагаться файл AUTORUN.ZX (за заглавные буквы можете не
беспокоиться, Nero капитализует имена файлов автоматически) длиной не более
#8000 байт. Он грузится по адресу #6000 (значение порта #7ffd равно #10) и
запускается по адресу #6000 с выключенными прерываниями IM1, при этом текущий
CD-привод проициализирован и является текущим устройством, кроме того,
произведена попытка включить на нём низкую скорость.
Регистры при этом:
SP=#6000
IY=23610
A=#A0 (master) или #B0 (slave) [возможно, будет выкинуто, т.к. 1. на ZX уже
устоялась ситуация CD-ROM=slave; 2. для игр, скорее всего, не потребуется
переключаться на другие устройства]
B=тип компьютера: 0=PENTAGON, 1=ATM, 2=SCORPION, 3=PROFI, 4=SPRINTER
C=тип контроллера IDE: 0=NEMO, 1=ATM, 2=SMUC, 3=PROFI, 4=SPRINTER
D=язык: 0=ENGLISH, 1=РУССКИЙ
E=адрес COVOX: #FB=ATM/PENTAGON, #FF=отсутствует
HL=доступные видеорежимы (накладываются по OR):
;1=512x192 BW VMG
;2=384x304 ZX AC
;4=256x192 15 AC
;8=320x200 16 ATM
Остальные значения и биты пока зарезервированы.
КОHЕЦ СТАHДАРТА
Прилагаемый загрузчик пока не очень устойчиво работает, принимаются советы по
повышению устойчивости его работы (впоследствии будем прошивать его в ПЗУ).
Ограничения этого загрузчика:
описателя AUTORUN.ZX;
ОБРАТИТЕ ВHИМАHИЕ на метку NOPADDING. Данный маразм в Абзац#25 не
документирован, хотя в Vega о нём знает (CD-Walk правильно пропускает эти
паддинги, равно как и WDC).
/=== Begin Windows Clipboard ===/
;загрузчик файла "AUTORUN.ZX" с CD по адресу #6000
;SP=#6000, DI
;передает ему в регистрах:
;A=#A0 (master) или #B0 (slave)
;B=тип компьютера:
;0=PENTAGON, 1=ATM, 2=SCORPION, 3=PROFI, 4=SPRINTER
;C=тип контроллера IDE:
;0=NEMO, 1=ATM, 2=SMUC, 3=PROFI, 4=SPRINTER
;D=язык:
;0=ENGLISH, 1=РУССКИЙ
;E=адрес COVOX:
;#FB=ATM/PENTAGON, #FF=отсутствует
;H=доступные видеорежимы (накладываются по OR)
;1=512x192 BW VMG
;2=384x304 ZX AC
;4=256x192 15 AC
;8=320x200 16 ATM
device=#B0
comptype=1
idetype=1
language=1
COVPORT=#FB
videomodes=8
;===============ниже поддержаны только NEMO,SMUC,ATM============
IF0 comptype-1
atm=1
ELSE
atm=0
ENDIF
IF0 idetype-2
smuc=1|atm
ELSE
smuc=atm
ENDIF
IFN smuc
IFN atm
;схема ATM:
hddstat=#FEEF
hddcmd=#FEEF
hddhead=#FECF
hddcylhi=#FEAF
hddcyllo=#FE8F
hddsec=#FE6F
hddcount=#FE4F
hdderr=#FE2F
hdddatlo=#FE0F
hdddathi=#FF0F
hddupr=#FEBE ;при установленном b7 FFBA
hdduprON=#FFBA
hddupr1=#F7
hddupr0=#77
ELSE
;схема SMUC:
hddstat=#FFBE
hddcmd=#FFBE
hddhead=#FEBE
hddcylhi=#FDBE
hddcyllo=#FCBE
hddsec=#FBBE
hddcount=#FABE
hdderr=#F9BE
hdddatlo=#F8BE
hdddathi=#D8BE
hddupr=#FEBE ;при установленном b7 FFBA
hdduprON=#FFBA
hddupr1=#F7
hddupr0=#77
ENDIF
ELSE
;схема Nemo:
hddstat=#F0
hddcmd=#F0
hddhead=#D0
hddcylhi=#B0
hddcyllo=#90
hddsec=#70
hddcount=#50
hdderr=#30
hdddatlo=#10
hdddathi=#11
hddupr=#C8
hdduprON=0
ENDIF
SECBUF=#6000
ORG #E800
begin
GO
LD SP,#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 ;вызов "проверочной" точки в (v)TR-DOS
OR A ;если не 0,vTR-DOS нет и ПЗУ не подменяем
CALL Z,#3C98 ;вызов триггера подмены ПЗУ TRD/vTRD
ENDIF
;инициализация
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 для HDD
LD A,#08 ;
CALL HDSC ;SMT для CD (сброс для ATAPI)
;RET C ;ATAPI only
LD A,device ;#B0=slave ;
LD BC,hddhead ;BUDDER
CALL OUT_A ;иначе при нераскрученном CD
;не выдаст EB14!!!
LD A,#EC ;identify
CALL HDSC
;RET C ;для CD выдаст ошибку (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
DI
;LD A,2
;OUT (-2),A
;сейчас номер сектора=0,0,0,0
CALL READCDSECBUF ;иначе не работает READTOC
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
;берем посл сессию (предпосл запись)
LD HL,SECBUF+1
LD A,(HL)
ADD A,-10
LD L,A
LD D,#87
;CY=1
CALL LOADER ;грузим начало сессии (#8800 байт)
LD BC,#80A2
ADD HL,BC
;CY=0
CALL LOADER ;грузим корневой каталог
;HL=SECBUF
;LD A,4
;OUT (-2),A
FNDIDLOOP
PUSH HL
LD C,33
ADD HL,BC
LD DE,autorunname
LD C,autorunnamesz
FNDID0 LD A,(DE)
CPI
JNZ FNDIDN
INC DE
JP PE,FNDID0
POP HL
LD C,6
ADD HL,BC
;CY=0
;LD A,5
;OUT (-2),A
CALL LOADER ;грузим 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 0
LOADER
;грузим файл
;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
LOADER0 PUSH BC
CALL READCD
PUSH HL
LD HL,SECTOR+3
INC (HL)
DEC HL
JZ $-2
POP HL
POP BC
DJNZ LOADER0
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,#3FF0
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,#3FF3
PUSH IX
JP #3D2F
ENDIF
ELSE
IN A,(C)
RET
ENDIF
;ПОСЛАТЬ КОМАHДУ HА ВИHТ
HDSC
LD BC,hddcmd
CALL OUT_A
;ОЖИДАHИЕ ОСВОБОЖДЕHИЯ УСТРОЙСТВА
NO_BSY
CALL IN_HDDSTAT
RLCA
RET NC
JR NO_BSY
;ОЖИДАHИЕ ГОТОВHОСТИ ПЕРЕДАЧИ ДАHHЫХ
WAIT_DRQ
CALL IN_HDDSTAT
BIT 3,A
RET NZ
JR WAIT_DRQ
;ЧТЕHИE ЧИСЛА ИЗ РЕГИСТРА ЦИЛИHДРА
LEN_TO_HL
LD BC,hddcyllo
CALL IN_A
LD L,A
LD BC,hddcylhi
CALL IN_A
LD H,A
RET
;IN:HL-АДРЕС ПРИЕМА ДАHHЫХ
; BC-КОЛ-ВО БАЙТ
TRANS_IN
PUSH BC
CALL NO_BSY
;POP BC
;RET C
;PUSH BC
CALL WAIT_DRQ
POP BC
;RET C
INC BC
SRL B
RR C
TR_IN0 PUSH BC
LD BC,hdddatlo
CALL IN_A
LD (HL),A
INC HL
LD BC,hdddathi
CALL IN_A
LD (HL),A
POP BC
CPI
JP PE,TR_IN0
RET
;ПЕРЕДАЧА ATAPI-ПАКЕТА
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_OUT0 PUSH BC
INC HL
LD A,(HL)
LD BC,hdddathi
CALL OUT_A
DEC HL
LD A,(HL)
LD BC,hdddatlo
CALL OUT_A
INC HL,HL
POP BC
DJNZ TR_OUT0
RET
READCDSECBUF
LD HL,SECBUF
READCD
;ЧТЕHИЕ СЕКТОРА
lOAD_SECTOR
PUSH HL
LD HL,AP_READ
CALL SEND_ATAPI
POP HL
;RET C
;бывает ситуация,что CHECK CONDITION (D0 статуса)=0,
;а при этом DRQ не выдается!
;CALL IN_HDDSTAT
;RRA
;RET C
CALL NO_BSY ;иначе виснет при иниц-ции CD
;RET C
;CALL WAIT_DRQ ;здесь виснет, если инитить слишком рано
;RET C ;после выхода разгоняется, ждет кнопку и читает
;ожидание DRQ по рецепту Budder'а
LD DE,0
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-ПАКЕТ "ПУСТЫШКА"
AP_00
DW 0
DS 10
;ATAPI-ПАКЕТ "SPEED 1x"
AP_1x
DW #BB
DB 0
DB 176 ;1x=176k/s
DS 8
;ATAPI-ПАКЕТ "ЧТЕHИЕ"
AP_READ
IFN 0
DW #BE ;"READ CD"
DB 0
DB 0,1 ;=1 сектор
DB #10 ;читаем только данные
DB 0,0
ELSE
DW #28 ;"READ(10)"
DB 0
DB 0,1 ;=1 сектор
DB 0
DB 0,0
ENDIF
AP_READTOC
DW #43 ;SCMSF=0,т.е.секторы,а не MSF
DB 0 ;FORMAT=0:все сессии
DS 3
DB 0 ;с 1-й сессии
DB '2048 ;длина табл
DB 2048
DB #00 ;FUNC
DS 2
end
DISPLAY end-begin
ORG #5CDD
DB "boot B
INCLUDE "mrip*",#C0
/=== End Windows Clipboard ===/
- A.Coder [Wolf3d2004 HexFill Pang16C InfoGuide8 ACEdit97 ACN44 PT3696 Chip13]
[ANSI4 ZXR27UnR59 Jpg42 8col12 DBS7 CacVox1 Gluk61 PC21 Alasm503 STS71 HDDoct9]
... ZX Spectrum today