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