diff --git a/Console/CONSOLE.ASM b/Console/CONSOLE.ASM index 900999e..6fd72fc 100644 --- a/Console/CONSOLE.ASM +++ b/Console/CONSOLE.ASM @@ -63,7 +63,7 @@ START: LD A,(IX-1) LD (TASKX),A PUSH IX - CALL CRLF + ;CALL CRLF CALL GETPATH POP IX ; @@ -417,7 +417,7 @@ COMP002 XOR A ;LD C,#FF LD C,A CPIR -.loop: ;CPI +;.loop: CPI ;JP NZ,.loop ; @@ -1286,7 +1286,7 @@ PDIGIT LD DE,10000 LD DE,10 CALL DIG LD A,L - ADD A,#30 + ADD A,"0" ;#30 ;!TEST ;LD (IX+0),A @@ -1673,6 +1673,7 @@ VERS: LD C,Dss.Version res 7,(ix+0) ld bc,100 ; 100 call .num16 + .decim: ld bc,10 ; 10 call .num16 ld a,l @@ -1680,7 +1681,8 @@ VERS: LD C,Dss.Version jr .num16_exit .tmp1__: BYTE 0 -.num16: ld a,2Fh + +.num16: ld a,'0'-1 and a inc a sbc hl,bc diff --git a/Console/build.txt b/Console/build.txt index ac4213d..abc4eff 100644 --- a/Console/build.txt +++ b/Console/build.txt @@ -1 +1 @@ -43 \ No newline at end of file +46 \ No newline at end of file diff --git a/DOS/CURSOR.ASM b/DOS/CURSOR.ASM new file mode 100755 index 0000000..d7261a7 --- /dev/null +++ b/DOS/CURSOR.ASM @@ -0,0 +1,63 @@ +delay_curs equ 11 ; частота мигания курсора + + + +cursor: db 3Eh ; ld a,.. +crFlag: db 0 ; флаг курсора 00-нет/01-есть + cpl + ld (crFlag),a +; Включить курсор +cursor_on: + ld c,8Eh ; узнать полож. курсора + rst 08h + ld (curs_posit+1),de + xor a + ld c,0B4h ; получить символ + rst 08h + ld bc,1BB5h ; b=знакоген., с=символ на экран + ld a,(crFlag) + or a + jr z,curs__ + ld b,1Ah ; черта + ld a,(D0642) ; флаги клавы + bit 1,a ; бит Ins + jr nz,$+4 + ld b,19h ; блок +curs__: xor a ; номер окна + rst 08h + ld a,1 + ld (curs_inv_flag),a + ld a,delay_curs + ret + +; Выключить курсор +cursor_off: + db 3Eh ; ld a,.. +curs_inv_flag: + db 0 ; флаг курсора: 00-выкл/01-вкл + or a + ret z + ld a,-1 + ld (crFlag),a + inc a + ld (curs_inv_flag),a + ld a,delay_curs + ld (curs_timer),a +curs_posit: + ld de,0 ; Y/X полож. + bit 7,e + ret nz + ld c,0B4h ; получить символ + xor a + rst 08h + xor a + ld bc,1BB5h ; символ на экран + rst 08h + ret + + +; Установить фокус на "Input Line" +focus_to_inpline: + call cursor_on ; вкл. курсор + ei + ret diff --git a/DOS/DOS.ASM b/DOS/DOS.ASM new file mode 100755 index 0000000..80d8a4a --- /dev/null +++ b/DOS/DOS.ASM @@ -0,0 +1,7531 @@ +; Последняя редакция: 9.03.2007 +; + + +; метки ## - не ясные места (закомментарино) +; метки @@ - замена ориг. кода +; + + +; буфер D2E7C или T0400 также исп. для ввода/вывода файловых операций ? + + + + +; Примечания по ДОС-у +; +; Выравнивание кода на границу происходит в двух местах: 0100h и 0900h +; (есть немного лишнего места). +; +; +; Добавления: +; ~~~~~~~~~~~ +; Появилась новая функция #08 DSS_RESCAN (Пересканировать девайсы системы). +; +; Функция #00 (версия ДОС) дополн. возвращает в BC номер билда (0..999). +; +; Добавлен код обслуживания курсора (на прерываниях) и регистрация в системе +; знакогенераторов курсора с номерами 1Ah/19h (черта/блок). Функция #32 дора- +; ботана под новый курсор, а также не выводит ascii-код #00 (от курс. клавиш +; и т.д.). Переключение формы курсора клавишей "Ins". +; +; В функции #5F (символ на принтер) добавлено отслеживание байта состояния +; принтера (7..3 биты). При ошибке, функция возвращает байт состояния, а не +; печатаемый символ, как в фирменной версии. +; +; ;Добавлена функция #0C (tmp_filename) +; +; +; + + + +; Исправления: +; ~~~~~~~~~~~~ +; 1) В отличии от оригинала, функции 0Ah/0Bh (Create file/New create file) +; перед созданием файла проверяют на переполнение таблицу свободных +; дескрипторов. + +; 2) Убрано фирменное ограничение макс. длины строки переменной окружения +; в 32 символа и некорректная отработка функции #46 (в командах "path", +; "set"). Теперь макс. длина строки 255 символов. +; +; 3) Исправлена фирменная ошибка, при которой происходило зависание +; системы (непредсказуемое поведение) при превышении макс. числа +; открытых дескрипторов (функции search_handle, release_handle). +; +; 4) Исправлена фирменная ошибка, из-за которой в операциях с файлами не +; отслеживался атрибут "системный". +; +; 5) Исправлено не отслеживание атрибута файла "r/o" в функции #0E (удаление +; файла). +; +; 6) Пофиксен глюк вывода списка файлов, если число файлов в списке +; превышало 509. Сейчас список выводится корректно и может содержать +; макс. 510 файлов. Если число файлов в каталоге превышает 510, то выдается +; код ошибки 35 "слишком много файлов" (для списка каталогов выдается +; код ошибки 7 "каталог не найден"). +; +; 7) Пофиксен глюк "PrintScreen", выдававший скен-код #C7 клавиши и +; устанавливавший бит LShift-a. Версия ДОС стала 1.61.9. +; +; +; + + + + +; ДОС выделяется блок из 3 банок (функ. Init_DOS), используемых в качестве +; банок расширения. +; Исп. лог. номеров банок: +; 0 - кэш списка каталога +; 1 - кэш FAT +; 2 - path-переменная (запуск файла) и др. переменные окружения, а также +; сохранение текст. экрана при переключении в граф. режим +; ;3 - страница структуры tsr-обработчиков (моя) +; +; +; +; +; + + + + + + include "dos.inc" + + + + org 0000h + + + +;RST 00h +L0000: jp Func_41 ; заглушка (завершить программу) +D0003: db -1 ; D0=сигнал переполн. буфера клавы, D1=сигнал перекл. на альт.раскладку + db -1 + db -1 + db -1 + db -1 + +;RST 08h, Вызов функций Биоса + push af + ld a,0 ; вкл. ПЗУ Биоса в 0-е окно + out (7Ch),a + pop af + ret + db -1 + +;RST 10h + jp A006C ; вектор ДОС-а + db -1 + db -1 + db -1 + db -1 + db -1 + +;RST 18h + jp drv_devices ; вектор дисковых устройств + db -1 + db -1 + db -1 + db -1 + db -1 + +;RST 20h, свободный + jp empty__ ; заглушка + db -1 + db -1 + db -1 + db -1 + db -1 + +;RST 28h, свободный + jp empty__ ; заглушка + db -1 + db -1 + db -1 + db -1 + db -1 + +;RST 30h + jp MOUSE_vector ; вектор мышки + db -1 + db -1 + db -1 + db -1 + db -1 + +;RST 38h + jp $+3 + push af + ex af,af' + push af + push bc + push de + push hl + exx + push bc + push de + push hl + push ix + push iy + call keyb_scan ; обработчик клавиатуры + ld c,80h ; обработчик аппаратн. прерыв. мышки + rst 30h + call cursor_interrupt ; вектор обслуж. курсора + pop iy + pop ix + pop hl + pop de + pop bc + exx + pop hl + pop de + pop bc + pop af + ex af,af' + pop af + ei + reti + + db -1 ;,-1,-1,-1 ; на границу 0064h + +;0064h + retn + db 0 ; 0066h (от немаск. прерывания в IM0) + db 0 + db 0 + jp $-5 + + +;------------------------------------------------- +; ДОС-овый вектор +;------------------------------------------------- +A006C: push hl + ld l,c ; номер команды + ld h,T0200 / 256 ; 0200h..02FFh массив мл.байтов адресов + ld c,(hl) ; загр. мл.байт адреса + inc h ; 0300h..03FFh массив ст.байтов адресов + ld h,(hl) ; загр. ст.байт адреса + ld l,c ; готовый адрес + ex (sp),hl ; в стек и + ret ; перейти на него + + + +; Вектор обслуживания курсора +cursor_interrupt: + ld a,(curs_inv_flag) + or a + ret z + ;di ;поставил + db 3Eh ; ld a,.. +curs_timer: + db 1 ; пауза мигания + dec a + call z,cursor + ld (curs_timer),a + ret + + + +; Начало boot-сектора +T0076: ds 3 ; 3 байта, код перехода на загрузчик +; 8 байт, OEM ID + db "DSS_" + db major_version + "0" + db "." + db (minor_version / 10) + "0" + db (minor_version % 10) + "0" +; BPB, 17 байт +D0081: dw 512 ;+11 ; байтов на сектор +D0083: db 2 ;+13 ; секторов на кластер + dw 1 ;+14 ; зарезерв. секторов +D0086: db 2 ;+16 ; число копий FAT-ов + dw 112 ;+17 ; записей в корне + dw 1440 ;+19 ; # всех секторов на диске + db 0F0h ;+21 ; байт формата +D008C: dw 2 ;+22 ; # секторов на FAT + dw 9 ;+24 ; секторов на сторону +D0090: dw 2 ;+26 ; кол-во сторон диска +; extended boot-record + dw 0,0 ;+28,+30 ; скрытых секторов + dw 0,0 ;+32,+34 ; всех секторов на диске + dw 80h ;+36 ; 0x00 физ. номер диска + db 29h ;+38 ; сигнатура расш. boot-записи + dw 0,0 ;+39,+41 ; серийный номер диска + db "NO NAME " +T00AC: db "FAT16 " + + + +;----------------------------------------------------------- +; Настройка знакогенератора курсора черточкой +;----------------------------------------------------------- +setup_znak: + in a,(0C2h) + push af ; сохр. порт + ld a,(list_dos_pages+2) ; 2-й лог. номер страницы расш. ДОС + out (0C2h),a + ; получить сист. знакоген. + ld de,8000h ; буфер для 2048 байт данных + push de + ld c,0B8h ; получить знакоген. + rst 08h + ; заполнить кодом 0FFh 2 нижние линии + ld hl,8000h+(2048-(2*256)) ; последние 512 байт + ld bc,511 + ld a,1Ah; ; номер знакоген. "черточка" + call fill_data_font + pop hl + ; заполнить остальные 6 линий (полный блок) + ld bc,2048-513 + ld a,19h; ; номер знакоген. "блок" + call fill_data_font + pop af + out (0C2h),a ; восст. порт + ret + +; Настройка знакоген. и его регистрация +; вход: a=номер знакоген. +; hl=данные +; bc=размер данных +fill_data_font: + ld e,l + ld d,h + ld (hl),-1 + inc de + ldir + ld de,8000h ; знакоген. + ld c,0B6h ; уст. знакоген. + rst 08h + ret + + + + ;ds 100h - $ ; выровнить на границу #0100 +L0100 equ $+100h AND 0FF00h + ds L0100 - $ + + + +;0100h. Массив списка выдел. страниц +list_pages: + ds 256 + + + +; Младшие разряды адресов функций +T0200: db Init_DOS%256, Func_01%256, Func_02%256, Func_03%256 ; 00..03 + db empty__%256, empty__%256, empty__%256, empty__%256 ; 04..07 + db Func_08%256, Func_09%256, Func_0A%256, Func_0B%256 ; 08..0B + db Func_0C%256, empty__%256, Func_0E%256, empty__%256 ; 0C..0F + db Func_10%256, Func_11%256, Func_12%256, Func_13%256 ; 10..13 + db Func_14%256, Func_15%256, Func_16%256, Func_17%256 ; 14..17 + db Func_18%256, Func_19%256, Func_1A%256, Func_1B%256 ; 18..1B + db Func_1C%256, Func_1D%256, Func_1E%256, empty__%256 ; 1C..1F + db empty__%256, Func_21%256, Func_22%256, empty__%256 ; 20..23 + db empty__%256, empty__%256, empty__%256, empty__%256 ; 24..27 + db empty__%256, empty__%256, empty__%256, empty__%256 ; 28..2B + db empty__%256, empty__%256, empty__%256, empty__%256 ; 2C..2F + db Func_30%256, Func_31%256, Func_32%256, Func_33%256 ; 30..33 + db empty__%256, Func_35%256, Func_36%256, Func_37%256 ; 34..37 + db Func_38%256, Func_39%256, Func_3A%256, Func_3B%256 ; 38..3B + db Func_3C%256, Func_3D%256, Func_3E%256, Func_3F%256 ; 3C..3F + db Func_40%256, Func_41%256, Func_42%256, Func_43%256 ; 40..43 + db Func_44%256, Func_45%256, Func_46%256, Func_47%256 ; 44..47 + db empty__%256, empty__%256, empty__%256, empty__%256 ; 48..4B + db empty__%256, empty__%256, empty__%256, empty__%256 ; 4C..4F + db Func_50%256, Func_51%256, Func_52%256, Func_53%256 ; 50..53 + db Func_54%256, Func_55%256, Func_56%256, Func_57%256 ; 54..57 + db Func_58%256, Func_59%256, Func_5A%256, Func_5B%256 ; 58..5B + db Func_5C%256, empty__%256, empty__%256, Func_5F%256 ; 5C..5F + db empty__%256, empty__%256, empty__%256, empty__%256 ; 60..63 + db empty__%256, empty__%256, empty__%256, empty__%256 ; 64..67 + db A0000%256, A0000%256, A0000%256, A0000%256 ; 68..6B + db A0000%256, A0000%256, A0000%256, A0000%256 ; 6C..6F + db A0000%256, A0000%256, A0000%256, A0000%256 ; 70..73 + db A0000%256, A0000%256, A0000%256, A0000%256 ; 74..77 + db A0000%256, A0000%256, A0000%256, A0000%256 ; 78..7B + db A0000%256, A0000%256, A0000%256, A0000%256 ; 7C..7F + db A0000%256, A0000%256, A0000%256, A0000%256 ; 80..83 + db A0000%256, A0000%256, A0000%256, A0000%256 ; 84..87 + db A0000%256, A0000%256, A0000%256, A0000%256 ; 88..8B + db A0000%256, A0000%256, A0000%256, A0000%256 ; 8C..8F + db A0000%256, A0000%256, A0000%256, A0000%256 ; 90..93 + db A0000%256, A0000%256, A0000%256, A0000%256 ; 94..97 + db A0000%256, A0000%256, A0000%256, A0000%256 ; 98..9B + db A0000%256, A0000%256, A0000%256, A0000%256 ; 9C..9F + db A0000%256, A0000%256, A0000%256, A0000%256 ; A0..A3 + db A0000%256, A0000%256, A0000%256, A0000%256 ; A4..A7 + db A0000%256, A0000%256, A0000%256, A0000%256 ; A8..AB + db A0000%256, A0000%256, A0000%256, A0000%256 ; AC..AF + db A0000%256, A0000%256, A0000%256, A0000%256 ; B0..B3 + db A0000%256, A0000%256, A0000%256, A0000%256 ; B4..B7 + db A0000%256, A0000%256, A0000%256, A0000%256 ; B8..BB + db A0000%256, A0000%256, A0000%256, A0000%256 ; BC..BF + db A0000%256, A0000%256, A0000%256, A0000%256 ; C0..C3 + db A0000%256, A0000%256, A0000%256, A0000%256 ; C4..C7 + db A0000%256, A0000%256, A0000%256, A0000%256 ; C8..CB + db A0000%256, A0000%256, A0000%256, A0000%256 ; CC..CF + db A0000%256, A0000%256, A0000%256, A0000%256 ; D0..D3 + db A0000%256, A0000%256, A0000%256, A0000%256 ; D4..D7 + db A0000%256, A0000%256, A0000%256, A0000%256 ; D8..DB + db A0000%256, A0000%256, A0000%256, A0000%256 ; DC..DF + db A0000%256, A0000%256, A0000%256, A0000%256 ; E0..E3 + db A0000%256, A0000%256, A0000%256, A0000%256 ; E4..E7 + db A0000%256, A0000%256, A0000%256, A0000%256 ; E8..EB + db A0000%256, A0000%256, A0000%256, A0000%256 ; EC..EF + db empty__%256, empty__%256, empty__%256, empty__%256 ; F0..F3 + db empty__%256, empty__%256, empty__%256, empty__%256 ; F4..F7 + db empty__%256, empty__%256, empty__%256, empty__%256 ; F8..FB + db empty__%256, empty__%256, empty__%256, empty__%256 ; FC..FF + +;0300h. Старшие разряды адресов функций + db Init_DOS/256, Func_01/256, Func_02/256, Func_03/256 ; 00..03 + db empty__/256, empty__/256, empty__/256, empty__/256 ; 04..07 + db Func_08/256, Func_09/256, Func_0A/256, Func_0B/256 ; 08..0B + db Func_0C/256, empty__/256, Func_0E/256, empty__/256 ; 0C..0F + db Func_10/256, Func_11/256, Func_12/256, Func_13/256 ; 10..13 + db Func_14/256, Func_15/256, Func_16/256, Func_17/256 ; 14..17 + db Func_18/256, Func_19/256, Func_1A/256, Func_1B/256 ; 18..1B + db Func_1C/256, Func_1D/256, Func_1E/256, empty__/256 ; 1C..1F + db empty__/256, Func_21/256, Func_22/256, empty__/256 ; 20..23 + db empty__/256, empty__/256, empty__/256, empty__/256 ; 24..27 + db empty__/256, empty__/256, empty__/256, empty__/256 ; 28..2B + db empty__/256, empty__/256, empty__/256, empty__/256 ; 2C..2F + db Func_30/256, Func_31/256, Func_32/256, Func_33/256 ; 30..33 + db empty__/256, Func_35/256, Func_36/256, Func_37/256 ; 34..37 + db Func_38/256, Func_39/256, Func_3A/256, Func_3B/256 ; 38..3B + db Func_3C/256, Func_3D/256, Func_3E/256, Func_3F/256 ; 3C..3F + db Func_40/256, Func_41/256, Func_42/256, Func_43/256 ; 40..43 + db Func_44/256, Func_45/256, Func_46/256, Func_47/256 ; 44..47 + db empty__/256, empty__/256, empty__/256, empty__/256 ; 48..4B + db empty__/256, empty__/256, empty__/256, empty__/256 ; 4C..4F + db Func_50/256, Func_51/256, Func_52/256, Func_53/256 ; 50..53 + db Func_54/256, Func_55/256, Func_56/256, Func_57/256 ; 54..57 + db Func_58/256, Func_59/256, Func_5A/256, Func_5B/256 ; 58..5B + db Func_5C/256, empty__/256, empty__/256, Func_5F/256 ; 5C..5F + db empty__/256, empty__/256, empty__/256, empty__/256 ; 60..63 + db empty__/256, empty__/256, empty__/256, empty__/256 ; 64..67 + db A0000/256, A0000/256, A0000/256, A0000/256 ; 68..6B + db A0000/256, A0000/256, A0000/256, A0000/256 ; 6C..6F + db A0000/256, A0000/256, A0000/256, A0000/256 ; 70..73 + db A0000/256, A0000/256, A0000/256, A0000/256 ; 74..77 + db A0000/256, A0000/256, A0000/256, A0000/256 ; 78..7B + db A0000/256, A0000/256, A0000/256, A0000/256 ; 7C..7F + db A0000/256, A0000/256, A0000/256, A0000/256 ; 80..83 + db A0000/256, A0000/256, A0000/256, A0000/256 ; 84..87 + db A0000/256, A0000/256, A0000/256, A0000/256 ; 88..8B + db A0000/256, A0000/256, A0000/256, A0000/256 ; 8C..8F + db A0000/256, A0000/256, A0000/256, A0000/256 ; 90..93 + db A0000/256, A0000/256, A0000/256, A0000/256 ; 94..97 + db A0000/256, A0000/256, A0000/256, A0000/256 ; 98..9B + db A0000/256, A0000/256, A0000/256, A0000/256 ; 9C..9F + db A0000/256, A0000/256, A0000/256, A0000/256 ; A0..A3 + db A0000/256, A0000/256, A0000/256, A0000/256 ; A4..A7 + db A0000/256, A0000/256, A0000/256, A0000/256 ; A8..AB + db A0000/256, A0000/256, A0000/256, A0000/256 ; AC..AF + db A0000/256, A0000/256, A0000/256, A0000/256 ; B0..B3 + db A0000/256, A0000/256, A0000/256, A0000/256 ; B4..B7 + db A0000/256, A0000/256, A0000/256, A0000/256 ; B8..BB + db A0000/256, A0000/256, A0000/256, A0000/256 ; BC..BF + db A0000/256, A0000/256, A0000/256, A0000/256 ; C0..C3 + db A0000/256, A0000/256, A0000/256, A0000/256 ; C4..C7 + db A0000/256, A0000/256, A0000/256, A0000/256 ; C8..CB + db A0000/256, A0000/256, A0000/256, A0000/256 ; CC..CF + db A0000/256, A0000/256, A0000/256, A0000/256 ; D0..D3 + db A0000/256, A0000/256, A0000/256, A0000/256 ; D4..D7 + db A0000/256, A0000/256, A0000/256, A0000/256 ; D8..DB + db A0000/256, A0000/256, A0000/256, A0000/256 ; DC..DF + db A0000/256, A0000/256, A0000/256, A0000/256 ; E0..E3 + db A0000/256, A0000/256, A0000/256, A0000/256 ; E4..E7 + db A0000/256, A0000/256, A0000/256, A0000/256 ; E8..EB + db A0000/256, A0000/256, A0000/256, A0000/256 ; EC..EF + db empty__/256, empty__/256, empty__/256, empty__/256 ; F0..F3 + db empty__/256, empty__/256, empty__/256, empty__/256 ; F4..F7 + db empty__/256, empty__/256, empty__/256, empty__/256 ; F8..FB + db empty__/256, empty__/256, empty__/256, empty__/256 ; FC..FF + + + + + +; буфер 512 байт +T0400: db ". ",10h,0,0,0,0 ; тек. каталог + ds 16 + db ".. ",10h,0,0,0,0 ; родит. каталог + ds 16 + ds 448 + + +;T0600. Выровнить на границу xx00h + + include "keyb.asm" ; включает "init_DOS" + + + +;///////////////////////////////////////////////////////////////////// +; Функция #56. Очистить окно. +; +; вход: D - строка левого верхнего угла окна +; E - столбец левого верхнего угла окна +; H - высота окна +; L - ширина окна +; A - символ заполнитель +; B - атрибут заполнитель +; выход: нет +;///////////////////////////////////////////////////////////////////// +Func_56:ld c,8Dh ; очистка экрана указ. символом + rst 08h + and a + ret + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #5C. Вывод строки на экран. +; +; вход: HL - указатель на строку символов +; выход: нет +;///////////////////////////////////////////////////////////////////// +Func_5C:ld a,(hl) + inc hl + or a + ret z + call Func_5B ; вывод "a" на экран + jr Func_5C + + + +;///////////////////////////////////////////////////////////////////// +; Функция #5B. Вывод символа на экран в тек. позиции. +; +; вход: A - символ +; выход: нет +;///////////////////////////////////////////////////////////////////// +Func_5B: + cp " " + jr nc,A0DFC + cp 0Dh ; в начало строки + jr z,A0E20 + cp 0Ah ; на след. строку + jr z,A0E28 + cp 9 ; Tab + jr z,A0E0F + cp 8 ; Backspace + jr z,A0E03 +A0DFC: push hl + ld bc,0182h ; вывести один символ без атрибута + rst 08h + pop hl + ret + +; Backspace +A0E03: ld c,8Eh ; узнать полож. курсора + rst 08h + xor a + cp e + jp z,Func_52 ; уст. полож. курсора + dec e + jp Func_52 ; уст. полож. курсора + +; Tab +A0E0F: ld c,8Eh ; узнать полож. курсора + rst 08h + ld a,e + and 0F8h + add a,8 + ld e,a ; X полож. курсора + jp Func_52 ; уст. полож. курсора + +; 0Dh - в начало строки +A0E20: ld c,8Eh ; узнать полож. курсора + rst 08h + ld e,0 + jp Func_52 ; уст. полож. курсора + +; 0Ah - на след. строку +A0E28: ld c,8Eh ; узнать полож. курсора + rst 08h + ld a,d + cp 31 + jr nc,A0E35 + inc d + jp Func_52 ; уст. полож. курсора + ; +A0E35: push hl + push de + ld bc,018Ah ; скроллинг вверх + ld de,0020h ; нач./число строк + ei + halt + di + rst 08h + ld de,1F00h ; Y/X полож. нижней строки + call Func_52 ; уст. полож. курсора + ld a," " ; символ + ld bc,5082h ; вывести 80 симв. + rst 08h + ei + pop de + call Func_52 ; уст. полож. курсора + pop hl + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #52. Установить положение курсора. +; +; вход: D - строка курсора +; E - колонка курсора +; выход: нет +;///////////////////////////////////////////////////////////////////// +Func_52:ld c,84h ; уст. полож. курсора + rst 08h + ret + + +;///////////////////////////////////////////////////////////////////// +; Функция #53. Узнать положение курсора. +; +; вход: нет +; выход: D - строка курсора +; E - колонка курсора +;///////////////////////////////////////////////////////////////////// +Func_53:ld c,8Eh ; узнать полож. курсора + rst 08h + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #57. Прочитать символ с экрана. +; +; вход: D - строка +; E - колонка +; выход: A - символ +; B - атрибут +;///////////////////////////////////////////////////////////////////// +Func_57:xor a + ld c,0B4h + rst 08h + ld a,l + ld b,h + and a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #58. Вывести символ на экран. +; Управляющие символы выводятся как обычные символы. +; +; вход: D - строка +; E - колонка +; A - символ +; B - атрибут +; выход: нет +;///////////////////////////////////////////////////////////////////// +Func_58:ld c,a + push bc + push de + ld c,0B4h ; символ с экрана + xor a + rst 08h + pop de + pop hl + ld c,0B5h ; символ на экран + xor a + rst 08h + and a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #59. Сохранить окно экрана. +; +; вход: D - строка +; E - колонка левого верхнего угла окна +; H - высота окна +; L - ширина окна +; B - страница буфера +; IX - адрес буфера +; выход: нет +;///////////////////////////////////////////////////////////////////// +Func_59:ld a,r ; во флаг P/V сост. триггера разреш. прерываний + push af + xor a + di + ld c,0B2h + rst 08h + pop af ; восст. флаг + scf + ccf + ret po ; прерывания разрешены + ei + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #5A. Восстановить окно экрана. +; +; вход: D - строка +; E - колонка левого верхнего угла окна +; H - высота окна +; L - ширина окна +; B - страница буфера +; IX - адрес буфера +; выход: нет +;///////////////////////////////////////////////////////////////////// +Func_5A:ld a,r ; во флаг P/V сост. триггера разреш. прерываний + push af + xor a + di + ld c,0B3h + rst 08h + pop af + scf + ccf + ret po ; прерывания разрешены + ei + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #55. Скроллинг экрана. +; +; вход: D - строка левого верхнего угла окна +; E - колонка левого верхнего угла окна +; H - высота окна +; L - ширина окна +; B = 1 - прокрутка вверх +; B = 2 - прокрутка вниз +; A = 0 - очищать строку +; выход: нет +;///////////////////////////////////////////////////////////////////// +Func_55:djnz A0EBA + ld b,a + ld c,h + push bc + push de + push hl + db 0DDh + ld h,d + db 0DDh + ld l,e + inc d + dec h + xor a + ld c,0B7h ; перемещ. окна + di + rst 08h + ei + pop hl + pop de + pop bc + xor a + cp b + ret nz ; не очищать строку + ld a,d + add a,h + dec a + ld d,a +A0EAA: push de + call Func_52 ; уст. полож. курсора + ld a," " + ld b,l + ld c,82h + rst 08h + pop de + call Func_52 ; уст. полож. курсора + and a + ret + ; +A0EBA: djnz A0EE0 + ld b,a + ld c,l + push de + push bc + db 0DDh + ld h,d + db 0DDh + ld l,e + db 0DDh + inc h + dec h + xor a + ld c,0B7h + di + rst 08h + ei + pop hl + pop de + xor a + cp b + jr z,A0EAA ; очистить строку + ret + ; +A0EE0: ld a,EINVFNC ; код "неверный номер функции" + scf + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #54. Выбрать активную страницу экрана. +; +; вход: B - страница экрана 0/1 +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_54:push bc + ld a,(mode_screen) ; тек. режим экрана + bit 7,a + jr nz,A0EF0 + ld c,a + call A0F04 +A0EF0: pop bc + ld a,b + and 1 + out (0C9h),a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #51. Получить текущий режим экрана. +; +; вход: нет +; выход: A - текущий режим экрана +; B - страница экрана 0/1 +;///////////////////////////////////////////////////////////////////// +Func_51:in a,(0C9h) ; страница экрана 0/1 + ld b,a + ld a,(mode_screen) ; тек. режим экрана + and a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #50. Выбор режима экрана. +; +; вход: A - режим экрана +; 02h - текстовый 40x32x16 цветов +; 03h - текстовый 80x32x16 цветов +; 81h - графический 320x256x256 цветов +; 82h - графический 640x256x16 цветов +; B - страница экрана 0/1 +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_50:bit 7,a + ld c,a + jr nz,A0F27 ; уст. граф. режимы +A0F04: ld ix,A1080 ; точка выхода (восст. экран граф. режима) + push ix + ex af,af' + ld a,(mode_screen) ; тек. режим экрана + ld (A1081+1),a + ex af,af' + inc a ; a=0 + dec a + jr z,A0F21 + dec a ; a=1 + jr z,A0F21 + dec a ; a=2 + jr z,A0F3F + dec a ; a=3 + jr z,A0F67 +A0F21: pop ix ; восст. баланс стека (заодно ix) + ld a,EERR48 ; код "ошибка 48" + scf + ret + +; Установка граф. режимов +A0F27: call A1042 ; сохр. экран текст. режима + and 7Fh + jp z,A0F8F ; a=80h + dec a ; a=81h + jp z,A0F93 + dec a ; a=82h + jp z,A0FBA + dec a ; a=83h + jp z,A0FE1 + ld a,EERR48 ; код "ошибка 48" + scf + ret + +; Уст. текст. режим 40x32. +A0F3F: push bc + ; текстовое, 8 точек/знакоместо, #0B - номер знакоген. + ld hl,T101A ; описатель окна (8 байт) + ld a,b + rlca + rlca + rlca + rlca + or b + and 11h + xor 10h + ld e,a ; флаги окна + call open_window + pop bc + ld a,c + ld (mode_screen),a ; тек. режим экрана + ld a,b + and 1 + out (0C9h),a + ld a,(mode_screen) ; тек. режим экрана + ld c,81h + rst 30h + ld a,0C0h + out (89h),a + xor a + ret + +; Уст. текст. режим 80x32. +A0F67: push bc + ; текстовое, 16 точек/знакоместо, #0B - номер знакоген. + ld hl,T1012 ; описатель окна (8 байт) + ld a,b + rlca + rlca + rlca + rlca + or b + and 11h + xor 10h + ld e,a ; флаги окна + call open_window + pop bc + ld a,c + ld (mode_screen),a ; тек. режим экрана + ld a,b + and 1 + out (0C9h),a + ld a,(mode_screen) ; тек. режим экрана + ld c,81h ; режим экрана для мышки + rst 30h + ld a,0C0h ; закр. спек-экран + out (89h),a + xor a + ret + ; +A0F8F: ld a,EERR48 ; код "ошибка 48" + scf + ret + ; +A0F93: push bc + ; графическое, 8 точек/знакоместо, 0-й экран + ld hl,T102A ; описатель окна (8 байт) + ld e,11h ; флаги окна + call open_window + ; графическое, 8 точек/знакоместо, 1-й экран + ld hl,T103A ; описатель окна (8 байт) + ld e,0 ; флаги окна + call open_window + pop bc + ld a,c + ld (mode_screen),a ; тек. режим экрана + ld a,b + and 1 + out (0C9h),a + ld a,(mode_screen) ; тек. режим экрана + ld c,81h + rst 30h + ld a,0C0h + out (89h),a + xor a + ret + +A0FBA: push bc + ; графическое, 16 точек/знакоместо, 0-й экран + ld hl,T1022 ; описатель окна (8 байт) + ld e,11h ; флаги окна + call open_window + ; графическое, 16 точек/знакоместо, 1-й экран + ld hl,T1032 ; описатель окна (8 байт) + ld e,0 ; флаги окна + call open_window + pop bc + ld a,c + ld (mode_screen),a ; тек. режим экрана + ld a,b + and 1 + out (0C9h),a + ld a,(mode_screen) ; тек. режим экрана + ld c,81h + rst 30h + ld a,0C0h + out (89h),a + xor a + ret + +A0FE1: ld a,EERR48 ; код "ошибка 48" + scf + ret + + +; тек. режим экрана +mode_screen: + db 3 ; 80x32x16 текстовый + + + +;------------------------------------------------- +; Открыть окно +; вход: hl=описатель окна +; e=флаги окна +;------------------------------------------------- +open_window: + push de + ld de,LFEE0 ; куда + ld bc,32 ; размер описателя (8..31 зарез.) + call A1001 ; скопир. описатель в сист. страницу + pop de + ld ix,LFEE0 ; описатель окна (8 байт) + ld c,0B0h ; откр. окно + rst 08h + ld a,0C0h ; закр. спек-экран + out (89h),a + xor a + ret + + +;----------------------------------------------------- +; Скопировать описатель окна в сист. страницу Биоса +; вход: hl=откуда +; de=куда +; bc=сколько +;----------------------------------------------------- +A1001: ld a,r ; во флаг P/V сост. триггера разреш. прерываний + in a,(0E2h) + ex af,af' ; сохр. флаг + ld a,0FEh ; страница переменных Биоса + out (0E2h),a + ldir + ex af,af' ; восст. флаг + out (0E2h),a + ret po ; прерывания разрешены + ei + ret + + + +;----------------------------------------------------------- +; Массив описателей окон +; +; флаги окна: +; bit4 = 1/0 - text/graf режим +; bit5 = 1/0 - 8/16 точек в знакоместе +; graf_mode bit3..0 - не исп. +; bit7..6 - номер палитры (номер экрана) +; text_mode bit7..6, 3..0 - номер знакогенератора +; исключение: bit7..6="11" -> бордер +;----------------------------------------------------------- + +; 80x32. текстовое, 16 точек/знакоместо, #0B - номер знакоген. +T1012: db 40 ;+0 X размер окна в знакоместах + db 32 ;+1 Y размер окна в знакоместах + db 0 ;+2 X полож. окна на экране + db 0 ;+3 Y полож. окна на экране + db 00011011b ;+4 режим знакоместа + db 0 ;+5 доп. режим знакоместа (bit0=1 спек. адресация экрана) + db 0 ;+6 X полож. в поле графики (в знакоместах) + db 0 ;+7 Y полож. в поле графики (в знакоместах) + +; 40x32. текстовое, 8 точек/знакоместо, #0B - номер знакоген. +T101A: db 40,32 ; X/Y габариты + db 0,0 + db 00111011b ;+4 5,4, bit3..0 номер знакоген. + db 0,0,0 + +; графическое, 16 точек/знакоместо, 0-й экран +T1022: db 40,32 ; X/Y габариты (в знакоместах) + db 0,0 + db 00000000b ;+4 + db 0,0,0 + +; графическое, 8 точек/знакоместо, 0-й экран +T102A: db 40,32 ; X/Y габариты (в знакоместах) + db 0,0 + db 00100000b ;+4 5-й бит + db 0,0,0 + +; графическое, 16 точек/знакоместо, 1-й экран +T1032: db 40,32 ; X/Y габариты (в знакоместах) + db 0,0 + db 01000000b ;+4 6-й бит + db 0 + db 40 ;+6 X полож. в поле графики (в знакоместах) + db 0 + +; графическое, 8 точек/знакоместо, 1-й экран +T103A: db 40,32 ; X/Y габариты (в знакоместах) + db 0,0 + db 01100000b ;+4 6,5 биты + db 0 + db 40 ;+6 X полож. в поле графики (в знакоместах) + db 0 + + +;-------------------------------------------------- +; Сохранить экран текст. режима. +; Для буфера экрана исп. 2-я банка расширения ДОС. +;-------------------------------------------------- +A1042: push af + ld a,(mode_screen) ; тек. режим экрана + bit 7,a + jr nz,A107E ; граф. режим + sub 2 + jr c,A107E ; меньше 02h + push bc + push de + push hl + push ix + push af + ld c,8Eh ; узнать полож. курсора + rst 08h + ld (A10A0+1),de + pop af ; режим экрана + ld ix,LC000 ; буфер + ld de,0000h ; Y/X полож. + ld hl,2050h ; Y/X размер (32x80) + or a + jr nz,$+4 ; 80x32 текст. режим + ld l,40 ; X размер + ld (A1090+1),hl + ld a,(list_dos_pages+2) ; номер банки расширения ДОС + ld b,a + xor a + ld c,0B2h ; с экрана в буфер + di + rst 08h + ei + pop ix + pop hl + pop de + pop bc +A107E: pop af + ret + + +;------------------------------------------------- +; Восстановить экран граф. режима. +; Буфер экрана во 2-й банке расширения ДОС. +;------------------------------------------------- +A1080: push af +A1081: ld a,0 ; тек. режим экрана + rlca ; 4 такта + jr nc,A10AB ; текстовый + push bc + push de + push hl + push ix + ld ix,LC000 ; буфер + ld de,0000h ; Y/X полож. +A1090: ld hl,2050h ; Y/X размер (32x80 или 32x40) + ld a,(list_dos_pages+2) ; номер банки расширения ДОС + ld b,a + xor a + ld c,0B3h ; из буфера на экран + di + rst 08h + ei +A10A0: ld de,0 ; Y/X полож. + ld c,84h ; уст. курсор + rst 08h + pop ix + pop hl + pop de + pop bc +A10AB: pop af + ret + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #5F. Вывод символа на принтер без ожидания. +; +; Интерпретация байта состояния принтера: +; 0..2 - не используются, обычно уст. в "1" +; 3 - ошибка принтера - есть/нет (1/0) +; 4 - принтер подключен/не подключен (1/0) +; 5 - бумаги нет/есть (1/0) +; 6 - принтер готов/выводит очередной символ (1/0) +; 7 - принтер свободен/занят (1/0) +; +; вход: A - символ +; выход: B - символ +; CF - ошибка, A=байт состояния (биты 7..3) +;///////////////////////////////////////////////////////////////////// +Func_5F:ld b,a + ld a,r ; во флаг P/V сост. триггера разреш. прерываний + ld a,b + di + push af ; сохр. флаг + xor a + out (1Bh),a + ld a,10h + out (1Bh),a + xor a + out (1Bh),a + in a,(1Bh) ; порт состояния принтера + ld c,a; + bit 5,a ; 0/1 есть/нет бумага + jr nz,A10CC ; нет бумаги + and 11011000b; + jr z,A10CC; ; ошиб. ситуация + ld a,b + out (1Ch),a ; символ в принтер + pop af ; восст. флаг + scf + ccf ; сбр. CF + ret po ; прерывания разрешены + ei + ret + ; +A10CC: pop af + ld a,c; ; байт состояния + scf ; уст. CF + ret po ; прерывания разрешены + ei + ret + + + +; Иниц. портов +A10D1: di + ld a,0CFh + ld bc,001Fh ; порт + out (c),a + ld a,63h + out (c),a + ld a,0C0h + out (1Eh),a + ld a,0Fh + out (1Dh),a + ld a,0 + out (19h),a + ld a,0 + out (19h),a + ld a,5 + out (19h),a + ld a,62h + out (19h),a + ret + + +; Установить начальный кластер для чтения +A10F6: ld hl,1 + ld (A10FD+1),hl + ret + + +A10FD: ld hl,1 +A1100: inc hl ; номер кластера + call A1132 ; прочитать из кеша FAT-а номер след. кластера + cp 0Ah + scf + ret z ; ошибка ? + ld a,d + or e + jr nz,A1100 + ld (A10FD+1),hl + xor a + ret + + +A1111: push hl + call A10FD + pop de + ret c + push hl + push hl + ex de,hl ; hl=номер кластера +A111A: call A1132 ; прочитать из кеша FAT-а номер след. кластера + ex de,hl + jr nc,A111A ; не конец цепочки + ex de,hl + pop de ; номер кластера + call A11C4 ; записать в кеш FAT-а номер кластера + pop hl + ld de,(D150E) ; номер кластера + call A11C4 ; записать в кеш FAT-а номер кластера + call A128B ; подкл. банку кеша FAT и записать его на диск + and a + ret + + +;----------------------------------------------------------- +; Прочитать из кеша FAT-а номер след. кластера +; вход: hl=номер кластера +; выход: hl=номер кластера +; de=номер след. кластера +; CF - конец цепочки +;----------------------------------------------------------- +A1132: ex de,hl + ld hl,(D12FF) + and a + sbc hl,de + ex de,hl + ld a,0Ah + ret c + exx + ld a,1 ; лог. номер дос-банки (кэш FAT-а) + call set_dos_page ; подключить банку расширения ДОС + exx + push hl + push af ; старая банка порта + ld a,(D150B) + cp "2" ; fat12 + jr z,A1177 + ; fat16, просто читать след. номер + ld a,h + ld b,a + and 0Fh + ld h,a + ld a,b + rrca + rrca + rrca + rrca + and 0Fh + add hl,hl + ld bc,(D12FD) + cp c + call nz,A125B ; прочитать в кеш 16 секторов FAT-а + ld de,LC000 ; начало кеша FAT-а + add hl,de ; на ячейку FAT + ld e,(hl) ; прочитать номер кластера + inc hl + ld d,(hl) + pop af + out (0E2h),a ; восст. порт + ld hl,0FFEFh + ;and a ;@@ + xor a; + sbc hl,de ; проверка на служ. кластеры + pop hl + ;ld a,0 + ret +; fat12 +A1177: ld d,h + ld e,l + add hl,hl + add hl,de + rr h ; сдвиг вправо через CF + rr l + push af ; сохр. флаг + ld a,h + ld b,a + and 1Fh + ld h,a + ld a,b + rlca + rlca + rlca + and 7 + ld bc,(D12FD) + cp c + call nz,A125B ; прочитать в кеш 16 секторов FAT-а + ld de,LC000 ; начало кеша FAT-а + add hl,de ; на ячейку FAT + pop af ; восст. флаг + ld e,(hl) + inc hl + ld d,(hl) + jr c,A11A3 ; номер не четный + ld a,d + and 0Fh + ld d,a + jr A11B7 + ; +A11A3: ld a,e + and 0F0h + ld e,a + rr d ; вправо на 4 битa + rr e + rr d + rr e + rr d + rr e + rr d + rr e +A11B7: pop af ; восст. порт + out (0E2h),a + ld hl,0FEFh + ;and a + xor a; + sbc hl,de ; проверка на служ. кластеры + pop hl + ;ld a,0 + ret + + +;----------------------------------------------------------- +; Записать в кеш FAT-а номер кластера +; вход: de=номер кластера +; hl=номер первого кластера ? +; выход: ;hl=номер след. кластера ? +; de=номер кластера +;----------------------------------------------------------- +A11C4: push de + ex de,hl + ld hl,(D12FF) + and a + sbc hl,de + ex de,hl + pop de + ld a,0Ah + ret c + exx + ld a,1 ; лог. номер дос-банки (кэш FAT-а) + call set_dos_page ; подключить банку расширения ДОС + exx + push hl + push af ; старая банка порта + ld a,1 + ld (D12FE),a + ld a,(D150B) + cp "2" ; fat12 + jr z,A120B + ; fat16, просто сохр. номер + push de + ld a,h + ld b,a + and 0Fh + ld h,a + ld a,b + rrca + rrca + rrca + rrca + and 0Fh + add hl,hl + ld bc,(D12FD) + cp c + call nz,A125B ; прочитать в кеш 16 секторов FAT-а + ld de,LC000 ; кеш FAT + add hl,de ; на ячейку FAT + pop de + ld (hl),e ; сохр. в кеше FAT-а + inc hl ; номер кластера + ld (hl),d ; + pop af ; восст. порт + pop hl + out (0E2h),a + xor a + ret +; fat12 +A120B: push de + ld d,h + ld e,l + add hl,hl + add hl,de + rr h + rr l + push af ; сохр. флаг + ld a,h + ld b,a + and 1Fh + ld h,a + ld a,b + rlca + rlca + rlca + and 7 + ld bc,(D12FD) + cp c + call nz,A125B ; прочитать в кеш 16 секторов FAT-а + ld de,LC000 ; кеш FAT + add hl,de + pop af + pop de + jr c,A123E ; номер не четный + ld (hl),e + inc hl + ld a,(hl) + and 0F0h + or d + ld (hl),a + pop af ; восст. порт + pop hl + out (0E2h),a + and a + ret + ; +A123E: sla e ; влево на 4 битa + rl d + rl e + rl d + rl e + rl d + rl e + rl d + ld a,(hl) + and 0Fh + or e + ld (hl),a ; сохр. в кеше FAT-а + inc hl ; номер кластера + ld (hl),d ; + pop af ; восст. порт + pop hl + out (0E2h),a + and a + ret + + +; Прочитать в кеш 16 секторов FAT-а +; вход: a=.. ? +A125B: push hl + push af + ld a,(D12FE) + or a + call nz,A129A ; запись кеша (всего ?) FAT-а на диск + pop af + ld l,a + ld h,0 + ld (D12FD),hl + add hl,hl ;1+1=2 + add hl,hl ;2+2=4 + add hl,hl ;4+4=8 + add hl,hl ;8+8=16 + ld de,(D14FC) + add hl,de + ex de,hl + ld ix,0 + add ix,de ; номер лог. сектора + ld hl,0 ; ст. разряд + ld de,LC000 ; куда (кеш FAT) + ld a,(disk) ; номер диска + ld b,16 ; число секторов + ld c,5 ; чтение секторов + rst 18h + pop hl + ret + + + +; Подключить банку кеша FAT и записать его на диск +A128B: exx + ld a,1 ; лог. номер дос-банки (кэш FAT-а) + call set_dos_page ; подключить банку расширения ДОС + exx + push af ; старая банка порта + call A129A ; запись кеша (всего ?) FAT-а на диск + pop af + out (0E2h),a ; восст. порт + ret + +; Запись кеша (всего ?) FAT-а на диск +A129A: ld hl,(D12FD) + ld h,0 + ld (D12FD),hl + add hl,hl ;1+1=2 + add hl,hl ;2+2=4 + add hl,hl ;4+4=8 + add hl,hl ;8+8=16 + push hl + ld b,h + ld c,l + ld de,16 + add hl,de + ld de,(D008C) ; секторов на FAT + ld a,16 ; число секторов + and a + sbc hl,de + jr c,A12C3 + ex de,hl + ld hl,16 + sbc hl,de + jr c,A12FA + ld a,l +A12C3: ld h,b + ld l,c + ld de,(D14FC) + add hl,de + ex de,hl + ld ix,0 + add ix,de ; номер лог. сектора + ld hl,0 ; ст. разряд + ld de,LC000 ; откуда (кеш FAT) + ld b,a ; число секторов + ld c,6 ; запись секторов + ld a,(disk) ; номер диска + push bc + rst 18h + pop bc ; b=число секторов + pop hl + ld de,(D14FE) + add hl,de + ex de,hl + ld ix,0 + add ix,de ; номер лог. сектора + ld de,LC000 ; откуда (кеш FAT) + ld hl,0 ; ст. разряд + ld a,(disk) ; номер диска + ld c,6 ; запись секторов + rst 18h + ret + ; +A12FA: pop hl + scf + ret + + +D12FD: db 0 +D12FE: db 0 +D12FF: dw 0FF0h ; макс. число кластеров FAT12 (без служ.) + + + + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #00. Версия ДОС. +; Возвращает номер версии дисковой системы. +; вход: нет +; выход: DE=номер версии/модификации +; BC=номер билда (0..999) +;///////////////////////////////////////////////////////////////////// + +Func_00:xor a + ld de,(major_version SHL 8) + minor_version ; 1.61 версия ДОС + ld bc,build_version ; номер билда + ld h,a + ld l,a + ret + + + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #01. Смена текущего диска. +; +; вход: A - номер диска (0=A,1=B,..) +; выход: A - макс. номер диска, если CF=0 +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_01:push af ; номер девайса + ld c,1 ; открыть девайс + rst 18h + pop bc + jr c,A1323 ; ошибка + ld a,b + ld (disk),a ; номер тек. диска + call A1370 + ret c + ld a,(last_drive) ; номер послед. диска + and a + ret + ; +A1323: cp EINVDRV ; код "неверный номер устройства" + scf + ret z + ld a,ENORDY ; код "нет готовности" + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #02. Номер текущего диска. +; +; вход: нет +; выход: A - номер диска (0=A,1=B,..) +;///////////////////////////////////////////////////////////////////// +Func_02:ld a,(disk) + and a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #03. Информация о диске. +; Возвращает информацию об общем и свободном пространстве дискового +; устройства. +; +; вход: A - номер диска (0=A,1=B,..0FFh-текущий) +; выход: A - размер кластера в секторах, если CF=0 +; HL - общее кол-во кластеров +; DE - свободных кластеров +; BC - размер сектора в байтах +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_03:inc a + jr z,A1338 + dec a + call Func_01 ; смена текущего диска + ret c +A1338: ld hl,2 ; номер кластера + ld bc,0 +A133E: push bc + call A1132 ; прочитать из кеша FAT-а номер след. кластера + pop bc + cp 0Ah + jr z,A1353 ; ошибка ? + xor a + cp e + jr nz,A134F + cp d + jr nz,A134F + inc bc +A134F: inc hl + jr A133E + ; +A1353: ld d,b ; свободных кластеров + ld e,c + ld hl,(D12FF) ; общее кол-во кластеров + dec hl + ld bc,(D0081) ; байтов на сектор (512) + ld a,(D0083) ; секторов на кластер + and a + ret + + +; Номер последнего диска в системе +last_drive: + db 2 ; "B" диск + ; список дисковых устройств ? + ds 5 + + + +; нет обращения +L1368: ld a,(disk) ; номер диска + ld c,3 ; проверка смены носителя в девайсе + rst 18h ; всегда выдает "менялся" + or a + ret z ; не менялся + ; +A1370: ld c,0E2h + in b,(c) + push bc + in a,(82h) + out (0E2h),a + ld de,LC400 ; буфер + ld a,(disk) ; номер диска + ld c,4 ; прочитать BPB + rst 18h + pop bc + out (c),b ; восст. порт + jp c,A14F0 ; ошибка (нет готовности) + push iy + ld de,0AA55h ; сигнатура + ld hl,(T0400+510) + and a + sbc hl,de + jp nz,A14EA ; ошибка "не известный формат" + ld hl,T0400 ; откуда + ld de,T0076 ; куда + ld bc,62 + ldir + ld iy,T0076 ; структура boot-сектора + ld a,(iy+21) + cp 0F0h ; байт формата + jp c,A14EA + ld hl,0 + ld e,(iy+14) ; de=зарезерв. секторов + ld d,(iy+15) + add hl,de + ld (D14FC),hl + ld (D14FC),hl + ld (D14FE),hl + ld e,(iy+22) ; de=число секторов на FAT + ld d,(iy+23) + ld a,(D0086) ; число копий FAT-ов + cp 1 + jr z,A13D2 + dec a + add hl,de + ld (D14FE),hl +A13D2: add hl,de + dec a + jr nz,A13D2 + ld (D1502),hl + ld c,(iy+11) ; bc=байтов на сектор + ld b,(iy+12) + rl c + rl b + rl c + rl b + rl c + rl b + ld c,b + ld b,0 + ld a,c + ld (D1504),a + ld e,(iy+17) ; de=записей в корне + ld d,(iy+18) + ex de,hl + dec hl + xor a +A13FB: inc a + jp z,A14EA + sbc hl,bc + jr nc,A13FB + ex de,hl + ld c,a + ld b,0 + ld (D1505),a + add hl,bc + ld (D1506),hl + ld c,(iy+11) ; bc=байтов на сектор + ld b,(iy+12) + ld hl,0 + ld a,(D0083) ; число секторов на кластер +A141A: add hl,bc + dec a + jr nz,A141A + ld (D1508),hl ; размер блока "секторов на кластер" + ex de,hl + ld hl,4000h-1 ; константа + xor a +A1426: inc a + jp z,A14EA + sbc hl,de + jr nc,A1426 + ld (D150A),a + ld hl,T00AC ; "FAT16 " + ld de,T14F4 ; "FAT" + ld b,3 +A1439: ld a,(de) + cp (hl) + jp nz,A14D1 + inc hl + inc de + djnz A1439 +A1442: ld a,(hl) + inc hl + cp " " + jr z,A1442 + cp "1" + jp nz,A14EA + ld a,(hl) + cp "6" + ld hl,0FFFFh ; ячейка FAT16 + jr z,A145D + cp "2" + jp nz,A14EA + ld hl,0FFFh ; ячейка FAT12 +A145D: ld (D150B),a ; "2"/"6" fat12/fat13 + ld (D150E),hl + ld hl,0 + ld c,(iy+24) ; bc=секторов на сторону + ld b,(iy+25) + ld a,(D0090) ; кол-во сторон диска +A146F: add hl,bc + dec a + jr nz,A146F + ld (D150C),hl + ld de,(D1506) + ld l,(iy+19) ; hl=всех секторов на диске + ld h,(iy+20) + ld a,h + or l + jr nz,A149B + ; extended boot-record + ld l,(iy+32) ; hl=мл.разряд всех секторов на диске + ld h,(iy+33) ; + ld c,(iy+34) ; bc=ст.разряд + ld b,(iy+35) ; + sbc hl,de + jr nc,A14A1 + dec bc + jr A14A1 + ; +A149B: sbc hl,de + ld bc,0 +A14A1: ld a,(D0083) ; секторов на кластер + scf +A14A5: rra + jr c,A14B3 + rr b + rr c + rr h + rr l + jr A14A5 + ; +A14B3: inc hl + ld (D12FF),hl + pop iy ; iy=структура дескр. + ld hl,0 + ld (D12FD),hl + ld a,1 ; лог. номер дос-банки (кэш FAT-а) + call set_dos_page ; подключить банку расширения ДОС + push af ; старая банка порта + xor a + call A125B ; прочитать в кеш 16 секторов FAT-а + pop af + out (0E2h),a + call A10F6 ; уст. начальный кластер для чтения + xor a + ret + ; +A14D1: ld a,(iy+15h) + cp 0F0h ; формат 720kB дискеты + jr c,A14EA + cp 0F8h ; байт-дескриптор винта + ld a,"6" + ld hl,0FFFFh ; ячейка FAT16 + jr z,A145D + ld a,"2" + ld hl,0FFFh ; ячейка FAT12 + jp A145D + ; +A14EA: pop iy + ld a,EINVMED ; код "не известный формат" + scf + ret + ; +A14F0: ld a,ENORDY ; код "нет готовности" + scf + ret + + +T14F4: db "FAT" + ; + db 0 + db 0 + db 0 + db 0 + +disk: db 1 ; номер диска ДОС + +D14FC: dw 0 +D14FE: dw 0 +D1500: dw 0 +D1502: dw 0 +D1504: db 0 +D1505: db 0 +D1506: dw 0 +D1508: dw 0 ; размер блока "секторов на кластер" +D150A: db 0 +D150B: db 0 ; "6"/"2" fat16/fat12 +D150C: dw 0 +D150E: dw 0FFFFh ; 0FFFFh/0FFFh fat16/fat12 + + +; Буфер текущего пути (каталога) системы +T1510: db '\' + ds 256 + + + +; <<< Массив структур дескрипторов, 44*10=440 байт >>> +; +; Структура дескриптора тек. каталога +handle: db ". " ;+0 имя файла (+0=0 - дескр. свободен) + db " " ;+8 расш. файла + db 10h ;+11 атрибут + ds 10 ;+12 резерв + dw 0 ;+22 время + dw 0 ;+24 дата + dw 0 ;+26 номер первого кластера + dw 0,0 ;+28 размер файла + dw 0 ;+32 мл.разряд указателя файла + dw 0 ;+34 ст.разряд + dw 0 ;+36 номер первого кластера каталога (из +26) + dw 0 ;+38 индекс записи в списке каталога (исп. #11 функ.) + db 0 ;+40 номер диска (drive or current) + db 0 ;+41 режим доступа к файлу (r,w,r/w). 7-й бит - признак изменения файла + db 0 ;+42 уровень тек. программы (задача (владелец)) + db 0 ;+43 резерв + +size_struc_handle equ $-handle ; размер структуры (44 байта) + + ; 9 файловых структур + ds size_struc_handle * max_handles ; 44*9=396 + + + + + +;------------------------------------------------- +; Поиск дескриптора файла. +; вход: a=номер дескр. +; выход: iy=адрес структуры дескр. +; CF - нет дескриптора +;------------------------------------------------- +search_handle: + inc a + cp max_handles+1 ; запред. число дескрипторов + jr nc,A17E3 + push de + ld iy,handle - size_struc_handle ; массив дескр. - 44 + ld de,size_struc_handle ; 44 размер структуры дескриптора + add iy,de + dec a + jr nz,$-3 ; ищем нужный дескр. + pop de + ld a,(iy+0) ; номер тек. дескр. + or a + ld a,EZERO ; код "Ok" + ret nz ; дескр. занят +A17E3: ld a,EINVHND ; код "не существующий дескриптор" + scf + ret + + +;----------------------------------------------------------- +; Освобождение дескриптора файла. +; вход: a=номер дескриптора +; выход: CF - при ошибке "не существующий дескриптор" +;----------------------------------------------------------- +release_handle: + inc a + cp max_handles+1 ; запред. число дескрипторов + jr nc,A17E3 + push de + ld iy,handle - size_struc_handle ; массив дескр. - 44 + ld de,size_struc_handle ; 44 размер структуры дескриптора + add iy,de + dec a + jr nz,$-3 ; ищем нужный дескриптор + pop de + ld a,(iy+0) ; имя файла в дескрипторе + or a ; структура свободна ? + ld a,EINVHND ; код "не существующий дескриптор" + exx + scf + ret z ; да + xor a + ld (iy+0),a ; освоб. тек. дескриптор + ret + + +;------------------------------------------------- +; Поиск свободного дескриптора. +; вход: нет +; выход: c=номер дескриптора +; CF - нет своб. дескриптора +;------------------------------------------------- +search_free_handle: + ld b,max_handles+1 ; 10 макс.число дескрипторов+1 + ld c,-1 ; счетчик номера дескр. + ld iy,handle - size_struc_handle ; массив дескр. - 44 + ld de,size_struc_handle ; 44 размер структуры дескриптора +A1815: add iy,de + inc c ; 0..9 + ld a,(iy+0) + or a ; тек. структура дескриптора свободна ? + ret z ; да + djnz A1815 ; на след. структуру + ld a,EMFILE ; код "слишком много откр. файлов" + scf + ret + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #15. Перемещение указателя в файле. +; +; вход: A - дескриптор файла +; HL:IX - смещение указателя в файле +; B - способ перемещения +; B=0 от начала файла +; B=1 от текущего значения указателя +; B=2 от конца файла +; выход: HL:IX - новое значение указателя +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_15:call search_handle ; поиск дескр. файла + ret c ; не найден + inc b + dec b + jr z,A1835 ; от начала + dec b + jr z,A184B ; от тек. полож. + dec b + jr z,A183D ; от конца +empty__:ld a,EINVFNC ; код "не верный номер функции" + scf + ret + +; От начала файла +A1835: ld bc,0 ; для мл. разряда + ld e,c ; для ст. разряда + ld d,c + jr A1857 + +; От конца файла +A183D: ld c,(iy+1Ch) ; iy=дескр. файла + ld b,(iy+1Dh) + ld e,(iy+1Eh) + ld d,(iy+1Fh) + jr A1857 + +; От тек. положения +A184B: ld c,(iy+20h) + ld b,(iy+21h) + ld e,(iy+22h) + ld d,(iy+23h) +A1857: add ix,bc ; мл. разряд + adc hl,de ; ст. разряд + db 0DDh + ld d,h + db 0DDh + ld e,l + ld (iy+20h),e + ld (iy+21h),d + ld (iy+22h),l + ld (iy+23h),h + xor a + ret + + +A186D: ld l,(iy+1Ch) + ld h,(iy+1Dh) + ld e,(iy+20h) + ld d,(iy+21h) + and a + sbc hl,de + ld l,(iy+1Eh) + ld h,(iy+1Fh) + ld e,(iy+22h) + ld d,(iy+23h) + sbc hl,de + ret + + + +A188B: pop bc + pop de + and a + ret + ; +A188F: pop bc + pop de + scf ; ошибка + ret + ; +A1893: push bc + ld (D1CFB),ix + ld a,(D0083) ; секторов на кластер + ld c,a + ld b,0 + call A1CD9 + db 0DDh + ld b,h + db 0DDh + ld c,l + push hl + ld l,(iy+26) ; номер первого кластера (из дескр.) + ld h,(iy+27) ; + ld a,h + or l + jr nz,A18BB + jr A188B ; файл нулевой длины + ; +A18B2: push bc + call A1132 ; прочитать из кеша FAT-а номер след. кластера + pop bc + jr c,A188B ; конец цепочки + ex de,hl ; hl=номер след. кластера + dec bc +A18BB: ld a,b + or c + jr nz,A18B2 ; прочитать след. сектор (кластер) + pop de + pop bc + ld a,(D0083) ; секторов на кластер + sub e + ld c,a + cp b + jr c,A18CA + ld c,b +A18CA: ld a,b + sub c + ld b,a + push hl + push bc + push de + call A1CB8 + pop de + add ix,de + jr nc,$+3 + inc hl + ld de,(D1CFB) ; буфер + ld a,(disk) ; номер диска + ld b,c ; число секторов + ld c,5 ; чтение секторов + rst 18h + jr c,A188F ; ошибка + pop bc + ld hl,(D1CFB) + ld de,(D0081) ; байтов на сектор (512) +A18EF: add hl,de + dec c + jr nz,A18EF + ld (D1CFB),hl + pop de + ld a,b + or a + ret z +A18FA: ld hl,D0083 ; секторов на кластер + ld a,b + sub (hl) + ld b,a + ld c,(hl) + jr nc,A1909 + ld b,0 + add a,(hl) + ld c,a + or a + ret z +A1909: ex de,hl ; hl=номер кластера + push bc + call A1132 ; прочитать из кеша FAT-а номер след. кластера + pop bc + jr c,A1938 ; конец цепочки + ex de,hl ; hl=номер след. кластера + push hl + push bc + call A1CB8 + ld de,(D1CFB) ; куда + ld a,(disk) ; номер диска + ld b,c ; число секторов + ld c,5 ; чтение секторов + rst 18h + jp c,A188F ; ошибка + pop bc + ld hl,(D1CFB) + ld de,(D0081) ; байтов на сектор (512) +A192E: add hl,de + dec c + jr nz,A192E + ld (D1CFB),hl + pop de + jr A18FA + ; +A1938: and a + ret + + + +A193A: pop bc +A193B: pop bc + pop de + scf + ret + ; +A193F: push bc + ld (D1CFB),ix + ld a,(D0083) ; секторов на кластер + ld c,a + ld b,0 + call A1CD9 + db 0DDh + ld b,h + db 0DDh + ld c,l + push hl + ld l,(iy+1Ah) ; hl=номер первого кластера + ld h,(iy+1Bh) ; + ld a,h + or l + jr nz,A198A + push bc + call A10FD + jr c,A193A + ld (iy+1Ah),l ; hl=номер первого кластера + ld (iy+1Bh),h ; + ld de,(D150E) ; номер кластера + call A11C4 ; записать в кеш FAT-а номер кластера + push hl + call A128B ; подкл. банку кеша FAT и записать его на диск + pop hl + pop bc + jr A198A + ; +A1977: push bc + call A1132 ; прочитать из кеша FAT-а номер след. кластера + jr nc,A1987 ; не конец цепочки + push hl ; номер кластера (не следующего) + call A1111 + pop hl + jr c,A193A + call A1132 ; прочитать из кеша FAT-а номер след. кластера +A1987: pop bc + ex de,hl ; hl=номер след. кластера + dec bc +A198A: ld a,b + or c + jr nz,A1977 + pop de + pop bc + ld a,(D0083) ; секторов на кластер + sub e + ld c,a + cp b + jr c,$+3 + ld c,b + ld a,b + sub c + ld b,a + push hl + push bc + push de + call A1CB8 + pop de + add ix,de + jr nc,$+3 + inc hl + ld de,(D1CFB) ; буфер + ld a,(disk) ; номер диска + ld b,c ; число секторов + ld c,6 ; запись секторов + rst 18h + jp c,A193B ; ошибка + pop bc + ld hl,(D1CFB) + ld de,(D0081) ; байтов на сектор (512) + add hl,de + dec c + jr nz,$-2 + ld (D1CFB),hl + pop de + ld a,b + or a + ret z +A19C9: ld hl,D0083 ; секторов на кластер + ld a,b + sub (hl) + ld b,a + ld c,(hl) + jr nc,A19D8 + ld b,0 + add a,(hl) + ld c,a + or a + ret z +A19D8: ex de,hl + push bc + call A1132 ; прочитать из кеша FAT-а номер след. кластера + jr nc,A19E9 ; не конец цепочки + push hl ; номер кластера (не следующего) + call A1111 + pop hl + jr c,A1A10 ; нет места на диске + call A1132 ; прочитать из кеша FAT-а номер след. кластера +A19E9: pop bc + ex de,hl ; hl=номер след. кластера + push hl + push bc + call A1CB8 + ld de,(D1CFB) ; буфер + ld a,(disk) ; номер диска + ld b,c ; число секторов + ld c,6 ; запись секторов + rst 18h + jp c,A193B ; ошибка + pop bc + ld hl,(D1CFB) + ld de,(D0081) ; байтов на сектор (512) + add hl,de + dec c + jr nz,$-2 + ld (D1CFB),hl + pop de + jr A19C9 + ; +A1A10: pop bc + ld a,ENOSPACE ; код "нет места на диске" + scf + ret + + +A1A15: xor a + ld (D1CFA),a + ld l,(iy+20h) + ld h,(iy+21h) + add hl,de + exx + ld e,a + ld d,a + ld l,(iy+22h) + ld h,(iy+23h) + adc hl,de + exx + ld c,(iy+1Ch) + ld b,(iy+1Dh) + and a + sbc hl,bc + exx + ld c,(iy+1Eh) + ld b,(iy+1Fh) + sbc hl,bc + exx + ret c + ex de,hl + sbc hl,de + ex de,hl + ld a,-1 + ld (D1CFA),a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #13. Чтение из файла. +; +; вход: A - дескриптор файла (0-й = чтение списка диска) +; HL - буфер +; DE - кол-во читаемых байт +; выход: DE - реальное кол-во прочитанных байт +; если CF=0: +; A=0 прочитаны все байты +; A=0FFh прочитано меньшее число байт +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_13:ld (D1D01),hl + ld (D1D03),hl + call search_handle ; поиск дескр. файла + ret c ; не найден + call A1A15 + ld a,d + or e + jp z,A1B02 + push de + ld a,(iy+40) ; номер диска из дескр. + call A2147 + jp c,A1B57 + ld c,(iy+32) ; мл.разряд указателя файла + ld a,(iy+33) ; + ld e,a + and 1 + ld b,a + ld d,(iy+34) ; ст.разряд + ld l,(iy+35) ; + ld h,0 + or a + rr l + rr d + rr e + ld a,b + or c + jp nz,A1B07 +A1A85: pop bc + push bc + srl b + jr z,A1ABA + ld (D1CFD),hl + ld (D1CFF),de + ld ix,(D1D01) + call A1893 + jp c,A1B57 + ld de,(D1D01) + ld hl,(D1CFB) + and a + sbc hl,de + ld c,h + ld b,0 + add hl,de + ld (D1D01),hl + srl c + ld hl,(D1CFF) + add hl,bc + ex de,hl + ld hl,(D1CFD) + ld c,b + adc hl,bc +A1ABA: pop bc + ld a,b + and 1 + ld b,a + or c + jr z,A1AEA + push bc + ld ix,LC400 + ld b,1 + in a,(0E2h) + push af + in a,(82h) + out (0E2h),a + call A1893 + pop bc + ld c,0E2h ; порт + out (c),b ; восст. порт + jp c,A1B57 + ld hl,T0400 ; откуда + ld de,(D1D01) + pop bc + ldir + ld (D1D01),de +A1AEA: ld hl,(D1D03) + ld de,(D1D01) + ex de,hl + and a + sbc hl,de + push hl + ex de,hl + db 0DDh + ld h,d + db 0DDh + ld l,e + ld hl,0 + call A184B + pop de +A1B02: ld a,(D1CFA) + or a + ret + ; +A1B07: push bc + push hl + push de + ld ix,LC400 + ld b,1 + in a,(0E2h) + push af + in a,(82h) + out (0E2h),a + call A1893 + pop bc + ld c,0E2h + out (c),b ; восст. порт + pop hl + jr c,A1B55 + ld bc,1 ;T0001 + add hl,bc + ex de,hl + pop hl + ld c,b + adc hl,bc + exx + pop de + ld hl,512 ;T0200 ? + and a + sbc hl,de + ld b,h + ld c,l + pop hl + and a + sbc hl,bc + jr nc,A1B42 + add hl,bc + ld b,h + ld c,l + ld hl,0 +A1B42: push hl + ld hl,T0400 ; откуда + add hl,de + ld de,(D1D01) ; куда + ldir + ld (D1D01),de + exx + jp A1A85 + ; +A1B55: pop hl + pop hl +A1B57: pop bc + scf + ret + ; +A1B5A: pop hl +A1B5B: pop hl +A1B5C: pop bc + scf + ret + ; +A1B5F: pop de + ld a,EROFILE ; код "файл r/o" + scf + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #14. Запись в файл. +; +; вход: A - дескриптор файла (0-й = запись списка диска) +; HL - буфер данных +; DE - кол-во записываемых байт +; выход: DE - реальное кол-во записанных байт +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_14:ld (D1D01),hl + ld (D1D03),hl + push de + call search_handle ; поиск дескр. файла + jr c,A1B5C ; не найден + ld a,(iy+41) ; режим доступа к файлу (r,w,r/w) + and 1 ; на чтение + jr nz,A1B5F ; запись не возможна (файл r/o) + set 7,(iy+41) ; уст. признак изменения файла + set 5,(iy+11) ; бит "архивный" в ячейке атрибута + ld a,(iy+40) ; номер диска + call A2147 + jr c,A1B5C + ld c,(iy+32) + ld a,(iy+33) + ld e,a + and 1 + ld b,a + ld d,(iy+34) + ld l,(iy+35) + ld h,0 + or a + rr l + rr d + rr e + ld a,b + or c + jp nz,A1C4E +A1BA7: pop bc + push bc + srl b + jr z,A1BD1 + push hl + push de + push bc + ld ix,(D1D01) + call A193F + pop bc + jp c,A1B5A + ld c,b + ld hl,(D1D01) + ld de,512 ; размер сектора + add hl,de + djnz $-1 + ld (D1D01),hl + pop hl + add hl,bc + ex de,hl + pop hl + ld c,b + adc hl,bc +A1BD1: pop bc + ld a,b + and 1 + ld b,a + or c + jr z,A1C19 + push hl + push de + push bc + ld ix,LC400 + ld b,1 + in a,(0E2h) + push af + in a,(82h) + out (0E2h),a + call A1893 + pop bc + ld c,0E2h + out (c),b ; восст. порт + ld de,T0400 ; куда + ld hl,(D1D01) ; откуда + pop bc + jp c,A1B5B + ldir + ld (D1D01),hl + pop de + pop hl + ld ix,LC400 + ld b,1 + in a,(0E2h) + push af + in a,(82h) + out (0E2h),a + call A193F + pop bc + ld c,0E2h + out (c),b ; восст. порт + ret c +A1C19: ld de,(D1D03) + ld hl,(D1D01) + and a + sbc hl,de + push hl + ex de,hl + db 0DDh + ld h,d + db 0DDh + ld l,e + ld hl,0 + call A184B + call A186D + pop de + ret nc + ld l,(iy+20h) + ld h,(iy+21h) + ld c,(iy+22h) + ld b,(iy+23h) + ld (iy+1Ch),l + ld (iy+1Dh),h + ld (iy+1Eh),c + ld (iy+1Fh),b + and a + ret + ; +A1C4E: push bc + push hl + push de + ld ix,LC400 + ld b,1 + in a,(0E2h) + push af + in a,(82h) + out (0E2h),a + call A1893 + pop bc + ld c,0E2h + out (c),b ; восст. порт + pop de + pop hl + exx + pop de + jp c,A1B5C + ld hl,512 ;T0200 + and a + sbc hl,de + ld b,h + ld c,l + pop hl + and a + sbc hl,bc + jr nc,A1C81 + add hl,bc + ld b,h + ld c,l + ld hl,0 +A1C81: push hl + ld hl,T0400 ; куда + add hl,de + ld de,(D1D01) ; откуда + ex de,hl + ldir + ld (D1D01),hl + exx + push hl + push de + ld ix,LC400 + ld b,1 + in a,(0E2h) + push af + in a,(82h) + out (0E2h),a + call A193F + pop bc + ld c,0E2h + out (c),b ; восст. порт + pop hl + jp c,A1B5B + ld bc,1 ;T0001 + add hl,bc + ex de,hl + pop hl + ld c,b + adc hl,bc + jp A1BA7 + + +A1CB8: dec hl + dec hl + ex de,hl + ld a,(D0083) ; секторов на кластер + ld b,a + ld hl,0 + ld ix,0 +A1CC6: add ix,de + jr nc,$+3 + inc hl + djnz A1CC6 + ld de,(D1506) + add ix,de + ld e,b + ld d,b + adc hl,de + ret + + +A1CD9: db 0DDh + ld h,d + db 0DDh + ld l,e + ex de,hl + ld hl,0 + ld a,32 +A1CE3: add ix,ix + ex de,hl + adc hl,hl + ex de,hl + adc hl,hl + sbc hl,bc + jr nc,A1CF4 + add hl,bc + dec a + jr nz,A1CE3 + ret + ; +A1CF4: inc ix + dec a + jr nz,A1CE3 + ret + + + +D1CFA: db 0 +D1CFB: dw 0 +D1CFD: dw 0 +D1CFF: dw 0 +D1D01: dw 0 +D1D03: dw 0 + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #16. Получение/изменение атрибута файла. +; +; вход: HL - указатель на имя файла +; B - режим доступа: +; B=0 получить атрибут +; B=1 установить атрибут +; A - атрибут файла +; выход: A - атрибут файла, если CF=0 +; код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_16:inc b + dec b + jr z,A1D12 ; b=0 + dec b + jr z,A1D24 ; b=1 + ld a,EINVFNC ; код "неверный номер функции" + scf + ret + +; Получить атрибут файла +A1D12: xor a ; атрибут записи + call A1E5F + ret c + ld b,(iy+11) ; атрибут записи из дескр. + push bc + call Func_12 ; закрыть файл + pop bc + ret c + ld a,b + and a + ret + +; Изменить атрибут файла +A1D24: push af + xor a ; атрибут записи + call A1E5F + pop bc + ret c + set 7,(iy+41) ; уст. признак изменения файла + res 3,b ; бит "метка тома" + ld (iy+11),b ; ячейка атрибутов записи + push bc + call Func_12 ; закрыть файл + pop bc + ret c + ld a,b + and a + ret + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #0A. Создание файла. +; +; вход: HL - указатель на имя файла +; A - атрибут файла +; выход: A - дескриптор файла, если CF=0 +; код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_0A:and 11100111b ; маска, скрыть биты dir/label + ld (D1F3A),a ; раб. ячейка + ld (file_name+1),hl ; имя файла + push hl + call search_free_handle ; поиск своб. дескриптора + pop hl + ret c ; не найден + call A20F8 ; тест на допуст. имя и настр. на диск + ret c + ld hl,D213A ; 8.3 имя + ld de,T2364 ; буфер имени 11 симв. формата + call A2384 ; преобр. имя 8.3 -> 11 формат + ret c ; недоп. имя + call search_rec_file ; поиск записи файла в списке диска + call nc,mark_delete ; найден, пометить запись как "удаленная" + jr A1D7B + + +;///////////////////////////////////////////////////////////////////// +; Функция #0B. Создание нового файла. +; Проверяет, существует ли файл с таким же именем. +; +; вход: HL - указатель на имя файла +; A - атрибут файла +; выход: A - дескриптор файла, если CF=0 +; код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_0B:and 11100111b ; маска, скрыть биты dir/label + ld (D1F3A),a ; раб. ячейка + ld (file_name+1),hl ; имя файла + push hl + call search_free_handle ; поиск своб. дескриптора + pop hl + ret c ; не найден + call A20F8 ; тест на допуст. имя и настр. на диск + ret c + ld hl,D213A ; 8.3 имя + ld de,T2364 ; буфер имени 11 симв. формата + call A2384 ; преобр. имя 8.3 -> 11 формат + ret c ; недоп. имя + call search_rec_file ; поиск записи файла в списке диска + ld a,EEXIST ; код "файл существует" + ccf + ret c ; найден + ; создать в буфере новую запись +A1D7B: ld hl,T2364 + ld de,T1F3B + ld bc,11 + ldir + ex de,hl + ld a,(D1F3A) ; раб. ячейка (здесь атрибут записи) + ld (hl),a ;+11 в записи + inc hl + ld bc,0A00h ; b=10 байт резерва + ld (hl),c + inc hl + djnz $-2 + push hl + call Func_21 ; узнать тек. дату и время + call A2599 ; закодировать время/дату + pop hl + ld (hl),e ;+22 время + inc hl + ld (hl),d + inc hl + ld (hl),c ;+24 дата + inc hl + ld (hl),b + inc hl + ld bc,0600h ; 6 ячеек, № кластера и размер файла + ld (hl),c + inc hl + djnz $-2 + call A1F5B ; скопир. новую запись в список диска (каталога) + call flush_cash_dir ; сбросить кеш каталога на диск + ; открыть созданный файл +file_name: + ld hl,0 ; адрес имени файла + xor a ; на чтение/запись + jp Func_11 ; открыть файл + + + +;///////////////////////////////////////////////////////////////////// +; Функция #0C. Создание файла с уникальным именем. +; В конце строки пути должно быть как минимум 12 байт, +; на размещение созданного имени файла. Сама строка должна +; заканчиваться нулем. +; Если созданный файл уже существует, он обнуляется и откры- +; вается на чтение/запись. +; +; вход: HL - указатель на строку пути (и/или с диском). +; A - атрибут файла +; выход: A - дескриптор файла, если CF=0 +; код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_0C:jp empty__ ; код "не верный номер функции" + ;push af + ;push hl + ; создать уник. имя + ;call Func_21 ; узнать тек. дату и время + ;call A2599 ; закодировать время/дату + ;; bc=дата, de=время + ;ld hl,T2364 ; буфер имени 11 симв. формата + ;ld a,b + ;call byte2dec + ;ld a,c + ;call byte2dec + ;ld a,d + ;call byte2dec + ;ld a,e + ;call byte2dec + ;pop hl + ;push hl + ;; перейти на конец строки + ;xor a + ;ld bc,256 + ;cpir + ;dec hl + ;ex de,hl + ;; добавить имя файла в конец строки + ;ld hl,T2364 ; буфер имени 11 симв. формата + ;ld bc,8 ; имя + ;ldir + ;ex de,hl + ;ld (hl),"." + ;inc hl + ;ld a,"$" ; расш. файла + ;ld (hl),a + ;inc hl + ;ld (hl),a + ;inc hl + ;ld (hl),a + ;inc hl + ;ld (hl),0 + ;pop hl ; имя файла + ;pop af ; атрибут + ;; создать файл + ;jp Func_0A + + +; Цифру в hex-формате в буфер. +; вход: hl=буфер +; a=цифра +;byte2dec: + ;push af + ;rra + ;rra + ;rra + ;rra + ;call $+4 + ;pop af + ;and 0Fh + ;add a,90h + ;daa + ;adc a,40h + ;daa + ;ld (hl),a + ;inc hl + ;ret + + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #0E. Удаление файла. +; Файлы "r/o" нельзя стереть данной функцией. +; +; вход: HL - указатель на имя файла +; A - атрибут файла +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_0E:bit 0,a + scf + ld a,EROFILE ; код "файл r/o" + ret nz + ld de,T2364 ; буфер имени 11 симв. формата + call A2384 ; преобр. имя 8.3 -> 11 формат + ret c + ld hl,T2364 + ld bc,11 + ld a,"?" + cpir + ld a,EINVFNAM ; код "неверное имя" + scf + ret z + call A228F ; прочитать список каталога + call search_rec_file ; поиск записи файла в списке диска + ret c ; не найден +; пометить запись как "удаленная" +mark_delete: + xor a ; лог. номер стр. (кэш списка каталога) + call set_dos_page ; подключить банку расширения ДОС + ld (ix+0),0E5h ; признак удаления файла + ld e,(ix+26) ; № первого кластера + ld d,(ix+27) + out (0E2h),a ; восст. порт + ld a,e + or d + jp z,flush_cash_dir ; сбросить кеш каталога на диск +A1DEA: ex de,hl ; hl=номер кластера + call A1132 ; прочитать из кеша FAT-а номер след. кластера + push de ; номер след. кластера + push af + ld de,0 ; номер кластера + call A11C4 ; записать в кеш FAT-а номер кластера + pop af + pop de + jr nc,A1DEA ; не конец цепочки + call A128B ; подкл. банку кеша FAT и записать его на диск + jp flush_cash_dir ; сбросить кеш каталога на диск + + + +;///////////////////////////////////////////////////////////////////// +; Функция #10. Переименование файла. +; Глобальные символы * и ? в именах файлов не допускаются. +; +; вход: HL - указатель на старое имя файла +; DE - указатель на новое имя файла +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_10:push de + ld de,T2364 ; буфер имени 11 симв. формата + call A2384 ; преобр. имя 8.3 -> 11 формат + pop de + ret c + ld hl,T2364 + ld bc,11 + ld a,"?" + cpir + ld a,EINVFNAM ; код "неверное имя" + scf + ret z + push de + call A228F ; прочитать список каталога + ld a,33h ; атрибут "arch + dir + r/o + hidden" + call search_record ; поиск записи в списке диска + pop hl ; 8.3 имя + ret c + ld de,T2364 ; буфер имени 11 симв. формата + call A2384 ; преобр. имя 8.3 -> 11 формат + ret c + ld hl,T2364 + ld bc,11 + ld a,"?" + cpir + ld a,EINVFNAM ; код "неверное имя" + scf + ret z + push ix ; адр. записи переимен. файла + ld a,33h ; атрибут "arch + dir + r/o + hidden" + call search_record ; поиск записи в списке диска + pop ix + ld a,EEXIST ; код "файл существует" + ccf + ret c + xor a ; лог. номер стр. (кэш списка каталога) + call set_dos_page ; подключить банку расширения ДОС + ld hl,T2364 + db 0DDh + ld d,h + db 0DDh + ld e,l + ld bc,11 + ldir + out (0E2h),a ; восст. порт + jp flush_cash_dir ; сбросить кеш каталога на диск + + +A1E5F: ld (D1F3A),a ; раб. ячейка (здесь атрибут записи) + call A20F8 ; тест на допуст. имя и настр. на диск + ret c + ld hl,D213A ; 8.3 имя + ld de,T2364 ; буфер имени 11 симв. формата + call A2384 ; преобр. имя 8.3 -> 11 формат + ret c + ld a,37h ; атрибут "все, кроме метки тома" + call search_record ; поиск записи в кэше списка каталога + jr nc,A1E8D ; на поиск своб. дескриптора + ; запись не найдена + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #11. Открытие файла. +; +; вход: HL - указатель на имя файла +; A - режим доступа: +; A=0 чтение/запись +; A=1 чтение +; A=2 запись +; выход: A - дескриптор файла, если CF=0 +; код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_11:ld (D1F3A),a ; раб. ячейка + call A20F8 ; тест на допуст. имя и настр. на диск + ret c + ld hl,D213A ; 8.3 имя + ld de,T2364 ; буфер имени 11 симв. формата + call A2384 ; преобр. имя 8.3 -> 11 формат + ret c +A1E89: call search_rec_file ; поиск записи файла в списке диска + ret c ; не найден +A1E8D: call search_free_handle ; поиск своб. дескриптора + ret c ; не найден + ; заполнить структуру дескриптора + ld a,c ; номер своб. дескриптора + ex af,af' + exx + ld (iy+38),e ; de=индекс записи в списке каталога (исп. #11 функ.) + ld (iy+39),d + exx + db 0FDh ; ld de,iy + ld d,h + db 0FDh + ld e,l + ld hl,T1F3B ; 32 байта + ld bc,32 + ldir ; заполнить дескриптор + ld a,(D1F3A) ; режим доступа к файлу (раб. ячейка) + ld (iy+41),a + ld a,(D2E70) ; уровень текущей программы (владелец) + ld (iy+42),a + xor a + ld (iy+32),a + ld (iy+33),a + ld (iy+34),a + ld (iy+35),a + ld a,(disk) ; номер диска + ld (iy+40),a + ld hl,handle+26 ; ячейка № первого кластера + ld e,(hl) + inc hl + ld d,(hl) + ld (iy+36),e ; № первого кластера + ld (iy+37),d + ex af,af' + and a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #12. Закрытие файла. +; +; вход: A - дескриптор файла +; выход: A - код ошибки, если CF=1 +; +;///////////////////////////////////////////////////////////////////// +Func_12:ld (D1F3A),a ; дескр. (раб. ячейка) + call search_handle ; поиск дескр. файла + ret c ; не найден + ld a,(D2E70) ; уровень текущей программы + cp (iy+42) ; уровень из дескриптора + ld a,EACCES ; код "ресурс не доступен" + scf + ret nz + bit 7,(iy+41) ; флаг изменения файла + jr z,A1F31 ; освоб. дескр. файла + ; файл изменялся + ld d,(iy+36) + ld e,(iy+37) + push de + xor a ; номер дескр. + call search_handle ; поиск дескр. файла + pop de + ld (iy+36),d + ld (iy+37),e + call A228F ; прочитать список каталога + ld a,(D1F3A) ; дескриптор (раб. ячейка) + call search_handle ; поиск дескр. файла + ld hl,LC000 + ld de,32 + ld c,(iy+38) ; bc=индекс записи в списке каталога + ld b,(iy+39) + jr A1F17 + ; +A1F15: add hl,de + dec bc +A1F17: ld a,b + or c + jr nz,A1F15 + db 0FDh + ld d,h + db 0FDh + ld e,l + ex de,hl + push hl + xor a ; лог. номер стр. (кэш списка каталога) + call set_dos_page ; подключить банку расширения ДОС + pop hl + ld bc,32 + ldir + out (0E2h),a ; восст. порт + call flush_cash_dir ; сбросить кеш каталога на диск +A1F31: ld a,(D1F3A) ; дескр. (раб. ячейка) + jp release_handle ; освоб. дескр. файла + + + +D1F3A: db 0 ; раб. ячейка (режим поиска/доступа/..) + + +; 32 байта. Буфер записи файла/каталога +T1F3B: ds 11 +D1F46: db 0 ;+11 ячейка атрибутов файла + ds 14 +D1F55: dw 0 + ds 4 + + + +;----------------------------------------------------------- +; Скопировать новую запись в кэш списка каталога +;----------------------------------------------------------- +A1F5B: xor a ; лог. номер стр. (кэш списка каталога) + call set_dos_page ; подключить банку расширения ДОС + push af ; старая банка порта + ld ix,LC000 ; начало списка диска + exx + ld de,0 ; сбр. индекс записи (исп. #11 функ.) + exx +A1F6A: ld a,(ix+0) + or a ; конец списка + jr z,A1F82 + cp 0E5h ; признак удал. записи + jr z,A1F82 + ld bc,32 + add ix,bc ; на след. запись + jr nc,A1F6A + ; за границей 0FFFFh + pop af + out (0E2h),a ; восст. порт + ld a,EROOT ; код "переполнение root-каталога" + scf + ret +; скопир. новую запись в список диска +A1F82: db 0DDh + ld d,h ; de=куда + db 0DDh + ld e,l + ld hl,T1F3B ; откуда 32 байта (новая запись) + ld bc,32 + ldir ; скопир. новую запись в список диска + pop af + out (0E2h),a ; восст. порт + ld hl,LC000 ; начало списка диска + ld bc,(size_cash_directory) + dec bc + add hl,bc + and a + sbc hl,de + ret nc + ld hl,(size_cash_directory) + ld bc,(D1508) ; размер блока "секторов на кластер" + add hl,bc + ld (size_cash_directory),hl + and a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #44. Преобразовать имя файла (11 -> 8.3 и обратно). +; +; вход: B=0, преобразовать из 11 символьного формата в формат ДОС +; HL - 11 символов имени файла +; DE - буфер для имени в формате ДОС (13 байт) +; B=1, преобразовать из формата ДОС в 11 символьный формат +; HL - имя файла в формате ДОС +; DE - 11 символов имени файла +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_44:inc b + dec b ; b=0 + jr z,A1FB8 ; преобр. имя 11 -> 8.3 формат + dec b ; b=1 + jp z,A2384 ; преобр. имя 8.3 -> 11 формат + ld a,EINVFNC ; код "неверный номер функции" + scf + ret + +;------------------------------------------------- +; Преобразовать имя 11 -> 8.3 формат +; +; вход: hl=откуда +; de=куда +;------------------------------------------------- +A1FB8: ld bc,08FFh ; b=счетчик +A1FBB: ld a,(hl) + cp " " + jr nz,A1FC5 + inc hl + djnz $-1 + jr A1FC9 + ; +A1FC5: ldi + djnz A1FBB +A1FC9: ld a,(hl) + cp " " + ld a,"." + jr nz,A1FD2 + ld a,0 +A1FD2: ld (de),a + inc de + ret z + ld b,3 +A1FD7: ld a,(hl) + cp " " + ret z + ldi + xor a + ld (de),a + djnz A1FD7 + ret + + + +D1FE2: dw 0 ; адрес раб. буфера (f_first, f_next) +D1FE4: dw 0 ; адрес след. записи (f_first, f_next) +D1FE6: db false ; флаг отработки "f_first" +D1FE7: db false ; флаг 8.3 или 11 формата имени (f_first, f_next) + + +;///////////////////////////////////////////////////////////////////// +; Функция #19. Поиск первого совпадающего файла. +; +; вход: HL - указатель на имя файла +; DE - рабочий буфер 44 байта, если B=0, иначе 46 байт ;256 байт +; A - атрибуты, используемые при поиске +; B=0 - имя найденного файла в формате 11 байт "FilenameExt" +; B=1 - имя найденного файла в формате DOS "filename.ext",0 +; выход: de'= индекс записи в списке каталога (исп. #11 функ.) +; A - код ошибки, если CF=1 +; +; формат раб. буфера: +; +00 8 db "FILE????" ; шаблон имени +; +08 3 db "???" ; шаблон расширения +; +11 1 db 20h ; атрибуты для поиска +; +12 10 ds 10 ; зарезервировано +; +22 2 dw 0000h ; время создания файла +; +24 2 dw 0000h ; дата создания файла +; +26 2 dw 0000h ; номер первого кластера +; +28 4 dw 0000h ; мл.разряд размер файла в байтах +; dw 0000h ; ст.разряд +; +32 1 db 20h ; атрибут найденного файла +; +33 11 db "FILENAMEEXT" ; имя найденного файла (копия из каталога) +;///////////////////////////////////////////////////////////////////// +Func_19:ld (D1F3A),a ; атрибут поиска + ld (D1FE2),de ; адрес раб. буфера + ld a,b + ld (D1FE7),a ; флаг 8.3 или 11 формата имени + push hl ; имя файла + call A228F ; прочитать список каталога (также указ. в строке) + pop hl + call A20F8 ; тест на допуст. имя и настр. на диск + ret c + ld hl,D213A ; 8.3 имя + ld de,T2364 ; буфер имени 11 симв. формата + call A2384 ; преобр. имя 8.3 -> 11 формат + ret c + ld a,(D1F3A) ; раб. ячейка (здесь атрибут записи) + call search_record ; поиск записи в списке диска + ret c ; запись не найдена/слишком много файлов + ld hl,T2364 ; буфер имени 11 симв. формата + ld de,(D1FE2) ; адрес раб. буфера + ld bc,11 + ldir ; перекачать "???????.." + ld a,(D1F3A) ; раб. ячейка (здесь атрибут записи) + ld (de),a ;+11 раб. буфер функции +A201D: inc de + ld bc,32 + add ix,bc + ld (D1FE4),ix ;; след. запись + ld hl,T1F3B+12 ; смещ. в записи + ld bc,20 + ldir + ld a,(T1F3B+11) ; ячейка атрибутов файла + ld (de),a ;+32 в раб. буфере функции + inc de + ld hl,T1F3B ; найденная запись файла/каталога + ld a,(D1FE7) ; флаг 8.3 или 11 формата имени + or a + jr nz,A2049 ; 11 -> 8.3 + ; скопир. имя найд. файла (формат 11) + ld bc,11 + ldir +A2042: ld a,true + ld (D1FE6),a ; флаг отработки "F_FIRST" + xor a + ret + ; преобр. 11 -> 8.3 формат +A2049: call A1FB8 + jr A2042 + + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #1A. Поиск следующего совпадающего файла. +; +; вход: de = указатель на рабочий буфер +; выход: de'= индекс записи в списке каталога (исп. #11 функ.) +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_1A:ld a,(D1FE6) ; флаг отработки "F_FIRST" + or a + ld a,EUNOPER ; код "невозможная операция" + scf + ret z + ld (D1FE2),de ; адрес раб. буфера + ld hl,T2364 ; буфер имени 11 симв. формата + ex de,hl + ld bc,11 + ldir + xor a + ld (D1FE6),a ; сбр. флаг отработки "f_first" + ld a,(hl) ; ячейка атрибутов записи + push hl + call A207B ; найти след. запись + pop de + ret c ; не найдена или слишком много файлов + jr A201D ; скопир. остальные 20 байт записи + + + +; поиск след. записи +A207B: ex af,af' ; сохр. атрибуты записи + xor a ; лог. номер стр. (кэш списка каталога) + call set_dos_page ; подключить банку расширения ДОС + push af ; старая банка порта + ex af,af' ; восст. атрибуты записи + cpl + ld c,a + exx + ld de,0 ; сбр. индекс записи (исп. #11 функ.) + exx + ld ix,(D1FE4) ;; адрес след. записи + db 0DDh + ld a,h + db 0DDh + or l + jr z,search_record_too_many ; вышли за границу 0FFFFh + jr search_record_loop ; на цикл поиска записи + + + + +;------------------------------------------------- +; Поиск записи каталога в списке каталога +; +; вход: a=атрибут записи +; выход: de'=индекс записи в списке каталога +; CF - каталог не найден +;------------------------------------------------- +search_rec_dir: + ld a,10h ; атрибут "dir" + call search_record + ret nc + ld a,ENOPATH ; код "неверный путь" + ret + + +;------------------------------------------------- +; Поиск записи файла в списке каталога. +; +; вход: a=атрибут записи +; выход: ix=адрес найденной записи +; de'=индекс записи в списке каталога (для #11 функ.) +; CF - при ошибке, A=код ошибки +;------------------------------------------------- +search_rec_file: + ld a,27h ; атрибут "все, кроме папки и метки тома" +search_record: + ex af,af' ; сохр. атрибут записи + xor a ; лог. номер стр. (кэш списка каталога) + call set_dos_page ; подключить банку расширения ДОС + push af ; старая банка порта + ex af,af' ; восст. атрибут записи + cpl + ld c,a + ld ix,LC000 ; кэш списка каталога диска + exx + ld de,0 ; сбр. индекс записи (исп. #11 функ.) + exx + ; цикл поиска записи +search_record_loop: + ld a,(ix+0) + or a + jr z,search_record_not_found + cp 0E5h ; код удал. записи + jp z,search_record_next + ld a,(ix+11) ; атрибут записи + and c ; искомый атрибут ? + jp nz,search_record_next ; нет + ld hl,T2364 ; готовое имя файла (11 симв. формат) + db 0DDh + ld d,h + db 0DDh + ld e,l + ld b,11 + ex de,hl +A20C9: ld a,(de) + cp "?" + jr z,A20D1 + cp (hl) + jp nz,search_record_next +A20D1: inc hl + inc de + djnz A20C9 + db 0DDh + ld d,h + db 0DDh + ld e,l + ld hl,T1F3B ; 32 буфер записи + ex de,hl + ld bc,32 + ldir ; скопир. найденную запись в буфер + pop af + out (0E2h),a ; восст. порт + and a + ret + ; +search_record_next: + exx + inc de ; ++индекс записи (исп. #11 функ.) + exx + ld de,32 + add ix,de ; на след. запись + jp nc,search_record_loop + ; выход за границу 0FFFFh +search_record_too_many: + ld e,ETMFILE ; код "слишком много файлов" + jr $+4 +search_record_not_found: + ld e,ENOFILE ; код "файл не обнаружен" + pop af + out (0E2h),a ; восст. порт + ld a,e ; код ошибки + scf + ret + + +;------------------------------------------------- +; Тест на допустимое имя и настроиться на диск. +; вход: hl=строка имени +;------------------------------------------------- +A20F8: ld de,D213A ; куда + ld bc,0DFFh ; b=счетчик +A20FE: ld a,(hl) + inc hl + cp '\' + jr z,A2114 + cp ":" + jr z,A2122 + ld (de),a + inc de + cp " "+1 + ccf + ret nc + djnz A20FE + ld a,EINVFNAM ; код "неверное имя" + scf + ret + ; +A2114: ld a,0 + ld (de),a + push hl + ld hl,D213A + call A2164 + pop hl + jr nc,A20F8 + ret + ; +A2122: ld a,(D213A) ; буква диска + cp "a" + jr c,A212F + cp "z"+1 + jr nc,A212F + sub 20h +A212F: sub "A" + push hl + call A2147 + pop hl + jr nc,A20F8 + ret + + +; Буфер имени 8.3 формата +D213A: db " ",0 ; 12 пробелов + + + +A2147: push af ; номер девайса + ld c,1 ; открыть девайс + rst 18h + pop bc + jr c,A215C ; ошибка + ld a,b + ld (disk),a ; номер диска + call A1370 + ret c + ld a,(last_drive) ; номер посл. диска + and a + ret + ; +A215C: cp EINVDRV ; код "bad drive number" + scf + ret z + ld a,ENORDY ; код "нет готовности" + scf + ret + + +A2164: xor a ; номер дескр. + call search_handle ; поиск дескр. файла + ld a,(hl) ; 8.3 имя + or a + jr nz,A2183 +A216D: ld de,0 + ld (iy+26),e + ld (iy+27),d + call A228F ; прочитать список каталога + ld hl,T1510 ; буфер тек. пути (каталога) системы + ld (hl),'\' + inc hl + ld (hl),0 + and a + ret + ; +A2183: cp "." + jr nz,A21AF + ld a,(iy+26) + or (iy+27) + jr nz,A2195 + inc hl + ld a,(hl) + or a + dec hl + jr z,A216D +A2195: exx + ld hl,T2364 + ld de,T2364+1 + ld bc,10 + ld (hl)," " + ldir + exx + ld de,T2364 +A21A7: ldi + ld a,(hl) + or a + jr nz,A21A7 + jr A21B6 + ; +A21AF: ld de,T2364 ; буфер имени 11 симв. формата + call A2384 ; преобр. имя 8.3 -> 11 формат + ret c +A21B6: call A21DC + ret c + ld (iy+26),e + ld (iy+27),d + ld de,L4000 + ld (iy+28),e + ld (iy+29),d + call A228F ; прочитать список каталога + and a + ret + + + +A21CE: ld bc,32 + add ix,bc ; на след. запись + jr nc,A21E6 + ; превышение границы #FFFF +A21D5: pop af + out (0E2h),a ; восст. порт + ld a,ENOPATH ; код "неверный путь" + scf + ret + ; +A21DC: xor a ; лог. номер стр. (кэш списка каталога) + call set_dos_page ; подключить банку расширения ДОС + push af ; старая банка порта + ld ix,LC000 ; кеш списка каталога +A21E6: ld a,(ix+0) + or a + jr z,A21D5 ; список пустой + cp 0E5h + jr z,A21CE ; файл удален + ld a,(ix+11) ; ячейка атрибутов + and 10h ; каталог ? + jr z,A21CE ; нет, на след. запись + ; каталог + ld hl,T2364 + db 0DDh + ld d,h + db 0DDh + ld e,l + ex de,hl + ld b,11 +A2201: ld a,(de) + cp "?" + jr z,A2209 + cp (hl) + jr nz,A21CE ; на след. запись +A2209: inc hl + inc de + djnz A2201 + ld a,(ix+0) + cp "." + jr nz,A2245 + ld a,(ix+1) + cp "." + jr nz,A223A + ; родит. каталог + ld hl,T1510 ; буфер тек. пути (каталога) системы + ld d,h + ld e,l + ld bc,256 + xor a + cpir + ld bc,256 + ld a,'\' + cpdr + inc hl + and a + ex de,hl + sbc hl,de + ex de,hl + jr nz,A2238 + inc hl +A2238: ld (hl),0 +A223A: ld e,(ix+26) + ld d,(ix+27) + pop af + out (0E2h),a ; восст. порт + and a + ret + ; +A2245: db 0DDh + ld e,l + db 0DDh + ld d,h + ld hl,T1510 ; буфер тек. пути (каталога) системы + ld bc,255 + xor a + cpir + dec hl + dec hl + ld a,'\' + cp (hl) + inc hl + jr z,$+4 + ld (hl),a + inc hl + ld bc,0820h ; b=счетчик, c=пробел +A225F: ld a,(de) + inc de + cp c + jr z,A2266 + ld (hl),a + inc hl +A2266: djnz A225F + ld a,(de) + inc de + cp c + jr z,A227F + ld (hl),"." + inc hl + ld (hl),a + inc hl + ld a,(de) + inc de + cp c + jr z,A227F + ld (hl),a + inc hl + ld a,(de) + cp c + jr z,A227F + ld (hl),a + inc hl +A227F: ;ld (hl),'\' ; ; концовка пути + ;inc hl; + ld (hl),0 + jr A223A + + + +;///////////////////////////////////////////////////////////////////// +; Функция #1E. Информация о текущем каталоге. +; +; вход: HL - буфер в памяти 256 байт +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_1E:ex de,hl ; de=куда + ld hl,T1510 ; откуда ; DIRSPEC + ld a,(hl) + or a + ldi + jr nz,$-4 + ret + + + +;------------------------------------------------- +; Прочитать список каталога +;------------------------------------------------- +A228F: xor a + ld l,a + ld h,a + push hl + pop ix + ld b,a ; от начала файла + call Func_15 ; перемещение указателя в файле + xor a ; лог. номер стр. (кэш списка каталога) + call set_dos_page ; подключить банку расширения ДОС + push af ; старая банка порта + ; очистить кеш каталога +/* ld hl,LC000 ;@@ + ld de,LC000+1 + ld bc,4000h-1 + ld (hl),l + ldir ; 21 * #3FFF = 344.043 +*/ ld (.stack),sp ; сохр. стек + ld de,0 ; байты заполнения + ld bc,400h / 2 + ld sp,0000h ; откуда (вниз) +.loop: push de + push de + push de + push de + push de + push de + push de + push de + push de + push de + push de + push de + push de + push de + push de + push de + dec bc + ld a,c + or b + jp nz,.loop + db 31h ; ld sp,.. +.stack: dw 0 + ; + ld a,(disk) ; номер диска + ld (iy+40),a ; сохр. в дескриптор + ld d,(iy+26) ; de=номер первого кластера + ld e,(iy+27) + ld a,d + or e + jr z,A22D2 ; root ?? + ld hl,LC000 ; куда + ld de,4000h ; сколько + xor a ; дескриптор + call Func_13 ; чтение из файла + ld (size_cash_directory),de ; число прочит. байтов + pop af + out (0E2h),a ; восст. порт + and a + ret + ; +A22D2: ld hl,(D1500) ; ст. разряд + ld ix,(D1502) ; номер лог. сектора + ld a,(D1505) + ld b,32 ; размер root-каталога + sub b + jr nc,A22E3 + add a,b + ld b,a ; число секторов +A22E3: ld a,(disk) ; номер диска + ld c,5 ; чтение секторов + ld de,LC000 ; буфер + rst 18h + pop af + out (0E2h),a ; восст. порт + and a + ret + + + +;------------------------------------------------- +; Сбросить кеш каталога на диск. +; вход: iy=структура дескриптора +;------------------------------------------------- +flush_cash_dir: + xor a + ld l,a + ld h,a + push hl ; ст. разряд + pop ix ; мл. разряд + ld b,a ; от начала файла + call Func_15 ; перемещение указателя в файле + xor a ; лог. номер стр. (кэш списка каталога) + call set_dos_page ; подключить банку расширения ДОС + push af ; старая банка порта + ld a,(disk) ; номер диска + ld (iy+40),a ; сохр. в дескрипторе + ld d,(iy+26) ; de=номер первого кластера + ld e,(iy+27) + ld a,d + or e + jr z,A2325 ; root ?? + ld hl,LC000 ; откуда + ld de,(size_cash_directory) ; сколько + xor a ; дескр. + call Func_14 ; запись в файл + pop af + out (0E2h),a ; восст. порт + and a + ret + ; +A2325: ld hl,(D1500) ; ст. разряд + ld ix,(D1502) ; лог. номер сектора + ld a,(D1505) + ld b,32 ; макс. число секторов ? + sub b + jr nc,$+4 + add a,b + ld b,a ; число секторов + ld a,(disk) ; номер диска + ld c,6 ; запись секторов + ld de,LC000 ; буфер + rst 18h + pop af + out (0E2h),a ; восст. порт + and a + ret + + +size_cash_directory: + dw 0 ; размер списка каталога + + + + +;----------------------------------------------------------- +; Подключить банку расширения ДОС в 3-е окно +; +; вход: a=лог. номер банки (0..2, в данной версии ДОС) +; выход: a=старая банка порта +;----------------------------------------------------------- +set_dos_page: + ld c,a + ld b,0 + ld hl,list_dos_pages ; 16 байт, номера банок расширения ДОС + add hl,bc + in a,(0E2h) ; сохр. порт + ld c,0E2h ; порт + outi ; один байт (hl) -> порт (bc) + ret + + +; Массив лог. номеров банок расширения ДОС. 16 байт. +list_dos_pages: + db -1 + db -1 + db -1 + db -1 + db -1 + db -1 + db -1 + db -1 + db -1 + db -1 + db -1 + db -1 + db -1 + db -1 + db -1 + db -1 + + + +; Буфер 11 симв. имени (первые 11 байт) +T2364: ds 8 ; имя файла +T236C: ds 3 ; расш. + ; + ds 21 ; 11+21=32 + + +;------------------------------------------------- +; Преобразовать имя 8.3 -> 11 формат +; вход: hl = 8.3 имя +; de = буфер имени 11 симв. формата +; при ошибке CF - недоп. имя +;------------------------------------------------- +A2384: push hl + push de + ld h,d + ld l,e + inc de + ld (hl)," " + ld bc,10 + ldir + pop de + pop hl + ld a,(hl) + cp "." + scf + jr z,A239A + cp " "+1 +A239A: ld a,EINVFNAM ; код "неверное имя" + ret c + ld bc,0902h ; b=счетчик +A23A0: ld a,(hl) + cp " "+1 + ccf + ret nc + cp '"' + jr z,A23E9 ; ошибка + cp "*" + jr z,A23ED + cp "+" + jr z,A23E9 ; ошибка + cp "," + jr z,A23E9 ; ошибка + cp "." + jr z,A23FE + cp "/" + jr z,A23E9 ; ошибка + cp ":" + jr z,A23E9 ; ошибка + cp ";" + jr z,A23E9 ; ошибка + cp "<" + jr z,A23E9 + cp "=" + jr z,A23E9 + cp ">" + jr z,A23E9 + cp "[" + jr z,A23E9 + cp '\' + jr z,A23E9 + cp "]" + jr z,A23E9 + cp "|" + jr z,A23E9 + call upper ; a..z -> A..Z + ld (de),a + inc hl + inc de + djnz A23A0 +A23E9: ld a,EINVFNAM ; код "неверное имя" + scf + ret + ; +A23ED: ld a,"?" + inc hl + djnz A23F6 + jr A23E9 + ; +A23F6: ld (de),a + inc de + djnz A23F6 + ld b,1 + jr A23A0 + +A23FE: ld a," " + inc hl + djnz A240D +A2403: ld b,4 + dec c + jr nz,A23A0 + jr A23E9 ; код "неверное имя" + ; +A240D: ld (de),a + inc de + djnz A240D + jr A2403 + + + +; a..z -> A..Z +upper: cp "a" + ret c + cp "z"+1 + jr nc,A2425 + sub 20h + ret + ; +A2425: cp "а" ; русская + ret c + cp "п"+1 + jr nc,A2430 + sub 20h + ret + ; +A2430: cp "р" ; русская + ret c + cp "Ё" + jr nc,A243B + sub 50h + ret + ; +A243B: cp "ё" + ret nz + dec a ; ё -> Ё + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #21. Текущая дата и время. +; +; вход: нет +; выход: D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; C - день недели +;///////////////////////////////////////////////////////////////////// +Func_21:ld c,0F5h + rst 08h + jp c,A24D0 + ld d,7 ; номер регистра + call A24BB ; чтение регистров CMOS + push af + ld d,8 + call A24BB + pop de + ld e,a + push de + ld d,4 + call A24BB + push af + ld d,2 + call A24BB + pop de + ld e,a + push de + ld d,0 + call A24BB + push af + ld d,6 + ld c,0F6h + rst 08h + pop de + ld e,a + push de + ld d,9 + call A24BB + push af + ld d,32h + ld c,0F6h + rst 08h + db 0DDh + ld h,a + pop af + cp 80 ;50h + push af + jr c,A248B + ld a,19h + db 0DDh + cp h + jr z,A249A + jr A2491 + ; +A248B: ld a,20h + db 0DDh + cp h + jr z,A249A +A2491: push af + ld d,32h + ld c,0F7h + rst 08h + pop af + db 0DDh + ld h,a +A249A: pop af + db 0DDh + ld l,a + db 0DDh + ld a,h + call A24BE + ld l,a + ld h,0 + ld c,l + ld b,h + db 0DDh + ld h,b + add hl,hl + add hl,hl + add hl,bc + add hl,hl + ld b,h + ld c,l + add hl,hl + add hl,hl + add hl,bc + add hl,hl + ex de,hl + add ix,de + pop bc + pop hl + pop de + and a + ret + + +; Чтение регистров CMOS +; вход: d=номер регистра +A24BB: ld c,0F6h + rst 08h +A24BE: ld e,a + rrca + rrca + rrca + rrca + and 0Fh + ld d,a + add a,a + add a,a + add a,d + add a,a + ld d,a + ld a,e + and 0Fh + add a,d + ret + + +A24D0: ld de,(D255D) + ld hl,(D255F) + ld bc,(D2561) + ld ix,(D2563) + and a + ret + + +A24E1: ld c,0 + ld (D255D),de + ld (D255F),hl + ld (D2561),bc + ld (D2563),ix + and a + ret + + +;///////////////////////////////////////////////////////////////////// +; Функция #22. Установить текущую дату и время. +; +; вход: D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_22:push ix + push bc + push hl + push de + ld c,0F5h + rst 08h + jr c,A24E1 + pop af + push af + ld d,7 ; номер регистра + call A2544 ; запись регистров CMOS + pop bc + ld a,c + ld d,8 + call A2544 + pop af + push af + ld d,4 + call A2544 + pop bc + ld a,c + ld d,2 + call A2544 + pop af + push af + ld d,0 + call A2544 + pop bc + ld a,c + ld d,6 + ld c,0F7h + rst 08h + pop hl + xor a + ld de,100 +A252E: inc a + sbc hl,de + jr nc,A252E + add hl,de + dec a + push hl + ld d,32h + call A2544 + pop bc + ld a,c + ld d,9 + call A2544 + and a + ret + + +; Запись регистров CMOS +; вход: d=номер регистра +A2544: call A254B + ld c,0F7h + rst 08h + ret + ; +A254B: ld bc,0AFFh ; константа +A254E: inc c + sub b + jr nc,A254E + add a,b + ld b,a + ld a,c + rlca + rlca + rlca + rlca + and 0F0h + or b + ret + + +; Дата по-умолчанию +D255D: dw 0101h ; день:месяц +D255F: dw 0000h ; часы:минуты +D2561: dw 0001h ; 00h=секунды +D2563: dw 2005 ; год + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #17. Информация о дате и времени файла. +; +; вход: A - дескриптор файла +; выход: D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_17:call search_handle ; поиск дескр. файла + ret c ; не найден + ; время/дату из структуры дескр. + ld e,(iy+22) ; время + ld d,(iy+23) ; + ld c,(iy+24) ; дата + ld b,(iy+25) ; + call A25C3 ; раскодировать время/дату + and a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #18. Изменение даты и времени файла. +; +; вход: A - дескриптор файла +; D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_18:push af + call A2599 ; закодировать время/дату + pop af ; дескриптор + push de + push bc + call search_handle ; поиск дескр. файла + pop bc + pop de + ret c ; не найден + ; время/дату в структуру дескр. + ld (iy+22),e ; время + ld (iy+23),d ; + ld (iy+24),c ; дата + ld (iy+25),b ; + set 7,(iy+41) ; уст. признак изменения файла + and a + ret + +;------------------------------------------------- +; Закодировать время/дату +; вход: de - день/месяц +; hl - часы/минуты +; b - секунды +; ix - год +; выход: de - время +; bc - месяц/день +; ix - год +;------------------------------------------------- +A2599: ld a,l + rlca + rlca + sla a + rl h + sla a + rl h + sla a + rl h + srl b + or b + ld l,a + ld bc,-1980 + add ix,bc + ld a,e + rlca + rlca + rlca + rlca + and 0F0h + db 0DDh + ld b,l + sla a + rl b + or d + ld c,a + ex de,hl + and a + ret + + +;------------------------------------------------- +; Раскодировать время/дату +; вход: de - время +; bc - месяц/день +; ix - год +; выход: de - день/месяц +; hl - часы/минуты +; b - секунды +; ix - год +;------------------------------------------------- +A25C3: ex de,hl + ld a,c + and 1Fh + ld d,a + srl b + rr c + ld a,c + rrca + rrca + rrca + rrca + and 0Fh + ld e,a + ld c,b + ld b,0 + ld ix,1980 + add ix,bc + ld a,l + and 1Fh + add a,a + ld b,a + srl h + rr l + srl h + rr l + srl h + rr l + srl l + srl l + and a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #1D. Смена текущего каталога. +; Меняет текущий каталог и текущий диск, если он указан в файловой +; спецификации. Если путь начинается с "\" - это означает путь от +; корневого каталога, иначе от текущего. +; +; вход: HL - указатель на имя каталога +; выход: нет +;///////////////////////////////////////////////////////////////////// +Func_1D:call A20F8 ; тест на допуст. имя и настр. на диск + ret c + ld hl,D213A + ld a,(hl) + or a + call nz,A2164 + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #1B. Создание каталога. +; +; вход: HL - указатель на имя каталога +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_1B:call A20F8 ; тест на допуст. имя и настр. на диск + ret c + ld hl,D213A ; 8.3 имя + ld de,T2364 ; буфер имени 11 симв. формата + call A2384 ; преобр. имя 8.3 -> 11 формат + ret c + call A228F ; прочитать список каталога + call search_rec_dir ; поиск записи каталога в списке диска + ld a,EEXISDIR ; код "каталог существует" + ccf + ret c ; каталог найден + call A10FD + ret c + push hl + ld de,(D150E) ; номер кластера + call A11C4 ; записать в кеш FAT-а номер кластера + call A128B ; подкл. банку кеша FAT и записать его на диск + ld hl,T2364 + ld de,T1F3B + ld bc,11 + ldir + ex de,hl + ld a,10h ; атрибут записи каталога + ld (hl),a + inc hl + ld bc,0A00h ; b=счетчик + ld (hl),c + inc hl + djnz $-2 + push hl + call Func_21 ; узнать тек. дату и время + call A2599 ; закодировать время/дату + pop hl + ld (hl),e ; de=время + inc hl + ld (hl),d + inc hl + ld (hl),c ; день + inc hl + ld (hl),b ; месяц + inc hl + pop de + push de + ld (hl),e + inc hl + ld (hl),d + inc hl + ld bc,0400h ; b=счетчик + ld (hl),c + inc hl + djnz $-2 + call A1F5B ; скопир. новую запись в список диска (каталога) + call flush_cash_dir ; сбросить кеш каталога на диск + ld hl,T0400 ; буфер + ld (hl),"." ; запись тек. каталога + ld bc,0A20h ; b=счетчик, c=пробел + inc hl + ld (hl),c + djnz $-2 + inc hl + ld de,T1F3B+11 ; ячейка атрибутов файла + ex de,hl + ld bc,21 + ldir + ex de,hl + ld (hl),"." ; запись родит. каталога + inc hl + ld (hl),"." + ld bc,0920h ; b=счетчик, c=пробел + inc hl + ld (hl),c + djnz $-2 + inc hl + push hl + xor a ; лог. номер стр. (кэш списка каталога) + call set_dos_page ; подключить банку расширения ДОС + pop hl + push af ; старая банка порта + ld a,(LC000) + cp "." + ld de,LC000+11 ; атрибуты записи + jr z,A26A9 + ld ix,T1F3B + xor a + ld (ix+26),a + ld (ix+27),a + ld de,T1F3B+11 ; ячейка атрибутов файла +A26A9: ex de,hl + ld bc,21 + ldir + pop af + out (0E2h),a ; восст. порт + ex de,hl + ld d,h + ld e,l + inc de + ld (hl),0 + ld bc,447 + ldir + pop hl + call A1CB8 + ld a,(D0083) ; секторов на кластер +A26C4: push af + push hl ; ст. разряд + push ix ; номер лог. сектора + in a,(0E2h) + push af + in a,(82h) + out (0E2h),a + ld de,LC400 ; буфер + ld b,1 ; число секторов + ld a,(disk) ; номер диска + ld c,6 ; запись секторов + rst 18h + pop af + out (0E2h),a + ld hl,T0400 ; откуда + ld de,T0400+1 ; куда + ld bc,512-1 + ld (hl),0 + ldir + pop ix + pop hl + inc ix + db 0DDh + ld a,h + db 0DDh + or l + jr nz,$+3 + inc hl + pop af + dec a + jr nz,A26C4 + and a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #1C. Удаление каталога. +; Можно удалить только пустой каталог. +; +; вход: HL - указатель на имя каталога +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_1C:call A20F8 ; тест на допуст. имя и настр. на диск + ret c + ld hl,D213A ; 8.3 имя + ld de,T2364 ; буфер имени 11 симв. формата + call A2384 ; преобр. имя 8.3 -> 11 формат + ret c + ld hl,T2364 + ld bc,11 + ld a,"?" + cpir + ld a,EINVFNAM ; код "неверное имя" + scf + ret z + call A228F ; прочитать список каталога + call search_rec_dir ; поиск записи каталога в списке диска + ret c ; не найден + ld hl,(D1F55) + push ix +A2724: push hl + call A1CB8 + ld a,(D0083) ; секторов на кластер +A272B: push af + push hl ; ст. разряд + push ix ; номер лог. сектора + in a,(0E2h) + push af + in a,(82h) + out (0E2h),a + ld de,LC400 ; буфер + ld bc,0105h ; чтение одного сектора + ld a,(disk) ; номер диска + rst 18h + pop af + out (0E2h),a + ld b,16 + ld hl,T0400 +A2748: ld a,(hl) + or a + jr z,A2783 + cp "." + jr z,A2761 + cp 0E5h ; байт удаления файла + jr z,A2761 + ld de,11 ; смещ. до байта атрибутов + add hl,de + ld a,(hl) + sbc hl,de + ;bit 3,a ;@@ бит "метка тома" + and 00001000b ; 7 тактов + jr z,A278A +A2761: ld de,32 + add hl,de + djnz A2748 + pop ix + pop hl + inc ix + db 0DDh + ld a,h + db 0DDh + or l + jr nz,$+3 + inc hl + pop af + dec a + jr nz,A272B + pop hl ; номер кластера + call A1132 ; прочитать из кеша FAT-а номер след. кластера + ex de,hl ; hl=номер след. кластера + jr nc,A2724 ; не конец цепочки +A277E: pop ix + jp mark_delete ; пометить запись как "удаленная" + ; +A2783: pop ix + pop hl + pop af + pop hl + jr A277E + ; +A278A: pop ix + pop hl + pop af + pop hl + pop ix + ld a,ENOEMPTY ; код "каталог не пуст" + scf + ret + + + + +D2795: dw 0 + + +;///////////////////////////////////////////////////////////////////// +; Функция #47. Получение информации приложения. +; +; вход: HL - буфер данных +; B - номер подфункции: +; B=0 - получение параметров командной строки +; B=1 - получение полного пути к каталогу программы +; B=2 - получение полного пути и имени файла программы +; выход: нет +;///////////////////////////////////////////////////////////////////// +Func_47: inc b + djnz A27A8 + ex de,hl + xor a + ld (de),a + ld hl,(D2795) + ld c,(hl) + inc c + ret z + inc hl + ldir + and a + ret + +; Получение параметров командной строки +A27A8: djnz A27CF + ex de,hl + ld hl,(D2795) + ld c,(hl) + inc hl + add hl,bc + inc hl + inc hl + push hl + ld bc,256 + xor a + cpir + ld a,'\' + cpdr + inc hl + inc hl + pop bc + and a + sbc hl,bc + ld a,b + ld b,h + ld h,a + ld a,c + ld c,l + ld l,a + ldir + xor a + ld (de),a + ret + +; Получение полного пути к каталогу программы +A27CF: djnz A27E1 + ex de,hl + ld hl,(D2795) + ld c,(hl) + inc hl + add hl,bc + inc hl + inc hl +A27DA: ld a,(hl) + ldi + or a + jr nz,A27DA + ret + ; +A27E1: ld a,EINVFNC ; код "неверный номер функции" + scf + ret + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #45. Разбор командной строки. +; +; вход: HL - указатель командной строки +; DE - указатель на буфер пользователя +; B - номер подфункции: +; 0 - Разобрать строку +; 1 - Выделить имя диска +; 2 - Выделить директорию +; 3 - Выделить имя файла +; 4 - Выделить расширение файла +; 5 - Выделить имя диска, путь к файлу, имя файла и расш. файла +; 6 - Зарезервировано +; 7 - Выделить параметр командной строки +; 8 - Преобразовать из 11 символьного формата в формат ДОС +; 9 - Преобразовать из формата ДОС в 11 символьный формат +; выход: нет +;///////////////////////////////////////////////////////////////////// +Func_45:exx + ld hl,T0400 + ld (D2947),hl + ld hl,T2952 + ld (D2943),hl + ld hl,T295F + ld (D2945),hl + ld hl,T2949 + ld (D2941),hl + exx + inc b + dec b + jr z,A2857 ; разобрать строку + dec b + jr z,A2825 ; выделить имя диска + dec b + jr z,A2845 ; выделить директорию + dec b + jr z,A284B ; выделить имя файла + dec b + jr z,A2851 ; выделить расширение файла + dec b + jr z,A2859 ; выделить диск, путь, файл и расш. + dec b ; зарезервировано + jr z,A2821 + dec b + jp z,Func_43 ; выделить параметр ком-строки + dec b + jp z,A1FB8 ; преобр. имя 11 -> 8.3 формат + dec b + jp z,A2384 ; преобр. имя 8.3 -> 11 формат +A2821: ld a,EINVFNC ; код "неверный номер функции" + scf + ret + +; Выделить имя диска +A2825: ld (D2941),de + call A287C + ret c + ld de,(D2941) + ld a,(de) + dec a + cp -1 + ret z + cp "@" + jr c,A2841 + cp "Z" + jr nc,A2841 + sub "A"-1 + ret + ; +A2841: ld a,EINVDRV ; код "не верный номер устройства" + scf + ret + +; Выделить директорию +A2845: ld (D2947),de + jr A287C + +; Выделить имя файла +A284B: ld (D2943),de ; куда + jr A287C + +; Выделить расширение файла +A2851: ld (D2945),de + jr A287C + +; Разобрать строку +A2857: jr A287C + +; Выделить диск, путь, файл и расш. +A2859: ex de,hl + ld c,(hl) + inc hl + ld b,(hl) + inc hl + ld (D2941),bc + ld c,(hl) + inc hl + ld b,(hl) + inc hl + ld (D2947),bc + ld c,(hl) + inc hl + ld b,(hl) + inc hl + ld (D2943),bc + ld c,(hl) + inc hl + ld b,(hl) + ld (D2945),bc + ex de,hl + jr A287C + + +A287C: ex af,af' + exx + xor a + ld hl,(D2947) + ld (hl),a + ld hl,(D2943) ; адрес буфера под имя файла + ld (hl),a + ld hl,(D2945) + ld (hl),a + ld hl,(D2941) + ld (hl),a + exx + ex af,af' +A2891: ld de,T2934 + ld bc,0D01h ; счетчики +A2897: ld a,(hl) + call upper ; a..z -> A..Z + ld (de),a + inc hl + inc de + inc c ; ++счетчик + cp '\' + jr z,A2916 + cp ":" + jr z,A2900 + cp " "+1 + jr c,A28BF + cp "?" + jr z,A28B9 + cp "*" + jr z,A28B9 +A28B3: djnz A2897 + ld a,EINVFNAM ; код "неверное имя" + scf + ret + ; +A28B9: ex af,af' + set 7,a + ex af,af' + jr A28B3 + ; +A28BF: ld a,2 + cp c + jr z,A28FD + push hl + ld hl,T2934 + ld de,(D2943) ; адрес буфера под имя файла + ld b,0 + dec c + dec c + ld a,c + ldir + ld c,a + xor a + ld (de),a + ld hl,(D2943) ; адрес буфера под имя файла + ld a,"." + cpir + jr nz,A28F8 + ld c,3 + ld de,(D2945) +A28E5: ld a,(hl) + or a + jr nz,A28EC + ld a," " + dec hl +A28EC: ld (de),a + inc hl + inc de + dec c + jr nz,A28E5 + xor a + ld (de),a + ex af,af' + set 1,a ; указано расш. файла + ex af,af' +A28F8: ex af,af' + set 0,a ; указано имя файла + ex af,af' + pop hl +A28FD: ex af,af' + and a + ret + + +A2900: xor a + ld (de),a + push hl + ld hl,T2934 + ld de,(D2941) + ld b,0 + ldir + pop hl + ex af,af' + set 3,a ; указано имя диска + ex af,af' + jp A2891 + + +A2916: xor a + ld (de),a + push hl + push bc + ld hl,(D2947) + ld bc,255 + cpir + dec hl + ex de,hl + ld hl,T2934 ; 12 пробелов + pop bc + ld b,0 + ldir + pop hl + ex af,af' + set 2,a ; указан путь файла + ex af,af' + jp A2891 + + + +T2934: db " ",0 ; 12 пробелов + + +D2941: dw T2949 +D2943: dw T2952 +D2945: dw T295F +D2947: dw T0400 ; 512 байт, ".", ".." записи + + +T2949: ds 9 + +T2952: db " ",0 ; 9 пробелов + +T295F: db " ",0 + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #43. Выделить параметр командной строки. +; +; вход: HL - указатель командной строки +; DE - буфер для выдел. параметра +; выход: HL - указатель на след. параметр ком-строки +; CF=0 - конец строки не достигнут (есть другие параметры) +; CF=1 - конец строки (в буфер перенесён последний параметр или ноль) +;///////////////////////////////////////////////////////////////////// +Func_43:xor a + ld (de),a +A2965: ld a,(hl) + inc hl + cp " " + ret c + jr z,A2965 +A296C: ld (de),a + ld a,(hl) + inc hl + inc de + cp " "+1 + jr nc,A296C + cp " " + ld a,0 + ld (de),a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #3C. Информация о памяти. +; +; вход: нет +; выход: HL - общее кол-во страниц +; BC - кол-во своб. страниц +;///////////////////////////////////////////////////////////////////// +Func_3C:ld c,0C0h + rst 08h + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #3D. Выделение блока памяти. +; +; вход: B - размер блока в страницах по 16kB +; выход: A - идентификатор блока памяти, если CF=0 +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_3D:ld c,0C2h + rst 08h + ld e,a + ld a,ENOMEM ; код "не хватает памяти" + ret c + ld d,0 + ld hl,list_pages ; массив списка выдел. страниц + add hl,de + ld a,(D2E70) ; уровень текущей программы + ld (hl),a + ld a,e + and a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #3E. Освобождение блока памяти. +; +; вход: A - идентификатор блока памяти +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_3E:ld e,a + ld d,0 + ld hl,list_pages ; массив списка выдел. страниц + add hl,de + ld a,(D2E70) ; уровень текущей программы + cp (hl) + ld a,EINVMEM ; код "не существующий блок памяти" + scf + ret nz + push de + ld a,e + ld c,0C3h + rst 08h + pop de + ld a,EINVMEM ; код "не существующий блок памяти" + ret c + ld hl,list_pages ; массив списка выдел. страниц + add hl,de + xor a + ld (hl),a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #3F. Изменение блока памяти. +; +; вход: A - идентификатор блока памяти +; B - новый размер блока +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_3F:ld e,a + ld d,0 + ld hl,list_pages ; массив списка выдел. страниц + add hl,de + ld a,(D2E70) ; уровень текущей программы + cp (hl) + ld a,EINVMEM ; код "не существующий блок памяти" + scf + ret nz + ld d,b + push de + ld a,e + call A29EE + pop de + ld a,EINVMEM ; код "не существующий блок памяти" + ret c + ld a,b + cp d + ret z + jr c,A29DB + ld b,d + ld a,e + ld c,9Dh + rst 08h + ld a,b + ld c,0C3h + rst 08h + xor a + ret + ; +A29DB: ld a,d + sub b + ld b,a + ld c,e + push bc + ld c,0C2h + rst 08h + pop bc + ld b,a + ld a,ENOMEM ; код "недостаточно памяти" + ret c + ld a,c + ld c,9Eh + rst 08h + xor a + ret + +A29EE: ld b,-1 + ld c,a +A29F1: inc b + push bc + ld a,c + ld c,0C4h + rst 08h + pop bc + jr nc,A29F1 + or a + scf + ret z + xor a + ret + +A29FF: ld hl,list_pages ; массив списка выдел. страниц + ld bc,256 +A2A05: ld a,(D2E70) ; уровень текущей программы + cpir + ret nz + push hl + push bc + dec hl + and a + ld de,256 + sbc hl,de + ld a,l + call Func_3E ; освоб. блок памяти + pop bc + pop hl + jr A2A05 + + + +;///////////////////////////////////////////////////////////////////// +; Функция #38. Подключение страницы памяти. +; +; вход: A - идентиф. блока памяти +; B - номер страницы в блоке (0,1,2,..) +; H - биты 6 и 7 задают номер окна, в которое будет подкл. страница +; выход: A - номер страницы, если CF=0 +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_38:bit 7,h + jr z,Func_39 ; в 1-е + bit 6,h + jr z,Func_3A ; во 2-е + jr Func_3B ; в 3-е + + +;///////////////////////////////////////////////////////////////////// +; Функция #39. Подключение страницы памяти в первое окно. +; +; вход: A - идентиф. блока памяти +; B - номер страницы в блоке (0,1,2,..) +; выход: A - номер страницы, если CF=0 +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_39:ld c,0C4h + ex de,hl + rst 08h + ex de,hl + ret c + ld c,0A2h + in b,(c) + out (c),a + ld a,b + ret + + +;///////////////////////////////////////////////////////////////////// +; Функция #3A. Подключение страницы памяти во второе окно. +; +; вход: A - идентиф. блока памяти +; B - номер страницы в блоке (0,1,2,..) +; выход: A - номер страницы, если CF=0 +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_3A:ld c,0C4h + ex de,hl + rst 08h + ex de,hl + ret c + ld c,0C2h ; порт + in b,(c) + out (c),a + ld a,b + ret + + +;///////////////////////////////////////////////////////////////////// +; Функция #3B. Подключение страницы памяти в третье окно. +; +; вход: A - идентиф. блока памяти +; B - номер страницы в блоке (0,1,2,..) +; выход: A - номер страницы, если CF=0 +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_3B:ld c,0C4h + ex de,hl + rst 08h + ex de,hl + ret c + ld c,0E2h + in b,(c) + out (c),a + ld a,b + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #40. Выполнить файл. +; +; вход: HL - указатель на имя файла +; B=0 - загрузить и выполнить программу +; выход: A - код завершения, если CF=0 +; код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_40: inc b + dec b + jp z,A2AFE + dec b + jp z,A2B09 + ld a,EINVFNC ; код "не верный номер функции" + scf + ret + + + +A2A5D: ld a,(hl) + inc hl + cp '\' + ret z + cp "/" + ret z + cp " "+1 + jr nc,A2A5D + ret + + +A2A6A: ld a,2 ; лог. номер стр. (path, перем. окруж.) + call set_dos_page ; подключить банку расширения ДОС + push af ; старая банка порта + call Func_02 ; получить номер тек. диска + add a,"A" + ld hl,LFD00 + ld (hl),a + inc hl + ld a,":" + ld (hl),a + inc hl + call Func_1E ; инфа о тек. каталоге + call A2AC1 + ld hl,LFC80 +A2A87: ld e,(hl) + inc hl + ld d,(hl) + inc hl + bit 1,(hl) + inc hl + push hl + push bc + ex de,hl + call z,A2AB8 + call Func_1D ; смена текущего каталога + jr c,A2AAC + ld hl,D2E7C ; 8.3 имя + ld de,T2364 ; буфер имени 11 симв. формата + call A2384 ; преобр. имя 8.3 -> 11 формат + jr c,A2AAC + call A2CB6 ; сравнить/добавить расш. с "EXE" (если задано) + jr c,A2AAC ; не совпадает + call search_rec_file ; поиск записи файла в списке диска +A2AAC: pop bc + pop hl + jr nc,A2AB3 ; запись найдена + djnz A2A87 + scf +A2AB3: pop bc + ld a,b + out (0E2h),a ; восст. порт + ret + +A2AB8: push hl + ld hl,LFD00 + call Func_1D ; смена текущего каталога + pop hl + ret + +A2AC1: ld hl,LFC7F + ld de,LFDFF + ld b,0 +A2AC9: ld (hl),c + inc hl + xor a + ld (de),a + ld c,a + inc de + ld (hl),e + inc hl + ld (hl),d + inc hl + inc b +A2AD4: ld a,(de) + cp '\' + jr nz,A2ADB + set 1,c +A2ADB: ld a,(de) + cp ";" + jr z,A2AC9 + inc de + cp ":" + jr z,A2AD4 + or a + jr nz,A2ADB + ld (hl),c + inc hl + ld (hl),a + inc hl + ld (hl),a + ret + + +T2AEE: db "PATH=",0 ; имя перем. окружения + + +; ++уровня текущей программы +A2AF4: ld hl,D2E70 + inc (hl) + ret + +; --уровня текущей программы +A2AF9: ld hl,D2E70 + dec (hl) + ret + + + +;------------------------------------------------------------------------ +; Загрузить и выполнить программу. +; функ. 40h, B=0. +; +; 1) Открывает exe-файл на чтение; +; 2) Считывает в рабочую область префикс exe-файла; +; 3) Выделяет блок памяти, требуемый для загрузки всего файла или первичного +; загрузчика, если его размер не равен нулю; +; 4) Сохраняет стек; +; 5) Подключает страницы из выделенного блока; +; 6) Строит префикс запуска программы и устанавливает на него регистр IX; +; 7) Считывает файл по адресу указанному в смещении 16 (Адрес расположения +; кода в памяти); +; 8) Закрывает exe-файл, если это не первичный загрузчик; +; 9) Устанавливает стек равным значению из смещения 20 (Адрес расп. стека); +; 10) Передает управление по адресу указанному в смещении 18 (Адрес запуска); +; +; Префикс запуска файла: +; +; -03 1 db ? ; Дескриптор файла, если exe-файл с первичным загрузчиком +; -02 1 db ? ; Идентификатор блока памяти +; -01 1 db ? ; Уровень текущей программы +; +00 1 db ? ; Длина ком-строки +; +01 127 ds ? ; Параметры ком-строки, заканчивается нулем +;------------------------------------------------------------------------ +A2AFE: ld (D2E78),hl + call A2A5D + ld hl,(D2E78) + jr c,A2B32 +; B=1. +A2B09: ld (D2E78),hl + ld a,1 + ld (D1F3A),a ; раб. ячейка + call A20F8 ; тест на допуст. имя и настр. на диск + ret c + ld hl,D213A ; 8.3 имя + ld de,T2364 ; буфер имени 11 симв. формата + call A2384 ; преобр. имя 8.3 -> 11 формат + ret c + call A2CB6 ; сравнить/добавить расш. с "EXE" (если задано) + ld a,ENOFILE ; код "файл не найден" + ret c + call A2AF4 + call A1E89 + jr nc,A2B75 + jr A2AF9 + ; +A2B32: ld a,1 + ld (D1F3A),a ; раб. ячейка + call A20F8 ; тест на допуст. имя и настр. на диск + ret c + ld hl,D213A ; 8.3 имя + ld de,T2364 ; буфер имени 11 симв. формата + call A2384 ; преобр. имя 8.3 -> 11 формат + ret c + call A2CB6 ; сравнить/добавить расш. с "EXE" (если задано) + ld a,ENOFILE ; код "файл не найден" + ret c + call A2AF4 + call A1E89 + jr nc,A2B75 + call A2AF9 + ld hl,T2AEE ; имя перем. окружения "PATH=" + ld de,LFE00 ; куда + ld b,1 ; получить перем. окружения + call Func_46 ; функция сист. окружения + ld hl,(D2E78) + ld de,D2E7C +A2B67: ld a,(hl) + ldi + or a + jr nz,A2B67 + call A2A6A + ld hl,(D2E78) + jr A2B09 + ; +A2B75: ld (D2E76),a ; сохр. дескр. файла + ld hl,D2E7C ; буфер + ld de,128 ; число чит. байт + ld a,(D2E76) ; дескр. файла + call Func_13 ; чтение из файла + jp c,A2CD7 + ld ix,D2E7C + ld hl,(D2E7C) + ld de,"XE" ; сигнатура + sbc hl,de + ld a,EINVEXE ; код "неправильный EXE-файл" + scf + jp nz,A2CD7 + ld a,(ix+3) + or a + ld a,ENSUPEXE ; код "не поддерж. версия EXE-файла" + scf + jp nz,A2CD7 + + + ld de,(D2E84) + ld a,e + or d + jp nz,A2CE4 + ld l,a + ld h,a + push hl + pop ix + ld b,2 ; от конца файла + ld a,(D2E76) ; дескр. файла + call Func_15 ; перемещение указателя в файле + ld de,(D2E8C) + ld a,d + and 3Fh + ld d,a + add ix,de + ld de,0 + adc hl,de + ld a,xh + sla a + rl l + rl h + sla a + rl l + rl h + or xl + jr z,1F + inc hl +1: ld a,h + or a + jp nz,A2CD5 + ld b,l + call Func_3D ; выделить блок памяти + jp c,A2CD5 + ld (D2E77),a ; идентиф. блока памяти + exx + pop de + ld hl,0 + add hl,sp + ld sp,(D2E7A) + push hl + push de + in a,(0E2h) + ld d,a + in a,(0C2h) + ld e,a + in a,(0A2h) + push de + push af + ld (D2E7A),sp + ld sp,hl + exx + ld a,(D2E77) ; идентиф. блока памяти + ld de,T2E71 + ld bc,00C4h + rst 08h + ld (de),a + inc de + ld a,(D2E77) ; идентиф. блока памяти + ld bc,01C4h + rst 08h + ld (de),a + inc de + ld a,(D2E77) ; идентиф. блока памяти + ld bc,02C4h + rst 08h + ld (de),a + inc de + ld a,(D2E77) ; идентиф. блока памяти + ld bc,03C4h + rst 08h + ld (de),a + ld hl,(D2E78) + ld de,T0400+1 + call A2E52 + ld a,128 ;80h + sub b + ld (T0400),a + ld sp,T307A + ld a,0FFh ; номер стр. + out (0A2h),a + out (0C2h),a + out (0E2h),a + ld hl,(D2E8C) + ld de,T2E71 + ld a,h + and 0C0h + cp 40h ; 40(00)h + jr z,A2C5E + cp 80h ; 80(00)h + jr z,A2C62 + cp 0C0h ; 0C0(00)h + jr z,A2C66 +A2C5E: ld a,(de) + out (0A2h),a + inc de +A2C62: ld a,(de) + out (0C2h),a + inc de +A2C66: ld a,(de) + out (0E2h),a + call A2DE9 + ld hl,(D2E82) + ld ix,(D2E80) + ld b,0 ; от начала файла + ld a,(D2E76) ; дескр. файла + call Func_15 ; перемещение указателя в файле + ld sp,L403F + ld de,(D2E8C) + xor a + ld l,a + ld h,a + sbc hl,de + ex de,hl ; de=число чит. байт + ld hl,(D2E8C) ; буфер + ld a,(D2E76) ; дескр. файла + call Func_13 ; чтение из файла + ld a,(D2E76) ; дескр. файла + call Func_12 ; закрыть файл + ld sp,(D2E90) + ld hl,(D2E8C) + ld de,128 ;T0080 + and a + sbc hl,de + ex de,hl + db 0DDh + ld h,d + db 0DDh + ld l,e + ld hl,(D2E8E) + ld de,A2CB3 ; адрес п/п "завершить процесс" + push de + push hl + ret + ; +A2CB3: jp Func_41 ; завершить программу (процесс) + + + +;------------------------------------------------- +; Если расш. файла не задано, задать "exe". +; Если расш. файла задано, сравнить его с "exe". +;------------------------------------------------- +A2CB6: ld hl,T2E6D ; "EXE" + ld de,T236C + ld b,3 + ld a,(de) + cp " " + jr nz,A2CCB ; задано расш. + ldi + ldi + ldi + xor a + ret + ; +; сравнить расш. с "EXE" +A2CCB: ld a,(de) + cp (hl) + scf + ret nz ; не совпадает + inc hl + inc de + djnz A2CCB + xor a ; Ok + ret + + +A2CD5: ld a,1Eh +A2CD7: push af + ld a,(D2E76) ; дескр. файла + call Func_12 ; закрыть файл + ld hl,D2E70 + dec (hl) ; --уровня текущей программы + pop af + ret + +A2CE4: ex de,hl + ld de,(D2E8C) + ld a,d + and 3Fh + ld d,a + adc hl,de + xor a + sla h + rla + sla h + rla + ld b,a + ld a,h + or l + jr z,A2CFC + inc b +A2CFC: call Func_3D ; выделить блок памяти + jr c,A2CD5 + ld (D2E77),a ; идентификатор блока памяти + exx + pop de + ld hl,0 + add hl,sp + ld sp,(D2E7A) + push hl + push de + in a,(0E2h) + ld d,a + in a,(0C2h) + ld e,a + in a,(0A2h) + push de + push af + ld (D2E7A),sp + ld sp,hl + exx + ld de,T2E71 + ld bc,00C4h + ld a,(D2E77) ; идентификатор блока памяти + rst 08h + ld (de),a + inc de + ld bc,01C4h + ld a,(D2E77) ; идентификатор блока памяти + rst 08h + ld (de),a + inc de + ld bc,02C4h + ld a,(D2E77) ; идентификатор блока памяти + rst 08h + ld (de),a + inc de + ld bc,03C4h + ld a,(D2E77) ; идентификатор блока памяти + rst 08h + ld (de),a + ld hl,(D2E78) + ld de,T0400+1 + call A2E52 + ld a,80h + sub b + ld (T0400),a + ld sp,T307A + ld a,0FFh ; номер стр. + out (0A2h),a + out (0C2h),a + out (0E2h),a + ld hl,(D2E8C) + ld de,T2E71 + ld a,h + and 0C0h + cp 40h ; 40(00)h + jr z,A2D76 + cp 80h + jr z,A2D7A + cp 0C0h + jr z,A2D7E +A2D76: ld a,(de) + out (0A2h),a + inc de +A2D7A: ld a,(de) + out (0C2h),a + inc de +A2D7E: ld a,(de) + out (0E2h),a + call A2DE9 + ld hl,(D2E82) + ld ix,(D2E80) + ld b,0 ; от начала файла + ld a,(D2E76) ; дескр. файла + call Func_15 ; перемещение указателя в файле + ld sp,L403F + ld hl,(D2E8C) ; буфер + ld de,(D2E84) ; число чит. байт + ld a,(D2E76) ; дескр. файла + call Func_13 ; чтение из файла + ld sp,(D2E90) + ld hl,(D2E8C) + ld de,128 + and a + sbc hl,de + ex de,hl + ld xh,d + ld xl,e + ld hl,(D2E8E) + ld de,A2CB3 ; дос-заглушка + push de + push hl + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #41. Завершить программу (процесс). +; +; вход: B - код завершения +; выход: A - код ошибки, если CF=1 +; +; Выход из EXE-файла: +; +; 1) Освобождаются все блоки памяти которые выделялась данному приложению. +; 2) Восстанавливаются страницы которые были подключены до запуска EXE-файла. +; 3) Вспоминается стек. +; 4) В регистр A помещается код возврата и выполняется RET. +; +;///////////////////////////////////////////////////////////////////// +Func_41: ld a,b + ld (return_code),a ; код завершения программы + call A29FF + ld hl,D2E70 + dec (hl) ; --уровня текущей программы + ld sp,(D2E7A) + pop af + pop hl + out (0A2h),a + ld a,l + out (0C2h),a + ld a,h + out (0E2h),a + pop de + pop hl + ld (D2E7A),sp + ld sp,hl + ex de,hl + ld a,(return_code) ; код завершения программы + and a + jp (hl) + + + +;///////////////////////////////////////////////////////////////////// +; Функция #42. Получить код завершения программы. +; +; вход: нет +; выход: A - код завершения +;///////////////////////////////////////////////////////////////////// +Func_42:ld a,(return_code) + and a + ret + +A2DE9: ld hl,(D2E8C) + dec h + ld d,h + ld e,l + inc de + ld bc,00FFh + ld (hl),b + ldir + ex de,hl + dec h + ld de,128 ;T0080 + add hl,de + ex de,hl + db 0DDh + ld h,d + db 0DDh + ld l,e + ld hl,T0400 ; откуда + ld c,(hl) + inc c + ldir + ex de,hl + ld (hl),b + ld a,(D2E70) ; уровень текущей программы + ld (ix-1),a ; в префикс exe-файла + ld a,(D2E77) ; идентификатор блока памяти + ld (ix-2),a ; в префикс exe-файла + ld a,(D2E76) ; дескр. файла + ld (ix-3),a ; в префикс exe-файла + inc hl + ld (hl),b + inc hl + call Func_02 ; получить номер тек. диска + add a,"A" + ld (hl),a + inc hl + ld a,":" + ld (hl),a + inc hl + push hl + call Func_1E ; инфа о тек. каталоге + pop hl + xor a + ld bc,256 + cpir + dec hl + dec hl + ld a,'\' + cp (hl) + inc hl + jr z,A2E3F + ld (hl),a + inc hl +A2E3F: ex de,hl + ld hl,D213A +A2E43: ld a,(hl) + ldi + cp " "+1 + jr nc,A2E43 + dec de + xor a + ld (de),a + ld (D2795),ix + ret + + +A2E52: ld bc,8021h +A2E55: ld a,(hl) + cp c + jr c,A2E61 + inc hl + djnz A2E55 + xor a + ld (de),a + ld b,80h + ret +A2E61: ld bc,8020h +A2E64: ld a,(hl) + ld (de),a + inc hl + inc de + cp c + ret c + djnz A2E64 + ret + + +T2E6D: db "EXE" + +D2E70: db 1 ; уровень текущей программы +T2E71: db 0 + db 0 + db 0 + db 0 + +return_code: + db 0 ; код завершения программы (процесса) + +D2E76: db 0 ; дескр. файла +D2E77: db 0 ; идентификатор блока памяти + +D2E78: dw 0 + + + +D2E7A: dw L317B ; адрес стека + + +; 512 байт. exe-заголовок, после раб. буфер +D2E7C: db "EXE" + db 0 ; exe версия +D2E80: dw 0 ; 512, мл. смещ. кода +D2E82: dw 0 ; ст. смещ. кода +D2E84: dw 0 ; end-beg, первичный загрузчик + dw 0,0,0 ; резерв +D2E8C: dw 0 ; адрес загрузки кода +D2E8E: dw L0000 ; адрес передачи управления +D2E90: ds 490 + + + +T307A: ds 257 +L317B: db 0 ; начало стека + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #46. Системное окружение. +; +; вход: B - номер подфункции: +; B=0, получение системного окружения +; HL - буфер +; B=1, получить переменную окружения +; HL - имя переменной +; DE - буфер для значения переменной +; B=2, установить/удалить переменную окружения +; HL - имя переменной и значение, разделенные символом "=" +; т.е. ПЕРЕМЕННАЯ=ЗНАЧЕНИЕ +; В конце строки должен стоять нуль. +; выход: A - состояние, если CF=0 +; DE - указывает на конец буфера (только для B=1) +; A=0FFh - переменная обнаружена +; A=0 - переменная не обнаружена +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +Func_46: inc b + jr z,A318E ; B=#FF + dec b + jr z,A31B2 ; B=0. получить сист. окружение + dec b + jr z,A31DB ; B=1. получить перем. окружения + dec b + jr z,A31FD ; B=2. установить/удалить перем. окружения + ld a,EINVFNC ; код "неверный номер функции" + scf + ret + +;------------------------------------------------- +; Инициализация буфера переменных окружения +;------------------------------------------------- +A318E: ld a,2 ; лог. номер стр. (path, перем. окруж.) + call set_dos_page ; подключить банку расширения ДОС + push af ; старая банка порта + ld de,LE400 ; начало буфера переменных окружения + xor a + ld (de),a + inc de + ld hl,DEFAULT_ENV + ld bc,1 + ldir + ld (de),a + ex de,hl + ld de,LE400 ; начало буфера переменных окружения + and a + sbc hl,de + ld (D3296),hl + pop af + out (0E2h),a ; восст. порт + and a + ret + +;------------------------------------------------- +; Получить сист. окружение +;------------------------------------------------- +A31B2: push hl + ld a,2 ; лог. номер стр. (path, перем. окруж.) + call set_dos_page ; подключить банку расширения ДОС + ld h,a ; старая банка порта + ld c,0E2h + in l,(c) + exx + ld hl,LE400 ; начало буфера переменных окружения + inc hl + pop de + ld bc,(D3296) + exx +A31C8: out (c),l + exx + ld a,(hl) + exx + out (c),h ; восст. порт + exx + ld (de),a + inc hl + inc de + dec bc + ld a,b + or c + exx + jr nz,A31C8 + xor a + ret + +;------------------------------------------------- +; Получить переменную окружения +;------------------------------------------------- +A31DB: push de + call A325F ; скопир. строку перем. окруж. в буферы + ld a,2 ; лог. номер стр. (path, перем. окруж.) + call set_dos_page ; подключить банку расширения ДОС + ex af,af' ; старая банка порта + call A323D ; найти конец всех переменных ? + pop de + ld a,0 + ld (de),a + jr nc,A31F7 +A31EE: ld a,(hl) + ldi + or a + jr nz,A31EE + dec de + ld a,-1 +A31F7: ex af,af' + out (0E2h),a ; восст. порт + ex af,af' + and a + ret + + +;------------------------------------------------- +; Установить/Удалить переменную окружения +; +; вход: hl=имя перем. и значение, раздел. символом "=" +;------------------------------------------------- +A31FD: ; в D2E7C "EXE" + ; в T0400 содержимое system.bat + call A325F ; скопир. строку перем. окруж. в буферы + ld a,2 ; лог. номер стр. (path, перем. окруж.) + call set_dos_page ; подключить банку расширения ДОС + push af ; старая банка порта + call A323D ; найти конец всех переменных ? + jr nc,A3214 + xor a + cpir + ld a,b + or c + jr z,A3214 + ldir +A3214: ld a,(T0400) + or a + jr z,A322D + ld hl,D2E7C ; 512 байт, буфер +A321D: ld a,(hl) + ldi + cp "=" ; символ разделения + jr nz,A321D + ld hl,T0400 ; откуда +A3227: ld a,(hl) + ldi + or a + jr nz,A3227 +A322D: xor a + ld (de),a + ld hl,LE400 ; начало буфера переменных окружения + ex de,hl + sbc hl,de + ld (D3296),hl + pop af + out (0E2h),a ; восст. порт + and a + ret + +; найти конец всех переменных ? +A323D: ld hl,LE400 ; начало буфера переменных окружения + ld bc,(D3296) + push hl +A3245: pop de + ld de,D2E7C ; 512 байт буфер + xor a + cpir + push hl +A324D: ld a,(hl) + or a + jr z,A325D + ld a,(de) + cp (hl) + inc hl + inc de + dec bc + jr nz,A3245 + cp "=" ; символ разделения + jr nz,A324D + scf +A325D: pop de + ret + +;----------------------------------------------------------- +; Скопировать строку переменной окружения в буферы +; (имя и значение в разные буферы) +; вход: hl=имя перем. и значение, раздел. символом "=" +;----------------------------------------------------------- +A325F: ld b,maxlen_env_string ; 255 макс. длина строки (имя+знач.) + ld de,D2E7C ; куда + xor a + ld (de),a + ld (T0400),a + ; скопир. в "D2E7C" имя переменной +A3269: ld a,(hl) + inc hl + cp "=" ; символ разделения + jr z,A3283 ; конец имени + or a + jr z,A327B ; конец строки + call upper ; a..z -> A..Z + ld (de),a + inc de + djnz A3269 + jr A3294 ; слишком длинная строка + +; значение не задано +A327B: ld a,"=" ; символ разделения + ld (de),a + inc de + xor a + ld (de),a + inc de + ret + + +A3283: ld (de),a ; сохр. "=" + inc de + xor a + ld (de),a ; в конец имени перем. + ; скопир. в "T0400" значение переменной (строку путей) + ld de,T0400 ; 512 байт, буфер + ld (de),a + ld c,255 ; чтобы "ldi" не портила "b" +A328D: ld a,(hl) + ldi + or a + ret z ; конец строки знач. переменной + djnz A328D +A3294: ld a,b + ld (de),a ; обрезать слишком длинную строку + inc de + scf + ret + + +D3296: dw 1 +DEFAULT_ENV: db 0 + + + + include "mouse.asm" ; код мышки + + + + db " " ; 12 + ds 20 + + db "FILENAME.EXT",0 + + + + +;------------------------------------------------- +; RST 18h. Вектор дисковых устройств +; вход: a=номер устройства (0-25) +;------------------------------------------------- +drv_devices: + push hl + push bc ; сохр. bc + ld c,a + add a,a ;1+1=2 + add a,c ;2+1=3 + ld c,a + ld b,0 + ld hl,A38FC ; таблица переходов + add hl,bc + ld a,(hl) + inc a + jr z,A38F4 ; было a=0FFh + dec a + inc hl + ld c,(hl) ; загр. адрес обработчика + inc hl ; + ld h,(hl) ; + ld l,c + pop bc ; восст. bc + ex (sp),hl ; адрес в стек + ret ; перейти на него + ; +A38F4: pop bc + pop hl + ld a,EINVDRV ; код "неверный номер устройства" + scf + ret + + + +A38FA: dw A38FC + + +; Таблица адресов обработчиков девайсов. 26 элементов (диски A..Z ?). +A38FC: db -1 ;00 + dw -1 + db -1 ;01 + dw -1 + db -1 ;02 + dw -1 + db -1 ;03 + dw -1 + db -1 ;04 + dw -1 + db -1 ;05 + dw -1 + db -1 ;06 + dw -1 + db -1 ;07 + dw -1 + db -1 ;08 + dw -1 + db -1 ;09 + dw -1 + db -1 ;10 + dw -1 + db -1 ;11 + dw -1 + db -1 ;12 + dw -1 + db -1 ;13 + dw -1 + db -1 ;14 + dw -1 + db -1 ;15 + dw -1 + db -1 ;16 + dw -1 + db -1 ;17 + dw -1 + db -1 ;18 + dw -1 + db -1 ;19 + dw -1 + db -1 ;20 + dw -1 + db -1 ;21 + dw -1 + db -1 ;22 + dw -1 + db -1 ;23 + dw -1 + db -1 ;24 + dw -1 + db -1 ;25 + dw -1 + db -1 ; конец + + + + +;----------------------------------------------------------- +; Просканировать систему на FDD/HDD девайсы и RAM-диски +;----------------------------------------------------------- +scan_all_devices: + xor a + ld (last_drive),a ; сбр. ячейку + ld hl,A38FC + ld (A38FA),hl ; восст. ячейку + ; FDD девайсы + ld c,a ; c="open device" + call A3D7A ; узнать число FDD-девайсов + ld de,A3D7A ; адрес обработчика тек. девайса + call A397B ; иниц. таблицу переходов + ; HDD девайсы + xor a + ld c,a ; c="open device" + call A39CC ; узнать число HDD-девайсов + ld de,A39CC ; адрес обработчика тек. девайса + call A397B ; иниц. таблицу переходов + ; RAM-диски + xor a + ld c,a ; c="open device" + call A3E5E ; узнать число RAM-дисков + ld de,A3E5E ; адрес обработчика тек. девайса + call A397B ; иниц. таблицу переходов + xor a + ret + + + +; Инициировать таблицу переходов девайса. +; вход: de=адрес обработчика девайса +; a=число девайсов (0=нет) +A397B: ld c,a + ld hl,last_drive ; ячейка номера посл. диска + add a,(hl) + ld (hl),a + ld a,c + ld c,0 ; сбр. + or a + ret z ; нет девайсов + ld hl,(A38FA) ; тек. полож. в таблице +A3989: ld (hl),c ; индекс ? + inc hl + ld (hl),e ; de=адрес обработчика + inc hl + ld (hl),d + inc hl + inc c ; ++индекс ? + dec a + jr nz,A3989 + ld (A38FA),hl ; сохр. новое полож. в таблице + dec a + ld (hl),a ; a=0FFh + ret + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #08 (DSS_RESCAN). Пересканировать девайсы системы. +; +; вход: нет +; выход: A - номер последнего лог. диска в системе +;///////////////////////////////////////////////////////////////////// +Func_08:di + call scan_all_devices ; перескан. все девайсы + ld a,(last_drive) + ei + ret + + + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #09. Номер системного диска. +; Возвращает номер диска, c которого загружена система. +; +; вход: B = 0 (01h - исп. boot-загрузчик системы) +; выход: A - номер системного диска (0=A,1=B,..) +;///////////////////////////////////////////////////////////////////// +Func_09: inc b + dec b + jr z,A39A5 + dec b + jr z,A39AA ; с какого диска загр. система (для загрузчика) + ld a,EINVFNC ; код "неверный номер функции" + scf + ret + ; +A39A5: db 3Eh ; ld a,.. +boot_disk: + db -1 ; номер диска, с которого загружалась система + and a + ret + +; Сообщить DSS с какого диска загружается система. +; Исп. загрузчик системы для иниц. ячейки "boot_disk". +A39AA: ld b,a + ld c,0 +A39AD: push bc + ld a,c + ld bc,0008h ; получить геометрию диска + ld de,55AAh ; сигнатура + rst 18h + pop bc + jr c,A39C3 ; ошибка + ex af,af' + cp b + jr nz,A39C3 + ld a,c + ld (boot_disk),a ; иниц. ячейку + and a + ret + ; +A39C3: inc c ; ++номер boot-диска + ld a,(last_drive) ; номер посл. диска системы + cp c + jr nz,A39AD + scf + ret + + +;------------------------------------------------- +; Обработчик HDD (rst 18h) +;------------------------------------------------- +A39CC: inc c + dec c ; c=0 + jr z,A3A01 + dec c ; c=1 open + jp z,A3BD1 + dec c ; c=2 close + jp z,A3BD3 + dec c ; c=3 media check (смена носителя) + jp z,A3BD5 + dec c ; c=4 get BPB + jp z,A3BD9 + dec c ; c=5 input (чтение секторов) + jp z,A3C27 + dec c ; c=6 output (запись секторов) + jp z,A3C1C + dec c ; c=7 + jp z,A3BCD + dec c ; c=8 узнать геометрию диска + jp z,A3B34 + dec c ; c=9 + jr z,A39FD + dec c ; c=10 + jp z,A3C06 + dec c ; c=11 + jp z,A3C11 +A39FD: ld a,1 ; код "bad command" + scf + ret + +; c=0 +A3A01: push iy + ld hl,T3A4C ; таблица лог.дисков (16*12) + ld (D3D78),hl ; адрес структуры тек. лог. диска + ld ix,L4000 ; буфер под список (5 байт) + ld c,5Fh ; список дисковых устройств + rst 08h + xor a + ld b,(ix+2) ; кол-во HDD устройств + cp b + jr z,A3A25 ; нет винтов + ; + ld c,80h ; мастер на первом канале +A3A19: push bc + ld a,c + ld (D3D6F),a ; номер девайса (80h/81h мастер/слейв) + call A3C9A ; узнать лог. диски винта и создать их таблицы + pop bc + inc c ; слейв на первом канале + djnz A3A19 + ; +A3A25: pop iy + ld hl,(D3D78) ; адрес структуры тек. лог. диска + ld de,T3A4C ; таблица лог.дисков (16*12) + xor a ; счетчик лог. дисков + sbc hl,de + ret z ; структура первого лог. диска + ld de,16 ; размер структуры лог. диска + inc a + sbc hl,de + jr nz,$-3 ; перейти на структуру первого лог. диска + and a ; a=кол-во лог.дисков + ret + + +; нет обращения +;L3A3B: ld a,0FFh + ;inc hl + ;cp (hl) + ;ret nz + ;inc hl + ;cp (hl) + ;ret nz + ;inc hl + ;cp (hl) + ;ret nz + ;inc hl + ;cp (hl) + ;ret nz + ;inc hl + ;cp (hl) + ;ret + + +; Таблица лог. дисков ДОС-а +; +; +0 - номер девайса (80h,...) +; +1,+2,+3,+4 - абс. номер нач. сектора лог. диска +; +5,+6,+7,+8 - размер лог. диска (число секторов) +; +; +T3A4C: ds 16*12 ; 192 C..N + + +; вход: a=0..11 (индекс) +; выход: ix,hl - абс. номер нач. сектора +; a - номер девайса (80h,...) +A3B0C: push de + push bc + push hl + ld l,a + ld h,0 + add hl,hl ;1+1=2 + add hl,hl ;2+2=4 + add hl,hl ;4+4=8 + add hl,hl ;8+8=16 + ex de,hl + ld iy,T3A4C ; таблица лог.дисков (16*12) + add iy,de + ld c,(iy+1) ; абсолютный номер + ld b,(iy+2) ; начального сектора + ld e,(iy+3) ; раздела + ld d,(iy+4) ; + pop hl + add ix,bc + adc hl,de + ld a,(iy+0) ; тип девайса (80h,...) + pop bc + pop de + ret + +;c=8. Узнать геометрию диска (CHS) +A3B34: bit 7,b + jr nz,A3B49 + inc b + dec b ; b=0 + jr z,A3B6F + dec b ; b=1 + jr z,A3B5C + dec b ; b=2 + jr z,A3B60 + ld a,EINVFNC ; код "неверный номер функции" + scf + ret + ; +A3B49: res 7,b + inc b + dec b + jr z,A3B65 + dec b + jr z,A3B67 + dec b + jr z,A3B6B + ld a,1 ; код "bad command" + scf + ret + ; +A3B5C: ld a,0Bh ; код "failure" + scf + ret + ; +A3B60: ld b,l + jp A3C32 + ; +A3B65: and a + ret + ; +A3B67: ld a,0Bh ; код "failure" + scf + ret + ; +A3B6B: ld a,0Bh ; код "failure" + scf + ret + +;c=8. Узнать геометрию диска (CHS) +;b=0. +; вход: a - индекс (0..11) +A3B6F: ex de,hl + ld bc,55AAh ; сигнатура раздела + and a + sbc hl,bc + ld l,a ; индекс раздела + ld a,0Bh ; код "failure" + scf + ret nz + push iy + ld h,0 + add hl,hl ; *16 + add hl,hl + add hl,hl + add hl,hl + ld b,h + ld c,l + ld iy,T3A4C ; таблица лог.дисков (16*12) + add iy,bc + ld e,(iy+5) ; размер раздела (число секторов) + ld d,(iy+6) ; + ld l,(iy+7) ; ст. разряд + ld h,(iy+8) ; + ld a,(iy+0) ; тип девайса (80h,...) + ld c,a + ld iy,LC1C0 ; LC000+01BEh+2 ?? + and 0Fh + jr z,A3BA7 ; + ld iy,LC1C8 ; LC000+01BEh+0Ah ?? +A3BA7: in a,(0E2h) + push af + ld a,0FEh ; номер стр. + out (0E2h),a + ld a,(iy+0) + exx + ld l,(iy+3) ; + ld h,(iy+4) ; + ld e,(iy+2) ; + ld d,0 + ld b,d + ld c,(iy+1) ; + exx + ex af,af' + pop af + out (0E2h),a + ld a,c + ex af,af' + pop iy + and a + ret + + +A3BCD: ld a,1 ; код "bad command" + and a + ret + +A3BD1: xor a + ret + +A3BD3: xor a + ret + +A3BD5: ld a,-1 + and a + ret + + + +A3BD9: push iy + push de + ld l,a + ld h,0 + add hl,hl ; *16 + add hl,hl + add hl,hl + add hl,hl + ld b,h + ld c,l + ld iy,T3A4C ; таблица лог.дисков (16*12) + add iy,bc + ld e,(iy+1) ; мл. разряд номера сектора + ld d,(iy+2) + ld l,(iy+3) ; ст. разряд + ld h,(iy+4) + db 0DDh + ld l,e + db 0DDh + ld h,d + ld a,(iy+0) ; тип девайса (80h,...) + pop de ; буфер + pop iy + ld bc,0155h ; прочитать один сектор + rst 08h + ret + +A3C06: push iy + call A3B0C ; получить абс. номер нач. сектора + ld c,52h ; чтение секторов в зад. блок памяти + rst 08h + pop iy + ret + +A3C11: push iy + call A3B0C ; получить абс. номер нач. сектора + ld c,53h ; ? + rst 08h + pop iy + ret + +A3C1C: push iy + call A3B0C ; получить абс. номер нач. сектора + ld c,56h ; записать "b" секторов + rst 08h + pop iy + ret + +A3C27: push iy + call A3B0C ; получить абс. номер нач. сектора + ld c,55h ; прочитать "b" секторов + rst 08h + pop iy + ret + +A3C32: push iy + call A3B0C ; получить абс. номер нач. сектора + ld c,54h ; проверка секторов (не работает?) + rst 08h + pop iy + ret + + +; на лог. диск раздела +A3C3D: ld e,(iy+8) ; абсолютный (лог.) номер + ld d,(iy+9) ; начального сектора + ld l,(iy+10) ; раздела + ld h,(iy+11) ; + ld ix,(D3D70) ; мл.разряд + add ix,de + ld de,(D3D72) ; ст.разряд + adc hl,de + db 0DDh + ld d,h + db 0DDh + ld e,l + ld ix,(D3D78) ; адрес структуры тек. лог. диска + ld (ix+1),e + ld (ix+2),d + ld (ix+3),l + ld (ix+4),h + ; + ld e,(iy+12) ; размер раздела (число секторов) + ld d,(iy+13) ; + ld l,(iy+14) ; ст. разряд + ld h,(iy+15) ; + ld (ix+5),e + ld (ix+6),d + ld (ix+7),l + ld (ix+8),h + ld a,(D3D6F) ; номер девайса (80h/81h мастер/слейв) + ld (ix+0),a + ld de,16 ; размер таблицы лог.диска ? + add ix,de + ld (D3D78),ix ; адрес структуры след. лог. диска +A3C90: ld de,16 ; размер раздела + add iy,de + pop bc + djnz A3CD3 ; проверить след. раздел + and a ; конец разделов в MBR + ret + + +;---------------------------------------------------- +; Узнать лог. диски винта и создать их таблицы +;---------------------------------------------------- +A3C9A: in a,(0E2h) ; сохр. стр. + push af + ld a,0FFh ; номер стр. + out (0E2h),a + call A3CA8 + pop af + out (0E2h),a ; восст. стр. + ret + +A3CA8: ld ix,0 + ld de,0 + ld (D3D74),de + ld (D3D76),ix + ; цикл +A3CB7: ld (D3D70),de ; мл.разряд номера сектора + ld (D3D72),ix ; ст.разряд + call read_one_sector ; прочитать один сектор (MBR, 0-й сектор) + ld hl,(LC000+510) ; конец сектора + ld de,0AA55h ; сигнатура таблицы разделов + and a + sbc hl,de + jr nz,A3D1A ; не знакомый раздел, выйти + ld iy,LC000+01BEh ; на описатель 1-го раздела + ld b,4 ; макс. число разделов винта +A3CD3: push bc + ; тест на расш. раздел + ld a,(iy+4) ; байт-идентиф. раздела + cp 5 ; "Расширенный" 0-2Гб (MS-DOS 3.3) + jr nz,A3CFE + ; на след. раздел +A3CDB: push iy + ld de,(D3D70) ; мл.разряд номера сектора + ld ix,(D3D72) ; ст.разряд + push de + push ix + call next_partition ; на след. раздел + pop ix + pop de + ld (D3D70),de ; мл.разряд номера сектора + ld (D3D72),ix ; ст.разряд + call read_one_sector ; прочитать один сектор + pop iy + jr A3C90 + ; + ; тест на расш. раздел +A3CFE: cp 0Fh ; "Расширенный" 0-2Гб (Win95) + jr z,A3CDB ; на след. раздел + ; тест на осн. раздел + cp 0Eh ; "Основной" 32Мб-2Гб FAT16 (Win95) + jp z,A3C3D ; на лог. диск раздела + cp 6 ; "Основной" 32Мб-2Гб FAT16 (MS-DOS 4.0) + jp z,A3C3D + cp 4 ; "Основной" 16Мб-32Мб FAT16 (MS-DOS 3.0) + jp z,A3C3D + cp 1 ; "Основной" 0Мб-15Мб FAT12 (MS-DOS 2.0) + jp z,A3C3D + call test_others; ; поставил + jr z,A3CDB; ; на след. раздел + pop bc + or a + ret z ; конец разделов +A3D1A: scf ; не знакомый раздел + ret + +; перейти на след. раздел +next_partition: + ld hl,(D3D74) + ld de,(D3D76) + ld a,l + or h + or e + or d + ld e,(iy+8) ; абсолютный (лог.) номер + ld d,(iy+9) ; начального сектора + ld l,(iy+10) ; раздела + ld h,(iy+11) ; + jr nz,A3D44 + ld (D3D74),de + ld (D3D76),hl + ld ix,(D3D76) + jp A3CB7 + ; +A3D44: ld ix,(D3D74) ; мл. разряд + add ix,de + push ix + ld de,(D3D76) ; ст. разряд + adc hl,de + push hl + pop ix + pop de + jp A3CB7 + +; тест на другие типы разделов +; вход: a - тип раздела +; выход: Z - на след. раздел +test_others: + cp 0Bh ; "Основной" 512Мб-2Тб FAT32 (OSR2) + ret z + cp 7 ; NTFS + ret z + cp 82h ; Linux swap + ret z + cp 83h ; Linux + ret z + cp 0EBh ; BeOS + ret + + +;------------------------------------------------- +; Чтение одного сектора в буфер 0C000h +;------------------------------------------------- +read_one_sector: + push iy + ld ix,(D3D70) ; мл.разряд номера сектора + ld hl,(D3D72) ; ст.разряд + ld de,LC000 ; буфер + ld bc,0155h ; прочитать один сектор + ld a,(D3D6F) ; номер девайса (80h/81h мастер/слейв) + rst 08h + pop iy + ret + + +D3D6F: db 0 ; номер девайса (80h/81h мастер/слейв) + ; +D3D70: dw 0 ; мл.разряд номера сектора +D3D72: dw 0 ; ст.разряд +D3D74: dw 0 +D3D76: dw 0 + ; +D3D78: dw T3A4C ; адрес структуры тек. лог. диска + + + + +;------------------------------------------------- +; Обработчик FDD (rst 18h) +;------------------------------------------------- +A3D7A: inc c + dec c ; c=0 + jr z,A3DA7 + dec c ; c=1 + jr z,A3DAB + dec c ; c=2 + jr z,A3DAF + dec c ; c=3 + jr z,A3DB1 + dec c ; c=4 + jr z,A3DB5 + dec c ; c=5 + jr z,A3DDB + dec c ; c=6 + jr z,A3DDF + dec c ; c=7 + jp z,A3E5A + dec c ; c=8 + jr z,A3DE3 + ld a,EINVFNC ; код "неверный номер функции" + scf + ret +; c=0 +A3DA7: ld a,2 + and a + ret +; c=1 +A3DAB: ld c,51h ; сбр. контроллер и настр. на диск + rst 08h + ret +; c=2 +A3DAF: xor a + ret +; c=3 +A3DB1: ld a,-1 + and a + ret +; c=4 +A3DB5: ld ix,0 ; мл. разряд номера сектора + ld hl,0 ; ст. разряд + push de + push af + ld bc,0155h ; прочитать один сектор + rst 08h + pop de + pop hl + ret c + ld bc,24 + add hl,bc + ld e,(hl) + push de + ld a,d + ld c,58h ; получить парам. носителя + rst 08h + ld a,h + pop hl + push hl + ld h,a + pop af + ld c,59h ; уст. парам. носителя + rst 08h + xor a + ret + +; c=5 +A3DDB: ld c,55h ; чтение с девайса + rst 08h + ret +; c=6 +A3DDF: ld c,56h ; запись на девайс + rst 08h + ret +; c=8 +A3DE3: bit 7,b + jr nz,A3DF0 + inc b + dec b + jr z,A3DFB + ld a,1 ; код "bad command" + scf + ret + ; +A3DF0: res 7,b + inc b + dec b + jr z,A3E41 + ld a,1 ; код "bad command" + scf + ret + ; +A3DFB: ex de,hl + ld bc,55AAh ; сигнатура + and a + sbc hl,bc + ld l,a + ld a,0Bh ; код "failur" + scf + ret nz + ld a,l + and 0Fh + push af + ld c,58h ; получить парам. носителя + rst 08h + jr c,A3E3C + push hl + push de + ld a,h + ld h,0 + add hl,hl + dec a + jr nz,$-2 + ld b,h + ld c,l + ex af,af' + xor a + ld l,a + ld h,a +A3E20: ex af,af' + add hl,bc + adc a,0 + dec de + ex af,af' + ld a,d + or e + jr nz,A3E20 + ex af,af' + ld e,a + ex de,hl + exx + pop de + pop hl + pop af + ex af,af' + ld a,b + ld c,l + ld b,0 + ld l,h + ld h,b + ex de,hl + exx + and a + ret + ; +A3E3C: pop af + ld a,2 ; код "bad drive number" + scf + ret + ; +A3E41: push af + exx + ex de,hl + ld h,l + ld l,c + pop af + and 0Fh + push af + push hl + push de + ld c,58h ; получить парам. носителя + rst 08h + pop de + pop hl + jr c,A3E3C + pop af + ld c,59h ; уст. парам. носителя + rst 08h + ret c + and a + ret +; c=7 +A3E5A: ld a,1 + and a + ret + + +;------------------------------------------------- +; Обработчик RAM-дисков +;------------------------------------------------- +A3E5E: inc c + dec c ; c=0 + jp z,A3EF5 + dec c ; c=1 + jr z,A3E7F + dec c ; c=2 + jr z,A3E81 + dec c ; c=3 + jr z,A3E83 + dec c ; c=4 + jr z,A3E87 + dec c ; c=5 + jr z,A3E93 + dec c ; c=6 + jr z,A3EC4 + ld a,1 ; код "bad command" + scf + ret +; c=1 +A3E7F: xor a + ret +; c=2 +A3E81: xor a + ret +; c=3 +A3E83: ld a,-1 + and a + ret +; c=4 +A3E87: ld ix,0 + ld hl,0 + ld b,1 +; c=5 +A3E93: push bc + push ix + push hl + push bc + call A3F35 + pop bc + ld ix,512 ; размер сектора ? +A3EA0: push bc + push ix + call A3F71 + pop ix + pop bc + djnz A3EA0 + pop hl + pop ix + pop bc + xor a + cp b + ld c,b + ld b,a + jr z,A3EBC + add ix,bc + ld c,b + adc hl,bc + xor a + ret + ; +A3EBC: inc b + add ix,bc + ld b,c + adc hl,bc + xor a + ret +; c=6 +A3EC4: push bc + push ix + push hl + push bc + call A3F35 + pop bc + ld ix,512 ; размер сектора ? +A3ED1: push bc + push ix + call A3FAD + pop ix + pop bc + djnz A3ED1 + pop hl + pop ix + pop bc + xor a + cp b + ld c,b + ld b,a + jr z,A3EED + add ix,bc + ld c,b + adc hl,bc + xor a + ret + ; +A3EED: inc b + add ix,bc + ld b,c + adc hl,bc + xor a + ret + +; c=0. Просканировать число RAM-дисков. +A3EF5: ;ld hl,0200h ; ## +; ld a,80h +;A3EFA: srl a ; / 2 (мл.бит в CF) +; rr h ; цикл. сдвиг вправо через CF +; jr nc,A3EFA + ; выход: h=0, a=20h + ld a,20h ; поставил + ld (D3F70),a + ld de,T3F25 ; таблица номеров (0..15) RAM-дисков + ld bc,00CEh ; получить id блока, назнач. на RAM-диск +A3F09: push bc + ld a,b ; номер RAM-диска 0..15 + rst 08h + or a + jr z,A3F11 ; блок не назначен + ld (de),a ; id блока в таблицу + inc de +A3F11: pop bc + inc b ; ++номер ram-диска + ld a,15+1 ; макс. номер + 1 + cp b + jr nz,A3F09 + ; выход за пределы 0..15 диапазона (нет своб. ram-дисков) + ld hl,T3F25 ; таблица номеров (0..15) RAM-дисков + ex de,hl + and a + sbc hl,de + ld a,l ; число RAM-дисков (0=нет) + ;ld hl,T3FEB; ; нужен ? + and a + ret + + +; Таблица номеров (0..15) RAM-дисков +T3F25: db -1,-1,-1,-1,-1,-1,-1,-1 + db -1,-1,-1,-1,-1,-1,-1,-1 + + + +A3F35: ld bc,T3F25 + add a,c + ld c,a + ld a,0 + adc a,b + ld b,a + ld a,(bc) + ex af,af' + db 0DDh + ld b,h + db 0DDh + ld c,l + ld a,(D3F70) +A3F47: rrca ; цикл. сдвиг вправо (мл.разряд в CF) + jr c,A3F54 + rr h + rr l + rr b + rr c + jr A3F47 + ; +A3F54: ld b,c ; лог. номер страницы + ld c,0C4h ; получить физ. номер страницы блока + ex af,af' + rst 08h + ex af,af' + ld a,(D3F70) + ld c,a + dec c + db 0DDh + ld a,l + and c + inc a + ld hl,LC000 + ld bc,512 + sbc hl,bc + add hl,bc + dec a + jr nz,$-2 + ret + +D3F70: db 0 + + +A3F71: ld a,d + cp 0A0h + ld c,0E2h + set 6,h + jr c,A3F7E + ld c,0A2h + res 7,h +A3F7E: in a,(c) + ex af,af' + di + out (c),a + db 0DDh + ld b,h + db 0DDh + ld h,c + db 0DDh + ld c,l + ldir + ex af,af' + db 0DDh + ld c,h + out (c),a + ld a,h + and 7Fh + ei + ret nz + ld c,0E2h + in b,(c) + ld a,0FEh + out (c),a + ex af,af' + db 0DDh + ld h,0C2h + db 0DDh + ld l,a + ld a,(ix+0) + ex af,af' + out (c),b + ld h,0C0h + ret + + +A3FAD: ld a,d + cp 0A0h + ld c,0E2h + set 6,h ; 00->40h + jr c,A3FBA + ld c,0A2h + res 7,h +A3FBA: in a,(c) + ex af,af' + di + out (c),a + db 0DDh + ld b,h + db 0DDh + ld h,c + db 0DDh + ld c,l + ex de,hl + ldir + ex de,hl + ex af,af' + db 0DDh + ld c,h + out (c),a + ld a,h + and 7Fh + ei + ret nz + ld c,0E2h + in b,(c) ; сохр. порт + ld a,0FEh ; номер стр. + out (c),a + ex af,af' + db 0DDh + ld h,0C2h + db 0DDh + ld l,a + ld a,(ix+0) + ex af,af' + out (c),b ; восст. порт + ld h,0C0h + ret + + + include "cursor.asm" + + + + + + +; вход: de=скен-код/ascii-код (d - сбр. 7-й бит) +; +;TSR: ld a,b +; and 00110000b ; биты Ctrl+Alt +; cp 00110000b ; 30h +; jp nz,A06DD ; сохр. de,bc в кольц. буфере клавы +; ; de=скен-код/ascii-код +; ; очистить буфер клавиатуры +; ld a,(D0641) +; ld (D0640),a +; ret; +; ; +; res 7,d +; ld a,d +; ld e,a +; ld d,0 ; de=индекс скен-кода (hot-клавиши) +; ; вкл. стр. с таблицей +; ld a,3 ; лог. номер дос-банки +; call set_dos_page ; подкл. дос-банку в 0C000h +; ld (tsr2+1),a ; старая банка 0E2h порта +; ; +; ld hl,0C000h +; add hl,de ; адрес элемента обраб. hot-клавиши +; ld a,(hl) +; or a +; jr z,tsr1 ; обраб. не определен +; ld (tsr2+1),a ; стр. обработчика +; inc hl +; ld a,(hl) ; адрес обработчика hot-клавиши +; inc hl +; ld h,(hl) +; ld l,a +; ld (tsr4+1),hl ; адрес обработчика +; jr tsr3 +; ; +;tsr1: +;tsr2: ld a,-1 +; out (0E2h),a ; восст. порт +; ret +; ; +;tsr3: call tsr1 ; вкл. страницу обработчика +;tsr4: jp 0 ; перейти на обработчик + + + + +; раб. буфер, исп. 16 байт (п/п рам-дисков) +;T3FEB: db 0 diff --git a/DOS/DOS.INC b/DOS/DOS.INC new file mode 100755 index 0000000..16445ae --- /dev/null +++ b/DOS/DOS.INC @@ -0,0 +1,91 @@ +true equ 1 +false equ 0 + +; номер версии ДОС +major_version equ 1 ; версия (0..9) +minor_version equ 61 ; модификация (0..99) +build_version equ 10 ; билд (0..999) + +; макс. число дескрипторов файлов в системе +max_handles equ 9 + +; макс. длина строки переменной окружения (имя + значение) +maxlen_env_string equ 255 + + + + +A0000 equ 0 +;A0101 equ 0101h ; 257 ? +L4000 equ 4000h +L403F equ 403Fh ; стек +LC000 equ 0C000h +LC1C0 equ 0C1C0h +LC1C8 equ 0C1C8h +LC400 equ 0C400h +LE400 equ 0E400h ; начало буфера переменных окружения +LFC7F equ 0FC7Fh +LFC80 equ 0FC80h +LFD00 equ 0FD00h +LFDFF equ 0FDFFh +LFE00 equ 0FE00h + ; +LFEE0 equ 0FEE0h ; 32 байта описателя окна (8..31 зарез.) + + + + + +; Коды ошибок ДОС +; +EZERO equ 0 ; No error +EINVFNC equ 1 ; Invalid function +EINVDRV equ 2 ; Invalid drive number +ENOFILE equ 3 ; File not found +ENOPATH equ 4 ; Path not found +EINVHND equ 5 ; Invalid handle +EMFILE equ 6 ; Too many open files +EEXIST equ 7 ; File already exists +EROFILE equ 8 ; File read only +EROOT equ 9 ; Root overflow +ENOSPACE equ 10 ; No free space +ENOEMPTY equ 11 ; Directory not empty +ECURDIR equ 12 ; Can't delete current directory +EINVMED equ 13 ; Invalid media +EUNOPER equ 14 ; Unknown operation (невозм. операция) +EEXISDIR equ 15 ; Directory exist +EINVFNAM equ 16 ; Invalid filename +EINVEXE equ 17 ; Invalid EXE-file +ENSUPEXE equ 18 ; Not supported EXE-file +EACCES equ 19 ; Access denied +ENORDY equ 20 ; Not ready +ESEEK equ 21 ; Seek error +ENOSECT equ 22 ; Sector not found +ECRC equ 23 ; CRC error +EWRTPRT equ 24 ; Write protect +EREAD equ 25 ; Read error +EWRITE equ 26 ; Write error +EDRVFAIL equ 27 ; Drive failure +EEXTND28 equ 28 ; Extended error: 28 +EEXTND29 equ 29 ; Extended error: 29 +ENOMEM equ 30 ; Not enough memory +EINVMEM equ 31 ; Invalid memory block +EEXTND32 equ 32 ; Extended error: 32 +EEXTND33 equ 33 ; Extended error: 33 +EEXTND34 equ 34 ; Extended error: 34 +ETMFILE equ 35 ; Too many files in directory (список файлов) +EDEPTH equ 36 ; (слишком большая влож. папок или >= 1024 папок) +EUABORT equ 37 ; User abort (операция прервана пользователем) +EERR38 equ 38 ; 38 +EERR39 equ 39 ; 39 +EERR40 equ 40 ; 40 +EERR41 equ 41 ; 41 +EERR42 equ 42 ; 42 +EERR43 equ 43 ; 43 +EERR44 equ 44 ; 44 +EERR45 equ 45 ; 45 +EERR46 equ 46 ; 46 +EERR47 equ 47 ; 47 +EERR48 equ 48 ; 48 +EERR49 equ 49 ; 49 +EERR50 equ 50 ; 50 diff --git a/DOS/KEYB.ASM b/DOS/KEYB.ASM new file mode 100755 index 0000000..6525e79 --- /dev/null +++ b/DOS/KEYB.ASM @@ -0,0 +1,1003 @@ +; Начинается с 0600h. Внутри идет выравнивание на границу 0900h. +; +; Также включает код "Init_DOS". +; + + + + +; раб. ячейки клавы + +T0600: ds 64 ; 40h (не менять размер, идет AND 3Fh) + ; +D0640: db 0 ; тек. адрес конца кольц. буфера? +D0641: db 0 ; адрес начала кольц. буфера? +; флаги клавы +D0642: db 2 + db 0 + db 0 + db 3 + ; +D0646: dw 0 + + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #30. Ожидание нажатия клавиатуры (без эха). +; +; вход: нет +; выход: A=код символа +; D=скен-код +; Е=код символа +; B=биты Ctrl,Alt,Shift +; C=др.служ.клавиши +;///////////////////////////////////////////////////////////////////// +Func_30:ld hl,D0641 + ld a,(D0640) + cp (hl) + jr z,Func_30 ; нет клавиши + call A06FC + ld a,e + and a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #31. Опрос клавиатуры без ожидания. +; +; вход: нет +; выход: A=код символа +; D=скен-код +; Е=код символа +; B=биты Ctrl,Alt,Shift +; C=др.служ.клавиши +; "Z" - нет клавиш +;///////////////////////////////////////////////////////////////////// +Func_31:ld hl,D0641 + ld a,(D0640) + cp (hl) + ret z ; нет клавиши + call A06FC + ld a,e + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #32. Ожидание нажатия клавиатуры (с эхом). +; +; вход: нет +; выход: A=код символа +; D=скен-код +; Е=код символа +; B=биты Ctrl,Alt,Shift +; C=др.служ.клавиши +;///////////////////////////////////////////////////////////////////// +Func_32: + call focus_to_inpline ; вкл. курсор + call Func_31 ; опрос клавы без ожидания + jr z,$-3 + push de + push bc + push af + call cursor_off ; выкл. курсор + pop af + or a ; добавил + call nz,Func_5B ; вывод "a" на экран + pop bc + pop de + ld a,e + and a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #33. Получить состояние клавиатуры. +; Возвращает состояние клавиатуры на данный момент. +; Данные берутся не из буфера клавиатуры (как в остальных функциях), +; а непосредственно из результатов последнего сканирования клавиатуры. +; +; вход: нет +; выход: A=0 - нет символов в буфере +; B=биты Ctrl,Alt,Shift +; C=др.служ.клавиши +;///////////////////////////////////////////////////////////////////// +Func_33:ld hl,D0641 + ld a,(D0640) + cp (hl) + ld bc,(D0642) ; флаги клавы + ld a,0 + ret z ; нет клавиши + dec a + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #37. Опрос буфера клавиатуры. +; Возвращаемые регистры, как и в функции 30h (WAITKEY). +; Информация о нажатии остается в буфере. +; +; вход: нет +; выход: A=код символа +; D=скен-код +; Е=код символа +; B=биты Ctrl,Alt,Shift +; C=др.служ.клавиши +; "Z" - нет символов в буфере +;///////////////////////////////////////////////////////////////////// +Func_37:ld hl,D0641 + ld a,(D0640) + cp (hl) + ret z ; нет клавиши + ld l,(hl) + ld h,T0600 / 256 ; 06h ст. байт адреса + ld e,(hl) + inc l + ld d,(hl) + inc l + ld b,(hl) + inc l + ld c,(hl) + ld a,e + ret + + + +;///////////////////////////////////////////////////////////////////// +; Функция #35. Очистить буфер клавиатуры и выполнить функцию. +; +; вход: B=номер функции 30h, 31h, 32h, 33h +; выход: В зависимости от указанной функции в регистре B. +;///////////////////////////////////////////////////////////////////// +Func_35:ld a,(D0641) ; адрес начала кольц.буфера + ld (D0640),a ; тек. адрес в кольц. буфере + ; + ld a,30h-1 + cp b + jr c,A06D1 + ld a,EINVFNC ; код "неверный номер функции" + scf + ret + ; +A06D1: ld a,35h ; номер функции + cp b + jr nc,A06DA + ld a,EINVFNC ; код "неверный номер функции" + scf + ret + ; +A06DA: ld c,b + rst 10h + ret + + + + +A06DD: ld hl,D0640 + ld a,(D0641) + sub 4 + and 3Fh ; ограничить адрес конца кольц. буфера + cp (hl) + jr z,A0716 ; бип, конец кольц. буфера + ld a,(hl) + inc (hl) ; ячейка D0640 + inc (hl) + inc (hl) + inc (hl) + res 6,(hl) ; значение 40h -> 00h (сбр. конец кольц. буфера?) + ld l,a + ld h,T0600 / 256 ; 06h ст. байт адреса + ld (hl),e + inc l + ld (hl),d + inc l + ld (hl),b + inc l + ld (hl),c + ret + +A06FC: ld hl,D0641 + ld a,(D0640) + cp (hl) + ret z ; нет клавиши + ld a,(hl) + inc (hl) + inc (hl) + inc (hl) + inc (hl) + res 6,(hl) ; значение 40h -> 00h (сбр. конец кольц. буфера?) + ld l,a + ld h,T0600 / 256 ; 06h ст. байт адреса + ld e,(hl) + inc l + ld d,(hl) + inc l + ld b,(hl) + inc l + ld c,(hl) + ret + +; бип +A0716: ex af,af' + bit 0,(ix+3) + jr z,A0728 + exx + ld de,230 ; задержка внутр. цикла + ld hl,50 ; задержка внеш. цикла + call beep ; звук + exx +A0728: ex af,af' + ret + + + + +A072A: set 7,(ix+2) + jr A0740 + +A0730: set 6,(ix+2) ; уст. бит "отжата" + jr A0740 + +A0736: set 5,(ix+2) + jr A0740 + +; сканирование клавы +keyb_scan: + ld ix,D0642 ; флаги клавы +A0740: in a,(19h) ; порт статуса + rra ; 0-bit, очередной байт пришел ? + ret nc ; нет + in a,(18h) + cp 0F0h ; клавиша отжата ? + jr z,A0730 ; да, уст. 6 bit + cp 0E0h ; признак "Upgrade Code" у Антона + jr z,A072A ; уст. 7 bit (расш. скен-код) + cp 0E1h ; Pause + jr z,A0736 ; уст. 5 bit + ; + ld l,a + bit 6,(ix+2) ; отжата клавиша ? + jr nz,A07B3 ; да, на сброс битов регистра "B" (ix+1) + call A0990 + call A0892 ; уст. биты регистра "B" (ix+1) + res 7,(ix+2) ; сбр. бит "расш. скен-код" ? + res 5,(ix+2) ; сбр. бит паузы + ret z ; не сохранять код, биты устанавливались + call A09B4 + ; + ld hl,1C00h ; Caps Lock + and a + sbc hl,de + call z,A07C8 + ld hl,0B800h ; Space + Ctrl, Alt + and a + sbc hl,de + call z,A07D1 ; перекл. бита Rus/Lat + ld hl,5000h ; Ins + and a + sbc hl,de + call z,A07EF + ld hl,4900h ; Num Lock + and a + sbc hl,de + call z,A07F8 ; инв. 3-й бит (бит Num Lock) + ld hl,0C900h ; Pause или Num Lock+80h (Num Lock+Ctrl/Atl/Shift) + and a + sbc hl,de + call z,A0801 + ld hl,4800h ; Scroll Lock + and a + sbc hl,de + call z,A081E ; инв. 2-й бит (бит Scroll Lock) + ld hl,0CF00h ; Del+80h (с Shift) + and a + sbc hl,de + call z,reboot_system ; тест на Ctrl+Alt + ld bc,(D0642) ; флаги клавы + jp A06DD ;## сохр. de,bc в кольц. буфере клавы + ;jp TSR; + ;ret ; не оптимизить + + +A07B3: res 6,(ix+2) ; сбр. бит "клавиша отжата" + call A0990 + call A0837 ; сбр. биты регистра "B" (ix+1) + res 7,(ix+2) ; сбр. бит "расш. скен-код" ? + ld h,0 + ld (D0646),hl + ret + +A07C8: ld a,(ix+0) + xor 1 + ld (ix+0),a + ret + +A07D1: bit 5,(ix+1) ; бит Ctrl ? + ret z ; нет + ld a,(ix+0) + xor 80h ; 7-й бит (1=Rus,0=Lat) + ld (ix+0),a + bit 1,(ix+3) + ret z + exx + ld de,190 ; задержка внутр. цикла + ld hl,20 ; задержка внеш. цикла + call beep ; звук + exx + ret + +A07EF: ld a,(ix+0) + xor 2 ; 1-й бит + ld (ix+0),a + ret + +A07F8: ld a,(ix+0) + xor 8 ; 3-й бит + ld (ix+0),a + ret + +; Pause или Num Lock + Ctrl, Atl, Shift +A0801: bit 5,(ix+1) ; бит Ctrl ? + ret z ; нет +; pop hl ; ?? + ld a,(ix+0) + xor 40h ; 6-й бит + ld (ix+0),a + bit 6,(ix+0) + ret z + ei +A0815: halt + bit 6,(ix+0) + jr nz,A0815 + di + ret + +A081E: ld a,(ix+0) + xor 4 + ld (ix+0),a + ret + + +; клавиша Del +reboot_system: + ;bit 5,(ix+1) ; бит Ctrl + ;ret z + ;bit 4,(ix+1) ; бит Alt + ;ret z + ld c,00110000b ; биты Ctrl+Alt + ld a,(ix+1) + and c + cp c + ret nz + ; софтовый ребут + xor a + ld bc,01FDh + rst 08h + ret + + + +;------------------------------------------------- +; Сбросить биты регистра "B" (ix+1) +;------------------------------------------------- +A0837: ld a,l + cp 37h + jr nz,A084A + res 2,(ix+1) + bit 0,(ix+1) + ret nz + res 4,(ix+1) + ret + ; +A084A: cp 39h + jr nz,A085C + res 0,(ix+1) + bit 2,(ix+1) + ret nz + res 4,(ix+1) + ret + ; +A085C: cp 36h + jr nz,A086E + res 3,(ix+1) + bit 1,(ix+1) + ret nz + res 5,(ix+1) + ret + ; +A086E: cp 3Ah + jr nz,A0880 + res 1,(ix+1) + bit 3,(ix+1) + ret nz + res 5,(ix+1) + ret + ; +A0880: cp 29h + jr nz,A0889 + res 7,(ix+1) ; сбр. бит LShift + ret + ; +A0889: cp 34h + ret nz + res 6,(ix+1) ; сбр. бит RShift + ret + + +;------------------------------------------------- +; Установить биты регистра "B" (ix+1) +;------------------------------------------------- +A0892: ld a,l + cp 37h + jr nz,A08A0 + set 2,(ix+1) + set 4,(ix+1) + ret + ; +A08A0: cp 39h + jr nz,A08AD + set 0,(ix+1) + set 4,(ix+1) + ret + ; +A08AD: cp 36h + jr nz,A08BA + set 3,(ix+1) + set 5,(ix+1) + ret + ; +A08BA: cp 3Ah + jr nz,A08C7 + set 1,(ix+1) + set 5,(ix+1) + ret + ; +A08C7: cp 29h + jr nz,A08D0 + ;-- поставил (фикс глюка PrintScreen) + ; при нажатии PrnScrn, клава выдает двойной код: LShift и PrnScrn + bit 7,(ix+2) ; был расш. скен-код (#E0) ? + jr z,$+4 ; нет (Ctrl,Alt,Shift не нажаты) + xor a ; флаг "Z" (не сохр. код #29 LShift) + ret + ;-- + set 7,(ix+1) ; уст. бит LShift + ret + ; +A08D0: cp 34h + ret nz + set 6,(ix+1) ; уст. бит RShift + ret + + + + +;///////////////////////////////////////////////////////////////////// +; +; Начальная инициализация ДОС +; +;///////////////////////////////////////////////////////////////////// +Init_DOS: + di + call init_keyb_ports ; иниц. LPT-портов для клавы + call A10D1 ; иниц. ?? портов + lpt-портов клавы + ld c,0 ; иниц. мышки + rst 30h + ld a,(mode_screen) ; тек. режим экрана + ld c,81h ; инфа о смене режима (для мышки) + rst 30h + call scan_all_devices ; определить все девайсы в системе + ei + ; уст. вектор на функцию #00 + ld de,Func_00 ; адрес функции "номер версии ДОС" + ld hl,T0200 ; таблица мл. разрядов адресов + ld (hl),e ; сохр. мл.разряд + inc h ; 0300h + ld (hl),d ; сохр. ст.разряд + ; + ld bc,03C2h ; выделить 3 банки памяти + ;ld bc,04C2h ; выделить 4 банки памяти + rst 08h + ld hl,list_dos_pages ; 16 байт, номера банок расширения ДОС + ld c,a ; дескр. блока + ld b,-1 +A00DF: inc b + push bc ; b=номер страницы в блоке + push hl + ld a,c ; дескр. блока + ld c,0C4h ; получить физ. номер стр. блока + rst 08h + pop hl + pop bc + ld (hl),a ; сохр. номер банки + inc hl + jr nc,A00DF + ; + call setup_znak ; настр. знакоген. курсора + ld b,-1 ; иниц. буфера окружения ? + call Func_46 ; системная окружения + jp Func_00 ; функция "номер версии ДОС" + + + + + + ;ds 0900h - $ ; выровнить на границу xx00h +L0900 equ $+100h AND 0FF00h + ds L0900 - $ + + + +; Должно начинаться точно с xx00h! (не стал фиксить (для скорости)). +; Скен-коды клавиш, 144 байта. +A0900: db 0,43h,0,3Fh,3Dh,3Bh,3Ch,46h + db 0,44h,42h,40h,3Eh,0Fh,0,0 + db 0 + db 37h,29h,0 + db 36h,10h,2,0 + db 0,0,2Ah,1Eh,1Dh,11h,3,0 + db 0,2Ch,2Bh,1Fh,12h,5,4,0 + db 0,38h,2Dh,20h,14h,13h,6,0 + db 0,2Fh,2Eh,22h,21h,15h,7,0 + db 0 +;A0939: + db 0 +;A093A: + db 30h,23h,16h,8,9,0,0,31h + db 24h,17h,18h,0Bh,0Ah +;A0947: + db 0,0,32h +;A094A: + db 33h,25h,26h,19h +;A094E: + db 0Ch,0,0,0,27h,0,1Ah,0Dh + db 0,0,1Ch,34h + db 28h,1Bh,0,35h + db 0,0,0,0,0,0,0,0 + db 0Eh,0,0,51h,0,54h,57h,0 + db 0,0,50h,4Fh,52h,55h,56h,58h + db 1,49h,45h,4Dh,53h,4Ch + db 4Bh,59h + db 48h,0,0,0,0,41h,0,0 + db 0,0,0,0,0,0,0,0 + db 0,0 + + + +A0990: bit 7,(ix+2) ; бит "расш. скен-код" ? + jr z,A09B0 + cp 11h ; Alt (левый/правый) + ld l,39h ; RAlt + ret z + cp 14h ; Ctrl (левый/правый) + ld l,3Ah ; RCtrl + ret z + cp 5Ah ; Enter + ld l,4Eh ; enter + ret z + cp 4Ah ; / + ld l,a;4Ah ; / + ret z + cp 7Ch ; "*" в доп.поле, PrintScreen + ld l,47h ; PrintScreen + ret z + ld l,a +A09B0: ld h,A0900 / 256 ; 09h ст. байт адреса + ld l,(hl) ; загрузить скен-код + ret + + +A09B4: ld d,l + ld e,0 + bit 7,(ix+0) + jp nz,A09F6 + ld a,(ix+1) + and 0C0h + jr nz,A09E3 + set 7,d + bit 4,(ix+1) + ret nz + bit 5,(ix+1) + ret nz + ld d,l + ld bc,T0B75 ; Lat-раскладка с вкл. CapsLock + bit 0,(ix+0) + jr nz,A09DE + ld bc,T0AC1 ; нормальная Lat-раскладка +A09DE: ld h,0 + add hl,bc + ld e,(hl) + ret + ; +A09E3: ld bc,T0B1B ; Lat-раскладка с Shift + bit 0,(ix+0) + jr z,A09EF + ld bc,T0BCF ; Lat-раскладка с вкл. CapsLock + Shift +A09EF: ld h,0 + add hl,bc + ld e,(hl) + set 7,d + ret + ; + ; +A09F6: ld a,(ix+1) + and 0C0h + jr nz,A0A1B + set 7,d + bit 4,(ix+1) + ret nz + bit 5,(ix+1) + ret nz + ld d,l + bit 0,(ix+0) + ld bc,T0CDD ; Rus-раскладка с вкл. CapsLock + jr nz,A0A16 + ld bc,T0C29 ; нормальная Rus-раскладка +A0A16: ld h,0 + add hl,bc + ld e,(hl) + ret + ; +A0A1B: ld bc,T0C83 ; Rus-раскладка с Shift + bit 0,(ix+0) + jr z,A0A27 + ld bc,T0D37 ; Rus-раскладка с вкл. CapsLock + Shift +A0A27: ld h,0 + add hl,bc + ld e,(hl) + set 7,d + ret + + + + + + + + + +;///////////////////////////////////////////////////////////////////// +; Функция #36. Управление настройками клавиатуры. +; +; вход: B=номер подфункции (0,1,2) +; выход: В зависимости от указанной функции в регистре B. +;///////////////////////////////////////////////////////////////////// +Func_36:inc b + dec b + jr z,A0A49 ; уст. раскладку клавиатуры + dec b + jr z,A0A3F ; получить состояние звуковых переменных + dec b + jr z,A0A44 ; уст. состояние звуковых переменных + ld a,EUNOPER ; код "невозможная операция" + scf + ret + +;B=1. Получить состояние звуковых переменных +A0A3F: ld a,(D0003) + and a + ret + +;B=2. Установить состояние звуковых переменных +; A=значение переменной +; D0 - сигнал переполнения буфера клавиатуры +; D1 - сигнал переключения на альтернативную раскладку клавиатуры +A0A44: ld (D0003),a + and a + ret + +;B=0. Установить раскладку клавиатуры +; A=номер раскладки +; 0 - normal +; 1 - shift +; 2 - caps lock +; 3 - caps lock + shift +; 4 - normal (альтернативная клав.) +; 5 - shift (альтернативная клав.) +; 6 - caps lock (альтернативная клав.) +; 7 - caps lock + shift (альтернативная клав.) +A0A49: ld bc,T0B1B - T0AC1 ; 90 размер раскладки в Таблице кодов клавиш + bit 7,a + jr nz,A0A87 + ld de,T0AC1 ; нормальная Lat-раскладка + or a + jr z,A0A83 + ld de,T0B1B ; Lat-раскладка с Shift + dec a + jr z,A0A83 + ld de,T0B75 ; Lat-раскладка с вкл. CapsLock + dec a + jr z,A0A83 + ld de,T0BCF ; Lat-раскладка с вкл. CapsLock + Shift + dec a + jr z,A0A83 + ld de,T0C29 ; нормальная Rus-раскладка + dec a + jr z,A0A83 + ld de,T0C83 ; Rus-раскладка с Shift + dec a + jr z,A0A83 + ld de,T0CDD ; Rus-раскладка с вкл. CapsLock + dec a + jr z,A0A83 + ld de,T0D37 ; Rus-раскладка с вкл. CapsLock + Shift + dec a + jr z,A0A83 + xor a ; код + scf + ret + ; +A0A83: ldir + xor a + ret + ; +A0A87: res 7,a + ld de,T0AC1 ; нормальная Lat-раскладка + or a + jr z,A0ABC + ld de,T0B1B ; Lat-раскладка с Shift + dec a + jr z,A0ABC + ld de,T0B75 ; Lat-раскладка с вкл. CapsLock + dec a + jr z,A0ABC + ld de,T0BCF ; Lat-раскладка с вкл. CapsLock + Shift + dec a + jr z,A0ABC + ld de,T0C29 ; нормальная Rus-раскладка + dec a + jr z,A0ABC + ld de,T0C83 ; Rus-раскладка с Shift + dec a + jr z,A0ABC + ld de,T0CDD ; Rus-раскладка с вкл. CapsLock + dec a + jr z,A0ABC + ld de,T0D37 ; Rus-раскладка с вкл. CapsLock + Shift + dec a + jr z,A0ABC + xor a + scf + ret + ; +A0ABC: ex de,hl + ldir + xor a + ret + + +; Таблица кодов клавиш (8 раскладок по 90 байт) +; Нормальная раскладка +T0AC1: db "`",1Bh,"1","2","3","4","5","6","7","8","9","0","-","=",8 + db 9,"q","w","e","r","t","y","u","i","o","p","[","]" + db 0 ; CapsLock + db "a","s","d","f","g","h","j","k","l",";","'",0Dh + db 0 ; Left Shift + db "z","x","c","v","b","n","m",",",".","/" + db 0 ; Right Shift + db '\' + db 0 ; Ctrl + db 0 ; Alt + db 20h ; Space + db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ; доп. поле + db 0 ; NumLock + db "/","*","-","+",0Dh + db 0,0,0,0,0,0,0,0,0,0,0 + ; +; Раскладка с Shift +T0B1B: db "~",1Bh,"!","@","#","$","%","^","&","*","(",")","_","+",8 + db 9,"Q","W","E","R","T","Y","U","I","O","P","{","}" + db 0 ; CapsLock + db "A","S","D","F","G","H","J","K","L",":",'"',0Dh + db 0 ; Left Shift + db "Z","X","C","V","B","N","M","<",">","?" + db 0 ; Right Shift + db "|" + db 0 ; Ctrl + db 0 ; Alt + db 20h ; Space + db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ; доп. поле + db 0 ; NumLock + db "/","*","-","+",0Dh + db 0,0,0,0,0,0,0,0,0,0,0 + ; +; Раскладка с вкл. CapsLock +T0B75: db "`",1Bh,"1","2","3","4","5","6","7","8","9","0","-","=",8 + db 9,"Q","W","E","R","T","Y","U","I","O","P","[","]",0 + db "A","S","D","F","G","H","J","K","L",";","'",0Dh,0 + db "Z","X","C","V","B","N","M",",",".","/",0 + db '\' + db 0 ; Ctrl + db 0 ; Alt + db 20h ; Space + db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ; доп. поле + db 0 ; NumLock + db "/","*","-","+",0Dh + db 0,0,0,0,0,0,0,0,0,0,0 + ; +; Раскладка с вкл. CapsLock + Shift +T0BCF: db "~",1Bh,"!","@","#","$","%","^","&","*","(",")","_","+",8 + db 9,"q","w","e","r","t","y","u","i","o","p","{","}",0 + db "a","s","d","f","g","h","j","k","l",":",'"',0Dh,0 + db "z","x","c","v","b","n","m","<",">","?",0 + db "|" + db 0 ; Ctrl + db 0 ; Alt + db 20h ; Space + db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ; доп. поле + db 0 ; NumLock + db "/","*","-","+",0Dh + db 0,0,0,0,0,0,0,0,0,0,0 + ; +; Нормальная раскладка +T0C29: db "ё",1Bh,"1","2","3","4","5","6","7","8","9","0","-","=",8 + db 9,"й","ц","у","к","е","н","г","ш","щ","з","х","ъ",0 + db "ф","ы","в","а","п","р","о","л","д","ж","э",0Dh,0 + db "я","ч","с","м","и","т","ь","б","ю",".",0 + db '\' + db 0 ; Ctrl + db 0 ; Alt + db 20h ; Space + db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ; доп. поле + db 0 ; NumLock + db "/","*","-","+",0Dh + db 0,0,0,0,0,0,0,0,0,0,0 + ; +; Раскладка с Shift +T0C83: db "Ё",1Bh,"!",'"',"#","$",":",",",".",";","?","%","_","+",8 + db 9,"Й","Ц","У","К","Е","Н","Г","Ш","Щ","З","Х","Ъ",0 + db "Ф","Ы","В","А","П","Р","О","Л","Д","Ж","Э",0Dh,0 + db "Я","Ч","С","М","И","Т","Ь","Б","Ю",",",0 + db "|" + db 0 ; Ctrl + db 0 ; Alt + db 20h ; Space + db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ; доп. поле + db 0 ; NumLock + db "/","*","-","+",0Dh + db 0,0,0,0,0,0,0,0,0,0,0 + ; +; Раскладка с вкл. CapsLock +T0CDD: db "Ё",1Bh,"1","2","3","4","5","6","7","8","9","0","-","=",8 + db 9,"Й","Ц","У","К","Е","Н","Г","Ш","Щ","З","Х","Ъ",0 + db "Ф","Ы","В","А","П","Р","О","Л","Д","Ж","Э",0Dh,0 + db "Я","Ч","С","М","И","Т","Ь","Б","Ю",".",0 + db '\' + db 0 ; Ctrl + db 0 ; Alt + db 20h ; Space + db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ; доп. поле + db 0 ; NumLock + db "/","*","-","+",0Dh + db 0,0,0,0,0,0,0,0,0,0,0 + ; +; Раскладка с вкл. CapsLock + Shift +T0D37: db "ё",1Bh,"!",'"',"#","$",":",",",".",";","?","%","_","+",8 + db 9,"й","ц","у","к","е","н","г","ш","щ","з","х","ъ",0 + db "ф","ы","в","а","п","р","о","л","д","ж","э",0Dh,0 + db "я","ч","с","м","и","т","ь","б","ю",",",0 + db "|" + db 0 ; Ctrl + db 0 ; Alt + db 20h ; Space + db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ; доп. поле + db 0 + db "/","*","-","+",0Dh + db 0,0,0,0,0,0,0,0,0,0,0 + + + + +; Звук. +; вход: hl=задержка внеш. цикла +; de=задержка внутр. цикла +beep: ld a,10h + out (0FEh),a ; порт + ld b,d + ld c,e + dec bc + ld a,b + or c + jr nz,$-3 + ld a,0 + out (0FEh),a ; порт + ld b,d + ld c,e + dec bc + ld a,b + or c + jr nz,$-3 + dec hl + ld a,h + or l + jr nz,beep + ret + + + +;------------------------------------------------- +; Иниц. LPT-портов для клавы +;------------------------------------------------- +init_keyb_ports: + ld a,0 + out (19h),a + ld a,1 + out (19h),a + ld a,0 + out (19h),a + ld a,3 + out (19h),a + ld a,0C1h + out (19h),a + ld a,4 + out (19h),a + ld a,7 + out (19h),a + ld a,5 + out (19h),a + ld a,62h + out (19h),a + ret + + + +;PR: push ix +; push hl +; push de +; push af +; push hl; +; ld c,8Eh +; rst 08h +; ld (_pr+1),de +; ld de,1500h +; ld c,84h +; rst 08h +; pop hl; +; ;ld a,l +; call HEX1 +;_pr: ld de,0 +; ld c,84h +; rst 08h +; call newline +; pop af +; pop de +; pop hl +; pop ix +; ret + +;HEXHL: ld a,h +; push hl +; call HEX1 +; pop hl +; ld a,l +;HEX1: push af +; rra +; rra +; rra +; rra +; call HEX2 +; pop af +;HEX2: and 0Fh +; add a,90h +; daa +; adc a,40h +; daa +;symb: jp Func_5B ; вывод символа на экран + +;newline:ld a,0Ah +; call Func_5B +; ld a,0Dh +; jp Func_5B diff --git a/DOS/MOUSE.ASM b/DOS/MOUSE.ASM new file mode 100755 index 0000000..a3b180e --- /dev/null +++ b/DOS/MOUSE.ASM @@ -0,0 +1,874 @@ +;=========================================================== +; Вектор мышки +;=========================================================== +MOUSE_vector: + bit 7,c + jr nz,A32E3 ; c >=80h + inc c + dec c ; c=0 иниц. мышки + jr z,init_mouse + dec c ; c=1 показать мышку + jr z,show_mouse + dec c ; c=2 скрыть мышку + jp z,hide_mouse + dec c ; c=3 узнать сост. мышки + jp z,get_mouse_status + dec c ; c=4 уст. координаты мышки + jp z,set_mouse_coords + dec c ; c=5 заглушка + jp z,A32DF + dec c ; c=6 заглушка + jr z,A32DF + dec c ; c=7 уст. Y границы перем. мышки + jp z,set_y_limit + dec c ; c=8 уст. X границы перем. мышки + jp z,set_x_limit + dec c ; c=9 загрузить курсор мышки + jp z,A3385 + dec c ; c=0Ah уст. символ/атрибут мышки для текст. режима + jp z,A341F + dec c ; c=0Bh получить курсор мышки + jp z,A33CC + dec c ; c=0Ch заглушка + jr z,A32DF + dec c ; c=0Dh заглушка + jr z,A32DF + dec c ; c=0Eh получить чувствит. мышки + jp z,A342D + dec c ; c=0Fh уст. чувств. мышки + jp z,A3428 +A32DF: ld a,EINVFNC ; код "неверный номер функции" + scf + ret + +; c >= 80h +A32E3: res 7,c + inc c + dec c ; c=80h Обработчик аппаратн. прерывания от мыши + jp z,A374B + dec c ; c=81h инфа для мышки о смене режима экрана + jp z,A3700 + dec c ; c=82h заглушка + jr z,A32F5 + dec c ; c=83h принуд. перерисовка мышки + jp z,A3760 +A32F5: ld a,EINVFNC ; код "неверный номер функции" + scf + ret + + +;----------------------------------------------------------- +; Функция #00. Инициализация драйвера мышки +;----------------------------------------------------------- +init_mouse: + di + ld a,55h + out (10h),a + ld a,2Dh + out (10h),a + ld a,0 + out (1Bh),a + ld a,1 + out (1Bh),a + ld a,0 + out (1Bh),a + ld a,3 + out (1Bh),a + ld a,41h + out (1Bh),a + ld a,4 + out (1Bh),a + ld a,47h + out (1Bh),a + ld a,5 + out (1Bh),a + ld a,0E0h + out (1Bh),a + ei + xor a + ret + + +;----------------------------------------------------------- +; Функция #01. Показать указатель мышки +;----------------------------------------------------------- +show_mouse: + push ix + push hl + push de + ex af,af' + push af + ld hl,(D378C) ; X координата мышки + ld de,(D378E) ; Y координата мышки + di + call A3524 + ld a,true + ld (enable_mouse_cursor),a ; флаг вывода указателя мышки + ei + pop af + ex af,af' + pop de + pop hl + pop ix + xor a + ret + + + +;----------------------------------------------------------- +; Функция #02. Скрыть указатель мышки +;----------------------------------------------------------- +hide_mouse: + push ix + push hl + push de + ex af,af' + push af + di + xor a ; false + ld (enable_mouse_cursor),a ; флаг вывода указателя мышки + call A34D7 + ei + pop af + ex af,af' + pop de + pop hl + pop ix + xor a + ret + + +;----------------------------------------------------------- +; Функция #03. Узнать сотояние мышки +; Возвращает координаты мышки и состояние кнопок +;----------------------------------------------------------- +get_mouse_status: + ld hl,(D378C) ; X координата + ld de,(D378E) ; Y координата + ld a,(D3792) ; 0 bit - левая, 1 bit - правая + and a + ret + + +;----------------------------------------------------------- +; Функция #04. Установить координаты указателя мышки +; Функция перемещает курсор в заданные координаты +; +; вход: hl/de = X/Y координаты +; выход: a = код ошибки, если CF=1 +;----------------------------------------------------------- +set_mouse_coords: + push ix + push hl + push de + ld (D378C),hl ; X координата мышки + ld (D378E),de ; Y координата мышки + ex af,af' + push af + di + call A3772 + ei + pop af + ex af,af' + pop de + pop hl + pop ix + xor a ;? + ret + + + +A3385: push bc + push de + push hl + push ix + ;ld a,l + ;ld (D37A6),a + ;ld a,h + ;ld (D37A7),a + ld (D37A6),hl; ; ширина/высота стрелки мышки + ld c,e + ld b,0 + ld (D379E),bc + ld c,d + ld (D37A0),bc + exx + ld a,(D37A6) ; 10 ширина стрелки мышки + ld c,a + ld b,0 + ld a,(D37A7) ; 14 высота стрелки мышки + ld l,b + ld h,b + add hl,bc + dec a + jr nz,$-2 + push hl + ld bc,257 ;A0101 ; 257 ? + and a + sbc hl,bc + ccf + exx + pop bc + pop hl + ld a,EINVHND ; код "несуществ. дескр. файла" + jr c,A33C7 + ld de,mouse_pointer ; 10x14 массив стрелки мышки + di + ldir + xor a ; код "Ok" +A33C7: pop hl + pop de + pop bc + ei + ret + + +A33CC: push ix + exx + ld a,(D37A6) ; 10 ширина стрелки мышки + ld c,a + ld b,0 + ld a,(D37A7) ; 14 высота стрелки мышки + ld l,b + ld h,b + add hl,bc + dec a + jr nz,$-2 + push hl + ld bc,257 ;A0101 ; 257 ? + and a + sbc hl,bc + ccf + exx + pop bc + pop hl + ld a,EINVHND ; код "несуществ. дескр. файла" + jr c,A340B + ld de,mouse_pointer ; 10x14 массив стрелки мышки + ex de,hl + di + ldir + ;ld a,(D37A6) ;@@ + ;ld l,a + ;ld a,(D37A7) + ;ld h,a + ld hl,(D37A6); ; ширина/высота стрелки мышки + ;ld bc,(D379E) + ;ld e,c + ;ld bc,(D37A0) + ;ld d,c + ld a,(D379E); + ld e,a; + ld a,(D37A0); + ld d,a; + xor a + ;ld c,a + ;ld b,a +A340B: ei + ret + + + +;----------------------------------------------------------- +; Функция #08. Установка гориз. границ перемещения мышки +; +; вход: hl = минимальная +; de = максимальная +;----------------------------------------------------------- +set_x_limit: + ld (D3794),hl + ld (D3796),de + xor a + ret + + + +;----------------------------------------------------------- +; Функция #07. Установка верт. границ перемещения мышки +; +; вход: hl = минимальная +; de = максимальная +;----------------------------------------------------------- +set_y_limit: + ld (D3798),hl + ld (D379A),de + xor a + ret + + + +A341F: ld (D37A2),hl + ld (D37A4),de + xor a + ret + + +A3428: ld (D379C),hl + xor a + ret + + +A342D: ld hl,(D379C) + xor a + ret + + +A3432: ld (A348B+1),hl + ld (A348E+1),de + srl d + rr e + srl d + rr e + srl d + rr e + ld d,e + srl h + rr l + srl h + rr l + srl h + rr l + ld e,l + in a,(89h) + db 0DDh + ld h,a + in a,(0A2h) + db 0DDh + ld l,a + di + ld a,54h ; номер стр. + out (0A2h),a + ld a,d + add a,a + add a,a + ld l,a + ld h,43h ; ст. разряд ? + in a,(0C9h) + rrca + and 80h + or 1 + add a,e + out (89h),a + inc l + ld a,(hl) + ld bc,(D37A2) + and b + xor c + ld (hl),a + inc l + ld a,(hl) + ld bc,(D37A4) + and b + xor c + ld (hl),a + db 0DDh + ld a,l + out (0A2h),a + db 0DDh + ld a,h + out (89h),a + ret + + +A348B: ld hl,0 +A348E: ld de,0 + srl d + rr e + srl d + rr e + srl d + rr e + ld d,e + srl h + rr l + srl h + rr l + srl h + rr l + ld e,l + in a,(89h) + db 0DDh + ld h,a + in a,(0A2h) + db 0DDh + ld l,a + di + ld a,50h + out (0A2h),a + ld a,d + add a,a + add a,a + ld l,a + ld h,43h ; ст. разряд ? + in a,(0C9h) + rrca + and 80h + or 1 + add a,e + out (89h),a + inc l + ld a,(hl) + ld (hl),a + inc l + ld a,(hl) + ld (hl),a + db 0DDh + ld a,l + out (0A2h),a + db 0DDh + ld a,h + out (89h),a + ret + +A34D7: ld a,0 + bit 7,a + jr z,A348B + in a,(0E2h) + ld b,a + in a,(89h) + ld c,a + push bc + ld a,50h + out (0E2h),a +A34E9: ld hl,0 +A34EC: ld de,0 + ld a,e + ex af,af' +A34F1: ld a,0 + and 1 + ld de,LC000 + jr z,A34FD + ld de,LC000+320 +A34FD: add hl,de +A34FE: ld a,0 ; 14 сохр. высота стрелки мышки + db 0DDh + ld h,a + ex af,af' +A3503: ld bc,10 + out (89h),a + ex af,af' + ld (A3510+1),hl + ld d,h + ld e,l + ldir +A3510: ld hl,0 + ex af,af' + inc a + jr z,A351B + db 0DDh + dec h + jr nz,A3503 +A351B: pop bc + ld a,b + out (0E2h),a + ld a,c + out (89h),a + xor a + ret + + +A3524: ld a,(D378B) + ld (A34D7+1),a + bit 7,a + jp z,A3432 + cp 82h ; 130 + jr nz,A3537 + srl h + rr l +A3537: ld ix,mouse_pointer ; 10x14 массив стрелки мышки + ld a,(D37A6) ; 10 ширина стрелки мышки + ld c,a + ld b,0 + ld (D37AA),bc + ld (A3503+1),bc + ld c,b + ld (D37A8),bc + ld a,(D37A7) ; 14 высота стрелки мышки + ld (A34FE+1),a + ld c,a + ld b,0 + ld (D37AC),bc + ld bc,(D37A0) + ld a,e + sub c + ld e,a + jr nc,A357B + neg + ld e,a + ld a,(D37A6) ; 10 ширина стрелки мышки + ld c,a + ld b,0 + ld a,(D37A7) ; 14 высота стрелки мышки + sub e +A3571: add ix,bc + dec e + jr nz,A3571 + ld c,a + ld (D37AC),bc +A357B: ld bc,(D379E) + and a + sbc hl,bc + jr nc,A359A + ld b,h + ld c,l + ld hl,0 + and a + sbc hl,bc + ld (D37A8),hl + ld a,(D37A6) ; 10 ширина стрелки мышки + sub l + ld l,a + ld (D37AA),hl + ld hl,0 +A359A: ld (A34E9+1),hl + ld (A34EC+1),de + push hl + in a,(0E2h) + ld h,a + in a,(89h) + ld l,a + ex (sp),hl + ld a,5Ch ; видео-страница + out (0E2h),a + ld a,e + ex af,af' + in a,(0C9h) + ld (A34F1+1),a + and 1 + ld de,LC000 + jr z,A35BE + ld de,LC000+320 ; начало 2-го экрана ? +A35BE: add hl,de + db 0DDh + ld d,h + db 0DDh + ld e,l + ex de,hl + ld bc,(D37AC) + db 0DDh + ld h,c + ex af,af' +A35CB: ld bc,(D37A8) + add hl,bc + ld bc,(D37AA) + out (89h),a + ex af,af' + ld (A35DD+1),de + ldir +A35DD: ld de,0 + ex af,af' + inc a + jr z,A35E8 + db 0DDh + dec h + jr nz,A35CB +A35E8: pop bc + ld a,b + out (0E2h),a + ld a,c + out (89h),a + xor a + ret + + +A35F1: in a,(1Bh) + rrca + ret nc + in a,(1Ah) + ld l,a + bit 6,a + ccf + ret z + in a,(1Bh) + rrca + jr nc,$-3 + in a,(1Ah) + ld e,a + bit 6,a + ccf + ret nz + in a,(1Bh) + rrca + jr nc,$-3 + in a,(1Ah) + ld d,a + bit 6,a + ccf + ret nz + ld a,e + and 3Fh + ld e,a + ld a,l + and 3 + rrca + rrca + or e + ld e,a + ld a,d + and 3Fh + ld d,a + ld a,l + and 0Ch + rrca + rrca + rrca + rrca + or d + ld d,a + ld a,l + rlca + rlca + rlca + res 6,a + jr nc,$+4 + set 6,a + rlca + rlca + and 3 + ld (D3792),a ; сост. кнопок: 0/1 bits - левая/правая + call A36C3 + ;ld a,e ;@@ + ;ld (D3790),a + ;ld a,d + ;ld (D3791),a + ld (D3790),de + scf + ret + + +A364B: ld hl,(D378C) ; X координата мышки + ld de,(D3790) + ld d,0 + bit 7,e + jr nz,A366F + add hl,de + ld (D378C),hl ; X координата мышки + ex de,hl + ld hl,(D3796) + and a + sbc hl,de + jr nc,A3689 + ld hl,(D3796) + ld (D378C),hl ; X координата мышки + jr A3689 + ; +A366F: ld a,e + neg + ld e,a + and a + sbc hl,de + ld (D378C),hl ; X координата мышки + jr c,A3683 + ld de,(D3794) + sbc hl,de + jr nc,A3689 +A3683: ld hl,(D3794) + ld (D378C),hl ; X координата мышки +A3689: ld hl,(D378E) ; Y координата мышки + ld de,(D3791) + ld d,0 + bit 7,e + jr nz,A36A9 + add hl,de + ld (D378E),hl ; Y координата мышки + ex de,hl + ld hl,(D379A) ; макс. Y граница для указателя + and a + sbc hl,de + ret nc + ld hl,(D379A) ; макс. Y граница для указателя + ld (D378E),hl ; Y координата мышки + ret + ; +A36A9: ld a,e + neg + ld e,a + and a + sbc hl,de + ld (D378E),hl ; Y координата мышки + jr c,A36BC + ld de,(D3798) ; мин. Y граница для указателя + sbc hl,de + ret nc +A36BC: ld hl,(D3798) ; мин. Y граница для указателя + ld (D378E),hl ; Y координата мышки + ret + + +A36C3: ld hl,(D379C) + ld a,l + or l + ret z + dec a + ret z + ld a,e + bit 7,a + ld b,0FFh + jr z,A36D6 + ld b,7Fh + neg +A36D6: inc b + sub l + jr nc,A36D6 + bit 7,b + jr z,A36E4 + ld a,b + res 7,a + neg + ld b,a +A36E4: ld e,b + ld a,d + bit 7,a + ld b,0FFh + jr z,A36F0 + ld b,7Fh + neg +A36F0: inc b + sub h + jr nc,A36F0 + bit 7,b + jr z,A36FE + ld a,b + res 7,a + neg + ld b,a +A36FE: ld d,b + ret + + +A3700: ld (D378B),a + or a + jr z,A3720 + cp 1 + jr z,A3720 + cp 2 ; 40x32x16 текстовый + jr z,A3723 + cp 3 ; 80x32x16 текстовый + jr z,A3737 + bit 7,a + jr z,A3720 + ; граф. режимы экрана + ;res 7,a ;@@ + cp 81h ; 320x256x256 + jr z,A3723 + cp 82h ; 640x256x16 + jr z,A3737 +A3720: xor a + scf + ret + +; 320x256x256 режим +A3723: ld de,319 ; макс. X граница +A3726: ld hl,0 ; мин. X/Y границы + call set_x_limit ; уст. X границу перем. указателя + ld de,255 ; макс. Y граница + jp set_y_limit ; уст. Y границу перем. указателя + +; 640x256x16 режим +A3737: ld de,639 ; макс. X граница + jr A3726 + + + + +;----------------------------------------------------------- +; Функция #80. Обработчик аппаратн. прерывания от мыши +; +; По приходу прерывания от мыши вызывается данная функция +; драйвера. В случае, когда требуется работа подпрограммы +; при запрещенных прерываниях, используйте данную функцию, +; чтобы избежать потери пакетов данных от мыши. +;----------------------------------------------------------- +A374B: in a,(0E2h) + ld b,a + in a,(89h) + ld c,a + push bc + call A3772 + call A3765 + pop bc + ld a,b + out (0E2h),a + ld a,c + out (89h),a + ret + + +A3760: call A3765 + and a + ret + + +A3765: call A35F1 + ret nc + call A364B + ld a,0 + ld (A3776+1),a + ret + + +A3772: db 3Eh ; ld a,.. +enable_mouse_cursor: + db false ; флаг вывода указателя мышки + or a + ret z ; не выводить указатель +A3776: ld a,0 + call A34D7 + ld hl,(D378C) ; X координата мышки + ld de,(D378E) ; Y координата мышки + call A3524 + ld a,-1 + ld (A3776+1),a + ret + + + + + +D378B: db 3 +D378C: dw 160 ; X координата мышки +D378E: dw 128 ; Y координата мышки +D3790: db 0 +D3791: db 0 +D3792: db 0 ; сост. кнопок: 0/1 bits - левая/правая + db 0; ; нужен ? + ; +D3794: dw 0 +D3796: dw 319 +D3798: dw 0 ; мин. Y граница для указателя +D379A: dw 255 ; макс. Y граница для указателя + +D379C: dw 0 +D379E: dw 0 +D37A0: dw 0 + ; +D37A2: dw 0FF00h +D37A4: dw 0FF77h + ; +D37A6: db 10 ; ширина стрелки мышки +D37A7: db 14 ; высота стрелки мышки + ; +D37A8: dw 0 +D37AA: dw 0 +D37AC: dw 0 + + + +; Стрелка мышки. Массив 10x14 байтов + 116 = 256 +mouse_pointer: + db 0,0,-1,-1,-1,-1,-1,-1,-1,-1 ; 1 + db 0,-2,0,-1,-1,-1,-1,-1,-1,-1 ; 2 + db 0,-2,-2,0,-1,-1,-1,-1,-1,-1 ; 3 + db 0,-2,-2,-2,0,-1,-1,-1,-1,-1 ; 4 + db 0,-2,-2,-2,-2,0,-1,-1,-1,-1 ; 5 + db 0,-2,-2,-2,-2,-2,0,-1,-1,-1 ; 6 + db 0,-2,-2,-2,-2,-2,-2,0,-1,-1 ; 7 + db 0,-2,-2,-2,-2,0,0,0,0,-1 ; 8 + db 0,-2,-2,0,-2,0,-1,-1,-1,-1 ; 9 + db 0,-2,0,0,-2,-2,0,-1,-1,-1 ; 10 + db 0,0,-1,-1,0,-2,0,-1,-1,-1 ; 11 + db 0,-1,-1,-1,0,-2,-2,0,-1,-1 ; 12 + db -1,-1,-1,-1,-1,0,0,-1,-1,-1 ; 13 + db -1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; 14 + ; + ds 256-140 ; 116 diff --git a/DOS/README.RUS b/DOS/README.RUS new file mode 100755 index 0000000..b873111 --- /dev/null +++ b/DOS/README.RUS @@ -0,0 +1,22 @@ +Версию ДОС обозвал как 1.61. +Установка: заменить оригинальный файл "system.dos". + + +1. Исправлена фирменная ошибка, при которой происходило зависание +системы (непредсказуемое поведение) при превышении макс. числа +открытых дескрипторов. Однажды, во времена портирования M80.EXE, +из-за данного бага и конечно неудачного расположения звезд на небе, +был снесен весь логический диск "C". + +2. Появилась новая функция: + + Функция #08 (DSS_RESCAN). Пересканировать девайсы системы. + вход: нет + выход: A - номер последнего лог. диска в системе + +Предназначена для создателей RAM-дисков. Для доступа к созданному +RAM-диску не нужно перезагружать компьютер. + +3. В отличии от оригинала, функции 0Ah/0Bh (Create file/New create file) +перед созданием файла проверяют на переполнение таблицу свободных +дескрипторов. diff --git a/DOS/SYSTEM.DOS b/DOS/SYSTEM.DOS new file mode 100755 index 0000000..dd27b47 Binary files /dev/null and b/DOS/SYSTEM.DOS differ diff --git a/DOS/pr.bat b/DOS/pr.bat new file mode 100755 index 0000000..ab47e4d --- /dev/null +++ b/DOS/pr.bat @@ -0,0 +1,12 @@ +@echo off +..\asmplus.exe dos.asm SYSTEM.DOS +if errorlevel 1 goto ERR +echo Ok! +goto END + +:ERR +del system.dos +echo ошибки компиляции... + +:END +del dos.lst diff --git a/DOS/readme.! b/DOS/readme.! new file mode 100755 index 0000000..15647ee --- /dev/null +++ b/DOS/readme.! @@ -0,0 +1 @@ +При создании файла, папки и др. операций с путем (диском) - ДОС меняет текущий путь !!!. diff --git a/DSS/VIDEO.ASM b/DSS/VIDEO.ASM index c5d0136..b228405 100644 --- a/DSS/VIDEO.ASM +++ b/DSS/VIDEO.ASM @@ -25,6 +25,24 @@ PCHARS: INC HL OR A RET Z + + ;!TEST FOR LP_PR_LINE_DIR + ;PUSH HL + ;CALL CURSOR + ;LD (.CHAR),A + ;LD A,(SLOT1) + ;PUSH AF + ;LD A,(SLOT0) + ;LD (SLOT1),A + ;LD HL,.CHAR + #4000 + ;LD BC,0*256 + BIOS.LP_PR_LINE_DIR + ;RST ToBIOS + ;POP AF + ;LD (SLOT1),A + ;POP HL + ;JP .loop + ; + CALL PUTCHAR ;!TEST CR+LF+SCROLL ;CALL CURSOR @@ -33,12 +51,18 @@ PCHARS: ;CALL Z,PUTCHAR.LFF ; JP .loop +;.CHAR: DZ " ",0 + ; PRINT CHAR ; A - CHAR PUTCHAR: - ;CP ' ' - ;JR NC,.CHAR + ;LD B,A + ;CALL CURSOR + ;LD A,B + + ;CP ' ' + ;JR NC,.CHAR CP #0D JR Z,.CR_ CP #0A @@ -49,8 +73,8 @@ PUTCHAR: JR Z,.BK_ CP #07 JR Z,.BELL - ;SCF - ;RET + ;SCF + ;RET .CHAR: LD BC,1*256 + BIOS.LP_PRINT_SYM ;!TEST CR+LF+SCROLL ;JP ToBIOS @@ -60,6 +84,12 @@ PUTCHAR: LD A,D OR E RET NZ + ;LD A,D ; в DE координаты текущего знакоместа + ;XOR E ; Проверяем на координаты #1F:#4F + ;XOR #50 + ;RET NZ ; если другие - то выход + ;LD E,A + ;CALL LOCATE ; .LFF: PUSH HL ;!FIXIT сохранять текущие прерывания ;PUSH DE diff --git a/DSS/build.txt b/DSS/build.txt index 7b27b25..e3e1916 100644 --- a/DSS/build.txt +++ b/DSS/build.txt @@ -1 +1 @@ -173 \ No newline at end of file +187 \ No newline at end of file diff --git a/DSS/defines.inc b/DSS/defines.inc index ad9ea69..045fb07 100644 --- a/DSS/defines.inc +++ b/DSS/defines.inc @@ -11,7 +11,7 @@ DEFINE NeedSafePort_Y 1 DEFINE TABisSPACES 0 DEFINE EnoughtOnly_LF 0 - DEFINE CLASSIC_CURSOR 1 + DEFINE CLASSIC_CURSOR 0 DEFINE SAVE_PATH_MACRO 0 DEFINE MINIMUM_BIOS_VERSION 2*256 + 55 ; version 2.55 ; diff --git a/SHELL/BATCH.ASM b/SHELL/BATCH.ASM new file mode 100644 index 0000000..2781906 --- /dev/null +++ b/SHELL/BATCH.ASM @@ -0,0 +1,463 @@ +; Обработка BAT-файлов +; + +;fhandle +BAT_FM: db 0 ; дескр. bat-файла +;count: db 0 ; число прочит. байт из файла + +; флаг echo-режима +echo_mode: + db true ; 1/0 on/off + +; буфер bat-файла +;T98B9: ds 256 + + + + +;------------------------------------------------- +; Запуск bat-файла +; вход: hl=имя файла +;------------------------------------------------- +A83E8: call BATCH + jp c,A83DD ; ошибка откр. файла (cpp.asm) + ret + + + +; вход: b=число слов "ZERO".."NINE" +MAKE_BATCH_PRM_ARRAY: + dec hl +.loop: inc hl + ld a,(hl) + or a + ret z + cp " " + jr z,.loop + cp 9 ; Tab + jr z,.loop + ex de,hl + ld (hl),e + inc hl + ld (hl),d + inc hl + ex de,hl +.B_FIND_SPACE: + inc hl + ld a,(hl) + cp " "+1 + jr nc,.B_FIND_SPACE + ld (hl),0 + or a + ret z + djnz .loop + ret + + +;------------------------------------------------- +; Загрузка и выполнение BAT-файла +; вход: hl=имя файла +; выход: "CF" - ошибка откр. файла +;------------------------------------------------- +BATCH: push hl ; сохр. имя bat-файла + ld de,work_buffer ; 512 местный буфер + call copy_string ; скопир. строку (с нулем) + ld hl,work_buffer ; 512 местный буфер + ld de,BAT_PRM_ARRAY ; таблица указат. на "ZERO".."NINE" + ld b,BAT_PRM_ARRAY.TOTAL ; число слов "ZERO".."NINE" + call MAKE_BATCH_PRM_ARRAY + jr nz,.B_ALL_P + ld hl,NULL ; ds 2*10 + ex de,hl +.B_CLR_P: + ld (hl),e + inc hl + ld (hl),d + inc hl + djnz .B_CLR_P + ex de,hl +.B_ALL_P: + pop hl ; восст. имя bat-файла + ld a,Dss.Open.R ; на чтение + ld c,Dss.Open ; открыть файл + RST ToDSS + push af ; сохр. код ошибки + call c,restore_disk_path ; восст. тек. диск и путь + ;R10 + CALL Restore_Screen + ;R10 + pop af + ret c + ld (BAT_FM),a ; дескр. bat-файла + ; выполн. команд bat-файла + call NEWLINE + xor a + ret + + +;--------------------------------------------------- +; Выполнение команд BAT-файла +;--------------------------------------------------- +NEWLINE: + ld de,struct_input_line+5 ;!HARDCODE +.ADDBAT: push de + call READBAT ; прочитать 128 байт из файла в "work_buffer1" + pop de + or a ; a=число прочит. байт + jr nz,.BATLINE + ex de,hl + ;ld de,T96AE ;;256 буфер (inline.asm) + ld de,struct_input_line+5 + sbc hl,de + jr z,.exit; ;[x] Vasil, убран баг с незакрытым BAT-файлом + ld a,l + ld (struct_input_line+4),a ; длина строки + call CMDMODE ; тест на bat-команды "rem","pause" +.exit: ld a,(BAT_FM) ; дескр. bat-файла + ld c,Dss.Close ; закрыть файл + RST ToDSS + ret + ; +.BATLINE: + ;ld hl,T99B9 ; откуда, 128 буфер (ccp.asm) "work_buffer1" + ld hl,work_buffer1 +.loop: call MOVWORD ; скопир. work_buffer1 -> struct_input_line+5 + jr c,.ADDBAT + ld a,b + ld (MOVWORD.count),a ; осталось пропарсить прочитанных байтов + push hl + ex de,hl + ;ld de,T96AE ;;256 буфер (inline.asm) + ld de,struct_input_line+5 + ;ld de,work_buffer+256;; + sbc hl,de + ld a,l + ;ld (D96AD),a ;; длина строки (inline.asm) + ld (struct_input_line+4),a ; длина строки + call CMDMODE ; тест на bat-команды "rem","pause" + ;ld de,T96AE ;;256 буфер (inline.asm) + ld de,struct_input_line+5 + ;ld de,work_buffer+256;; + pop hl + jr .loop + + +;------------------------------------------------- +; Чтение данных (hl) -> (de), при необходимости +; подкачка из файла. +; +; вход: hl=откуда +; de=куда +;------------------------------------------------- +MOVWORD: +.count+1: ld a,0 ; (число прочит. байт из файла)/128 + ld b,a +.loop: ld a,(hl) + ld (de),a + cp " " + jr c,.loop2 + inc hl + inc de + djnz .loop + scf + ret + ; прочитать доп. блок из файла +.loop2: ld a,(hl) + cp " " + ret nc + inc hl + djnz .loop2 + push de + call READBAT ; прочитать 128 байт из файла + pop de + ;ld hl,BATBUFF ; 128 буфер (ccp.asm) "work_buffer1" + ld hl,work_buffer1 + ld b,a ; число прочит. байт + or a + jr nz,.loop2 + scf + ret + +; прочитать 128 байт из файла +READBAT: + ;ld hl,T99B9 ; 128 буфер под данные (ccp.asm) "work_buffer1" + ld hl,work_buffer1 + ld de,128 ; сколько + ld a,(BAT_FM) ; дескр. bat-файла + ld c,Dss.Read ; чтение файла + RST ToDSS + ld a,e + ld (MOVWORD.count),a ; (число прочит. байт из файла)/128 + ret + + +; Тест на bat-команды "rem","pause" +CMDMODE: + ;xor a + ;ld (D96A6),a ; (inline.asm) + call EVALCMD ; (batch.asm) + ;ld ix,T96AC ; нужно?? закоментарил (inline.asm) + ;ld hl,T96AE ;;256 буфер (inline.asm) + ld hl,struct_input_line+5 + ;ld hl,work_buffer+256;; + ld a,(hl) + cp "@" ; 40h + jr nz,A8240 + dec hl + ;ld hl,struct_input_line+4;; + dec (hl) + jr z,A825B + ld c,(hl) ; длина строки + inc hl + ld b,0 + ;ld hl,work_buffer+256;; + ld d,h + ld e,l + inc hl + ldir + jr A825B + ; +A8240: ld a,(echo_mode) ; флаг echo-режима + or a + jr z,A825B ; off + ; вывести сист. путь и строку содержимого bat-файла + ;ld de,T96AE ;;256 буфер (inline.asm) + ;ld de,struct_input_line+5 + ;call A95DE ; вывод экран. пути с ">" (inline.asm) + ; вывести экран. путь и введ. команду + ld c,BIOS.LP_GET_PLACE ; узнать полож. курсора + RST ToBIOS + ld (YXpos),de ; Y/X начало ком-строки + ld (cursor_position),de ; Y/X позиция курсора + call print_compath ; вывести путь + новая ширина поля ввода + ld de,(YXpos) ; Y/X начало ком-строки + ld c,Dss.Locate ; уст. полож. курсора + RST ToDSS + ;ld hl,work_buffer+256;; + ld hl,struct_input_line+4 ; длина строки + ld a,(hl) + ld b,a + inc hl ;+5 + push bc + ld c,BIOS.LP_PRINT_LINE2 ; вывод строки без атрибутов + RST ToBIOS + pop bc ; b=длина строки + ld a,(width_inpline) ; ширина поля ввода (76..48) + sub b + ei + ret z ; правый край экрана + jr c,A8250; ; строка больше ширины экрана + ; заполнить строку до конца экрана + dec a ; чтобы не сработал скроллинг экрана ;!FIXIT scroll + ld b,a ; число вывод. символов + ld a," " ; символ + ld c,BIOS.LP_PRINT_SYM ; вывод символа без атрибута + RST ToBIOS + ei + ;!TEST +A8250: call newline + ; + ; + ;ld a,(D96AD) ;; длина строки (inline.asm) + ;ld a,(struct_input_line+4);- + ;or a + ;ret z + ;call newline + ;jr A8264 + ; +A825B: ;ld a,(D96AD) ;; длина строки (inline.asm) + ld a,(struct_input_line+4) + or a + ret z +;A8264: ld hl,T96AE ;;256 буфер (inline.asm) + ;ld hl,struct_input_line+5 + ;dec hl + ; убрать концевые пробелы строки + ld hl,struct_input_line+4 + ld c,(hl) ; hl=длина строки (inline.asm) + ld b,0 + inc hl + ;ld hl,work_buffer+256;; +A826C: ld a,(hl) + cp " " + jr nz,A8276 + inc hl + dec c + jr nz,A826C + ret + ; +A8276: ld d,h + ld e,l + add hl,bc + ld (hl),b ; 0 в конец строки (первого конц. пробела) + sbc hl,bc + ld a,c + ex af,af' + ld a," " + cpir + jr nz,A8286 + inc c +A8286: ex af,af' + sub c + ld c,a ; длина слова или строки ? + ld hl,BATLIST ; команды "pause","rem" + dos-команды + ; de=struct_input_line+5, c=длина строки (без конц. пробелов) + ; выполн. команду или запустить файл + jp A8312 + + + + + + +; должна убрать конц. пробелы и уст. длину строки, если урезалась +EVALCMD: xor a + ld hl,struct_input_line+4 ;!HARDCODE + ld c,(hl) + ld b,a + inc hl + add hl,bc + ld (hl),a ; 0 в конец строки + sbc hl,bc + ld de,work_buffer2 ; 256 буфер + call EVALSTR + ld hl,work_buffer2 ;work_buffer+256 + ld de,struct_input_line+5 ; куда + ld bc,255 +.loop: ld a,(hl) + ldi + inc b + or a + jr nz,.loop + dec b + ld a,b + ld (struct_input_line+4),a ; длина строки (edline.asm) + and a + ret + +; HL - STRING WITH %VAR% +EVALSTR: ld a,(hl) + cp "%" + jr z,.TVARIABLE +.VARL1: ldi + or a + jr nz,EVALSTR + ld bc,0 + ld (.TVAR_PNT),bc + ret + ; +.TVARIABLE: +.TVAR_PNT+1: ld bc,0 + ld a,b + or c + ld a,"%" + ld (.TVAR_PNT),de + jr nz,.TVAR1 + inc hl + ld a,(hl) + cp "9"+1 + jr c,.TVAR0 +.TVAR2: ld a,"%" ; > "9" + dec hl + jp .VARL1 +.TVAR0: cp "0" + jr c,.TVAR2 ; < "0" + ; BATCH PARAM %0, %1, %2 ... + inc hl + push hl + ld (.TVAR_PNT),bc + sub "0" + add a,a + ld c,a + ld hl,BAT_PRM_ARRAY ; таблица указат. на "ZERO".."NINE" + add hl,bc + ld a,(hl) + inc hl + ld h,(hl) + ld l,a + or h + jr z,.NOBTP ; NO BATCH PARM + call copy_string ; скопир. строку (с нулем) + dec de +.NOBTP: pop hl + jp EVALSTR + ; +.TVAR1: push hl + ld h,d + ld l,e + dec hl + and a + sbc hl,bc + jr z,.TNOVAR + ld a,"=" + ld (de),a + inc de + xor a + ld (de),a + ld d,b ; de=буфер значения перем. + ld e,c + ld h,b ; hl=имя перем. + ld l,c + inc hl + ld bc,Dss.Environ.Get*256 + Dss.Environ ; получить перем. окружения + RST ToDSS +.TNOVAR: pop hl + inc hl + ld bc,0 + ld (.TVAR_PNT),bc + jp EVALSTR + + + +; !! Не делать одну команду > 256 символов)) !! +; + ; BAT-команды (не отделять от дос-команд) +BATLIST: DZ 'PAUSE' : DW cmd_pause ;CPAUSE + DZ 'REM' : DW cmd_rem ;CREM + ; + ; DSS-команды +CMDLIST: DZ 'CD' : DW cmd_chdir ;CCHDIR + DZ 'DIR' : DW cmd_dir ;DIR + DZ 'ECHO' : DW cmd_echo ;CECHO + DZ 'ECHO.' : DW cmd_echoLN + DZ 'PATH' : DW cmd_path ;CPATH + DZ 'MD' : DW cmd_mkdir ;CMKDIR + DZ 'REN' : DW cmd_rename ;CRENAM + DZ 'DEL' : DW cmd_del ;CDELET + DZ 'RD' : DW cmd_rmdir ;CRMDIR + DZ 'SET' : DW cmd_set ;CSET + DZ 'TIME' : DW cmd_time ;CTIME + DZ 'DATE' : DW cmd_date ;CDATE + DZ 'VER' : DW cmd_version ;VERS + DZ 'CLS' : DW cmd_cls ;CLS + DZ 'CHDIR' : DW cmd_chdir ;CCHDIR + DZ 'MKDIR' : DW cmd_mkdir ;CMKDIR + DZ 'RENAME' : DW cmd_rename ;CRENAM + DZ 'ERASE' : DW cmd_del ;CDELET + DZ 'RMDIR' : DW cmd_rmdir ;CRMDIR + DZ 'HELP' : DW cmd_help ;HELP + DZ 'VERSION' : DW cmd_version ;VERS + DZ 'EXIT' : DW cmd_exit ;CEXIT + DZ 'REBOOT' : DW cmd_reboot ;REBOOT + DB #00 + + +IZERO DB "ZERO",0 +IONE DB "ONE",0 +ITWO DB "TWO",0 +ITHREE DB "THREE",0 +IFOUR DB "FOUR",0 +IFIVE DB "FIVE",0 +ISIX DB "SIX",0 +ISEVEN DB "SEVEN",0 +IEIGHT DB "EIGHT",0 +ININE DB "NINE",0 + +BAT_PRM_ARRAY: + DW IZERO, IONE, ITWO, ITHREE, IFOUR, IFIVE, ISIX, ISEVEN, IEIGHT, ININE + DW 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; 10 число слов "ZERO".."NINE" +.TOTAL EQU ($-BAT_PRM_ARRAY)/4 + DISPLAY "First compilation test: 10 = ",/D, BAT_PRM_ARRAY.TOTAL + ASSERT BAT_PRM_ARRAY.TOTAL = 10, "BAT_PRM_ARRAY.TOTAL" +NULL: DB 0 +;TVAR_PNT: DW 0 diff --git a/SHELL/Commands/CHDIR.ASM b/SHELL/Commands/CHDIR.ASM new file mode 100644 index 0000000..8fc7750 --- /dev/null +++ b/SHELL/Commands/CHDIR.ASM @@ -0,0 +1,39 @@ +;/////////////////////////////////////////////////// +; +; CD, CHDIR. Смена каталога +; +;/////////////////////////////////////////////////// +cmd_chdir: + ex de,hl + ;ld de,T9186 ; буфер + ld de,work_buffer1; + ld c,Dss.GSwitch ; выделить параметр ком-строки + RST ToDSS + xor a + ;ld hl,T9186 + ld hl,work_buffer1; + cp (hl) + jr nz,A877B + ld (hl),"." ; ".." родит. папка + inc hl + ld (hl),"." + inc hl + ld (hl),0 + dec hl + dec hl +A877B: ld c,Dss.ChDir ; сменить тек. каталог + RST ToDSS + ;call c,print_err_message + jp c,print_err_message ; вывод сообщения +; call newline + jp save_disk_path ; сохр. тек. диск и путь +; ; вывод сист. пути на экран +; ld c,8Eh ; узнать полож. курсора +; RST ToBIOS +; ld (YXpos),de ; Y/X начало ком-строки +; ld (cursor_position),de ; Y/X позиция курсора +; ;call print_compath ; вывести путь + новая ширина поля ввода +; ;ld de,(YXpos) ; Y/X начало ком-строки +; ;ld c,84h ; уст. полож. курсора +; ;RST ToBIOS +; ret diff --git a/SHELL/Commands/CLS.ASM b/SHELL/Commands/CLS.ASM new file mode 100644 index 0000000..9888897 --- /dev/null +++ b/SHELL/Commands/CLS.ASM @@ -0,0 +1,66 @@ +;/////////////////////////////////////////////////// +; +; CLS. Очистить экран +; +; Можно задать один аргумент - цвет экрана. +; Если аргумент не задан, исп. по-умолчанию #07. +;/////////////////////////////////////////////////// +cmd_cls:ex de,hl ; hl=ком-строка + ;ld de,T9186 ; буфер под параметр + ld de,work_buffer1; + push de + ld c,Dss.GSwitch ; выделить параметр ком-строки + RST ToDSS + pop hl + jp nc,invalid_param ; "Invalid parametr" (>1 парам.) + ld b,7 ; атрибут очистки по-умолчанию + ld a,(hl) + or a + jr z,cls_clear + call ascii2byte + jp c,invalid_param ; "Invalid parametr" + and 7 + ld b,a + inc hl + ld a,(hl) + or a + jr z,cls_clear + ld a,b + rlca + rlca + rlca + rlca + ld b,a + ld a,(hl) + call ascii2byte + jp c,invalid_param ; "Invalid parametr" + or b + ld b,a +cls_clear: + ld a,b + ld (color_screen),a ; атрибут + ld de,0 ; Y/X полож. + ld hl,#2050 ; Y/X размер + ld c,BIOS.LP_CLS_WIN ; очистить окно (выводом пробелов) + RST ToBIOS + ; уст. курсор в Home + ld de,0 ; Y/X полож. + ld c,Dss.Locate + RST ToDSS + ret + + +; ascii -> int +ascii2byte: + cp "0" + ret c + cp "9"+1 + jr c,$+10 + and 5Fh + cp "F"+1 + ccf + ret c + sub 7 + sub "0" + or a + ret diff --git a/SHELL/Commands/DATE.ASM b/SHELL/Commands/DATE.ASM new file mode 100644 index 0000000..ebfc58e --- /dev/null +++ b/SHELL/Commands/DATE.ASM @@ -0,0 +1,152 @@ +; Обработчики команд DATE и TIME +; + + +;/////////////////////////////////////////////////// +; +; DATE. Вывод или установка даты +; +;/////////////////////////////////////////////////// +cmd_date: + ex de,hl ; hl=ком-строка + ;ld de,T9186 ; буфер + ld de,work_buffer1; + ld c,Dss.GSwitch ; выделить параметр ком-строки + RST ToDSS + ;ld de,T9186 + ld de,work_buffer1; + ld a,(de) + or a + jr z,cmd_dt1 + call A893C + jp c,invalid_param ; "Invalid parametr" + xor a + cp h + jp nz,invalid_param ; "Invalid parametr" + ld a,31 + cp l + jp c,invalid_param ; "Invalid parametr" + ld b,l + push bc + call A893C + pop bc + jp c,invalid_param ; "Invalid parametr" + xor a + cp h + jp nz,invalid_param ; "Invalid parametr" + ld a,12 + cp l + jp c,invalid_param ; "Invalid parametr" + ld c,l + push bc + call A893C + push hl + ld c,Dss.SysTime + RST ToDSS + pop ix + pop de + ld c,Dss.SetTime + RST ToDSS +cmd_dt1:ld c,Dss.SysTime + RST ToDSS + push ix + push de + ld a,d ; число + ld hl,PRM1 ; куда + call A8913 ; десят. вывод в буфер + ld a,"." + ld (hl),a + inc hl + pop de + ld a,e ; число + call A8913 ; десят. вывод в буфер + ld a,"." + ld (hl),a + inc hl + push hl + pop ix + pop hl + call A8964 + ld de,2 ; индекс "Current date: %1" + jp MESSAGE ; вывести строку + + + + +;/////////////////////////////////////////////////// +; +; TIME. Вывод или установка времени +; +;/////////////////////////////////////////////////// +cmd_time: + ex de,hl + ;ld de,T9186 + ld de,work_buffer1; + ld c,Dss.GSwitch + RST ToDSS + ;ld de,T9186 + ld de,work_buffer1; + ld a,(de) + or a + jr z,cmd_tm1 + call A893C + jp c,invalid_param ; "Invalid parametr" + xor a + cp h + jp nz,invalid_param ; "Invalid parametr" + ld a,23 + cp l + jp c,invalid_param ; "Invalid parametr" + ld b,l + push bc + call A893C + pop bc + jp c,invalid_param ; "Invalid parametr" + xor a + cp h + jp nz,invalid_param ; "Invalid parametr" + ld a,59 + cp l + jp c,invalid_param ; "Invalid parametr" + ld c,l + push bc + call A893C + pop bc + jp c,invalid_param ; "Invalid parametr" + xor a + cp h + jp nz,invalid_param ; "Invalid parametr" + ld a,59 + cp l + jp c,invalid_param ; "Invalid parametr" + push bc + ld a,l + push af + ld c,Dss.SysTime + RST ToDSS + pop bc + pop hl + ld c,Dss.SetTime + RST ToDSS +cmd_tm1:ld c,Dss.SysTime + RST ToDSS + push bc + push hl + ld a,h ; число + ld hl,PRM1 ; куда + call A8913 ; десят. вывод в буфер + ld a,":" + ld (hl),a + inc hl + pop de + ld a,e ; число + call A8913 ; десят. вывод в буфер + ld a,":" + ld (hl),a + inc hl + pop af ; число + call A8913 ; десят. вывод в буфер + xor a + ld (hl),a ; в конец строки + ld de,3 ; индекс "Current time: %1" + jp MESSAGE ; вывести строку diff --git a/SHELL/Commands/DEL.ASM b/SHELL/Commands/DEL.ASM new file mode 100644 index 0000000..320b4cd --- /dev/null +++ b/SHELL/Commands/DEL.ASM @@ -0,0 +1,16 @@ +;/////////////////////////////////////////////////// +; +; DEL, ERASE. Удалить файл +; +;/////////////////////////////////////////////////// +cmd_del:ex de,hl + ;ld de,T9186 + ld de,work_buffer1; + ld c,Dss.GSwitch + RST ToDSS + ;ld hl,T9186 + ld hl,work_buffer1; + ld c,Dss.Delete + RST ToDSS + call c,print_err_message ; вывод сообщения + ret diff --git a/SHELL/Commands/DIR.ASM b/SHELL/Commands/DIR.ASM new file mode 100644 index 0000000..fc0a75b --- /dev/null +++ b/SHELL/Commands/DIR.ASM @@ -0,0 +1,555 @@ +;/////////////////////////////////////////////////// +; +; DIR. Вывод списка файлов и папок +; +;/////////////////////////////////////////////////// +cmd_dir: push de + ld c,Dss.CurDisk ; узнать тек. диск + RST ToDSS + ld (disk+1),a ; номер диска + call read_disk_info ; прочитать метку и серийный номер диска + pop de + ld hl,0 + ld (D88DC),hl + ld (D88DE),hl + ld (D88E0),hl + ex de,hl + ld a,(hl) + or a + jr nz,$+5 ; задана маска имен + ld hl,mask_fname ; "*.*" + ;ld de,T9186 ; буфер + ld de,work_buffer1 ; 80 + ld c,Dss.GSwitch ; выделить параметр ком-строки + RST ToDSS + ;ld hl,T9186 ; имя файла + ;ld de,T9186 ; буфер + ld hl,work_buffer1 ; имя файла + ld de,work_buffer1 ; 80 буфер + ld a,37h ; атрибут (все, кроме метки тома) + ld bc,0*256 + Dss.F_First ; f_first (формат 11) + RST ToDSS + jp c,print_err_message ; вывод сообщения + ; %1 + ;ld a,(system_path) ; буфер полного сист. пути + ;ld (T90F6),a + ;ld a,":" + ;ld (T90F7),a + ;xor a + ;ld (T90F8),a + ld a,(screen_path) ; диск + ld hl,PRM1 + ld (hl),a + inc hl + ld (hl),":" + inc hl + ld (hl),0 + ; %2 + ld hl,serial_string ; строка серийного номера диска + ld de,PRM2 ; куда + call ncopy_string ; скопир. строку (с нулем) + ;call print_sys_path ; вывод сист. пути на экран + ; %3 + ld hl,screen_path ; экран. путь + ld de,PRM3 ; 16 буфер + ;ld a,(hl) + ;ldi ; скопир. строку + ;or a + ;jr nz,$-4 + call copy_string ; скопир. строку (с нулем) + ; + ld de,0 ; индекс "Volume in drive %1 has no label..." + call MESSAGE ; вывести строку + ; цикл вывода списка файлов/папок +A882C: ;ld hl,T9186 ; раб. буфер + ld hl,work_buffer1 ; 80 + ld de,33 + add hl,de + call A88E2 + ;ld ix,T9186 + ld ix,work_buffer1 ; 80 + ld a,(ix+32) ; атрибут тек. записи + and 10h ; папка ? + jr nz,A8866 ; да + ; прибавить размер тек. файла + ld hl,(D88DC) + inc hl + ld (D88DC),hl + ld e,(ix+30) + ld d,(ix+31) + ld hl,(D88E0) + exx + ld e,(ix+28) + ld d,(ix+29) + ld hl,(D88DE) + add hl,de + exx + adc hl,de + exx + ld (D88DE),hl + exx + ld (D88E0),hl +A8866: ;ld de,T9186 ; раб. буфер + ld de,work_buffer1 ; 80 буфер + ld c,Dss.F_Next ; поиск след. + RST ToDSS + jr nc,A882C ; назад в цикл + jr A8872 ; конец списка, на десят. вывод + + +; Десятичный вывод +A8872: ld hl,(D88DC) + ld ix,PRM1 ; буфер + call A8964 + ld hl,(D88DE) ; мл. разряд + exx + ld hl,(D88E0) ; ст. разряд + exx + call A8A8F ; десятичный 32-х разрядный вывод + ld hl,T8B37 ; "0" + ld a,(hl) + cp " " + jr nz,A8892 + ld a,"0" + ld (hl),a +A8892: ld de,T8B46 ; "0 000 000 000" + ld hl,T8B2E ; "0000000000" + ld a,(hl) + ldi + cp " " + jr z,$+4 + ld a,"," ; разд. разрядов + ld (de),a + inc de + ldi + ldi + ld a,(hl) + ldi + cp " " + jr z,$+4 + ld a,"," ; разд. разрядов + ld (de),a + inc de + ldi + ldi + ld a,(hl) + ldi + cp " " + jr z,$+4 + ld a,"," ; разд. разрядов + ld (de),a + inc de + ldi + ldi + ldi + ld hl,T8B46 ; "0 000 000 000" + ld de,PRM2 ; куда + call ncopy_string ; скопир. строку (с нулем), макс.15 симв. + ld de,9 ; индекс " %1 file(s) %2 bytes" + jp MESSAGE ; вывести строку + + + + +; Подготовить строку списка файлов/папок +A88E2: ld bc,8 + ld de,PRM1 ; буфер + ldir + xor a + ld (de),a + ld de,PRM2 ; куда + ldi + ldi + ldi + ld (de),a + ;ld ix,T9186 + ld ix,work_buffer1 + call A89A4 ; вывести в буфер имя файла и его размер (у папки