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 ; вывести в буфер имя файла и его размер (у папки ) + call A89FA ; вывести в буфер дату файла/папки + call A8A19 ; вывести в буфер время файла/папки + ld de,10 ; индекс "%1 %2 %3 %4 %5" + jp MESSAGE ; вывод строки + + + +; Вывести в буфер имя файла и его размер (у папки ) +A89A4: ld a,(ix+32) + ld hl,T8B38 ; " " + and 10h ; папка ? + jr nz,A89F4 ; да + ld l,(ix+28) ; мл. разряд + ld h,(ix+29) + exx + ld l,(ix+30) ; ст. разряд + ld h,(ix+31) + exx + push ix + call A8A8F ; десятичный 32-х разрядный вывод + ld hl,T8B37 + ld a,(hl) + cp " " + jr nz,A89CD + ld a,"0" + ld (hl),a +A89CD: ld de,T8B46 ; "0 000 000 000" + ld hl,T8B2E ; "0000000000" + ldi + ld a," " + ld (de),a + inc de + ldi + ldi + ldi + ld (de),a + inc de + ldi + ldi + ldi + ld (de),a + inc de + ldi + ldi + ldi + ld hl,T8B46 ; "0 000 000 000" + pop ix +A89F4: ld de,PRM3 ; 16 буфер + jp ncopy_string ; скопир. строку (с нулем), макс.15 симв. + + + +; Скопировать в буфер дату файла/папки +A89FA: ld b,(ix+25) + ld c,(ix+24) + ld hl,T8B46 ; "0 000 000 000" + call A8A53 ; вывод в буфер даты + ld (hl),0 + ld hl,T8B46 ; "0 000 000 000" + ld de,PRM4 ; 16 куда + ld a,(hl) + cp "0" + jr nz,$+4 + ld (hl)," " + jp ncopy_string ; скопир. строку (с нулем), макс.15 симв. + + + +; Скопировать в буфер время файла/папки +A8A19: ld b,(ix+22) + ld c,(ix+23) + ld hl,T8B46 ; "0 000 000 000" + call A8A38 ; скопир. в буфер время файла/папки + ld (hl),0 + ld hl,T8B46 ; "0 000 000 000" + ld de,PRM5 ; 80 буфер строки + ld a,(hl) + cp "0" + jr nz,$+4 + ld (hl)," " + jp ncopy_string ; скопир. строку (с нулем), макс.15 симв. + + +; в буфер время файла/папки +A8A38: srl c + rr b + srl c + rr b + srl c + rr b + srl b + srl b + ld a,c + call A8A7E + ld (hl),":" ; раздел. времени + inc hl + ld a,b + jr A8A7E + + +; в буфер дату файла/папки +A8A53: ld a,c + and 1Fh + push bc + call A8A7E + ld (hl),"." ; раздел. даты + inc hl + pop bc + ld a,c + srl b + rla + rla + rla + rla + and 0Fh + call A8A7E + ld (hl),"." ; раздел. даты + inc hl + ld a,b + add a,80 + cp 100 + jr c,A8A7E +A8A75: sub 100 + cp 100 + jr nc,A8A75 +A8A7E: ld c,2Fh + inc c + sub 10 + jr nc,$-3 + add a,10 + add a,"0" + ld (hl),c + inc hl + ld (hl),a + inc hl + ret + + +; Десятичный 32-х разрядный вывод +A8A8F: ld ix,T8B2E ; "0000000000" + exx + ld de,3B9Ah + exx + ld de,0CA00h + call A8B15 ; 1,000,000,000 + exx + ld de,05F5h + exx + ld de,0E100h + call A8B15 ; 100,000,000...999,999,999 + exx + ld de,98h + exx + ld de,9680h + call A8B15 ; 10,000,000...99,999,999 + exx + ld de,0Fh + exx + ld de,4240h + call A8B15 ; 1,000,000...9,999,999 + exx + ld de,1 + exx + ld de,86A0h + call A8B15 ; 100,000...999,999 + exx + ld de,0 + exx + ld de,10000 + call A8B15 ; 10,000...99,999 + exx + ld de,0 + exx + ld de,1000 + call A8B15 ; 1,000...9,999 + exx + ld de,0 + exx + ld de,100 + call A8B15 ; 100..999 + exx + ld de,0 + exx + ld de,10 + call A8B15 ; 10..99 + ld a,l + add a,"0" + ld (ix+0),a + inc ix + ld hl,T8B2E ; "0000000000" + ld de,2030h ; " ","0" +A8B04: ld a,(hl) + cp e + jr nz,A8B0D + ld (hl),d + inc hl + jr A8B04 + ; +A8B0D: ld hl,T8B37 ; "0" + ld a,(hl) + cp d + ret nz + ld (hl),e + ret + + +A8B15: xor a +A8B16: inc a + sbc hl,de + exx + sbc hl,de + exx + jp nc,A8B16 + add hl,de + exx + adc hl,de + exx + dec a + add a,"0" + ld (ix+0),a + inc ix + ret + + + + +D88DC: dw 0 +D88DE: dw 0 +D88E0: dw 0 + + + +T8B2E: db "000000000" +T8B37: db "0" +T8B38: db " ",0 +T8B46: db "0 000 000 000",0 + db 0 + + + + + +;!FIXIT перенести в DSS - FN #04: GET_BPB +; прочитать BPB диска +read_disk_info: +disk: ld a,0 ; сохр. номер диска + ld c,1 ; open device + rst 18h + jr c,get_inf_data_err ;!FIXIT нет обработчика ошибк + ld a,(disk+1) + ld de,work_buffer ; буфер + ld c,4 ; get BPB + rst 18h + push af + ld a,(disk+1) ; номер диска + ld c,2 ; close device + rst 18h + pop af + jr c,get_inf_data_err ;!FIXIT нет обработчика ошибки +; +get_inf_data_err: +; + + ; Серийный номер лог. диска + ld hl,(work_buffer+41) ; ст.часть + ld de,serial_string ; xxxx-xxxx + call hex16 + ld a,"-" + ld (de),a + inc de + ld hl,(work_buffer+39) ; мл.часть + call hex16 + ; + ; Метка диска + ld a,(disk+1) ; номер диска + cp 2 ; меньше "C:" ? + jr nc,get_inf_data1 ; метка в BPB + ; floppy, метка - как запись файла + ld c,Dss.ChDisk ; уст. диск + RST ToDSS + ; уст. корень диска + ld hl,root_path ; "\",0 + ld c,Dss.ChDir + RST ToDSS + ; поиск метки + ld hl,mask_fname ; "*.*" имя метки + ld de,work_buffer1 ; куда + ld a,8 ; атрибут метки тома + ld bc,0*256 + Dss.F_First ; f_first, формат 11 + RST ToDSS + push af + call restore_path ; восст. тек. путь + pop af + jr c,no_volume_label ; метки нет + ld hl,work_buffer1+33 ; начало метки в буфере f_first + jr volume_label + ; +get_inf_data1: ;!FIXIT так там пробелы стоять могут, если метка короче 11 символов + ld hl,work_buffer+53 ; конец метки в BPB + ld a,(hl) + cp " " ; есть метка ? + ld hl,work_buffer+43 ; начало метки в BPB + jr nz,volume_label ; да +;!FIXIT сделать через аргументы %1-%9 +; нет метки +no_volume_label: ;!FIXIT сделать через PRM %4 + ld hl,volume_string1 ; "has no label " + ld de,MSG0.volume_string ; куда + ld bc,14 + ldir + ret +;!FIXIT сделать через аргументы %1-%9 +; есть метка +volume_label: + ex de,hl + ld hl,MSG0.volume_string ; куда + ld (hl),"i" + inc hl + ld (hl),"s" + inc hl + ld (hl)," " + inc hl + ex de,hl + ; скопир. имя метки + ld bc,11 ; макс. длина метки + ld a,(hl) + cp " "+1 + jr nc,$+6 + inc hl + dec c + jr $-7 + ld a,11 + sub c + ldir + ld b,a + or a ; длина метки 11 симв. ? + ret z ; да + ; дополнить хвост. пробелами + ld (de),a + inc de + djnz $-2 + ret + + + + +; Вывод HL в hex-формате +; de=буфер +; hl=число +hex16: ld a,h + call hex8 + ld a,l +; вывод "a" +hex8: push af + rrca + rrca + rrca + rrca + call $+4 + pop af + and 0Fh + add a,90h + daa + adc a,40h + daa + ld (de),a + inc de + ret + + + + +; маска файлов +mask_fname: + db "*.*",0 + +; корень диска +root_path: + db '\',0 + + + +; Серийный номер диска +serial_string: + db "xxxx-xxxx",0 + +volume_string1: ;!FIXIT сделать через PRM + db "has no label " ; 14 diff --git a/SHELL/Commands/ECHO.ASM b/SHELL/Commands/ECHO.ASM new file mode 100644 index 0000000..d86c5b1 --- /dev/null +++ b/SHELL/Commands/ECHO.ASM @@ -0,0 +1,58 @@ +;/////////////////////////////////////////////////// +; +; ECHO. Вывод сообщений на экран +; +;/////////////////////////////////////////////////// +cmd_echo: + ex de,hl + ld a,(hl) ; ком-строка + or a + jr z,A862E ; без аргументов + ex de,hl + ; тест аргументов на "on","off" + push de + ld b,3 ; длина сравнения + ld hl,T8C21 ; "ON",0 + call A874E ; сравнить строки + pop de + ld a,true ; режим "on" + jr z,A864B + push de + ld b,4 ; длина сравнения + ld hl,T8C24 ; "OFF",0 + call A874E ; сравнить строки + pop hl + ld a,false ; режим "off" + jr z,A864B + ; аргументы не "on","off" +A8623: ld c,Dss.PChars + RST ToDSS + jp newline + +; Показать тек. режим эха +A862E: ld a,(echo_mode) ; флаг echo-режима + or a + ld de,7 ; индекс "on" + jr nz,$+5 ; false + ld de,8 ; индекс "off" + call A8BC6 ; найти строку по индексу + ld de,PRM1 ; куда (аргумент %1) + call ncopy_string ; скопир. строку (с нулем), макс.15 симв. + ld de,6 ; индекс "Echo is %1" + jp MESSAGE + ; +A864B: ld (echo_mode),a ; флаг echo-режима + ret + + +;/////////////////////////////////////////////////// +; +; Команда "ECHO." Вставка пустой строки на экран +; +;/////////////////////////////////////////////////// +cmd_echoLN: + ex de,hl + ld a,(hl) ; ком-строка + or a + jp z,newline ; без аргументов + jr A8623 ; вывести аргументы diff --git a/SHELL/Commands/EXIT.ASM b/SHELL/Commands/EXIT.ASM new file mode 100644 index 0000000..2e20b9d --- /dev/null +++ b/SHELL/Commands/EXIT.ASM @@ -0,0 +1,12 @@ +;/////////////////////////////////////////////////// +; +; EXIT. Выход в родительский процесс +; +;/////////////////////////////////////////////////// +cmd_exit: +.TASKX+1: ld a,2 ; уровень текущего шелла + dec a + dec a + ret z ; a=2 (primary шелл) + pop hl ; восст. баланс стека (убрать вызов A82E7 в гл. цикле оболочки) + jp back_to_parent_process ; вернуться в родит. процесс diff --git a/SHELL/Commands/HELP.ASM b/SHELL/Commands/HELP.ASM new file mode 100644 index 0000000..782b68a --- /dev/null +++ b/SHELL/Commands/HELP.ASM @@ -0,0 +1,8 @@ +;/////////////////////////////////////////////////// +; +; HELP. Вывод экрана помощи +; +;/////////////////////////////////////////////////// +cmd_help: + ld de,11 ; индекс "COMMANDS: ..." + jp MESSAGE diff --git a/SHELL/Commands/MKDIR.ASM b/SHELL/Commands/MKDIR.ASM new file mode 100644 index 0000000..f55682a --- /dev/null +++ b/SHELL/Commands/MKDIR.ASM @@ -0,0 +1,17 @@ +;/////////////////////////////////////////////////// +; +; MD, MKDIR. Создать папку +; +;/////////////////////////////////////////////////// +cmd_mkdir: + 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.MkDir ; создать папку + RST ToDSS + call c,print_err_message ; вывод сообщения + ret diff --git a/SHELL/Commands/PATH.ASM b/SHELL/Commands/PATH.ASM new file mode 100644 index 0000000..949cfc5 --- /dev/null +++ b/SHELL/Commands/PATH.ASM @@ -0,0 +1,49 @@ +T858C: db "PATH=",0 ; строка + +;/////////////////////////////////////////////////// +; +; PATH. Установка пути +; +;/////////////////////////////////////////////////// +cmd_path: + ld a,(de) ; ком-строка + or a + jr z,A85B9 ; аргументов не было + ; уст. путь + inc de + cp 9 ; Tab + jr z,cmd_path + cp " "+1 + jr c,cmd_path + dec de + ex de,hl + dec hl + ld (hl),"=" + dec hl + ld (hl),"H" + dec hl + ld (hl),"T" + dec hl + ld (hl),"A" + dec hl + ld (hl),"P" ; начало строки имени + ld bc,Dss.Environ.Set*256 + Dss.Environ ; устан./удалить перем. окружения + RST ToDSS + call c,print_err_message ; вывод сообщения + ret + +; Показать системный путь +A85B9: ;ld de,T9186 ; куда + ld de,work_buffer1; + ld hl,T858C ; имя переменной "PATH=" + ld bc,Dss.Environ.Get*256 + Dss.Environ ; получить переменную окружения + RST ToDSS + jp c,print_err_message ; вывод сообщения + ld hl,T858C ; "PATH=",0 + ld c,Dss.PChars + RST ToDSS + ;ld hl,T9186 ; строка + ld hl,work_buffer1; + ld c,Dss.PChars + RST ToDSS + jp newline diff --git a/SHELL/Commands/PAUSE.ASM b/SHELL/Commands/PAUSE.ASM new file mode 100644 index 0000000..01a0d68 --- /dev/null +++ b/SHELL/Commands/PAUSE.ASM @@ -0,0 +1,11 @@ +;/////////////////////////////////////////////////// +; +; PAUSE. Пауза (в bat-файле) +; +;/////////////////////////////////////////////////// +cmd_pause: + ld de,4 ; индекс "Press any key to continue ..." + call MESSAGE ; вывод строки + ld c,Dss.WaitKey ; ждем нажатия клавиши + RST ToDSS + ret diff --git a/SHELL/Commands/REM.ASM b/SHELL/Commands/REM.ASM new file mode 100644 index 0000000..77fa229 --- /dev/null +++ b/SHELL/Commands/REM.ASM @@ -0,0 +1,6 @@ +;/////////////////////////////////////////////////// +; +; REM. Комментарий (в bat-файле) +; +;/////////////////////////////////////////////////// +cmd_rem:ret diff --git a/SHELL/Commands/REN.ASM b/SHELL/Commands/REN.ASM new file mode 100644 index 0000000..454d88a --- /dev/null +++ b/SHELL/Commands/REN.ASM @@ -0,0 +1,23 @@ +;/////////////////////////////////////////////////// +; +; REN, RENAME. Переименовать файл +; +;/////////////////////////////////////////////////// +cmd_rename: + ex de,hl + ;ld de,T9186 + ld de,work_buffer1; + ld c,Dss.GSwitch + RST ToDSS + ;ld de,T9206 + ld de,work_buffer+256; + ld c,Dss.GSwitch + RST ToDSS + ;ld hl,T9186 + ;ld de,T9206 + ld hl,work_buffer1; + ld de,work_buffer+256; + ld c,Dss.Rename + RST ToDSS + call c,print_err_message ; вывод сообщения + ret diff --git a/SHELL/Commands/RMDIR.ASM b/SHELL/Commands/RMDIR.ASM new file mode 100644 index 0000000..800231a --- /dev/null +++ b/SHELL/Commands/RMDIR.ASM @@ -0,0 +1,17 @@ +;/////////////////////////////////////////////////// +; +; RD, RMDIR. Удалить папку +; +;/////////////////////////////////////////////////// +cmd_rmdir: + 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.RmDir ; удалить папку + RST ToDSS + call c,print_err_message ; вывод сообщения + ret diff --git a/SHELL/Commands/Reboot.asm b/SHELL/Commands/Reboot.asm new file mode 100644 index 0000000..d2a8d66 --- /dev/null +++ b/SHELL/Commands/Reboot.asm @@ -0,0 +1,10 @@ +;R12 +cmd_reboot: DI + LD C,BIOS.FullInit + RST ToBIOS + LD BC,2*256 + BIOS.REINIT + RST ToBIOS + + DI + HALT +;R12 \ No newline at end of file diff --git a/SHELL/Commands/SET.ASM b/SHELL/Commands/SET.ASM new file mode 100644 index 0000000..e388ec9 --- /dev/null +++ b/SHELL/Commands/SET.ASM @@ -0,0 +1,35 @@ +;/////////////////////////////////////////////////// +; +; SET. Установить переменную окружения +; +;/////////////////////////////////////////////////// +cmd_set:ld a,(de) ; ком-строка + or a + jr z,A85EE ; пустая + ; уст. переменную окружения + inc de + cp 9 + jr z,cmd_set + cp " "+1 + jr c,cmd_set + dec de + ex de,hl + ld bc,Dss.Environ.Set*256 + Dss.Environ + RST ToDSS + call c,print_err_message ; вывод сообщения + ret + +; Показать системное окружение +A85EE: ;ld hl,T9186 ; куда + ld hl,work_buffer1; + ld bc,Dss.Environ.Read*256 + Dss.Environ ; получить сист. окружение + RST ToDSS + ;ld hl,T9186 + ld hl,work_buffer1; +A85F8: ld c,Dss.PChars + RST ToDSS + call newline + ld a,(hl) + or a ; конец сист. окружения ? + jr nz,A85F8 ; нет + ret diff --git a/SHELL/Commands/VER.ASM b/SHELL/Commands/VER.ASM new file mode 100644 index 0000000..b779bfd --- /dev/null +++ b/SHELL/Commands/VER.ASM @@ -0,0 +1,84 @@ +;/////////////////////////////////////////////////// +; +; VER, VERSION. Вывод версии ДОС +; +;/////////////////////////////////////////////////// +cmd_version: + LD C,Dss.Version + RST ToDSS + LD L,D + LD H,E + LD DE,PRM1 + CALL .Set_Ver_to_PRM ; set DSS version + ;R13 + LD HL,256*CONSOLE_MODF + CONSOLE_VERS + LD BC,CONSOLE_BUILD + LD DE,PRM2 + CALL .Set_Ver_to_PRM ; set Shell version + ;R13 + LD DE,VERSMSG + JP MESSAGE + ; вход: hl=число, de=буфер +.num_ver: +.num_mod: + ld ix,.tmp1__ + res 7,(ix+0) + jr .decim + + ; вход: hl=число, de=буфер +.num_build: + ld ix,.tmp1__ + res 7,(ix+0) + ld bc,100 ; 100 + call .num16 + +.decim: ld bc,10 ; 10 + call .num16 + ld a,l + add a,"0" + jr .num16_exit + +.tmp1__: BYTE 0 + +.num16: ld a,'0'-1 + and a + inc a + sbc hl,bc + jr nc,$-3 + add hl,bc + cp "0" + jr z,$+6 + set 7,(ix+0) + bit 7,(ix+0) + ret z +.num16_exit: + ld (de),a ; сохр. в буфере + inc de + ret + ; +; Вход: +; L - номер версии (0..9) +; H - номер модификации (0..99) +; BC - номер билда (0..999) +; DE - номер параметра +.Set_Ver_to_PRM: + PUSH BC + PUSH HL + LD H,0 + CALL .num_ver ;decim2 номер версии (0..9) + LD A,'.' + LD (DE),A + INC DE + POP HL + LD L,H + LD H,0 + CALL .num_mod ;decim2 номер модификации (0..99) + POP HL + LD A,'.' + LD (DE),A + INC DE + CALL .num_build ;decim3 номер билда (0..999) + XOR A + LD (DE),A + RET +; diff --git a/SHELL/EDLINE.ASM b/SHELL/EDLINE.ASM new file mode 100644 index 0000000..55b76f6 --- /dev/null +++ b/SHELL/EDLINE.ASM @@ -0,0 +1,1006 @@ +; Расчитана на функцию #32 ДОС с новым курсором. +; + +; Функция строки редактирования. Имеет историю вводимых строк. +; Функция использует для своей работы временный буфер: +; +; work_buffer - этот буфер использует история +; ;work_buffer+256 - возвращается набранная строка +; +; Клавиши: +; Esc - сбросить текущую строку +; Enter - выход из функции (в work_buffer+256 готовая строка) +; Ins - смена режима ввода (вставка/замена) +; , курсор - прокрутка истории +; PageUp - в начало истории +; PageDown - в конец истории +; Ctrl+Del - стереть историю +; +; +; Используется как заготовка для шелла ДОС. Выводит системный путь. +; Макс. длина экран. пути 34 символа (с диском), остальное обрезается. +; + + + + +;true equ 1 +;false equ 0 + +max_screen_path equ 32 ; макс. длина экран. пути (без диска) +max_len_comline equ 254 ; макс. длина ком-строки (больше не делать) +history_size equ 256 ; размер history-буфера + +; события (внутренние) +evNothing equ 0 ; нет событий +evKeyboard equ 1 ; нажата обычная клавиша +evCombKey equ 2 ; нажата комбин. клавиш или курсорные + + + + + + +;=========================================================== +; Строка редактирования +; +; Выход из строки по клавише , +; ;в work_buffer+256 = набранная строка (или пустая) +;=========================================================== +input_line: + ld a,1 + ld (insert_mode),a + ld c,BIOS.LP_GET_PLACE ; узнать полож. курсора + RST ToBIOS + ld e,4 ; X начало + ld (YXpos),de ; Y/X начало ком-строки + ld (cursor_position),de ; Y/X позиция курсора + call clear_inpline ; очистить структуру ~input line~ + call print_compath ; вывести путь + новая ширина поля ввода + jp event_input_line ; на обраб. строки ввода + + + + +;--------------------------------------------------------------- +; Вывод пути в ком-строке на экран + новая ширина поля ввода +;--------------------------------------------------------------- +print_compath: + ; узнать длину сист. пути + ld hl,system_path ; сист. путь + ld e,l + ld d,h + ld bc,max_len_comline ; 254 + xor a + ld (print_compath_flag),a ; сбр. флаг + cpir + dec hl + push hl ; сохр. конец пути + sbc hl,de + ld a,l ; длина строки + cp max_screen_path+1 ; 33 + jr c,print_compath__ + ; длина пути > 32 + ld a,max_screen_path ; 32 + ld (print_compath_flag),a ; уст. флаг +print_compath__: + ld c,a ; полная длина строки + ld b,0 + ex af,af' ; сохр. длину строки + pop hl ; восст. конец пути + ld de,screen_path+2 ; куда + ; скопировать строку + and a + sbc hl,bc ; hl=начало перекачки + ldir +print_compath_flag+1: + ld a,0 ; флаг переполн. строки + or a + jr z,print_compath1__ + ld hl,screen_path+2 + ld (hl),'\' + inc hl + ld a,"." + ld (hl),a + inc hl + ld (hl),a +print_compath1__: + xor a + ld (de),a ; зануление строки + ex af,af' ; восст. длину строки + add a,2 ; + длина "X:" + ld b,a + inc a + ld (YXpos),a ; X начало ком-строки + ld a,width_inpline.MAX-1 ; ширина экрана - 1 + sub b + ld (width_inpline),a ; новая ширина поля ввода (76..48) + push bc + ; очистить экран. строку + ld de,(cursor_position) ; Y/X полож. + ld e,0 + ld hl,#0150 ; Y/X размер + ld a,(color_screen) ; атрибут + ld b,a + ld a," " ; символ очистки + ld c,BIOS.LP_CLS_WIN2 ; очистить окно + RST ToBIOS + pop bc + ; вывести экран. путь + ld hl,screen_path ; экран. путь + ;call print_inpchar ; вывод строки по счетчику + ld c,BIOS.LP_PRINT_LINE2 + RST ToBIOS; + ld a,">" + ld bc,1*256 + BIOS.LP_PRINT_SYM ; символ без атрибута + RST ToBIOS + ;jr print_inpline ; вывод строки ввода + ;------------------------------------------------- + ; Вывод строки ~input line~ на экран + ;------------------------------------------------- +print_inpline: + ld de,(YXpos) ; Y/X начало ком-строки + ld c,Dss.Locate ; уст. курсор + RST ToDSS + ld hl,struct_input_line ; структура буфера ~input line~ + push hl + pop iy + ld a,(iy+3) ;+3 смещ. строки за левый край + add a,l + ld l,a + jr nc,$+3 + inc h + inc hl + inc hl + inc hl + inc hl + inc hl + ld a,(width_inpline) ; ширина поля + ld c,a + ld b,a + push bc + xor a + ld de,work_buffer ; врем. буфер + push de + ld (de),a + inc de + djnz $-2 + ld a,(iy+0) + sub (iy+3) + cp c + jr nc,$+3 + ld c,a + ld a,(iy+4) ; число введ. символов + sub c + jr nc,$+4 + add a,c + ld c,a + pop de + push de + ld a,b + or c + jr z,$+4 + ldir + pop hl + pop bc + ld a,b ; длина строки + or a + ;call nz,print_inpchar ; вывод строки по счетчику + ld c,BIOS.LP_PRINT_LINE2 + call nz,ToBIOS + ld a,(YXpos) ; X начало ком-строки + ld e,(iy+2) ;+2 тек. полож. курсора в строке + add a,e + cp width_inpline.MAX ; ширина экрана + jr c,prne1__ + ld b,width_inpline.MAX-1 + sub b + ld d,a ; "наезд" за правый край + ld a,e + sub d + ld (iy+2),a ;+2 новое полож. курсора + ld a,b +prne1__:ld (cursor_position),a ; X полож. курсора на экране + ret + + +; Вывод строки по счетчику +;print_inpchar: + ;ld a,(hl) + ;inc hl + ;push hl + ;push bc + ;ld bc,0182h + ;RST ToBIOS +; ld c,86h +; RST ToBIOS + ;pop bc + ;pop hl + ;djnz print_inpchar +; ret + + + + +;------------------------------------------------- +; Чтение событий +;------------------------------------------------- +handle_event: + ld de,(cursor_position) + ld c,Dss.Locate + RST ToDSS + ld c,Dss.EchoKey ; опрос клавы + RST ToDSS + ld hl,what ; поле событий + ld a,e + or a + jr z,handle_event_comb + ld (hl),evKeyboard ;+0 событие + inc hl + ld (hl),e ;+1 код клавиши + inc hl + ld (hl),d ;+2 скен-код клавиши + ret +handle_event_comb: + ld (hl),evCombKey ;+0 событие + inc hl + ld (hl),b ;+1 флаги клавы + inc hl + ld (hl),d ;+2 код курс. клавиш + ret + +; поле событий +what: ds 3 + + + + + + +step_scroll equ 1 ; шаг X скроллинга строки + + +;================================================= +; Обработчик событий ~Input Line~ +;================================================= +event_input_line: + call handle_event ; читаем событие + ld hl,event_input_line + push hl + ld iy,struct_input_line ; структура буфера ~input line~ + ld hl,what ; список событий + ld a,(hl) + inc hl + cp evKeyboard + jr z,EvComKeys + cp evCombKey + jp z,EvComComb + ret + +; +Enter: pop hl ; восст. баланс стека (выход из обработчика) + xor a + ;ld (work_buffer+256),a ; задать пустую строку + ld hl,struct_input_line+4 ; число введ. символов + ld e,(hl) + cp e + ret z ; пустая строка + ld c," " ; пробел + ld d,a + add hl,de + ld a,(hl) + cp c + jr nz,ent1__ ; нет конц. пробелов + ld b,e + ; убрать конц. пробелы ком-строки + ld a,(hl) + cp c + jr nz,$+8 + dec hl + dec (iy+4) ; --число введ. символов + djnz $-8 + inc hl + ld (hl),d ; в конец ком-строки + ld a,b + or a + ret z ; были одни пробелы + ld de,struct_input_line+4 ; число введ. символов + ld (de),a ; новое число (для history_adding) +ent1__: call history_adding ; добавить строку в history + ; скопир. строку во врем. буфер +; ld hl,struct_input_line+4 ; откуда +; ld de,work_buffer+254 ; куда +; ld a,(hl) ; скопир. строку (с нулем) +; ldi +; or a +; jr nz,$-4 + ;call clear_input_line ; очистить строку ввода +; ld a,(YXpos+1); ; Y начало ком-строки +; inc a +; cp 32 +; jr c,$+3 +; xor a +; ld (YXpos+1),a; + ; восст. буфер +; ld hl,work_buffer+254 ; откуда +; ld de,struct_input_line+4 ; куда +; ld a,(hl) ; скопир. строку (с нулем) +; ldi +; or a +; jr nz,$-4 + ; уст. историю на посл. пустую строку + ld a,(history_count) ; число строк в истории + ld (history_cur_string),a ; номер тек. строки истории + ret + + +; Событие - обычная клавиша +EvComKeys: + ld a,(hl) ;+1 what + cp #1B ; Esc + jp z,clear_input_line ; очистить строку ввода + cp #0D ; Enter + jr z,Enter + cp 8 ; Backspace + jr z,inpline_work + cp " " + ret c +inpline_work: + ld de,input_line_done + push de + ld hl,struct_input_line ; структура буфера ~input line~ + ex af,af' + res 7,(iy+1) ;+1 флаг ReadyString + ld a,(insert_mode) ; режим ввода: 1-inser, 0-overwrite + and 1 + rrca ; вправо (мл.бит -> перенос) + or (iy+1) + ld (iy+1),a ;+1 флаг ReadyString + ex af,af' + cp 8 ; Backspace + jp z,back_space + ex af,af' + ld a,(iy+4) ; InputSymb + cp (iy+0) ; Max len + jr nz,ILn___ + ld a,(iy+2) + add a,(iy+3) + cp (iy+0) + ;ret nc + JR NC,LastChar_BEEP + bit 7,(iy+1) + ;ret nz + JR NZ,NoMoreChars_BEEP +ILn___: ld a,(iy+4) + sub (iy+3) + sub (iy+2) + jr z,no_insert + dec (iy+4) + bit 7,(iy+1) + jr z,no_insert + inc (iy+4) + ; ввод в середину текста (вставка) + ld c,a + ld b,0 + ld hl,struct_input_line ; структура буфера ~input line~ + ld a,(iy+4) ;+4 число введ. символов + add a,l + ld l,a + jr nc,$+3 + inc h + inc hl + inc hl + inc hl + inc hl + inc hl + ld d,h + ld e,l + dec hl + lddr +no_insert: + ld hl,struct_input_line ; структура буфера ~input line~ + ld a,(iy+2) ; X тек. полож. курсора в строке + add a,(iy+3) + add a,l + ld l,a + jr nc,$+3 + inc h + inc hl + inc hl + inc hl + inc hl + inc hl + ex af,af' + ld (hl),a ; сохр. символ в строке + inc (iy+4) + inc (iy+2) + ld a,(width_inpline) ; ширина поля ввода + cp (iy+2) ; X тек. полож. курсора в пределах строки + jr nz,$+8 + ; курсор за полем + inc (iy+3) ; смещ. строки за левый край + dec (iy+2) ; X тек. полож. курсора в пределах строки + call print_inpline ; вывести строку на экран + pop de ; восст. баланс стека +input_line_done: + ret +LastChar_BEEP: + ;!TODO если символы привысили максимальное число, то на экране + ; в строке остаётся эхо нажатой клавиши, которая не влезла + ; и висит до нажатия очередной клавиши. Исправить. + LD A,7 ;ASCII BELL + LD C,Dss.PutChar + JP ToDSS + +NoMoreChars_BEEP: + ;!TODO если символы привысили максимальное число, то на экране + ; в строке остаётся эхо нажатой клавиши, которая не влезла + ; и висит до нажатия очередной клавиши. Исправить. + LD A,7 ;ASCII BELL + LD C,Dss.PutChar + JP ToDSS + +; Событие - курс. клавиши или комбинации +EvComComb: + ld b,(hl) ;+1 what + inc hl + ld a,(hl) ;+2 what + ld hl,struct_input_line ; структура буфера ~input line~ + ld de,input_line_done ; точка выхода + push de + cp #54 ; курсор влево + jr z,Left + cp #56 ; курсор вправо + jr z,Right + cp #58 ; курсор вверх, пред. строка истории + jp z,history_prev + cp #52 ; курсор вниз, след. строка истории + jp z,history_next + cp #59 ; PageUp, в начало истории + jp z,history_begin + cp #53 ; PageDown, в конец истории + jp z,history_last + cp #4F ; Del, удалить символ в тек. позиции + jp z,Delete + cp #57 ; Home, в начало строки + jp z,Home + cp #51 ; End, в конец строки + jp z,End1 + cp #50 ; Ins, смена режима ввода + jr z,change_insert_mode + bit 5,b ; Ctrl бит + jr z,$+7 + cp #4F+#80 ; Ctrl+Del, очистить историю команд + jp z,clear_history + pop de + ret + +; Смена режима ввода +change_insert_mode: + ld a,(insert_mode) + xor 1 + ld (insert_mode),a + ret + +; Курсор влево +Left: ld a,(iy+2) + dec a + jp p,ComPrint + ld a,(iy+3) ; смещ. строки за левый край + sub step_scroll ; шаг скроллинга + ret c ; курсор в крайнем левом полож. + ld (iy+3),a ; X смещ. строки за левый край (в символах) + ld a,(iy+2) ; X полож. курсора в пределах строки + add a,step_scroll-1 ; шаг скроллинга +ComPrint: + ld (iy+2),a + jp print_inpline ; вывести строку на экран + +; Курсор вправо +Right: ld a,(iy+2) ; X полож. курсора в пределах строки + add a,(iy+3) ; смещ. строки за левый край + cp (iy+4) ; число введ. символов + ret z + ld a,(width_inpline) ; ширина поля ввода + ld b,a + ld a,(iy+2) ; X полож. курсора в пределах строки + inc a + cp b + jr nz,ComPrint + inc (iy+3) ; смещ. строки за левый край + ld a,(iy+2) ; X полож. курсора в пределах строки + sub step_scroll-1 ; шаг скроллинга + jr ComPrint + +; Backspace - удалить символ левее курсора +back_space: + ld a,(iy+2) ; X тек. полож. курсора в строке + or a + jr nz,back_space1 + ld a,(iy+3) ; смещ. строки за левый край + sub step_scroll ; шаг скроллинга + ret c + ld (iy+3),a + inc (iy+2) ;+2 тек. полож. курсора в строке +back_space1: + ld hl,struct_input_line ; структура буфера ~input line~ + ld a,(iy+2) ;+2 X тек. полож. курсора в строке + add a,(iy+3) ;+3 смещ. строки за левый край + add a,l + ld l,a + jr nc,$+3 + inc h + inc hl + inc hl + inc hl + inc hl + inc hl + ld d,h + ld e,l + dec de + ld a,(iy+4) ;+4 число введ. символов + sub (iy+3) ; смещ. строки за левый край + sub (iy+2) ; X полож. курсора в пределах строки + jr z,$+7 ; курсор за концом строки + ld c,a + ld b,0 + ldir ; обновить остаток строки + xor a + ld (de),a ; в конец строки + dec (iy+2) ; X полож. курсора в пределах строки + dec (iy+4) ; число введ. символов + jp print_inpline ; вывести строку на экран + +; Delete - удалить символ в тек. позиции +Delete: ld hl,struct_input_line ; структура буфера ~input line~ + ld a,(iy+2) ; X тек. полож. курсора в строке + inc a + add a,(iy+3) ; смещ. строки за левый край + add a,l + ld l,a + jr nc,$+3 + inc h + inc hl + inc hl + inc hl + inc hl + inc hl + ld d,h + ld e,l + dec de + ld a,(iy+4) ;+4 число введ. символов + sub (iy+3) ; смещ. строки за левый край + sub (iy+2) ; X тек. полож. курсора в строке + ret z ; курсор за концом строки + ld c,a + ld b,0 + ldir ; обновить остаток строки + xor a + ld (de),a ; в конец строки + dec (iy+4) ; число введ. символов + jp print_inpline ; вывести строку на экран + +; Home - в начало строки +Home: ld a,(iy+2) ; X тек. полож. курсора в строке + add a,(iy+3) ; смещ. строки за левый край + ret z + xor a ; X полож. курсора + ld (iy+2),a ; X полож. курсора в пределах строки + ld (iy+3),a ; смещ. строки за левый край + jp ComPrint ; вывести строку на экран + +; End - в конец строки +End1: ld a,(iy+4) ;+4 число введ. символов + sub (iy+3) ;+3 смещ. строки за левый край + cp (iy+2) ;+2 X тек. полож. курсора в строке + ret z + add a,(iy+3) ; смещ. строки за левый край + ld c,a + ld (iy+3),0 ; смещ. строки за левый край + ld a,(width_inpline) ; ширина поля ввода + sub c + jr z,EndLp + jr nc,EndNIL + neg +EndLp: inc (iy+3) ; X смещ. строки за левый край + sub step_scroll ; шаг скроллинга + jr nc,EndLp +EndNIL: ld a,(iy+4) ; число введ. символов + sub (iy+3) ; смещ. строки за левый край + jp ComPrint ; вывести строку на экран + + + + +; Очистить буфер строки +clear_input_line: + call clear_inpline ; очистить структуру ~input line~ + jp print_inpline ; вывести строку на экран + + +; очистить структуру ~input line~ +clear_inpline: + xor a + ld hl,struct_input_line ; структура буфера ~input line~ + ld b,(hl) ;+0 макс. длина строки + inc hl + ld (hl),a ;+1 сбр. флаг ReadyString + inc hl + ld (hl),a ;+2 X тек. полож. курсора в строке + inc hl + ld (hl),a ;+3 смещ. строки за левый край + inc hl + ld (hl),a ;+4 число введ. символов + cp b + ret z + inc hl ;+5 буфер редакт. строки + ld (hl),a + djnz $-2 + ret + + + +; Вставить строку из history-буфера +; вход: de=структура строки: +0=длина строки, +1=строка +put_from_history: + call clear_inpline ; очистить строку ввода + ld a,(de) ;+0 длина строки + ld c,a +put_history_loop: + inc de + ld hl,struct_input_line ; структура буфера ~input line~ + ld a,(iy+2) ; X тек. полож. курсора в строке + add a,(iy+3) + add a,l + ld l,a + jr nc,$+3 + inc h + inc hl + inc hl + inc hl + inc hl + inc hl + ld a,(de) + ld (hl),a + inc (iy+4) ; число введ. символов + inc (iy+2) ; X тек. полож. курсора в строке + ld a,(width_inpline) ; ширина поля ввода + cp (iy+2) ; X тек. полож. курсора в пределах строки + jr nz,$+8 + ; курсор за правым краем поля ввода + inc (iy+3) ; смещ. строки за левый край + dec (iy+2) ; X тек. полож. курсора в пределах строки + dec c + jr nz,put_history_loop + ; вывести строку на экран + jp print_inpline + + + +; Очистить историю команд +clear_history: + call clear_input_line ; очистить строку ~input line~ + xor a + ld (history_count),a ; число строк в history + ld (history_cur_string),a ; номер тек. строки history + ld hl,history_buff ; конец посл. строки + ld (history_end),hl + ret + + + + + + +;======================================================================== +; History Код +;======================================================================== + +history_count: + db 0 ; число строк в истории + ; +history_cur_string: + db 0 ; номер тек. строки истории + ; +history_end: + dw history_buff ; конец послед. строки истории + + + +;------------------------------------------------- +; В начало истории +;------------------------------------------------- +history_begin: + ld a,(history_count) + or a + ret z ; нет строк + xor a + ld (history_cur_string),a + jr history_copy ; перейти на 1-ю строку + +;------------------------------------------------- +; В конец истории +;------------------------------------------------- +history_last: + ld a,(history_count) + or a + ret z ; нет строк + ld (history_cur_string),a ; уст. послед. пустую строку + jp clear_input_line ; вернуть пустую строку + +;------------------------------------------------- +; Следующая строка +;------------------------------------------------- +history_next: + ld a,(history_count) + or a + ret z ; нет строк + dec a + ld b,a + ld hl,history_cur_string + ld a,(hl) + cp b + jr c,$+7 + inc b + ld (hl),b + jp clear_input_line ; вернуть пустую строку + ; + inc a + ld (hl),a + jr history_copy + +;------------------------------------------------- +; Предыдущая строка +;------------------------------------------------- +history_prev: + ld a,(history_count) + or a + ret z ; нет строк + ld b,a + ld hl,history_cur_string + ld a,(hl) + or a + jr z,history_copy ; уперлись в начало истории + cp b + jr c,$+3 + ld a,b + dec a + ld (hl),a +; перейти на строку по ее индексу +history_copy: + call history_index + jp put_from_history ; строку из history в буфер ком-строки + +; вход: а=индекс строки +; выход: de=строка (ее структура из history-буфера) +history_index: + ld b,0 + ld hl,history_buff ; буфер истории + or a ; индекс строки + jr z,hist_index ; 1-я строка истории + ld c,(hl) ; размер строки + inc c + add hl,bc ; на след. строку + dec a + jr nz,$-4 +hist_index: + ex de,hl + ret + + +;----------------------------------------------------------- +; Добавить новую строку в конец буфера истории. +; Если строка не влезает, удаляются самые старые строки до +; тех пор, пока появится достаточно места для новой строки. +;----------------------------------------------------------- +history_adding: + ld de,struct_input_line+4 ; структура строки + call history_compare ; сравнить строки + ret z ; уже есть такая строка + ld bc,(history_end) ; адрес конца посл. строки + ld hl,history_buff+history_size ; адрес конца буфера + and a + sbc hl,bc ; hl=размер своб. места + ld a,(de) ; длина новой строки + inc a + ld c,a + xor a + ld b,a + sbc hl,bc ; умещ. в своб. месте буфера истории ? + jr nc,history_add_ok ; да + ; удалить первую (самую старую) строку из буфера + ;push de + ld de,history_buff ; буфер истории + ld a,(de) ; длина 1-й строки + inc a + ld c,a + xor a + ld b,a + ld hl,(history_end) + sbc hl,bc + ld (history_end),hl ; конец посл. строки + ld l,e ; hl=history_buff + ld h,d + add hl,bc ; начало 2-й строки + push hl + ld hl,history_size ; размер буфера + and a + sbc hl,bc + ld c,l ; размер остатка буфера + ld b,h + pop hl ; начало 2-й строки + ldir + ld hl,history_count + dec (hl) ; --число строк в history + ;pop de ; восст. адрес struct_input_line+4 + jr history_adding + ; +history_add_ok: + ld hl,(history_end) ; адрес конца посл. строки + ex de,hl + ldir + ld (history_end),de ; конец посл. строки + ld hl,history_count + ld a,(hl) + ld (history_cur_string),a ; тек. строка history + inc (hl) ; ++число строк в history + ret + + +; Сравнить строки. Если строки равны, то переместить +; тек. строку в конец истории. +; вход: de=структура строки: +0=длина строки, +1=строка +; выход: Z-есть строка +; NZ-нет строки +history_compare: + ld hl,history_count + ld b,(hl) ; число строк в history + dec b + inc b + jr z,hist_comp_quit ; history-буфер пустой + ex af,af' + xor a ; сбр. индекс сравн. строки + ex af,af' + ld hl,history_buff ; буфер истории +history_comp_loop: + push de + ld (move_cur_str+1),hl ; тек. строка истории + ld c,(hl) ; длина тек. строки history + ld a,(de) ; длина новой строки + inc hl + inc de + cp c + jr z,hist_comp_loop ; строки одинаковой длины + ld a,l + add a,c + ld l,a + ld a,h + adc a,0 + ld h,a + jr hist_comp_next + ; +; сравнить строки +hist_comp_loop: + ld a,(de) + cp (hl) + jr nz,hist_comp_notequal ; строки не равны + inc hl + inc de + dec c + jr nz,hist_comp_loop + ; строки равны + jr move_to_end_history ; найденную строку в конец истории + ; +hist_comp_notequal: + inc hl + dec c + jr nz,$-2 ; до конца строки +hist_comp_next: + pop de + ex af,af' + inc a ; ++индекс сравн. строки + ex af,af' + djnz history_comp_loop +hist_comp_quit: + xor a + dec a ; NZ-флаг + ret + +; переместить тек. строку в конец истории +move_to_end_history: + ld a,(history_count) ; число строк истории + ld c,a + dec c + ex af,af' ; индекс найденной строки + cp c + jr nc,not_move_to_end ; найденная строка уже в конце + ; сохр. строку во врем. буфере +move_cur_str: + ld hl,0 ; тек. строка истории + ld de,work_buffer ; врем. буфер + ld c,(hl) ;+0 длина строки + inc c ; учесть ячейку длины строки + xor a + ld b,a + push bc + push hl + ldir + pop de ; куда (на место старой строки) + pop bc + ; сдвинуть остаток буфера на место сохр. строки + push hl + ld hl,(history_end) ; конец посл. строки истории + and a + sbc hl,de + and a + sbc hl,bc + ld c,l ; величина сдвига + ld b,h + pop hl ; откуда + ldir + ; восст. строку из врем. буфера в конец истории + ld hl,work_buffer ; врем. буфер + ld c,(hl) + inc c + ld b,a + ldir +not_move_to_end: + ld a,(history_count) + dec a + ld (history_cur_string),a ; тек. строка history + pop de + xor a ; Z флаг + ret + + + + + + + +cursor_position: + dw 0 ; Y/X полож. курсора + +width_inpline: +.MAX EQU 80 + db width_inpline.MAX-4 ; тек. ширина поля ввода + +YXpos: dw 0 ; Y/X начало ком-строки + + +; режим ввода +insert_mode: + db 1 ; 01/00 inser/overwrite + + + +; экранный путь +screen_path: + db "A:" + ds max_screen_path+1 ; 32+1 + +; системный путь +system_path: + ;db "\BORLAND\LMDTOOLS\TESTING\PROGRAM\SOURCES\TURBO\PR",0 + ds 256 + + + +; Структура строки ввода ~input line~ +struct_input_line: + db max_len_comline ;+0 254 макс. число ввод. символов + db 0 ;+1 флаг ReadyString + db 0 ;+2 X тек. полож. курсора в пределах строки + db 0 ;+3 X смещ. строки за левый край (в символах) + db 0 ;+4 число введенных символов + ds max_len_comline+1 ;+5 строка ввода + + +; Буфер истории +history_buff: + ds history_size ; 256 + + +; Рабочий буфер +work_buffer: + ds 512 diff --git a/SHELL/ERROR.ASM b/SHELL/ERROR.ASM new file mode 100644 index 0000000..902f4fd --- /dev/null +++ b/SHELL/ERROR.ASM @@ -0,0 +1,309 @@ +;------------------------------------------------- +; Вывод сообщения ошибки по индексу +; вход: a=номер ошибки +;------------------------------------------------- +print_err_message: + ld e,a + ld d,0 + inc de + ld hl,ERR0 ; массив строк + ld bc,ERR0.Size ; размер массива + call A8BCD ; найти строку + call PRINTZ ; формат. вывод строки + call newline + jp newline + + + +; Вывод строки ошибки +;A850D: +invalid_param: + ld de,5 ; индекс "Invalid parametr" + jr MESSAGE + + + +;------------------------------------------------- +; Вывод сообщения ошибки по индексу +; вход: de=индекс строки +;------------------------------------------------- +MESSAGE: + call A8BC6 ; найти строку по индексу + jp PRINTZ ; формат. вывод строки + ;jp A82CC ; узнать и уст. полож. курсора + + +; Найти строку по индексу +; вход: de=индекс строки +; выход: hl=строка +A8BC6: inc de + ld hl,MSG0 ; начало массива строк + ld bc,MSG0.Size ; размер массива +A8BCD: xor a + cpir + ret po + ret nz + ;R11 + XOR A + CP (HL) + JR Z,.no_mess + ; + dec de + ld a,d + or e + jr nz,A8BCD + ret +.no_mess: INC HL + RET + +;[x] исправлен баг с выходом за пределы буфера PRM. Чуть оптимизирована +;----------------------------------------------------------------------; +; Форматированный вывод строки с подстановкой аргументов вместо %1-%9 +; вход: hl=буфер строки +;----------------------------------------------------------------------; +PRINTZ: ld a,(hl) + inc hl + or a + ret z + cp '%' + jr z,.check_PRM +.char: ld c,Dss.PutChar + RST ToDSS + jp PRINTZ +.bad_PRM: + ld a,'%' + jp .char +.check_PRM: + ld a,(hl) + cp '9'+1 + jr nc,.bad_PRM + inc hl + sub '1' + push hl + ;!TEST + ;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 размер отдельного подбуфера + ADD A + ADD A + ADD A + ADD A + LD L,A + LD H,0 + ; + ld bc,PRM1 ; буфер + add hl,bc + ld c,Dss.PChars ; вывод строки + RST ToDSS + pop hl + jp PRINTZ + + + +;!FIXIT перенести к общим буферам как у меня +; буферы аргументов командной строки +PRM1: BLOCK 16,0 ; аргумент %1 +PRM2: BLOCK 16,0 ; аргумент %2 +PRM3: BLOCK 16,0 ; аргумент %3 +PRM4: BLOCK 16,0 ; аргумент %4 +PRM5: BLOCK 16,0 ; аргумент %5 +PRM6: BLOCK 16,0 ; аргумент %6 +PRM7: BLOCK 16,0 ; аргумент %7 +PRM8: BLOCK 16,0 ; аргумент %8 +PRM9: BLOCK 16,0 ; аргумент %9 + + + +;!TODO не забыть заменить цифры на эти метки +DIR1MSG EQU 0 +VERSMSG EQU 1 +DATEMSG EQU 2 +TIMEMSG EQU 3 +PAUSMSG EQU 4 +ILLGMSG EQU 5 +ECHOMSG EQU 6 +ON__MSG EQU 7 +OFF_MSG EQU 8 +DIR2MSG EQU 9 +DIR3MSG EQU 10 +HELPMSG EQU 11 + +MSG0: db 0 +; 0 + db "Volume in drive %1 " +.volume_string: ;!FIXIT сделать через PRM + db "has no label ",0Dh,0Ah ;0 + db "Volume Serial Number is %2",0Dh,0Ah + db 0Dh,0Ah,"Directory of %3",0Dh,0Ah,0Ah,0 +; 1 + db "Estex DSS version %1. Console version %2.",CR,LF,0 ;R13 +; 2 + db "Current date: %1",0Dh,0Ah,0 ;2 + db "Current time: %1",0Dh,0Ah,0 ;3 + db "Press any key to continue . . .",0Dh,0Ah,0Ah,0 ;4 + db "Invalid parametr",0Dh,0Ah,0 ;5 + db "Echo is %1",0Dh,0Ah,0 ;6 + db "on",0 ;7 + db "off",0 ;8 + db " %1 file(s) %2 bytes",0Dh,0Ah,0Ah,0 ;9 +; 10 FILENAME EXT SIZE DATE TIME + db "%1 %2 %3 %4 %5",0Dh,0Ah,0 ;10 +; 11 + DB "COMMANDS:",CR,LF,CR,LF + DB "DIR REN | RENAME PATH HELP ",CR,LF + DB "CD | CHDIR DEL | ERASE SET VER | VERSION ",CR,LF + DB "MD | MKDIR TIME ECHO EXIT ",CR,LF + DB "RD | RMDIR DATE CLS REBOOT ",CR,LF,0 + ;R11 + BYTE 0 + DZ "Unknown command" + ; +.Size EQU $-MSG0 + +/* +MSG0: DB 0 + DB "Volume in drive %1 has no label",CR,LF ; !FIXIT + DB "Volume Serial number is %2",CR,LF + DB "Directory of %3",CR,LF,CR,LF,0 + DB "Estex DSS: Version %1",CR,LF,0 ;R02 + DB "Current date: %1",CR,LF,0 + DB "Current time: %1",CR,LF,0 + DB "Press any key to continue . . .",CR,LF,0 + DB "Invalid parametr",CR,LF,0 + DB "Echo is %1",CR,LF,0 + DB "on",0 + DB "off",0 + DB " %1 file(s) %2 bytes",CR,LF,CR,LF,0 +; FILENAME EXT SIZE DATE TIME + DB "%1 %2 %3 %4 %5",CR,LF,0 + DB "COMMANDS:",CR,LF,CR,LF + DB "DIR REN | RENAME PATH HELP ",CR,LF + DB "CD | CHDIR DEL | ERASE SET VER | VERSION ",CR,LF + DB "MD | MKDIR TIME ECHO EXIT ",CR,LF + DB "RD | RMDIR DATE CLS REBOOT ",CR,LF,0 + ;R11 + BYTE 0 + DZ "Unknown command" + ; +.Size EQU $-MSG0 + +*/ +;----------------------------------------------------------------------- +;!FIXIT функция вызывающая вывод ошибки делает в начале фильтр по номерам и несколько первых отшиваются +ERR0: DB #00 + DZ "Bad command or file name" + DZ "Invalid function" ; 01 - неверный номер функции + DZ "Invalid drive number" ; 02 - неправильный номер устройства + DZ "File not found" ; 03 - файл не обнаружен + DZ "Path not found" ; 04 - неверный путь + DZ "Invalid handle" ; 05 - несуществующий файловый манипулятор + DZ "Too many open files" ; 06 - нет свободного файлового манипулятора + DZ "File already exist" ; 07 - файл существует + DZ "File read only" ; 08 - файл только для чтения + DZ "Root overflow" ; 09 - переполнение ROOT (корневого каталога) + DZ "No free space" ; 10 - нет свободного места на диске + DZ "Directory not empty" ; 11 - каталог не пуст + DZ "Can't delete current directory" ; 12 - неудачная попытка удалить текущий каталог + DZ "Invalid media" ; 13 - неизвестный формат + DZ "Unknown operation" ;R02 ; 14 - невозможная операция + DZ "Directory exist" ; 15 - каталог уже есть + DZ "Invalid filename" ; 16 - неверное имя + DZ "Invalid EXE-file" ; 17 - неправильный EXE-файл + DZ "Not supported EXE-file" ; 18 - не поддерживаемая версия EXE-файла + DZ "Access denied" ; 19 - ресурс не доступен + DZ "Not ready" ; 20 - нет готовности + DZ "Seek error" ; 21 - ошибка позиционирования + DZ "Sector not found" ; 22 - сектор не найден + DZ "CRC error" ; 23 - ошибка CRC + DZ "Write protect" ; 24 - защита записи + DZ "Read error" ; 25 - ошибка чтения + DZ "Write error" ; 26 - ошибка записи + DZ "Drive failure" ; 27 - сбой диска + DZ "Extended error 28" + DZ "Extended error 29" + DZ "Not enough memory" ; 30 - недостаточно памяти + DZ "Invalid memory block" ; 31 - несуществующий блок памяти + DZ "Extended error 32" + DZ "Maximum PATH size exceeded" ; 33 - превышен максимальный размер переменной + DZ "Extended error 34" + DZ "Too many files in directory" ; 35 - слишком много файлов в директории + DZ "Directory nesting too large or number of folders > 1023" ; 36 - слишком большая вложенность каталогов или количество папок > 1023 + DZ "Operation aborted by user" ; 37 - операция прервана пользователем + DZ "Common error" ; 38 - общая ошибка + DZ "Unexpected application termination" ; 39 - unexpected application termination / неожиданное завершение приложения + DZ "40" + DZ "41" + DZ "42" + DZ "43" + DZ "44" + DZ "45" + DZ "46" + DZ "Wrong video mode" ; 48 - неправильный видеорежим + DZ "48" + DZ "49" + DZ "50" + ;R11 + DB 0 ; ограничитель, чтоб при ошибке больше, чем есть сообщений выдавалось общее: + DZ "Unknown error" + ; +.Size EQU $-ERR0 +;----------------------------------------------------------------------- +/* +; Сообщения ошибок ДОС +ERR0: db 0 + db "Bad command or file name",0 ;0 + db "Invalid function",0 ;1 + db "Invalid drive number",0 ;2 + db "File not found",0 ;3 + db "Path not found",0 ;4 + db "Invalid handle",0 ;5 + db "Too many open files",0 ;6 + db "File already exist",0 ;7 + db "File read only",0 ;8 + db "Root overflow",0 ;9 + db "No free space",0 ;10 + db "Directory not empty",0 ;11 + db "Can't delete current directory",0 ;12 + db "Invalid media",0 ;13 + db "Unknown operation",0 ;14 + db "Directory exist",0 ;15 + db "Invalid filename",0 ;16 + db "Invalid EXE-file",0 ;17 + db "Not supported EXE-file",0 ;18 + db "Access denied",0 ;19 + db "Not ready",0 ;20 + db "Seek error",0 ;21 + db "Sector not found",0 ;22 + db "CRC error",0 ;23 + db "Write protect",0 ;24 + db "Read error",0 ;25 + db "Write error",0 ;26 + db "Drive failure",0 ;27 + db "Extended error 28",0 ;28 + db "Extended error 29",0 ;29 + db "Not enough memory",0 ;30 + db "Invalid memory block",0 ;31 + db "Extended error 32",0 ;32 + db "Extended error 33",0 ;33 + db "Extended error 34",0 ;34 + db "Too many files in directory",0 ;35 список файлов + db "36",0 ;36 (слишком большая влож. папок или >= 1024 папок) + db "User abort",0 ;37 User abort (операция прервана пользователем) + db "38",0 ;38 + db "39",0 ;39 + db "40",0 ;40 + db "41",0 ;41 + db "42",0 ;42 + db "43",0 ;43 + db "44",0 ;44 + db "45",0 ;45 + db "46",0 ;46 + db "47",0 ;47 + db "48",0 ;48 + db "49",0 ;49 + db "50",0 ;50 +.Size EQU $-ERR0 +*/ diff --git a/SHELL/README.txt b/SHELL/README.txt new file mode 100644 index 0000000..c4e6a8c --- /dev/null +++ b/SHELL/README.txt @@ -0,0 +1,34 @@ +Сорцы рабочие!. Практически ничего не убирал из них, на случай вылезания +глюков. +Команда DIR выводит теперь метку и серийник дисков. + + +bat-команды: + PAUSE + REM + +дос-команды: + CD,CHDIR + CLS + DATE,TIME + DEL,ERASE + DIR + ECHO,ECHO. + EXIT + HELP + MD,MKDIR + PATH + REN,RENAME + RD,RMDIR + SET + VER,VERSION + + +Перемещение по истории команд: + + Esc - сбросить текущую строку + Ins - смена режима ввода (вставка/замена) + курс. клавиши вверх/вниз - прокрутка истории + PageUp - в начало истории + PageDown - в конец истории + Ctrl+Del - стереть историю diff --git a/SHELL/SHELL.ASM b/SHELL/SHELL.ASM new file mode 100644 index 0000000..43a733f --- /dev/null +++ b/SHELL/SHELL.ASM @@ -0,0 +1,510 @@ +; Последняя редакция: 22.10.2006 +; + + +; - Исправлен фирм. баг, при котором строка в bat-файле, длиннее ширины +; экрана, обрезалась по ширине экрана и остаток строки не выводился. +; - Исправлен фирм. баг, при котором в команде "dir" строка выводимого +; пути имела макс. 15 символов. +; - Пофиксено неверное изменение диска/пути после ошибок выполнения команд. +; - Добавлена команда "ECHO." для вставки пустой строки. +; - Команда DIR выводит метку и серийный номер дисков. +; +; + + + includelua 'Shared_includes/lua/Functions.lua' + include 'shared_includes/constants/bios_equ.inc' + include 'shared_includes/constants/dss_equ.inc' + include 'SHELL/version.inc' + +; +; Program EQU section +;---------------------------------------------------------------------[] +CR EQU 13 +LF EQU 10 +;---------------------------------------------------------------------[] +; + +true equ 1 +false equ 0 + +work_buffer1 equ entry - (256+128) ; 2-й раб. буфер ;!FIXIT перенести в конец +work_buffer2 equ entry - 256 ; 3-й раб. буфер ;!FIXIT перенести в конец + + + + + org 7F00h + + db "EX" ; exe ID + db 45h ; exe тип + db 0 ; exe версия + dw 512 ; 512, мл. смещ. кода + dw 0 ; ст. смещ. кода + dw 0 ; end-beg, первичный загрузчик + dw 0,0,0 ; резерв + dw entry ; адрес загрузки кода + dw shell ; адрес передачи управления + dw 0C000h ; адрес стека + ds 490 ; резерв + + +; Версия/Модификация/Билд шелла +entry: db "0.01.003" ;!FIXIT перенести в конец + +;============================================================== +; Точка входа в Шелл +;============================================================== +shell: + ;!TODO merge: активировать когда буферы будут через структуру, а не нулями + ;LD HL,WORK_BUFFERS + ;LD DE,WORK_BUFFERS+1 + ;LD BC,BUFFERS_STRUCT-1 + ;LD (HL),0 + ;LDIR + ; + + ; сохр. уровень тек. шелла + ld a,(ix-1) + ld (cmd_exit.TASKX),a + push ix + call save_disk_path ; сохр. тек. диск и путь + pop hl ; hl=ix + ; + ; Тест на опции запуска самого шелла + call GET_CMD + ld a,(RUNMODE) ; бит-флаги опций + bit 7,a ; "P" 7-й бит (идет вызов из boot-загрузчика) + jr nz,FPRIMAR + bit 5,a ; "S" 5-й бит (запуск 2-й копии шелла) + ;jp nz,option_s + jr nz,run_shell + bit 4,a ; "C" 4-й бит (выполнить bat-файл) + jr nz,option_c + bit 6,a ; 6-й бит (вводились дополн. параметры) + jr z,back_to_parent_process + ; вводились дополн. параметры + call CMDMODE ; (batch.asm) выполн. команду или запустить файл + call save_disk_path ; узнать и сохр. тек. диск и путь + ; + ; Вернуться в родит. процесс +back_to_parent_process: + ld bc,0*256 + Dss.Exit + RST ToDSS + ret + + + + +;--------------------------------------------------------------- +; Опция "S". Запуск 2-й копии шелла. Без отработки AUTOEXEC.BAT. +; Можно выйти по EXIT. +;--------------------------------------------------------------- +; option_s: +; call cmd_version ; версия ДОС +; jr run_shell + + + +;--------------------------------------------------------------- +; Опция "C". Выполнить BAT-файл. +; После выполнения файла, возвращается в родительский процесс. +;--------------------------------------------------------------- +option_c: + ;ld hl,T96AE ; имя bat-файла, 256 буфер (inline.asm) + ;ld hl,work_buffer+256;; + ld hl,struct_input_line+5 ; имя bat-файла + call BATCH ; обработка bat-файла (batch.asm) + call save_disk_path ; узнать и сохр. тек. диск и путь + jr back_to_parent_process ; вернуться в родит. процесс + + + +;--------------------------------------------------------------- +; Опция "P". Запуск копии шелла. С отработкой AUTOEXEC.BAT. +; С ней идет вызов шелла из boot-загрузчика. +; Можно выйти по EXIT, но не из запущенного boot-загрузчиком. +;--------------------------------------------------------------- +FPRIMAR: + ld c,Dss.CTRLKey ; узнать сост. клавы в данный момент + RST ToDSS + ld hl,autoexec_fname ; имя файла "system.bat" + ld a,b + and #C0 ; нажаты Shift-ы ? + call z,BATCH ; нет, выполнить bat-файл (batch.asm) +;============================================================== +; Запуск копии шелла +;============================================================== +run_shell: + call newline +run_shell_loop: + ;call A82CC ; узнать и уст. полож. курсора + ; вывести тек.сист. путь и войти в строку редактирования + call save_disk_path ; узнать и сохр. тек. диск и путь +run_shell_loop1: + call input_line + call newline ; на новую строку + ld a,(struct_input_line+4) ; число введ. символов + or a + jr z,run_shell_loop1 ; пустая + ; Парсинг и выполнение команд + call A82E7 + jr run_shell_loop ; назад в цикл + + + + + + +; Тест опций шелла +; вход: hl=адрес ком-строки +GET_CMD: + ld e,(hl) ; длина строки + inc hl + ld d,0 + ex de,hl ; hl=длина строки, de=строка + add hl,de + ; убрать концевые пробелы + dec hl + ld a,(hl) + cp " " + jr z,$-4 + inc hl + ld (hl),0 ; в конец ком-строки +.NEXTPRM: + ex de,hl ; hl=тек. адрес в строке +.SKIPSP: + ld a,(hl) + inc hl + cp " " + ret c + jr z,.SKIPSP + dec hl + cp '/' ; опция + jr nz,.PROCESS + ld de,work_buffer1 ; 128 буфер для параметра + ld c,Dss.GSwitch ; выдел. параметр ком-строки + RST ToDSS + push af + ex de,hl + ld hl,work_buffer1 ; 128 буфер для параметра + inc hl + call set_option_flag ; уст. биты флагов + pop af + jr nc,.NEXTPRM + ret +; уст. бит-флаг +.PROCESS: + ld a,(RUNMODE) + set 6,a ; 6-й бит (вводились дополн. параметры) ;!HARDCODE + ld (RUNMODE),a + ; скопир. параметр из ком-строки + ; в буфер строки редактирования + ;copy_to_input_line: + ld iy,struct_input_line ; структура буфера ~input line~ + push hl + call clear_inpline ; обнулить структуру "input line" + pop de ; de=хвост строки +.loop: ld hl,struct_input_line ; структура буфера ~input line~ + ld a,(iy+2) ; X тек. полож. курсора в строке + add a,(iy+3) + add a,l + ld l,a + jr nc,1F + inc h +1: inc hl + inc hl + inc hl + inc hl + inc hl + ld a,(de) ; символ из строки + ld (hl),a + or a + ret z ; конец строки + inc (iy+4) ; число введ. символов + inc (iy+2) ; X тек. полож. курсора в строке + ld a,(width_inpline) ; ширина поля ввода + cp (iy+2) ; X тек. полож. курсора в пределах строки + jr nz,2F + ; курсор за правым краем поля ввода + inc (iy+3) ; смещ. строки за левый край + dec (iy+2) ; X тек. полож. курсора в пределах строки +2: ld a,(de) ; символ из строки + inc de ; продв. поток + cp " " + jr nc,.loop + ret + +; Тест на опции шелла и уст. бит-флагов +; вход: hl=строка опций +set_option_flag: + ld a,(RUNMODE) ; ячейка бит-флагов + ld c,a + ld a,(hl) + cp "a" + jr c,setopt1 + cp "z"+1 + jr nc,$+4 + and 5Fh ; a..z -> A..Z +setopt1: cp "P" ; запуск шелла с отраб. autoexec.bat + jr nz,setopt2 + set 7,c + jr setopt4 + ; +setopt2: cp "S" ; запуск 2-й копии шелла (без отраб. autoexec.bat) + jr nz,setopt3 + set 5,c + jr setopt4 + ; +setopt3:cp "C" ; выполн. bat-файл и вернуться в родит. процесс + ret nz + set 4,c +setopt4: ld a,c + ld (RUNMODE),a + ret + + + + + +;!TODO проверить 4 нижеидущие процедуры когда в DSS будут нормально пути запоминаться +; Сохранить тек. диск и путь +;GETPATH: +save_disk_path: + ; узнать тек. каталог + ld hl,system_path ; 256 буфер сист. пути + ld c,Dss.CurDir + RST ToDSS +save_disk: + ; узнать тек. диск + ld c,Dss.CurDisk + RST ToDSS + add a,"A" + ld (screen_path),a ; 33 строка экранного пути + ret + +; Восстановить тек. диск и путь (после ошибки) +restore_disk_path: + ; уст. тек. диск + ld a,(screen_path) ; 33 строка экранного пути + sub "A" + ld c,Dss.ChDir + RST ToDSS +restore_path: + ; уст. тек. каталог + ld hl,system_path ; 256 буфер сист. пути + ld c,Dss.ChDir + RST ToDSS + ret + + + + +; на новую строку ;!FIXIT сделать через .PChars +newline:ld a,_cc.cr + ld c,Dss.PutChar + RST ToDSS + ld a,_cc.lf + ld c,Dss.PutChar + RST ToDSS + ret + + +; Сравнение строк +; in: de=string1 +; hl=string2 +; b=длина строки +A874E: ld a,(de) + cp "a" + jr c,$+8 + cp "z"+1 + jr nc,$+4 + and 5Fh ; a..z -> A..Z + cp (hl) + ret nz + inc hl + inc de + djnz A874E + ret + + +; Скопир. строку (с нулем), макс. 15 символов +; (hl) -> (de) +ncopy_string: + ld bc,15 ; макс. длина строки + ld a,(hl) + ldi + ret po + or a + jr nz,$-5 + ret + +; Скопир. строку (с нулем) +; (hl) -> (de) +copy_string: + ld a,(hl) + ldi + or a + jr nz,copy_string + ret + + + + + + +; Десятичный вывод в буфер +; вход: a=число +; hl=буфер +A8913: ld c,2Fh + inc c + sub 10 + jr nc,$-3 + add a,10 + add a,"0" + push af + ld a,c + ld (hl),a + inc hl + pop af + ld (hl),a + inc hl + ret + + + +A893C: ld hl,0 +A893F: ld a,(de) + inc de + or a + ret z + cp "." ; раздел. даты + ret z + cp "-" ; раздел. даты + ret z + cp ":" ; раздел. времени + ret z + ld b,h + ld c,l + add hl,hl + add hl,hl + add hl,bc + add hl,hl + call A895A + ret c + add a,l + ld l,a + jr nc,A893F + inc h + jr A893F + + +; char -> int +A895A: cp "0" + ret c + cp "9"+1 + ccf + ret c + sub "0" + ret + + +A8964: ld de,10000 + ld a,0C8h ; ret z + ld (D8996),a + call A898E + ld de,1000 + call A898E + ld de,100 + call A898E + ld de,10 + call A898E + ld a,l + add a,"0" + ;!TEST + ;ld (ix+0),a + ;inc ix + ;ld (ix+0),0 + LD (IX+0),A + LD (IX+1),0 + ; + ret + + +A898E: xor a + inc a + sbc hl,de + jr nc,$-3 + add hl,de + dec a +D8996: ret z + add a,"0" + ld (ix+0),a + inc ix + xor a ; nop + ld (D8996),a + ret + + + + +Restore_Screen: + LD C,Dss.GetVMod + RST ToDSS + AND #80 + RET Z + LD BC,1 * 256 + Dss.SetVMod + LD A,Dss.SetVMod.txt80x32 + JP ToDSS + + + +; цвет экрана шелла +color_screen: + db 07h + + +; Имя файла "autoexec.bat" +autoexec_fname: + db "system.bat",0 + + +; бит-флаги опций самого шелла +RUNMODE: db 0 + + + +; буфер расш. файла +T8C1A: ds 3 + db 0 + +T8C1E: db "BAT" ; расш. bat-файла +T8C21: db "ON",0 +T8C24: db "OFF",0 + + + include "edline.asm" ; строка редактирования + include "batch.asm" ; парсинг bat-файлов + include "shell_exec.asm" ; выполн. введ. команд с консоли + include "error.asm" ; функции вывода сообщений ошибок + ; + include "Commands/exit.asm" ; выход в родит. процесс + include "Commands/pause.asm" ; пауза + include "Commands/rem.asm" ; комментарий + include "Commands/ver.asm" ; вывод версии ДОС + include "Commands/cls.asm" ; очистка экрана + include "Commands/date.asm" ; вывод или установка даты/времени + include "Commands/dir.asm" ; вывод списка директории + include "Commands/chdir.asm" ; смена тек. каталога + include "Commands/mkdir.asm" ; создание каталога + include "Commands/rmdir.asm" ; удаление каталога + include "Commands/del.asm" ; удаление файла + include "Commands/ren.asm" ; переименование файла или каталога + include "Commands/echo.asm" ; эхо-режим + include "Commands/help.asm" ; вывод экрана помощи + include "Commands/path.asm" ; задать сист. путь + include "Commands/set.asm" ; задать переменную окружения + include "Commands/reboot.asm" ; софт ресет + ; +; \ No newline at end of file diff --git a/SHELL/SHELL_EXEC.ASM b/SHELL/SHELL_EXEC.ASM new file mode 100644 index 0000000..de9b2d9 --- /dev/null +++ b/SHELL/SHELL_EXEC.ASM @@ -0,0 +1,193 @@ +; раб. ячейка +D8374: dw 0 + + + +;------------------------------------------------------------- +; Разбор и выполнение введенных команд и имен файлов +;------------------------------------------------------------- +A82E7: call EVALCMD ; (batch.asm) + ld hl,struct_input_line+5 + dec hl + ;ld hl,struct_input_line+4;; + ld c,(hl) ; длина строки + ld b,0 + inc hl ; struct_input_line+5 + ;ld hl,work_buffer+256;; +A82F2: ld a,(hl) + cp " " + jr nz,A82FC + inc hl + dec c + jr nz,A82F2 + ret + ; +A82FC: ld d,h + ld e,l + add hl,bc + ld (hl),0 + sbc hl,bc + ld a,c + ex af,af' + ld a," " + cpir + jr nz,A830C + inc c +A830C: ex af,af' + sub c + ld c,a + ld hl,CMDLIST ; список команд ДОС-а + ; de=struct_input_line+5, c=длина строки +; от bat-отработки +A8312: push bc + push de +A8314: ld a,(de) + cp "a" + jr c,A8321 + cp "z"+1 + jr nc,A8321 + and 5Fh ; a..z -> A..Z +A8321: cp (hl) + jr nz,COMP002 ; не дос-команды + inc hl + inc de + dec c + jr nz,A8314 + xor a + cp (hl) + jr nz,COMP002 + pop bc + pop bc + ld a,(de) + cp " " + jr nz,A8338 + inc de +A8338: inc hl + ld a,(hl) + inc hl + ld h,(hl) + ld l,a + jp (hl) ; на соотв. обработчик дос-команды + +; Не дос-команды. Тест на задание диска и запуск файла +COMP002: xor a + LD C,A + CPIR + inc hl + inc hl + pop de + pop bc + ld a,(hl) + or a + jr nz,A8312 ; назад в цикл, еще не дошли конца списка дос-команд + ld h,d + ld l,e + ; hl=struct_input_line+5 + ld b,(hl) ;+0 1-й символ + inc hl + ld c,(hl) ;+1 2-й символ + inc hl + ld a,(hl) ;+2 3-й символ + or a ; задан диск типа "x:" ? + jr nz,A8376 ; нет, имеем больше 2-х символов + ld a,":" ; постфикс буквы диска + cp c ; 2-й символ + jr nz,A8376 ; задан не диск + ld a,b ; 1-й символ + cp "a" + jr c,A8369 + cp "z"+1 + jr nc,A8369 + and 5Fh ; a..z -> A..Z +A8369: sub "A" ; номер диска + ld c,Dss.ChDisk ; сменить тек. диск + RST ToDSS + jp c,print_err_message ; вывод сообщения + ; тест на существование папки на целевом диске + ld hl,system_path ; буфер сист. пути + ld c,Dss.ChDir ; уст. тек. путь + RST ToDSS + jp nc,save_disk_path ; Ok + ; уст. корень, нет такой папки на новом диске + ld hl,system_path+1 ; буфер сист. пути + ld (hl),0 + dec hl + ld (hl),'\' + ld c,Dss.ChDir ; уст. тек. путь + RST ToDSS + jp c,print_err_message ; вывод сообщения + jp save_disk_path ; Ok + +; задан не диск +A8376: ex de,hl ; восст. адрес начала строки + ld (D8374),hl ; struct_input_line+5 + ld de,T8C1A ; буфер + ld bc,4*256 + Dss.EX_Path ; выделить расш. файла + RST ToDSS + ld hl,(D8374) ; имя файла + jr c,A83D7 ; выполнить exe-файл + bit 1,a ; есть расш. ? + jr z,A839D ; нет + ; есть расш. файла + ld de,T8C1A ; буфер расш. файла + ld hl,T8C1E ; "BAT" + ld b,3 ; длина сравнения + call A874E ; сравнить строки + ld hl,(D8374) + jp z,A83E8 ; выполнить bat-файл (batch.asm) + jr A83D7 ; выполнить exe-файл + +A839D: ld bc,0*256 + Dss.Exec ; загр. и выполнить программу + RST ToDSS + ;R10 + CALL Restore_Screen + ;R10 + ret nc ; Ok + ld hl,(D8374) + cp 3 ; код ошибки "файл не обнаружен" + jr nz,A83DD + push hl + ;ld a,(D96AD) ;; длина строки (inline.asm) + ld a,(struct_input_line+4) ; длина строки + ld b,a +A83AF: ld a,(hl) + cp " "+1 + jr c,A83B7 + inc hl + djnz A83AF +A83B7: ld e,b + ld d,0 + add hl,de + push hl + ld e,4 + add hl,de + pop de + ex de,hl + ld c,b + ld b,0 + inc c + lddr + inc hl + ld (hl),"." + inc hl + ld (hl),"B" + inc hl + ld (hl),"A" + inc hl + ld (hl),"T" + pop hl + jp A83E8 ; выполнить bat-файл (batch.asm) + + +; Выполнить exe-файл +; hl=имя файла +A83D7: ld bc,0*256 + Dss.Exec ; загрузить программу, выполнить файл + RST ToDSS + ;R10 + CALL Restore_Screen + ;R10 + ret nc +A83DD: cp DSS_Error.sys.INVALID_HANDLE ; код ошибки "нет дескриптора" + jp nc,print_err_message ; вывод сообщения + xor a ; индекс "Bad command or file name" + jp print_err_message diff --git a/SHELL/build.txt b/SHELL/build.txt new file mode 100644 index 0000000..7c6ba0f --- /dev/null +++ b/SHELL/build.txt @@ -0,0 +1 @@ +55 \ No newline at end of file diff --git a/SHELL/version.inc b/SHELL/version.inc new file mode 100644 index 0000000..d78a3bc --- /dev/null +++ b/SHELL/version.inc @@ -0,0 +1,22 @@ +;------------------[ Достаём текущую дату и BUILD++ ]-----------------[] + LUA PASS1 + Console_build = increase_build("./SHELL/build.txt") + if Console_build > 999 then + Console_build = 999 + print("WARNING! Build > 999","WARNING! Build > 999","WARNING! Build > 999","WARNING! Build > 999","\aWARNING! Build > 999\a") + end + ENDLUA + LUA ALLPASS + sj.insert_label("lua_BUILD", Console_build) + ENDLUA +;---------------------------------------------------------------------[] + +; +; Shell full version +; номер версии (0..9) +CONSOLE_VERS EQU 1 +; номер модификации (0..99) +CONSOLE_MODF EQU 2 +; номер билда (0..999) +CONSOLE_BUILD EQU lua_BUILD +; \ No newline at end of file