hddstat EQU 0XF0
hddcmd EQU 0XF0
hddhead EQU 0XD0
hddcylhi EQU 0XB0
hddcyllo EQU 0X90
hddsec EQU 0X70
hddcount EQU 0X50
hdderr EQU 0X30
hdddatlo EQU 0X10
hdddathi EQU 0X11
hddupr EQU 0XC8
hdduprON EQU 0
HDDBINI CALL SET_7FFD_0
LD HL,HDDREAD
LD DE,0XE800 ;0X5B60
LD B,8 ;BC,HDDRDLN
LDIR
RET
HDDBOOT DI
CALL HDDBINI
INIT0 LD A,0XA0 ;MASTER+CHS АДРЕСАЦИЯ
LD (devnum),A
CALL SELDEVICE
LD A,0X0C
LD BC,hddupr
PUSH BC
CALL OUT_A ;начинаем сброс
LD B,0
DJNZ $
LD A,8
POP BC
CALL OUT_A ;сбросили!
CALL NO_BSY
LD A,0X10 ;Команда RECALIBRATE
CALL HDSC ;Запись COMMAND
INIT2 IN A,(LOW (hddstat)) ;Чтение STATUS REGISTER (0111)
BIT 7,A ;Проверка бита BSY занятость HDD
JR NZ,INIT2 ;Переход если накопитель занят
AND 0XE9
CP 0X40
;CP 0X50 ;Проверка битов DSC (уст-ка головок)
;и DRDY(готовность HDD)
JR NZ,INIT0 ;Если установлены - выход
JP 0XE800
;,**************************************************************
;ЧТЕНИЕ СЕКТОРОВ
HDDREAD PHASE 0XE800
CALL NO_BSY ;ЗАПИСАТЬ В РЕГИСТРЫ ЦИЛИНДРА,ГОЛОВКИ,СЕКТОРА
LD BC,hddhead ;РЕГИСТР НАКОПИТЕЛЯ/ГОЛОВКИ
LD A,0XA0 ;ГОЛОВКА 0,ВИНТ MASTER 0XB0-SLAVE
CALL OUT_A
LD BC,hddcylhi ;РЕГИСТР ЦИЛИНДРА (HI)
XOR A
CALL OUT_A
LD BC,hddcyllo ;РЕГИСТР ЦИЛИНДРА (LOW)
CALL OUT_A
LD BC,hddsec ;РЕГИСТР НОМЕРА СЕКТОРА
LD A,3 ;НОМЕР СЕКТОРА
CALL OUT_A
LD BC,hddcount ;РЕГИСТР СЧЕТЧИКА СЕКТОРА
LD A,0X30 ;СКОЛЬКО СЕКТОРОВ 24K
CALL OUT_A
LD A,0X20
CALL HDSC ;КОМАНДА "ЧИТАТЬ"
LD HL,0X6000
PUSH HL
LD B,0X30
READ1 PUSH BC
CALL WAIT_DRQ
;ЧИТАЕМ СЕКТОР
LD B,0
READ_1 PUSH BC
LD BC,hdddatlo ;МЛАДШИЙ БАЙТ
INI
LD BC,hdddathi ;СТАРШИЙ БАЙТ
INI
POP BC
DJNZ READ_1
POP BC
DJNZ READ1
RET
;ОЖИДАНИЕ ГОТОВНОСТИ ПЕРЕДАЧИ ДАННЫХ
WAIT_DRQ
CALL IN_HDDSTAT
BIT 3,A
RET NZ
JR WAIT_DRQ
;ПОСЛАТЬ КОМАНДЫ НА ВИНТ
HDSC PUSH AF
CALL SELDEVICE
POP AF
LD BC,hddcmd
CALL OUT_A
;ОЖИДАНИЕ ОСВОБОЖДЕНИЯ УСТРОЙСТВА
NO_BSY CALL IN_HDDSTAT
RLCA
RET NC
JR NO_BSY
IN_HDDSTAT
CALL SELDEVICE
LD BC,hddstat
IN_A IN A,(C)
RET
SELDEVICE
devnum EQU $+1
LD A,device
LD BC,hddhead
OUT_A OUT (C),A
RET
CDBOOTGO
;загрузчик файла "AUTORUN.ZX" с CD по адресу 0X6000
;SP=0X6000, DI
;передает ему в регистрах:
;A=0XA0 (master) или 0XB0 (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:
;0XFB=ATM/PENTAGON, 0XFF=отсутствует
;HL=доступные видеорежимы (накладываются по OR)
;1=512x192 BW VMG
;2=384x304 ZX AC
;4=256x192 15 AC
;8=320x200 16 ATM
device EQU 0XB0
comptype EQU 0
idetype EQU 0
language EQU 1
COVPORT EQU 0XFB
videomodes EQU 4;8
;===============ниже поддержаны только NEMO,SMUC,ATM============
; IF comptype-1
;atm=1
; ELSE
;atm=0
; ENDIF
; IF idetype-2
;smuc=1|atm
; ELSE
;smuc=atm
; ENDIF
; IFN smuc
; IFN atm
;схема ATM:
;hddstat=0XFEEF
;hddcmd=0XFEEF
;hddhead=0XFECF
;hddcylhi=0XFEAF
;hddcyllo=0XFE8F
;hddsec=0XFE6F
;hddcount=0XFE4F
;hdderr=0XFE2F
;hdddatlo=0XFE0F
;hdddathi=0XFF0F
;hddupr=0XFEBE ;при установленном b7 FFBA
;hdduprON=0XFFBA
;hddupr1=0XF7
;hddupr0=0X77
; ELSE
;схема SMUC:
;hddstat=0XFFBE
;hddcmd=0XFFBE
;hddhead=0XFEBE
;hddcylhi=0XFDBE
;hddcyllo=0XFCBE
;hddsec=0XFBBE
;hddcount=0XFABE
;hdderr=0XF9BE
;hdddatlo=0XF8BE
;hdddathi=0XD8BE
;hddupr=0XFEBE ;при установленном b7 FFBA
;hdduprON=0XFFBA
;hddupr1=0XF7
;hddupr0=0X77
; ENDIF
; ELSE
;схема Nemo:
;hddstat=0XF0
;hddcmd=0XF0
;hddhead=0XD0
;hddcylhi=0XB0
;hddcyllo=0X90
;hddsec=0X70
;hddcount=0X50
;hdderr=0X30
;hdddatlo=0X10
;hdddathi=0X11
;hddupr=0XC8
;hdduprON=0
; ENDIF
SECBUF EQU 0X6000
;DISP 0XE800
begin
;GO
; LD SP,0X6000
; LD (IY+1),0XCC
; EI
; HALT
; XOR A
; OUT (-2),A
; LD DE,0X5801
; LD H,D,L,A
; LD BC,767
; LD (HL),L
; LDIR
; IFN atm
; CALL 0X3D46 ;вызов "проверочной" точки в (v)TR-DOS
; OR A ;если не 0,vTR-DOS нет и ПЗУ не подменяем
; CALL Z,0X3C98 ;вызов триггера подмены ПЗУ TRD/vTRD
; ENDIF
;инициализация
iniini
; LD A,device ;0XB0=slave
; LD BC,hddhead
; CALL OUT_A ;есть внутри NO_BSY
CALL NO_BSY
;LD A,0XFE
;IN A,(-2)
;RRA
;JNC SKIPINI
;LD A,0X10 ;
;CALL HDSC ;ZET9 для HDD
LD A,0X08 ;
CALL HDSC ;SMT для CD (сброс для ATAPI)
;RET C ;ATAPI only
; LD A,device ;0XB0=slave ;
; LD BC,hddhead ;BUDDER
; CALL OUT_A ;есть в HDSC ;иначе при нераскрученном CD
;не выдаст EB14!!!
LD A,0XEC ;identify
CALL HDSC
;RET C ;для CD выдаст ошибку (VEGA)
LD B,30
HALT
DJNZ $-1
CALL LEN_TO_HL
LD BC,0XEB14
OR A
SBC HL,BC
JP NZ,iniini;0 ;HDD
;LD A,1
;OUT (-2),A
LD HL,AP_00
CALL SEND_ATAPI ;VEGA
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
LD 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,0X87
;CY=1
CALL LOADER ;грузим начало сессии (0X8800 байт)
LD BC,0X80A2
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
JR NZ,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 ;0XB0=slave
LD BC,comptype*256+idetype ;1=ATM,1=ATM
LD DE,language*256+COVPORT ;1=RUS,0XFB
LD HL,videomodes ;8=ATM
RET
FNDIDN
POP HL
LD C,(HL)
INC HL
LD B,(HL)
DEC HL
LD A,B
OR C
JR NZ,NOPADDING
INC H
LD L,A
NOPADDING
ADD HL,BC
LD A,H
CP 64
JR NC,FNDIDLOOP
RST 0
LOADER
;грузим файл
;HL указывает на поле координат файла в motorola порядке
;CY=1: размер в DE
;CY=0: размер в (HL+4)
PUSH DE
LD DE,SECTOR
LD BC,4
LDIR
POP DE
JR C,$+5
LD E,(HL)
INC HL
LD D,(HL)
EX DE,HL
SCF
LD DE,2048
INC B
SBC HL,DE
JR NC,$-3
LD HL,SECBUF
PUSH HL
LOADER0 PUSH BC
CALL READCD
PUSH HL
LD HL,SECTOR+3
INC (HL)
DEC HL
JR Z,$-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,0X2A53
; PUSH BC
; LD BC,0X4177
; JP 0X3D2F
; ELSE
; LD IX,0X3FF0
; PUSH IX
; JP 0X3D2F
; ENDIF
; ELSE ;nemo
; OUT (C),A
; RET
; ENDIF
;IN_HDDSTAT
; LD A,device
; LD BC,hddhead
; CALL OUT_A
; 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,0XFF77
; OUT (C),A
; POP BC,AF
; RET
; ELSE
; LD IX,0X3FF3
; PUSH IX
; JP 0X3D2F
; ENDIF
; ELSE
; IN A,(C)
; RET
; ENDIF
;ПОСЛАТЬ КОМАНДУ НА ВИНТ
;HDSC
; PUSH AF
; LD A,device
; LD BC,hddhead
; CALL OUT_A
; POP AF
; LD BC,hddcmd
; CALL OUT_A
;ОЖИДАНИЕ ОСВОБОЖДЕНИЯ УСТРОЙСТВА
;NO_BSY
; CALL IN_HDDSTAT
; RLCA
; RET NC
; JR NO_BSY
;ОЖИДАНИЕ ГОТОВНОСТИ ПЕРЕДАЧИ ДАННЫХ
;WAIT_DRQ
; CALL IN_HDDSTAT
; BIT 3,A
; RET NZ
; JR WAIT_DRQ
;ЧТЕНИE ЧИСЛА ИЗ РЕГИСТРА ЦИЛИНДРА
LEN_TO_HL
LD BC,hddcyllo
CALL IN_A
LD L,A
LD BC,hddcylhi
CALL IN_A
LD H,A
RET
;IN:HL-АДРЕС ПРИЕМА ДАННЫХ
; 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 ;0XB0=slave
;LD BC,hddhead
;CALL OUT_A
LD BC,hddcyllo
XOR A
CALL OUT_A
LD BC,hddcylhi
LD A,HIGH (2048)
CALL OUT_A
LD A,0XA0
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
INC HL
POP BC
DJNZ TR_OUT0
RET
READCDSECBUF
LD HL,SECBUF
READCD
;ЧТЕНИЕ СЕКТОРА
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
RDCDDRQ CALL IN_HDDSTAT
BIT 3,A
JR NZ,READ_P2
INC DE
BIT 2,D ;4,D
JR Z,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 EQU $-autorunname
;ATAPI-ПАКЕТ "ПУСТЫШКА"
AP_00
DW 0
DUPL 10,0
;ATAPI-ПАКЕТ "SPEED 1x"
AP_1x
DW 0XBB
DB 0
DB 176 ;1x=176k/s
DUPL 8,0
;ATAPI-ПАКЕТ "ЧТЕНИЕ"
AP_READ
; IFN 0
; DW 0XBE ;"READ CD"
;SECTOR DB 0,0,0,0
; DB 0
; DB 0,1 ;=1 сектор
; DB 0X10 ;читаем только данные
; DB 0,0
; ELSE
DW 0X28 ;"READ(10)"
SECTOR DB 0,0,0,0
DB 0
DB 0,1 ;=1 сектор
DB 0
DB 0,0
; ENDIF
AP_READTOC
DW 0X43 ;SCMSF=0,т.е.секторы,а не MSF
DB 0 ;FORMAT=0:все сессии
DUPL 3,0
DB 0 ;с 1-й сессии
DB HIGH (2048) ;длина табл
DB LOW (2048)
DB 0X00 ;FUNC
DUPL 2,0
;end
; DISPLAY end-begin
; ORG 0X5CDD
; DB "boot B"
; INCLUDE "mrip.a80" ;,0XC0
DEPHASE