; Порты ВГ93 REGCOM equ 0x0F ; порт команд и статуса REGTRK equ 0x3F ; порт дорожки REGSEC equ 0x5F ; порт сектора REGDATA equ 0x7F ; порт данных REGCTRL equ 0xFF ; порт управления L4000 equ 0xC000 ; буфер структуры дорожки ; Форматилка FFORMAT:ld a,2 ; число попыток иниц. ВГ93 после глюков ld (try_init),a FFORM1: call ClearMap ; очистить карту call Fresh ; обновить константы окна форм-ния call HiddenMouse ; скрыть мышку call init_interlive ; уст. интерлив для всех форматов call L0B21 ; созд. в стр. BuffTrk структуру дорожки ld a,(_OS) or a jr z,.loc1 ; ms-dos dec a jr nz,.loc2 ; cpm-80 ; tr-dos call SysAreaTRDOS jr .loc2 ; ms-dos .loc1: call L09A8 ; созд. с L2400.. структуру сист. области ; откр. окно иниц. дисковода .loc2: ld a,(ColDialWn) ; сохр. цвет окна ld (TmpColor),a ld a,1Fh ; цвет окна ld (ColDialWn),a ld hl,InitFdd ; "Resetting drive..." call PutDialWn call HiddenMouse ; скрыть мышку call set_1440 ; Открыть порты ВГ93 ld a,1Ch out (SysPort),a call A0626 ; сбросить контроллер ; дернуть головкой ld a,70 out (REGDATA),a ld a,18h ; перейти на задан. дорожку call A092C ; занести команду call A092A ; на 0-ю дорожку ; ; проверить наличие дискеты call L0C65 ; тест на чтение сектора jr z,.loc3 ; Ok call set_720 call L0C65 ; тест на чтение сектора jr z,.loc3 ; Ok cp 0x80 ; проверяем на отсутствие дискеты jr z,Pars1 ; нет дискеты ; тест на защиту от записи .loc3: call L0906 ; тест на запись сектора bit 6,a jr nz,Pars1 ; "защита записи" ; call ClsDial ; закрыть окно ld a,(TmpColor) ld (ColDialWn),a call HiddenMouse ; скрыть мышку ld a,(Mode1) ; "Quick format" or a jr nz,.loc4 call L0BFF ; форматирование call RestoreTime ; восст. сист. время jp c,Abort ; прерывание операции jp nz,Parsing ; есть ошибки записи/чтения ; .loc4: xor a ld (RetCode),a ; очистить код возврата ошибок ld a,(ColDialWn) ; сохр. цвет окна push af ld a,17h ; цвет вывод. окна ld (ColDialWn),a ld hl,SystemArea ; "Writing system area..." call PutDialWn call HiddenMouse ; скрыть мышку call L09D9 ; запись сист. области call ClsDial ; закрыть окно диалога pop af ld (ColDialWn),a ; ld a,(RetCode) or a jr nz,Parsing ; были ошибки при записи сист. области call A092A ; на 0-ю дорожку ; Закрыть порты ВГ93 call Abort ld a,(_OS) or a jp nz,okno1 ; при tr-dos, cp/m-80 ; ld a,(cSystem) ; флаг копир. системных файлов or a call nz,WriteSysFiles ; запись сист. файлов на дискету call CreateLabel ; создать метку дискеты, если задана jp okno1 ; "Форм. завершено", выход из функции fformat Abort: call A0626 ; сбросить контроллер ; закрыть порты ВГ93 ld a,4 out (SysPort),a ld c,1 ; показать мышку RST ToDSS.Mouse ret ; закрыть окно "Resseting drive..." Pars1: ;нет диска, R/O call ClsDial ld a,(TmpColor) ld (ColDialWn),a ; ; Разбор ошибок записи/чтения Parsing:;любые ошибки call Abort ld a,(RetCode) bit 6,a ; бит "запрещена запись" jr nz,ReadOnly and 0x18 ; 4,3 биты jr z,nodisk ld hl,try_init dec (hl) jp nz,FFORM1 jp okno2 ; "ошибка записи сист. области или не совм. формат" ; ; нет дискеты (код 80h) nodisk: call okno3 ; "Вставьте дискету" ld a,(hl) cp cmOkey ret nz ; дискета вынута (в процессе форм-ния) jp FFORM1 ReadOnly: ld a,(ColDialWn) push af ld a,4Fh ; цвет окна форматирования ld (ColDialWn),a ld hl,Protect ; "Защита от записи" call DialogW pop af ld (ColDialWn),a ret ; Число попыток иниц. ВГ93 после ошибок "R/O" и (или) ; "ошибка записи сист. области или не совм. формат" try_init: db 2 ; Обновить константы окна процесса форм-ния Fresh: call Reset_Map ; сбросить tracks, side call L0D92 ; вывод номера дорожки call L0D93 ; вывод стороны ; сбросить число bad-секторов и доступн. емкость дискеты ld hl,-1 ; коррект. для CalcAvail ld (BadSect),hl ld hl,(avail1) ; мл.разряд ld bc,(MinusSc+1) ; 512/256/1024 add hl,bc ; коррект. для CalcAvail ld (Avail),hl ld hl,(avail1+2) ; мл.разряд ld (Avail+2),hl jp CalcAvail ; вывести нач. данные ; Скрыть мышку HiddenMouse: ld c,2 RST ToDSS.Mouse ret ; Вкл. режим 1.44Mb set_1440: ld a,13h ; 1.44Mb jr set_hz ; Вкл. режим 720kB set_720: ld a,12h ; 720kB set_hz: ld c,8Fh ; turbo RST ToBIOS ret ; Сбросить карту в начальное состояние Reset_Map: xor a ld (tracks),a ld (side),a inc a ld (sect),a ld a,5 ld (count),a ld a,maska ; 05h атрибут норм. сектора ld (bad),a ld hl,0D0Fh ld (cursor),hl ; восст. полож. метки ret ;[]======================================================[] ; Занести в контроллер диск и сторону L0870: ld a,(side) xor 1 ; 1 = 0-я сторона, 0 = 1-я сторона add a,a add a,a add a,a add a,a ld c,a ld a,(DISK) or c or 00001100b ; 0Ch out (REGCTRL),a ret ; Сброс ВГ93 ; установка на тек. диск и 0-ю сторону A0626: ex af,af' ld a,(DISK) ; диск and 3 ld c,a ld a,00011000b ; сброс ВГ93 нулем 2-го бита or c out (REGCTRL),a set 2,a ; 1Ch out (REGCTRL),a call A0929 ; сбр. контроллер ex af,af' ret ;---- ; прерывание FDC A0929: ld a,0D0h ; abort (force interrupt) out (REGCOM),a call delay ; delay 16 usec in a,(REGDATA) ; чтение регистра данных (clear DRQ) in a,(REGCOM) ; чтение статуса (clear INTRQ) ld a,0D0h ; abort again (why?) out (REGCOM),a call delay ; delay 16 usec in a,(REGCOM) ; получить статус (регистр команд) ret delay: ; >=16. usec delay ;ld b,5 ;djnz $ ; 13 T-states each ld a,1Fh dec a jr nz,$-1 ret ;---- ; сброс контроллера ;A0929: ld a,0D0h ; jr A092C ; головку на 0-ю дорожку A092A: ld a,8 ; послать команду A092C: out (REGCOM),a exx ld b,3+3; ; 3 счетчик call delay ; микро-пауза .loc2: ld de,0 .loc3: in a,(REGCOM) ;bit 7,a ; дискета менялась ? (NZ-да) ;... rrca ; тест на 0-й бит jr nc,.loc4 ; готов dec de ld a,d or e jr nz,.loc3 djnz .loc2 .loc4: in a,(REGCOM) ; получить код статуса exx ret ; Ожидание готовности НГМД L07AF: xor a ld (side),a ; тек. сторона L07B3: call L0870 ; в контроллер сторону и диск ld a,3+6; ; 3 число попыток ожидания ld (L0ACB),a ; цикл ожидания .loc1: ld hl,0 .loc2: in a,(REGCOM) and 0x81 ; 7 и 0 биты ret z dec hl ld a,h or l jr nz,.loc2 ; декремент попыток ожидания ld hl,L0ACB ; число попыток dec (hl) jr nz,.loc1 ; 3 попытки ожидания закончены call A0929; ;закоммент. сброс контроллера ;call A0626 ; сбросить обращение к ВГ93 ld a,0x80 ; код - нет диска or a ret ; Запись сист. области ms-dos или trd-бута L09D9: ld a,(density) ld c,8Fh ; turbo on/off RST ToBIOS xor a ld (tracks),a call A092A ; перейти на 0-ю дорожку ld hl,L2400 ; буфер сист. области ld (L0AC8),hl ld a,(_OS) or a jr z,_msdos dec a jr z,_trdos ret ;jp _cpm80 ; Копирует 2-ю FAT и записывает сист. область дискеты, ; при вкл. опции копирует загрузчик Estex в секторы 2..4. _msdos: ld a,(MS_Boot.media5) ; число секторов на FAT ld e,a ld hl,0 ld bc,512 .loc0: add hl,bc dec a jr nz,.loc0 ld a,e push hl ld hl,0 ld de,L2400+512 ; начало 1-й FAT .loc1: add hl,bc dec a jr nz,.loc1 pop bc add hl,de ex de,hl ldir ; ; bpb boot loader ld a,(cSystem) ; флаг создания сист. дискеты or a jr z,.loc2 ; копир. загрузчика Estex в сист. область ld hl,ES_Boot ; код загрузчика ld de,L2400+512 ; начало 1-й FAT ld bc,1536 ; 512*3 сект. = размер загрузчика ldir ; скоррект. BPB в буфере ld a,(MS_Boot.media5) inc a ld (L2400+14),a ld a,1 ; число копий FAT ld (L2400+16),a ; смещ. на число копий ; ; .loc2: call L07AF ; ожидание готовности нгмд ; запись 0-й стороны ld a,1 ld (sect),a ; 1-й сектор (boot) call L0870 ; сторону и диск в контроллер L08F0: call L0906 ; запись сектора ret nz ; ошибки записи ld a,(sect) ; тек. сектор inc a ld (sect),a loc02: cp 18+1 ; запредельный сектор jr nz,L08F0 ; запись 1-й стороны ld a,1 ld (side),a ; тек. сторона ld (sect),a ; тек. сектор call L0870 ; сторону и диск в контроллер L08F6: call L0906 ; запись сектора ret nz ; ошибки записи ld a,(sect) ; тек. сектор inc a ld (sect),a loc03: cp 18+1 ; запред. сектор ? jr nz,L08F6 ; запись загрузчика через sys ld a,(cSystem) ; флаг создания сист. дискеты or a ret z ; ; ret ; Запись сист. области TR-DOS. ; При boot-диске корректирует начало своб. места, ; число своб. секторов и число запис. файлов _trdos: xor a ; вычислить число своб. секторов ld hl,(BadSect) ex de,hl ld hl,2544 ; общее число секторов sbc hl,de ; минус bad-секторы ld (L2400+2277),hl ; число своб. секторов ld e,16 ; предустановка ; ld a,(sFlag1) or a jr nz,.loc8 ; ошибки работы с файлом "boot.$b" ld a,(cSystem) ; флаг создания boot-дискеты or a jr z,.loc8 ; не загрузочная ; call copy1 ; скопировать тело бута ld a,(NameBt+14) ld c,a add a,e ld e,a ; e=1000h+размер бута xor a ld b,a sbc hl,bc ; минус размер бута (в секторах) ; число файлов, запис. на диск inc a ld (L2400+2276),a ; занести реальное число своб. секторов ld (L2400+2277),hl ; вычисл. начало своб. места ld a,c cp 16 jr c,.loc6 ; размер бута меньше 16-ти секторов add a,10h rrca rrca rrca rrca ld h,a ld l,b jr .loc7 .loc6: ld hl,0100h add hl,bc .loc7: ld (L2400+2273),hl ; начало своб. места на диске ; .loc8: call L07AF ; ожидание готовности нгмд .loc2: ld a,1 ; с 1-го сектора ld (sect),a call L0870 ; сторону и диск в контроллер .loc3: call L0906 ; запись сектора ret nz ; ошибки записи dec e ld a,(sect) ; тек. сектор inc a ld (sect),a cp 16+1 ; запред. сектор jr nz,.loc3 ; след. сторона ld a,(side) xor 1 ld (side),a ld a,e or a ret z ; записана только сист. область sub 16 jr c,.loc4 ; остаток меньше 16-ти секторов ld a,(side) or a call z,NxtTrack jr .loc2 ; .loc4: add a,16 ; a=остаток секторов ld b,a ld a,1 ; с 1-го сектора ld (sect),a exx call L0870 ; сторону и диск в контроллер exx .loc5: push bc call L0906 ; запись сектора pop bc ret nz ; ошибки записи ld hl,sect ; тек. сектор inc (hl) djnz .loc5 ret ; Скопировать тело бута из буфера TRBoot в буфер L2400+1000h copy1: exx in a,(Page1) ex af,af' ld a,(hPages.TRBoot) out (Page1),a ; подкл. буфер ld hl,4000h ; начало Page1 ld de,L2400+1000h SizeBt: ld bc,4000h ldir ex af,af' out (Page1),a ; подкл. буфер exx ret ; заголовок бута "boot.$b" NameBt: ds 17 L0906: ld a,(sect) ; тек. сектор out (REGSEC),a ; регистр сектора ld a,0xA0 ; запись сектора ; ЗАПИСЬ СЕКТОРА (дорожки) ; 0x00 - Ok ; 0x40 - Read-Only ; 0x80 - No disk ; Z - без ошибок, NZ - ошибки ; Коды возврата действительны при записи секторов. A0875: push de ld hl,(L0AC8) ; адрес буфера ld de,0 ld b,4 ; счетчик di ld c,REGDATA ; порт данных out (REGCOM),a ; послать команду .loc1: in a,(REGCTRL) and 0C0h jr nz,.loc2 dec de ld a,e or d jr nz,.loc1 djnz .loc1 ld a,0x80 jr .loc4 ; нет диска .loc2: outi ; (hl) -> в порт .loc3: in a,(REGCTRL) and 0C0h jr z,.loc3 jp p,.loc2 in a,(REGCOM) .loc4: ld (RetCode),a ld (L0AC8),hl pop de ei ex af,af' call A0929 ex af,af' or a ret ; Запись дорожки L091B: in a,(Page3) push af ld a,(hPages.BuffTrk) out (Page3),a ; подкл. буфер структуры дорожки ld hl,L4000 ; начало данных ld (L0AC8),hl call L0870 ; в контроллер сторону и диск ld a,(tracks) ;- тек. дорожка out (REGTRK),a ;- регистр дорожки ld a,0xF4 ; запись дорожки call A0875 pop af out (Page3),a ret ; Уст. головку на след. дорожку NxtTrack: ld hl,tracks inc (hl) ; Уст. головку на тек. дорожку L0759: ld a,(tracks) ; тек. дорожка out (REGDATA),a ; регистр данных ld a,18h ; перейти на задан. дорожку jp A092C ; занести команду ; ЧТЕНИЕ СЕКТОРА. ; Чтение происходит в никуда, т.е. верификация. ; Read-Only не ловит ; 0x00 - Ok ; 0x08 - ошибка CRC ; 0x10 - не найдены требуемые дорожка, сектор или сторона ; 0x80 - No disk ; Z - без ошибок, NZ - ошибка L0C65: ld a,(sect) ; тек. сектор out (REGSEC),a ; в регистр сектора ld a,(side) ; тек. сторона add a,a add a,a add a,a or 0x80 ; 0-я сторона: 80h ; 1-я сторона: 88h call A092C ; занести команду di ld c,REGCOM ld b,3 ; счетчик попыток .loc1: ld de,0 ; счетчик .loc2: in a,(c) and 0x18 ; 4,3-й биты jr nz,.loc6 ; ошибка in a,(REGDATA) dec de ld a,d or e jr nz,.loc3 djnz .loc1 ld a,0x80 ; код "нет диска" or a jr .loc5 .loc3: in a,(c) and 1 ; 0-й бит jr nz,.loc2 ; контр. занят in a,(c) and 0x18 ; тест на 4,3-й биты .loc5: ld (RetCode),a ei ex af,af' call A0929 ex af,af' or a ret .loc6: djnz .loc1 jr .loc5 ; Чтение (верификация) секторов одной стороны ; Z - Ok ; NZ - есть ошибки ; "CY" - процесс прерван L0C87: ld a,maska ; 05h ld (bad),a ; признак норм. сектора ld (flg_bad+1),a ; сбр. флаг наличия bad-секторов ld (flg_wrn+1),a ; сбр. флаг наличия warn-секторов ld a,1 ld (sect),a ; тек. сектор call L0870 ; сторону и диск в контроллер L0C8C: ld a,3+1 ; 3 попытки ld (L0C63),a ; тек. попытки чтения сектора L0C91: call L0D25 ; признак нажатия клавиши ret c ; процесс прерван call L0C65 ; тест на чтение сектора jr z,L0CC3 ; без ошибок ; анализ ошибки cp 0x80 jr z,L0CB7 ; отсутствует диск ; сектор не читается xor a ld (flg_wrn+1),a ; уст. флаг "были подозр. секторы" ld hl,L0C63 ; тек. попытки чтения сектора dec (hl) ; уменьшить число попыток jr nz,L0C91 ; повторить чтение ; все попытки истекли ld a,(tracks) ; тек. дорожка or a ; нулевая ? jr nz,L0CB8 ; плохая нулевая дорожка (на парсинг ошибок) L0CB7: xor a dec a ret ; Отметить сектор как "BAD" L0CB8: xor a ld (flg_bad+1),a ; уст. флаг "были bad-секторы" ld a,(_OS) ; тип ОС-и ms-dos ? or a call z,L0ACF ; вычислить ячейку bad-сектора в FAT-е push bc call CalcAvail ; ++bad-сект. с выводом "Available bytes" pop bc L0CC3: ld hl,sect inc (hl) ; инкремент тек. сектора loc06: ld a,18+1 cp (hl) ; запред. сектор ? jr nz,L0C8C ; читать след. сектор ; все секторы стороны прочитаны flg_bad:ld a,1 or a jr z,_done1 ; были "bad" flg_wrn:ld a,1 or a jr z,_done2 ; были "warn" xor a ret ; _done1: ld a,2 ld (bad),a xor a ret _done2: xor a ld (bad),a ret ;[]==============================================================[] ; вычислить ячейку bad-сектора в FAT-е L0ACF: ld hl,(MS_Boot.media6) ; секторов на сторону add hl,hl ; *2 (секторов на всю дорожку) ex de,hl ld hl,0 ld a,(tracks) ; тек. дорожка L0AD8: add hl,de dec a jr nz,L0AD8 ld a,(side) ; тек. сторона or a jr z,L0AE8 ld de,(MS_Boot.media6) ; секторов на сторону add hl,de L0AE8: ld a,(sect) ; тек. сектор ld e,a add hl,de ld a,(LastSect) ; номер посл. служ. сектора дискеты cpl inc a ld e,a ld d,0xFF add hl,de xor a ld a,h rra ld h,a ld a,l rra ld l,a ld a,(MS_Boot.media1) ; секторов на кластер ld e,a ld d,0 add hl,de ; Помечает в буфере FAT-а bad-сектор push hl push de ld a,l rrca ; четный/не четный ? jr nc,L0A1C ; четный сектор call L0A2C ld a,(hl) and 0x0F or 0x70 ld (hl),a inc hl ld (hl),0xFF jr L0A28 L0A1C: call L0A2C ld (hl),0xF7 inc hl ld a,(hl) and 0xF0 or 0x0F ld (hl),a L0A28: xor a pop de pop hl ret L0A2C: push hl xor a ld a,h rra ld h,a ld a,l rra ld l,a pop de add hl,de ld de,L2400+512 ; начало 1-й FAT add hl,de ret ;[]============================================[] ; Установка смещения порядковых номеров ; секторов на +2 (лучший вариант). ; add_offset: ld hl,(MS_Boot.media6) ; число секторов в тек. формате ld a,(_OS) ; тип ОС-и or a jr z,.loc0 ; ms-dos ld l,16 ; число секторов tr-dos dec a ret nz ; cpm/80 .loc0: ld c,l ld b,0 ld hl,(INTERL+1) ; массив номеров секторов ld d,h ld e,l add hl,bc ; в конец массива ld b,c inc b .loc1: ld a,(hl) push af ; накопить в стеке номера секторов dec hl djnz .loc1 inc hl ; inc hl ;- смещ. на 2 сектора inc hl ;- ld b,c dec b ;- число секторов - 2 dec b ;- .loc2: pop af ld (hl),a inc hl djnz .loc2 ; pop af ld (de),a inc de pop af ld (de),a pop af ; выровнять баланс стека ret ; Установить интерлив для всех форматов init_interlive: ; для 720kB, 1.44Mb..1.64Mb ld b,20 ; число секторов ld hl,INTERL1 ld c,1 .loc1: ld (hl),c inc c inc hl djnz .loc1 ; для 1.68Mb..1.74Mb ld b,10 ld de,010Ch ; c=12 call .loc2 ld (hl),d inc hl ; для 800kB..830kB ld b,5 ld de,0106h call .loc2 ; для TR-DOS ld b,8 ld de,0109h .loc2: ld (hl),d inc hl ld (hl),e inc d inc e inc hl djnz .loc2 ret ; Таблицы интерливов секторов ; ; 720kB, 1.44Mb..1.64Mb INTERL1:ds 20 ; 1,2,3,...20 ; 1.68Mb..1.74Mb INTERL2:ds 21 ; 1,x,2,x,3,x,... (интерлив = 2) ; 800kB..830kB INTERL3:ds 10 ; интерлив = 2 ; TR-DOS INTERL4:ds 16 ; интерлив = 2 ; Получить тек. номер сектора из таблицы ; интерлива и настроить раб. ячейку L0B05: push hl ld a,(L0BA9) ; счетчик секторов ld c,a ld b,0 INTERL: ld hl,INTERL1 ; таблица интерлива секторов add hl,bc ld a,(hl) ; получить интерлив сектора ld (sect),a ; тек. сектор pop hl ret ; размер GAP1-а GAP1 equ 50 ; межсекторный пробел (перем. величина, задается при форматировании) GAP3 dw 108 ; по-умолчанию для 1.44Mb ; Подготовить заголовки секторов дорожки (одной стороны) L0BAA: in a,(Page3) push af ld a,(hPages.BuffTrk) out (Page3),a ; подкл. буфер дорожки xor a ld (L0BA9),a ; обнулить счетчик секторов ; ld hl,GAP1+16 ld (L0BB5+1),hl ld a,GAP1 ld (GAP+1),a ld hl,L4000+96 ; перейти на начало сектора (обойти GAP4A) ; ; цикл иниц. заголовков секторов L0BB2: call L0B05 ; получить тек. номер сектора из таблицы интерлива L0BB5: ld bc,GAP1+16 ;# перейти на заголовок сектора (66=GAP1+12синхро+IDAM) add hl,bc ; hl=адрес заголовка exx ld bc,16 ; 12 синхро-байт + IDAM ld hl,(GAP3) add hl,bc ld (L0BB5+1),hl ; уст. межсект. пробел exx ; заголовок сектора ld a,(tracks) ; тек. дорожка ld (hl),a inc hl ; ld a,(_OS) or a jr z,.loc1 dec a jr z,.loc2 ; для TR-DOS всегда 0-я сторона ; .loc1: ld a,(side) ; тек. сторона .loc2: ld (hl),a inc hl ld a,(sect) ; тек. сектор ld (hl),a inc hl L0BB6: ld bc,553 ; после заголовка сектора до конца сектора add hl,bc ld a,(L0BA9) ; счетчик тек. сектора inc a ld (L0BA9),a loc05: cp 18 ; посл. сектор ? jr nz,L0BB2 pop af out (Page3),a ; восст. раб. страницу ret ; Создает в буфере структуру дорожки ; Буфер: 0xC000..0xFFFF L0B21: in a,(Page3) push af ld a,(hPages.BuffTrk) out (Page3),a ; подкл. буфер дорожки call CLEAR ; заполнить буфер кодом 0x4E ld hl,L4000 ; начало буфера данных дорожки xor a ld (L0BA9),a ; обнулить счетчик секторов ; Начало дорожки ; GAP4A, 80 байт ld bc,504Eh ; 80 байт 4Eh call FILL ; c -> (hl), dec b ld bc,0C00h ; 12 синхро-байт call FILL ld bc,03F6h ; 3 байта F6 | call FILL ; | IAM ld (hl),0FCh ; 1 байт FC | inc hl ; начало сектора (+96 первого сектора от нач. дорожки) L0B3E: ; GAP1, 50 байт GAP: ld b,GAP1 ; GAP1/GAP3 ld c,4Eh call FILL ; c -> (hl), dec b ; синхро-байты ld bc,0C00h ; 12 синхро-байтов call FILL ; ld bc,03F5h ; 3 байта F5 маркера | call FILL ; | IDAM ld (hl),0FEh ; и FE, его идентификатор | inc hl ; Заголовок сектора ld bc,0300h ; 3 байта заголовка сектора call FILL SecCode:ld (hl),2 ; код размера сектора inc hl ld (hl),0F7h ; 1 байт CRC inc hl ld bc,164Eh ; 22 байта GAP2 call FILL ld bc,0C00h ; 12 синхро-байтов call FILL ; DATA AM ld bc,03F5h ; 3 байта маркера call FILL ld (hl),0FBh ; и его идентификатор inc hl ; Область данных ld bc,00E5h ; 256 байтов заполнителя call FILL ; c -> (hl), dec b ld a,(_OS) ; тип текущей ОС or a jr z,.loc1 ; ms-dos dec a jr z,.loc2 ; tr-dos ; cpm-80 ld bc,00E5h ; 256 call FILL ld bc,00E5h ; 256 call FILL .loc1: ld bc,00E5h ; 256 call FILL ; CRC области данных .loc2: ld (hl),0F7h ; 1 байт ; Конец сектора inc hl ld a,(GAP3) ld (GAP+1),a ; уст. межсект. пробел ld a,(L0BA9) ; счетчик номера тек. сектора inc a ld (L0BA9),a loc08: cp 18 ; последний сектор ? jr nz,L0B3E ; GAP4B, остаток дорожки (буфер уже заполнен 0x4E) pop af out (Page3),a ; вкл. рабочую страницу 0xC000 ret FILL: ld (hl),c inc hl djnz FILL ret ; Заполнение буфера структуры дорожки кодом 0x4E CLEAR: ld (L0ACD),sp ld sp,0 ; заполнение с 0xFFFF ld bc,0x4E4E ; код заполнения .loc1: push bc ld hl,0 add hl,sp ld a,h cp 0xC0 ; ст. байт нижней границы jr nz,.loc1 ld a,l or a jr nz,.loc1 ld sp,(L0ACD) ret ; Создает в буфере системную область дискеты (boot-сектор, FAT, Root dir). ; Буфер: L2400... ; макс. длина области: 0x4C00 для 1.74Mb L09A8: ld de,L2400 ; буфер Boot-сектора ld hl,MS_Boot ; ms-dos boot-сектор ld bc,512 ; длина boot-а ldir ex de,hl ; hl = начало FAT в буфере loc07: ld bc,16896 ; 6656/16896 длина FAT-ов + Root dir ld e,0 ; байт заполнения call L0994 ; перекачка е -> (hl) ld a,(MS_Boot.media4) ; байт-описатель формата диска ld hl,L2400+512 ld (hl),a ; занести первым байтом в FAT inc hl ld (hl),0FFh ; 2 и 3-й байты FAT inc hl ld (hl),0FFh ret L0994: ld (hl),e inc hl dec bc ld a,b or c jr nz,L0994 ret ; Настроить форматилку на тек. формат дискеты FSETUP: ld a,(_OS) or a jr nz,noMSDOS frm1: ld a,18 ; число секторов ld (loc05+1),a ld (loc08+1),a SSect: ld hl,18 ; секторов на сторону ld (MS_Boot.media6),hl inc a ; запред. сектор ld (loc02+1),a ld (loc03+1),a ld (loc06+1),a frm2: ld a,34 ; посл. служ. сектор дискеты ld (LastSect),a frm3: ld a,1 ; секторов на кластер ld (MS_Boot.media1),a frm4: ld a,0xF0 ; байт формата ld (MS_Boot.media4),a frm5: ld hl,16896 ; размер FAT-ов + Root dir ld (loc07+1),hl frm6: ld hl,224 ; записей в корне ld (MS_Boot.media2),hl ASect: ld hl,2880 ; секторов на диске ld (MS_Boot.media3),hl FSect: ld hl,9 ; секторов на FAT ld (MS_Boot.media5),hl ret ; noMSDOS:dec a jr nz,SetCPM ; Настроить форматилку на формат TR-DOS ld a,16 ; число секторов jr setOS ; Настроить форматилку на формат CP/M-80 SetCPM: ld a,5 ; число секторов setOS: ld (loc05+1),a ld (loc08+1),a inc a ; запред. сектор ld (loc06+1),a ret ; Создает в буфере системную область TR-DOS дискеты. SysAreaTRDOS: ; очистить место до бута ld hl,L2400 ; буфер сист. области ld bc,1000h ; 16*256 ld e,0 ; байт заполнения call L0994 ; очистить сист. область ld a,(sFlag1) or a jr nz,.loc0 ; ошибки работы с файлом "boot.$b" ld a,(cSystem) ; флаг создания boot-дискеты or a jr z,.loc0 ; не загрузочная ; ld hl,NameBt ld de,L2400 ld bc,13 ldir inc hl ldi ex de,hl ld (hl),0 inc hl ld (hl),1 ; .loc0: ld hl,L2400+2274 ; +226 от начала ld (hl),1 ; ст.байт начало своб. места на диске inc hl ld (hl),22 ; тип разметки диска inc hl ; число файлов на диске inc hl ld (hl),240 ; число своб. секторов inc hl ; ld (hl),9 ; inc hl ld (hl),16 ; +231 число секторов на дорожке ; ld de,LABEL ; буфер имени метки форматилки ld a,(de) or a jr nz,.loc1 ; метка задана ld de,.loc4 ; метка по умолчанию .loc1: ld hl,L2400+2293 ; перейти на метку в буфере ex de,hl ld b,11 ; длина метки .loc2: ld a,(hl) or a jr z,.loc3 ld (de),a inc hl inc de djnz .loc2 ret .loc3: ld a," " ld (de),a inc de djnz .loc3 ret ; tr-dos метка по умолчанию .loc4: db "FFORMAT",0 LastSect: db 34 ; 34/14, посл. служ. сектор DISK: db 0 ; диск (0=A,1=B) L0AC8: dw 0 ; тек. адрес в сист. буфере L0ACB: db 0 ; счетчик попыток ожидания L0ACD: dw 0 ; сохр. стека L0BA9: db 0 ; счетчик секторов L0C63: db 0 ; тек. попытки чтения сектора ;L0C64: db 0 ; тек. число 3-х разовых попыток чтения BadSect:dw 0 ; число bad-секторов sect: db 0 ; тек. сектор side: db 0 ; тек. сторона tracks: db 0 ; тек. дорожка RetCode:db 0 ; код возврата записи сектора/дорожки density:db 0 ; 13h/12h режим 1.44Mb/720kB ; Главная функция форматирования L0BFF: ld a,(density) ld c,8Fh ; turbo on/off RST ToBIOS ld hl,0 ld (BadSect),hl ; число bad-секторов call InitElapsedTime ; сохр. и сбросить время call L07AF ; ожидание готовности нгмд ; цикл формат. дорожек L0C14: call FORMAT_TRK ; форматирование ret c ; формат. прервано ret nz ; есть ошибки чтения ; нет ошибок ld a,(Mode2) ; "Optimize sectors" or a call nz,add_offset ; смещ. +2 к порядк. номерам секторов ld hl,tracks inc (hl) ; ++тек. дорожки TRACKS: ld a,82 cp (hl) jr nc,L0C14 xor a ; конец форм-ния (или при ошибках) ret ; Форматир. одной дорожки FORMAT_TRK: xor a ld (side),a ; тек. сторона ld (RetCode),a ; сбр. возвр. код .loop: ;ld a,2 ;ld (L0C64),a ; число 3-х разовых попыток call L0BAA ; иниц. заголовков секторов дорожки call L0759 ; уст. головку на тек. дорожку call L091B ; запись целой дорожки call L0C87 ; тест на чтение секторов одной стороны ret c ; выход - процесс прерван ret nz ; есть ошибки чтения call Map ; вывод карты call L0D93 ; вывод "Side: X" call L0D92 ; вывод "Cylinder: XX" call ElapsedTime ; вывод времени работы call L0D25 ; признак нажатия клавиши ret c ; процесс прерван ld hl,side inc (hl) ; смена стороны ld a,(hl) ; тек. сторона cp 1+1 ; запредельная ? jr nz,.loop xor a ret ; Вывод тек. номера дорожки L0D92: ld de,1323h ; Y/X полож. курсора LD C,BIOS.LP_SET_PLACE RST ToBIOS ld a,(tracks) ; тек. дорожка ld l,a ld bc,10 ; десятки ld h,b ld de,space4 ld iy,tmp1 res 7,(iy+0) call GetLenN16 ld a,l add a,"0" ld (de),a ld hl,space4 ld bc,0285h ; вывод строки ld e,ColFormNumber ; атрибут RST ToBIOS ret ; Вывод тек. стороны L0D93: ld de,1316h ; Y/X полож. курсора LD C,BIOS.LP_SET_PLACE RST ToBIOS ld a,(side) ; тек. сторона add a,"0" ld bc,0181h ; вывод символа ld e,ColFormNumber ; атрибут RST ToBIOS ret ; Сохранение и сброс тек. времени InitElapsedTime: ld c,0F5h ; проверить наличие м/с CMOS RST ToBIOS jr nc,.loc1 ; есть м/с xor a ; false ld (cmos),a ret .loc1: ld a,1 ; true ld (cmos),a ld de,140Fh ; Y/X полож. курсора LD C,BIOS.LP_SET_PLACE RST ToBIOS ld hl,.string ld bc,0E85h ; вывод строки ld e,ColFormText ; цвет строки RST ToBIOS ld hl,.time ld bc,0885h ; вывод строки ld e,ColFormNumber ; атрибут RST ToBIOS ; сохр. тек. время ld c,21h RST ToDSS ld (hours),hl ; часы/минуты ld a,b ld (seconds),a ; секунды ; сбросить время ld h,0 ; часы ld l,h ; минуты ld b,h ; секунды ld c,22h ; уст. текущие дату и время RST ToDSS ret .string:db "Elapsed time: " .time: db "00:00:00" hours: dw 0 ; часы/минуты seconds:db 0 ; секунды cmos: db 0 ; флаг наличия м/с CMOS (false/true) ; Вывести время работы ElapsedTime: ld a,(cmos) or a ret z ; нет м/с CMOS ld de,141Dh ; Y/X полож. курсора LD C,BIOS.LP_SET_PLACE RST ToBIOS ; ld c,21h ; получить тек. время RST ToDSS ex de,hl ld a,d ld hl,elptime call GetData ; часы ld a,e call GetData ; минуты ld a,b call GetData ; секунды ; ld hl,elptime ld bc,0885h ; вывод строки ld e,ColFormNumber ; атрибут RST ToBIOS ret elptime:db "00:00:00" ; Вывод десятков с ведущим нулем ; вх: A=число ; HL=буфер GetData:ld c,"0"-1 .loc1: inc c sub 10 jr nc,.loc1 ld (hl),c inc hl add a,58 ld (hl),a inc hl inc hl ret ; Восст. системное время RestoreTime: push af ld a,(cmos) or a jr z,.loc1 ; нет м/с CMOS ; получить тек. время (elapsed time) ld c,21h RST ToDSS ; d - день ; e - месяц ; ix - год ; h - час ; l - минуты ; b - секунды push de ex de,hl ; de = elapsed time ld hl,(hours) ; часы/минуты ld a,(seconds) ; секунды call CalcTime pop de ; уст. время ld c,22h RST ToDSS .loc1: pop af ret ; корректировка времени CalcTime: ld c,60 ; секунды add a,b cp c jr c,.loc1 inc e ; ++минуты sub c .loc1: ld b,a ; минуты ld a,l add a,e cp c jr c,.loc2 inc d ; ++часы sub c .loc2: ld l,a ; часы ld a,d add a,h cp 24 jr c,.loc3 sub 24 .loc3: ld h,a ret ;-------------------------------------------------+ ; MS-DOS загрузчик дискет (из fformat), 512 байт. | ; формат 1.44Mb. | ; для 720kB см. метку '#' | ;-------------------------------------------------+ MS_Boot: .pc_code: db 0xEB,0x3C,0x90 ; 3 байта, код перехода на загрузчик ; 8 байт, OEM ID db "DSS " .dss_major_ver: db "1." .dss_minor_ver: db "71" ;BPB, 17 байт .BPB: dw 512 ; байт на сектор .media1: db 1 ; # 2, секторов на кластер .reserved: dw 1 ; зарезерв. секторов .fat_num: db 2 ; число FAT-ов .media2: dw 224 ; # 112, записей в корне .media3: dw 2880 ; # 1440, всех секторов на диске .media4: db 0xF0 ; # 0xF9, байт формата .media5: dw 9 ; # 3, секторов на FAT .media6: dw 18 ; # 9, секторов на сторону dw 2 ; кол-во сторон диска ;extended boot-record dw 0,0 ; скрытых секторов dw 0,0 ; всех секторов на диске dw 0 ; физ. номер диска db 0x29 ; сигнатура расш. boot-записи .serial: dw 0000,0000 ; серийный номер дискеты 2D3A:96C2 .label: db "NO NAME " ; 11 байт, метка дискеты db "FAT12 " ; 8 байт, ID файловой системы ;--------------; /* db 0xFA,0x33,0xD2,0x8E,0xD2,0xBC,0xF0,0x7B db 0xFB,0xB8,0xC0,0x07,0x8E,0xD8,0xE8,0x89 db 0x00,0xBE,0xFE,0x00,0xFC,0xBB,0x70,0x00 db 0xE8,0x25,0x00,0x32,0xE4,0xCD,0x16,0x3C db 0x1B,0x74,0x18,0x3C,0x0D,0x74,0x08,0x3C db 0x20,0x74,0x04,0x3C,0x6F,0x75,0xEC,0xBE db 0xDF,0x01,0xE8,0x0B,0x00,0xBE,0xC1,0x01 db 0xE8,0x05,0x00,0xE8,0x5C,0x00,0xCD,0x19 db 0xAC,0x0A,0xC0,0x74,0x46,0x3C,0x01,0x75 db 0x05,0xAC,0x8A,0xD8,0xEB,0xF2,0x3C,0x02 db 0x75,0x0A,0xAD,0x8B,0xD0,0x56,0xE8,0x62 db 0x00,0x5E,0xEB,0xE4,0x3C,0x03,0x75,0x0A db 0xAC,0xA2,0x00,0x00,0x89,0x36,0x01,0x00 db 0xEB,0xD6,0x3C,0x04,0x75,0x0C,0xFE,0x0E db 0x00,0x00,0x74,0x04,0x8B,0x36,0x01,0x00 db 0xEB,0xC6,0x33,0xC9,0xA8,0x80,0x74,0x05 db 0x24,0x7F,0x8A,0xC8,0xAC,0x41,0xE8,0x17 db 0x00,0xEB,0xB5,0x36,0xA1,0x6C,0x04,0x05 db 0x04,0x00,0x36,0x39,0x06,0x6C,0x04,0x72 db 0xF9,0xC3,0xB8,0x03,0x00,0xCD,0x10,0xC3 db 0x56,0x3C,0x0A,0x74,0x10,0xB4,0x09,0xCD db 0x10,0x02,0xD1,0x80,0xFA,0x50,0x73,0x05 db 0xE8,0x08,0x00,0x5E,0xC3,0xFE,0xC6,0x32 db 0xD2,0xEB,0xF5,0xB4,0x02,0xCD,0x10,0xC3 ; 21 байт db " FFORMAT Version " db major_version + "0","." db (minor_version / 10) + "0",(minor_version % 10) + "0" ; db 0xBA,0x20,0x01,0x1F,0x03,0x07,0xCF,0xB0 db 0x04,0x91,0xB0,0x01,0x4E,0x80,0xC9,0xA7 db 0xCD,0x80,0xBB,0x01,0x1F,0x93,0xB0,0x03 db 0x06,0x91,0xB0,0x01,0x4E,0x80,0xBA,0xA7 db 0x20,0x80,0xBA,0x01,0x07,0x81,0xB0,0x01 db 0x1F,0x91,0xB0,0x04,0x91,0xB0,0x01,0x4E db 0x80,0xC8,0xA7,0xCD,0x80,0xBC,0x01,0x07 db 0x81,0xB0,0x01,0x1F,0x91,0xB0,0x93,0xB0 db 0x01,0x07,0xA9,0xB0,0x01,0x1F,0x91,0xB0 db 0x03,0x07,0xCF,0xB0,0x04,0x01,0x70 ; 16 байт db " RLE Boot record" db 0xC6,0x20,0x01,0x4F,0x02,0x15,0x0A ; 36 байт db "Sorry, but this disk is not bootable" db 0x02,0x16,0x0B ; 33 байта db "Insert SYSTEM disk into the drive" db 0x01,0x7F,0x02,0x22,0x0D ; не нажатый бутон db "",82h,20h,01h,7Ch,"O",01h,7Fh,"k",82h,20h,"" db 0x01,0x40,0x80,0xDC,0x02,0x23,0x0E,0x89 db 0xDF,0x02,0x00,0x19,0x00,0x01,0x4E,0x02 db 0x22,0x0D,0x20,0x01,0x7F ; нажатый бутон db "",82h,20h,01h,7Ch,"O",01h,7Fh,"k",82h,20h,"" db 0x01,0x4E,0x02,0x23,0x0E,0x89,0x20,0x02 db 0x00,0x19,0x00 dw 0xAA55 */ ;[]========================================================[] ; Опрос статуса нажатия клавиши ; выход: NZ - нажата (буфер не пуст) L0D25: ld c,31h RST ToDSS ret z cp 0Dh ; Enter jr z,.loc3 cp 1Bh ; Esc jr z,.loc3 and 5Fh cp "C" ; Hot-key jr z,.loc3 xor a ret ; очистить буфер клавы .loc3: ld bc,3135h RST ToDSS ; окно "прервать процесс ?" call okno0 ld a,(hl) cp cmOkey jr z,.loc2 .loc1: call HiddenMouse ; скрыть мышку ld a,(tracks) out (REGDATA),a ld a,18h ; перейти на задан. дорожку call A092C ; занести команду call L07B3 ; ожидание готовности НГМД ret z ; нет ошибок call okno3 ; "Вставьте дискету" ld a,(hl) cp cmOkey jr z,.loc1 .loc2: call Fresh xor a scf ret