; Порты ВГ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,SYS_PORT.CNF_3 out (SYS_PORT.RAM),a call A0626 ; сбросить контроллер ; дернуть головкой ld a,70 out (REGDATA),a ld a,18h ; перейти на задан. дорожку call FDC_CMD ; занести команду call FDC_CMD.zeroTrk ; на 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 SysWR ; запись сист. области call ClsDial ; закрыть окно диалога pop af ld (ColDialWn),a ; ld a,(RetCode) or a jr nz,Parsing ; были ошибки при записи сист. области call FDC_CMD.zeroTrk ; на 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,SYS_PORT.CNF_0 out (SYS_PORT.RAM),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 or %0001'1000 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-ю дорожку FDC_CMD.zeroTrk: ld a,8 ; послать команду FDC_CMD: 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-бута SysWR: ld a,(density) ld c,8Fh ; turbo on/off RST ToBIOS xor a ld (tracks),a call FDC_CMD.zeroTrk ; перейти на 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 ; сторону и диск в контроллер .loopWr0: call L0906 ; запись сектора ret nz ; ошибки записи ld a,(sect) ; тек. сектор inc a ld (sect),a .maxSector0+1: cp 18+1 ; запредельный сектор jr nz,.loopWr0 ; запись 1-й стороны ld a,1 ld (side),a ; тек. сторона ld (sect),a ; тек. сектор call L0870 ; сторону и диск в контроллер .loopWr1: call L0906 ; запись сектора ret nz ; ошибки записи ld a,(sect) ; тек. сектор inc a ld (sect),a .maxSector1+1: cp 18+1 ; запред. сектор ? jr nz,.loopWr1 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,(SLOT1) ex af,af' ld a,(hPages.TRBoot) out (SLOT1),a ; подкл. буфер ld hl,4000h ; начало SLOT1 ld de,L2400+1000h SizeBt: ld bc,4000h ldir ex af,af' out (SLOT1),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,(SLOT3) push af ld a,(hPages.BuffTrk) out (SLOT3),a ; подкл. буфер структуры дорожки ld hl,L4000 ; начало данных ld (L0AC8),hl call L0870 ; в контроллер сторону и диск ld a,(tracks) ;- тек. дорожка out (REGTRK),a ;- регистр дорожки ld a,0xF4 ; запись дорожки call A0875 pop af out (SLOT3),a ret ; Уст. головку на след. дорожку NxtTrack: ld hl,tracks inc (hl) ; Уст. головку на тек. дорожку L0759: ld a,(tracks) ; тек. дорожка out (REGDATA),a ; регистр данных ld a,18h ; перейти на задан. дорожку jp FDC_CMD ; занести команду ; ЧТЕНИЕ СЕКТОРА. ; Чтение происходит в никуда, т.е. верификация. ; 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 FDC_CMD ; занести команду 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,(SLOT3) push af ld a,(hPages.BuffTrk) out (SLOT3),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 (SLOT3),a ; восст. раб. страницу ret ; Создает в буфере структуру дорожки ; Буфер: 0xC000..0xFFFF L0B21: in a,(SLOT3) push af ld a,(hPages.BuffTrk) out (SLOT3),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 (SLOT3),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,MS_Boot.SIZE ; длина boot-а ldir ;!TEST 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 call CreateLabel ; создать метку дискеты, если задана call CreateSerialNumber 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 .sectorsAll+1: ld a,18 ; число секторов ld (loc05+1),a ld (loc08+1),a .sectorsSide+1: ld hl,18 ; секторов на сторону ld (MS_Boot.media6),hl inc a ; запред. сектор ld (_msdos.maxSector0),a ld (_msdos.maxSector1),a ld (loc06+1),a .lastSector+1: ld a,34 ; посл. служ. сектор дискеты ld (LastSect),a .sectorsPerCluster+1: 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,0xFE,0x00 ; 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 файловой системы block 510-62,0 dw #AA55 .SIZE EQU $-MS_Boot ;[]========================================================[] ; Опрос статуса нажатия клавиши ; выход: 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 FDC_CMD ; занести команду call L07B3 ; ожидание готовности НГМД ret z ; нет ошибок call okno3 ; "Вставьте дискету" ld a,(hl) cp cmOkey jr z,.loc1 .loc2: call Fresh xor a scf ret