MODULE FDD_LOW_FORMAT ; Порты ВГ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 RET 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 ; "ошибка записи сист. области или не совм. формат" ; ;!FIXIT "запрещена запись" ReadOnly: ;!FIXIT нет дискеты (код 80h) nodisk: ;call okno3 ; "Вставьте дискету" ;ld a,(hl) ;cp cmOkey ;ret nz ;; дискета вынута (в процессе форм-ния) ;jp FFORM1 ;!FIXIT "ошибка записи сист. области или не совм. формат" okno2: DI HALT ; 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 ; вывести нач. данные ;!FIXIT вывод номера дорожки L0D92: ;!FIXIT вывод стороны L0D93: DI HALT ; Скрыть мышку ; 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 ; !HARDCODE ; .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,BuffTrk ; начало данных 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" - процесс прерван ;!FIXIT надо ли? maska equ 05h ; 5/2/0 "маска" ok/bad/wrn для уст.атрибута цвета bad: db maska ; атрибут bad=0k+03h 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 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 ; 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 (C2) | 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 маркера (A1) | 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 байта F5 маркера (A1) 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 ;!FIXIT вот нахера стеком? ; Заполнение буфера структуры дорожки кодом 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 CLEAR: LD HL,BuffTrk LD (HL),#4E LD DE,BuffTrk + 1 LD BC,#4000-1 LDIR 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,BOOT_SECTOR.Floppy_3x5_1x44 ; байт формата ; 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 ; Главная функция форматирования 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 ; 0-2. 3 байта, код перехода на загрузчик ; ; 8 байт, OEM ID ; db "DSS " ; .dss_major_ver: db "1." ; .dss_minor_ver: db "71" ;3-10 ; ;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 BOOT_SECTOR.Floppy_3x5_1x44 ; # 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 ;!FIXIT убрать лишнее ; Вычисление и вывод доступного пространства дискеты CalcAvail: ld de,1529h ; Y/X полож. "Available bytes" LD C,BIOS.LP_SET_PLACE RST ToBIOS and a ; сбр. перенос ld de,space2 ; буфер числа ld hl,(Avail) ; мл.разряд MinusSc:ld bc,512 sbc hl,bc ld (Avail),hl exx ld hl,(Avail+2) ; ст.разряд ld bc,0 sbc hl,bc ld (Avail+2),hl call Hex7Dec ld hl,space2 ld bc,0785h ; вывод строки ld e,ColFormNumber ; атрибут RST ToBIOS ; ld de,142Ch ; Y/X полож. "Bad sectors" LD C,BIOS.LP_SET_PLACE RST ToBIOS ld hl,(BadSect) inc hl ld (BadSect),hl ld iy,tmp1 res 7,(iy+0) ld de,space3 call Hex4Dec ; вывод кол-ва bad-секторов ld hl,space3 ld bc,0485h ; вывод строки ld e,ColFormNumber ; атрибут RST ToBIOS ret ///////////////////////////////////////////////////////////////////////// ; ПЕРЕНЕСТИ В КОНЕЦ КАК EQU ; ///////////////////////////////////////////////////////////////////////// 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 count: db 5 Avail: dw 0,0 ; число доступ. байт avail1: dw 0,0 ; ячейка для восст. "Avail" ; Таблицы интерливов секторов ; ; 720kB, 1.44Mb..1.64Mb INTERL1: ds 20 ; 1,2,3,...20 BuffTrk: EQU $ ; буфер трека ///////////////////////////////////////////////////////////////////////// ENDMODULE