ACNews #45
31 января 2006

Прогрммирование - ZX-СТАНДАРТ НА АВТОЗАПУСКАЕМЫЕ CD v1.0

<b>Прогрммирование</b> - ZX-СТАНДАРТ НА АВТОЗАПУСКАЕМЫЕ CD
 v1.0
Поскольку кто первый встал - того и тапки, то:

               ZX-СТАНДАРТ НА АВТОЗАПУСКАЕМЫЕ CD
                              v1.0

На автозапускаемом 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, #DD=SCORP, ..., #FF=отсутствует 
HL=доступные видеорежимы (накладываются по OR): 
 ;1=512x192 BW VMG
 ;2=384x304 ZX AC
 ;4=256x192 15 AC
 ;8=320x200 16 ATM
Остальные значения и биты пока зарезервированы.

                        КОНЕЦ СТАНДАРТА

Прилагаемый загрузчик пока не очень устойчиво работает,
принимаются советы по повышению устойчивости его работы
(впоследствии будем прошивать его в ПЗУ). Ограничения этого
загрузчика:
- не более 30 сессий на диске (информация берётся из последней); 
- не более #8000 байт расстояние от начала корневого каталога до 
конца описателя AUTORUN.ZX; 
- IY, IM1 и #7ffd предполагаются уже установленными. 

;загрузчик файла "AUTORUN.ZX" с CD по адресу #6000
device=#B0
comptype=1
idetype=1
language=1
COVPORT=#FB
videomodes=8

;===============ниже поддержаны только NEMO,SMUC,ATM============
        IFO comptype-1
atm=1
        ELSE
atm=0
        ENDIF
        IFO 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=#FEбF
hddcount=#FEЧF
hdderr=#FE2F
hdddatlo=#FEOF
hdddathi=#FFOF
 hddupr=#FEBE ;при установленном b7 FFBA
 hdduprON=#FFBA
 hddupr1=#F7
 hdduprO=#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
 hdduprO=#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
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 ;грузим 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
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
        IN A,(C)
        RET
       ENDIF

;ПОСЛАТЬ КОМАНДУ НА ВИНТ
HDSC
        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

;ЧТЕНИЕ ЧИСЛА ИЗ РЕГИСТРА ЦИЛИНДРА
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_INO  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_INO
        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_OUTO 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_OUTO
        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
       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-ПАКЕТ "ЧТЕНИЕ"
AP_READ
       IFN 0
        DW #BE   ;"READ CD"
SECTOR  DB 0,0,0,0
        DB 0
        DB 0,1   ;=1 сектор
        DB #10   ;читаем только данные
        DB 0,0
       ELSE
        DW #28   ;"READ(10)"
SECTOR  DB 0,0,0,0
        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 #SCDD
        DB "boot    B
        INCLUDE "mrip*",#C0



Другие статьи номера:

Новости - Мы одолжили у Макса Тимонина АТМку и сделали на ней игру "Time Gal"

Прогрммирование - ZX-СТАНДАРТ НА АВТОЗАПУСКАЕМЫЕ CD v1.0


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Список BBS - Работа станций BBS сети ZXNet.
Проходилка - обещаный разбор игры PIJAMARAMA (MICRO-GEN'87).
Железо - Про неисчерпаемые возможности NeoGS.
Детям - поучающее обьявления Alone Coder'a для детей 17 школы.
Сплошные приколы - ENLIGHT'96 лучшая 4 demo. Прощание RINDEX'а с читателями...

В этот день...   21 ноября