DEVICE ZXSPECTRUM128
include "../_sdk/sys_h.asm"
;1992, IskraSOFT corp. СПб, Россия
;LL0000=0;$-#a7
;LL5db2=$-#f5
;LL5da8=$-#ff
;LL0010=0x10;$-#97
;LL5fc1=$-#e6
;LL5dc9=$-#de
;LL5ddf=$-#c8
;LL6091=$-#16
LL0005=5;$-#a2
;LL609c=$-#0b
LL000f=0x0f;$-#98
;LL6169=$-#3e
;LL0300=0x300;$-#a7
SCRHGT=24
NEDOOS=1
MAXCMDSZ=COMMANDLINE_sz-1-4-4 ;not counting terminator (-4 for "cmd ")
org PROGSTART
begin
;0x5da4=23972
if NEDOOS
ld sp,0xc000
ld e,3
OS_SETGFX ;e=0:EGA, e=2:MC, e=3:6912, e=6:text ;+SET FOCUS ;e=-1: disable gfx (out: e=old gfxmode)
ld a,(user_scr0_high) ;ok
SETPG4000 ;TODO убрать для textmode
call keepdir
ld hl,COMMANDLINE
call skipword
call skipspaces
ld (par1addr),hl
call skipword
push hl
call skipspaces
ld (par2addr),hl
pop hl
ld (hl),0
endif
call domenu;LL5dbd
if NEDOOS
jr c,failquit ;CY=error
else
ret c ;CY=error
endif
okquit;LL5da8
if NEDOOS
ld hl,0
QUIT
failquit
ld hl,-1
QUIT
else
xor a
ld a,#f4
ret
endif
LL5dac
;hl=адрес комстроки
call LL5db2 ;run (p_com+exebat)
if NEDOOS
jr c,failquit ;CY=error
else
ret c ;CY=error
endif
jr okquit;LL5da8
LL5db2
;run (p_com+exebat)
;hl=адрес комстроки
if NEDOOS
;cmd <hl>
push hl
call findCR
dec hl
ld (hl),0
;run "cmd <command to run>"
OS_SETSYSDRV
pop hl ;ld hl,cmdbuf
call loadandrun ;nz=error, e=id
jp nz,failquit
jp okquit
else
xor a
ld b,#01 ;???
ld c,#48 ;72(48):run - = p_com(#49) + exebat(#44). (Выход см. exebat). Передаются регистры IX,B.
;73(49):p_com - Заполнить внутренний буфер командной строки. HL = адрес строки, оканчивающейся кодом 13. При длине строки более 128 символов возвращает ошибку (флаг C)
;68(44):exebat - Запуск файла по пути и имени файла, находящегося во внутреннем буфере командной строки. Вход: A=0: стандартрая обработка типа файла, т.е. обращение к файлу S:extent.txt, A>0: DE = адрес буфера с путем и именем текстового файла. Выход: CARRY SET - серьезная ошибка, иначе: Z - O.K., NZ - какая-нибудь досадная мелочь
rst #10
ret c ;CY=error
ld c,#41 ;65(41):fmrst - Восстанавливает первоначальное состояние среды. (устройство, каталог и файл, запоминаемые процедурами работающими с командной строкой). Выход: с обр. ошибок, иначе сохраняет AF.
rst #10
endif
ret
domenu;LL5dbd
ld a,#01
ld (LL5fc1),a ;1=надо вызвать exe, 0=надо вызвать bat или большую программу?
if NEDOOS
;открываем либо файл-параметр (если он .mnu), либо SYSPATH/файл-параметр (если он .mnu), либо SYSPATH/mainmenu
ld hl,(par1addr)
xor a
ld c,0xff
cpir
ld de,tdotmnuz+5
ld b,5
checkdotmnu0
dec hl
dec de
ld a,(de)
cp (hl)
jr nz,checkdotmnu_nomnu
djnz checkdotmnu0
ld de,(par1addr)
OS_OPENHANDLE
or a
jr z,_LL5ddf
OS_SETSYSDRV
ld de,(par1addr)
OS_OPENHANDLE
or a
jr z,_LL5ddf
checkdotmnu_nomnu
OS_SETSYSDRV
ld de,mainmenufilename;LL6091
OS_OPENHANDLE
or a
scf
ret nz ;error (CY)
ld hl,(par1addr)
ld (par2addr),hl
_LL5ddf
ld a,b
ld (curhandle),a
else
;открываем либо файл-параметр, либо mainmenu, либо mainmenupath/mainmenu
ld c,#40;64(40):oparm - Открывает файл-параметр. Путь к файлу (полный или от текущего каталога) лежит в буфере командной строки вместе с именем файла или его маской.
rst #10
jr c,_LL5dc9 ;error
jr z,_LL5ddf ;file opened
_LL5dc9 ld hl,mainmenufilename;LL6091
ld c,#25;37(25):fopen - Поиск и открытие файла или каталога по имени и типу. HL - адрес описателя (имя, тип). (подкаталог открывается, т.е. его описатель (19 байт) считываются в сис. область описателя каталога. Выход: если ошибок нет: и если BIT5=0, то файл открыт, в A - регистр состояния файла (FSTAT), в HL' - адрес 32-байтового описателя файла (FNAME) если BIT5=1, то функция FOPEN открыла внутренний подкаталог
rst #10
jr nc,_LL5ddf ;file opened
ld hl,mainmenupath;LL6088
ld c,#42;66(42):comstr - Разбирается с указанным путем и открывает данное устройство и каталог (файл не открывает!) или снимает ключ. Вход: HL = адрес командной строки. Выход: флаг C: ошибка ввода/вывода (восстанавливается прежняя среда); NC,Z: A=0: HL'= 11-байтовый описатель/шаблон файла (если имя/маска файла не указано после пути, то шаблон из #FF); A>0: HL'= адрес символа "/" (обнаружен ключ), A=первый символ после ключа. NC,NZ: или пути нет, или ключа нет (пустая строка), или синтаксическая ошибка в командной строке.
rst #10
ret c ;error
ld hl,mainmenufilename;LL6091
ld c,#25;37(25):fopen - Поиск и открытие файла или каталога по имени и типу. HL - адрес описателя (имя, тип). (подкаталог открывается, т.е. его описатель (19 байт) считываются в сис. область описателя каталога. Выход: если ошибок нет: и если BIT5=0, то файл открыт, в A - регистр состояния файла (FSTAT), в HL' - адрес 32-байтового описателя файла (FNAME) если BIT5=1, то функция FOPEN открыла внутренний подкаталог
rst #10
ret c ;error
_LL5ddf
endif
;file opened
if NEDOOS
ld a,(curhandle)
ld b,a
OS_GETFILESIZE ;b=handle, out: dehl=file size
ld a,d
or e
scf
ret nz ;error (CY)
ex de,hl
else
ld c,#35;53(35):bkfcb - Возврат адреса описателя файла в HL'(=FNAME)
rst #10
exx
push hl
pop ix
ld e,(ix+#0e)
ld d,(ix+#0f)
endif
;de=filesz
if NEDOOS
ld hl,menutext+128;LL623a
add hl,de
ret c ;error (no free mem)
ex de,hl
ld de,menutext;LL623a
;de=menutext, hl=filesz
push de
push hl
ld a,(curhandle)
ld b,a
push bc
OS_READHANDLE
pop bc
OS_CLOSEHANDLE
pop hl
pop de
or a
scf
ret nz ;error (CY)
else
ld ix,menutext;LL623a
push ix
pop hl
add hl,de ;hl=menutext+filesz?
inc hl
ld c,#10;16(10):g_cnfg - Возврат вектора конфигурации ядра. HL'- адрес вектора конфигурации ядра, А - номeр канала системного устройства
rst #10
push hl
exx
ld bc,LL0005
add hl,bc ;hl=адрес вектора конфигурации ядра+5
ld e,(hl)
inc hl
ld d,(hl) ;free mem???
exd ;hl=free mem???
pop de
xor a
sbc hl,de
ld a,#82
ret c ;no free mem???
exx
;ix=menutext, de=filesz
xor a
ld h,a
ld l,a
ld c,#29 ;41(29):rpart - Чтение части файла. A,HL - указатель, IX - адрес в памяти, DE - длина в байтах.
rst #10
ret c ;error
push ix
pop hl
endif
;hl=menutext
;de=filesz
add hl,de ;hl=menutext+filesz
ld (hl),#0d
inc hl
ld (hl),#03 ;конец текста
if !NEDOOS
ld c,#41 ;65(41):fmrst - Восстанавливает первоначальное состояние среды. (устройство, каталог и файл, запоминаемые процедурами работающими с командной строкой). Выход: с обр. ошибок, иначе сохраняет AF
rst #10
ret c ;error
endif
;file loaded
ld e,'H';#48 ;H - строки подсказки
call LL609c ;поиск первой строки типа e в menutext?
jr z,_LL5e2a ;z=не найдено
ld a,#01
ld (hintspresent),a;(LL6226),a
_LL5e2a ld e,'K';#4b ;K - строка ключей (одна в тексте) ;например: K/A1/K40/J5/C160/O21
call LL609c ;поиск первой строки типа e в menutext?
call nz,interpret_keys_hl;LL5fc9 ;интерпретируем ключи
;ищем самую широкую строку типа 'A' (menuwid) и высоту окна (menuhgt):
ld e,'A';#41
ld d,#01
_LL5e36 call LL609e ;поиск строки типа e номер d в тексте menutext? ;out: z="(hl)==#03" (конец текста?) или error?
jr z,_LL5e49 ;z=не найдено
inc d
ld c,a
ld a,(menuwid);(LL6232)
cp c
jr nc,_LL5e44
ld a,c
_LL5e44 ld (menuwid),a;(LL6232),a
jr _LL5e36
_LL5e49 inc d
ld a,d
cp #02
ret z ;в меню нет ни одной строки
cp SCRHGT-3;21;#15
jr c,_LL5e54
ld a,SCRHGT-4;20;#14
_LL5e54 ld (menuhgt),a;(LL622d),a
;ещё раз ищем высоту окна???
ld e,'A';#41
ld d,#01
_LL5e5b call LL609e ;поиск строки типа e номер d в тексте menutext? ;out: z="(hl)==#03" (конец текста?) или error?
ret z ;не найдено
inc d
dec hl
ld a,e
cp (hl)
jr nz,_LL5e5b
ld a,d
cp SCRHGT-5;19;#13
ret nc
;ищем menuwid_chrs, menux ;TODO fix for textmode
ld a,(menuwid);(LL6232)
ld c,#21
dec a
cp c
jr c,_LL5e73
ld a,c
_LL5e73 ld (menuwid),a;(LL6232),a
ld b,a
add a,a
add a,b ;*3
srl a
srl a ;*3/4
inc a
inc a
inc a ;*3/4 +3
srl a
add a,a ;чётное
ld (menuwid_chrs),a;(LL622e),a
ld b,a
ld a,(menux);(LL622b)
cp #ff
jr nz,_LL5e96
ld a,#20
sub b
srl a
ld (menux),a;(LL622b),a
_LL5e96 sla a
sla a
ld b,#01
ld c,#03
inc a
_LL5e9f cp c
jr c,_LL5ea6
sub c
inc b
jr _LL5e9f
_LL5ea6 ld a,b ;???
ld a,(menuwid);(LL6232)
and #07
cp #04
jr z,LL5eb8
cp #05
jr z,LL5eb8
cp #07
jr nz,LL5eb9
LL5eb8 inc b
LL5eb9 ld a,b
ld (LL6231),a ;??? NU
;TODO fix for textmode:
ld a,(hintx);(LL621d)
sla a
sla a
ld b,#00
ld c,#03
inc a
_LL5ec9 cp c
jr c,_LL5ed0
sub c
inc b
jr _LL5ec9
_LL5ed0 ld a,b
inc a
inc a
ld (LL6223),a ;??? NU
;
ld a,(menuy);(LL622c)
cp #ff
jr nz,_LL5ee9
ld a,(menuhgt);(LL622d)
ld b,a
ld a,SCRHGT;#18
sub b
srl a
ld (menuy),a;(LL622c),a
_LL5ee9
;TODO fix for textmode:
ld a,(hintwid);(LL6224)
srl a
srl a
ld b,a
set 7,b
ld c,#03
xor a
LL5ef6 add a,c
dec b
bit 7,b
jr nz,LL5ef6
inc a
inc a
ld (LL6220),a ;hintwid_chrs?
;
ld a,(action);(LL6087)
ld b,a
bit 0,a ;1 = окно меню с тенью
jr z,_LL5f11
ld a,(shadowcolor);(LL6230)
res 7,a
ld (shadowcolor),a;(LL6230),a
_LL5f11 xor a ;окно с одинарной рамкой
bit 2,b ;4 = окно меню с 2-ой рамкой
jr z,_LL5f18
ld a,#02 ;окно с двойной рамкой
_LL5f18
ld ix,MENU;LL622b
if NEDOOS
call sR_WT
else
ld c,#61 ;97(61):wt - Вывод окна. Подфункция в рег. A: A=0 окно с одинарной рамкой, А=1 без рамки, А=2 с двойной рамкой, A=3..127 без рамки, A=128..255 только подкраска. IX= вектор окна
rst #10
endif
ld a,(action);(LL6087)
and #0a
ld (action),a;(LL6087),a
ld a,(flags);(LL6235)
and #14
ld (flags),a;(LL6235),a
ld a,(action);(LL6087)
bit 3,a ;8 = не выполнять строку Р
jr nz,_LL5f43
ld e,'P';#50 ;P - строка для вызова внутренних команд (одна в тексте)
call LL609c ;поиск первой строки типа e в menutext?
ld ix,MENU;LL622b
call nz,LL5db2 ;run (p_com+exebat)
ret c ;error
_LL5f43 ld a,(flags);(LL6235)
and #1f
ld (flags),a;(LL6235),a
ld ix,MENU;LL622b
call cycleinmenu;LL60ca
jr c,LL5fc2 ;выполнить строку 'T'
call LL5fb4 ;поиск строки типа 'A' номер cursory в тексте menutext? ;out: z="(hl)==#03" (конец текста?) или error?
ld e,'Z';#5a ;Z - строка для вызова внутренних команд
call LL60a1 ;поиск строки типа e номер d в тексте hl? ;out: z="(hl)==#03" (конец текста?) или error?
call nz,LL5db2 ;run (p_com+exebat)
ret c
ld a,(flags);(LL6235)
res 5,a
ld (flags),a;(LL6235),a
ld a,(action);(LL6087)
bit 1,a ;2 = выполнить соответстующую командную строку Z и вернуться снова в меню
jr nz,_LL5f43 ;???
call LL5fb4 ;поиск строки типа 'A' номер cursory в тексте menutext? ;out: z="(hl)==#03" (конец текста?) или error?
ld e,'C';#43 ;C или c - строки для вызова командных строк (C - стандартный вызов, с - вызов строки через SHELL ( для больших программ ( например редактора, т.е. для программ у которых адрес загрузки меньше 25000) и пакетов)
call LL60a1 ;поиск строки типа e номер d в тексте hl? ;out: z="(hl)==#03" (конец текста?) или error?
ret z ;z=не найдено
push af
dec hl
ld a,'c';#63
inc hl
cp (hl)
jr nz,_LL5f84
xor a
ld (LL5fc1),a ;0=надо вызвать bat или большую программу?
_LL5f84 pop af
LL5f85 ret z
ld a,'*';#2a ;подставлять имя файла в конце комстроки (не документировано!!!)
cp (hl)
jr nz,LL5fa5
;берём файл под курсором
if NEDOOS
;брать из второго параметра комстроки: menu.com menu.mnu filename.ext
ld de,(par2addr)
else
ld c,#8a ;138(8A):g_curs - Возвращает параметры панельного курсора. Выход: A=E'= номер файла, D'= позиция Y в окне (=H для wtpos), B' - номер текущей панели (0 - левая, 1 - правая), HL' - адрес вектора окна панели
rst #10
ld e,a
ld c,#27 ;39(27):gname - Возвращает описатель файла, не открывая его на входе в рег.Е - номер файла. Выход: если O.K., то HL' - адрес описателя файла в электронном диске
rst #10
ret c
endif
push hl ;адрес '*'?
call findCR;LL61a1
dec hl
ld (hl),#20 ;вместо CR
inc hl
if NEDOOS
ex de,hl
call strcopy
else
exx
push hl ;адрес описателя файла в электронном диске
exx
pop de ;адрес описателя файла в электронном диске
exd ;hl=адрес описателя файла в электронном диске
ld c,#4f ;79(4F):convr - Преобразует 11-байтовый описатель имени и расширения файла (в HL), в 13-байтовое имя файла с расширением через точку и с "13" в конце (в DE). На выходе DE' - адрес #0D
rst #10
endif
pop hl ;адрес '*'?
inc hl ;hl=адрес комстроки типа "command bla-bla filename.ext"
LL5fa5 pop bc
if NEDOOS
jp LL5dac ;run (p_com+exebat),okquit
else
ld a,(LL5fc1)
or a
jp nz,LL5dac ;run (p_com+exebat),okquit
;вызвать bat или большую программу?
ld c,#49 ;73(49):p_com - Заполнить внутренний буфер командной строки. HL = адрес строки, оканчивающейся кодом 13. При длине строки более 128 символов возвращает ошибку (флаг C).
rst #10
xor a
ld c,#93 ;147(93):shexe - Выход в оболочку с запуском RST exebat(#44) с A=0
rst #10
endif
LL5fb4 ;поиск строки типа 'A' номер cursory в тексте menutext? ;out: z="(hl)==#03" (конец текста?) или error?
ld a,(cursory);(LL6234)
ld d,a
ld e,'A';#41
call LL609e ;поиск строки типа e номер d в тексте menutext? ;out: z="(hl)==#03" (конец текста?) или error?
dec hl
ld d,#01
ret ;z=не найдено
LL5fc1 nop ;0=надо вызвать bat или большую программу, 1=надо вызвать exe?
LL5fc2 ld e,'T';#54 ;C/c,T - строки для вызова командных строк (T - должна стоять командная строка, вызываемая при отказе (SS + A)
call LL609c ;поиск первой строки типа e в menutext?
jr LL5f85 ;там ret z и проверка на '*'...
interpret_keys_hl;LL5fc9
;hl=строка ключей типа /A1/K40/J5/C160/O21
ld a,'/';#2f
cp (hl)
ret nz
inc hl
ld b,(hl)
push bc ;b=тип ключа
inc hl
push hl ;hl=начало числа в ключе
xor a
ld b,a
LL5fd4 ld a,#20
cp (hl)
jr z,_LL5fe7
ld a,'/';#2f
cp (hl)
jr z,_LL5fe7
ld a,#0d
cp (hl)
jr z,_LL5fe7
inc hl
inc b
jr LL5fd4
_LL5fe7 pop de ;de=начало числа в ключе
push hl ;hl=строка ключей типа /A1/K40/J5/C160/O21 - после числа
exd ;hl=начало числа в ключе
ld a,b ;длина буфера
ld b,#00
if NEDOOS
call sa_d
else
ld c,#7d ;125(7D):a_d - преобразование строки ASCII-символов в 4-байтовое число. Ведущие пробелы игнорируются. HL - адрес ASCII - буфера, А - длина буфера ( если А=0, то до кода 13 ), В - основание системы счисления по умолчанию (не более 16, B=0 понимается как 10). Система счисления может также определяться по первому символу буфера: #,h,H - 16; .,d - 10; o,O - 8; %,b,B - 2. Выход: 32-разрядное число в DE'HL'. BC' - продолжение ASCII-буфера. Возможные ошибки (флаг C): нецифровой символ (A=0), переполнение (A=1)
rst #10
endif
exx
ld b,l ;result
pop de ;de=строка ключей типа /A1/K40/J5/C160/O21
ld hl,LL5ffd
pop af ;a=тип ключа
if NEDOOS
call sanaly
else
ld c,#7e ;126(7E):analys - Передача управления подпрограмме по адресу из таблицы. HL - aдрес таблицы, А - код команды. Таблица состоит из записей по 3 байта: 0(1) код команды, 1(2) адрес процедуры. В последней записи должен лежать байт #FF и адрес отработки ситуации "код не найден"
rst #10 ;(в de'hl' мы передали числовой параметр для этого ключа)
endif
exd
;hl=строка ключей типа /A1/K40/J5/C160/O21
jr interpret_keys_hl;LL5fc9 ;продолжаем разбор ключей
; Cписок ключей:
; А - значения : 0 - по умолчаеию;
; 1 - окно меню с тенью;
; 2 - выполнить соответстующую
; командную строку Z и
; вернуться снова в меню;
; 4 - окно меню с 2-ой рамкой;
; 8 - не выполнять строку Р;
; xx - суммарное действие,
; например : 1+4=5 xx=5 .
; B - значения :16 - по умолчанию;
; 4 - короткий курсор;
; 16- подсказка без рамки;
; xx - суммарное действие.
; E - координата x меню
; (по умолчанию центровка по X);
; D - координата Y меню
; (по умолчанию центровка по Y);
; F - положение курсора в меню
; (по умолчанию в первой строке меню);
; J - цвет курсора меню
; (по умолчанию %00111001 );
; T - цвет тени (по умолчанию 0 );
; K - цвет меню (по умолчанию %00001111);
; O - цвет курсора при выходе из меню
; (по умолчанию %00100000 );
; G - Y подсказки (по умолчанию 0 );
; I - цвет подсказки
; (по умолчанию %00001111 );
; H - X подсказки (по умолчанию 0 );
; N - высота подсказки (по умолчанию 1 );
; C - длина подсказки (по умолчанию 32 ).
LL5ffd DB 'A';#41
dw setkey_action;LL6041
db 'B';#42
dw setkey_flags;LL6046
db 'C';#43
dw setkey_hintwid;LL604b
DB 'D';#44
dw setkey_menuy;LL6050
db 'E';#45
dw setkey_menux;LL6055
db 'F';#46
dw setkey_cursory;LL605a
db 'G';#47
dw setkey_hinty;LL605f
db 'H';#48
dw setkey_hintx;LL6064
DB 'I';#49
dw setkey_hintcolor;LL6069
db 'J';#4a
dw setkey_cursorcolor;LL606e
db 'K';#4b
dw setkey_menucolor;LL6073
db 'L';#4c
dw LL6078
db 'M';#4d
dw LL607d
db 'N';#4e
dw setkey_hinthgt;LL6082
db 'O';#4f
dw setkey_exitcursorcolor;LL603c
db 'T';#54
dw setkey_shadowcolor;LL6030
DB #ff
dw reter;LL6045
setkey_shadowcolor;LL6030
ld a,b
and #07
ld b,a
add a,a
add a,a
add a,a
or b
ld (shadowcolor),a;(LL6230),a
ret
setkey_exitcursorcolor;LL603c
ld a,b
ld (exitcursorcolor),a;(LL6239),a
ret
setkey_action;LL6041
ld a,b
ld (action),a;(LL6087),a
reter;LL6045
ret
setkey_flags;LL6046
ld a,b
ld (flags),a;(LL6235),a
ret
setkey_hintwid;LL604b
ld a,b
ld (hintwid),a;(LL6224),a
ret
setkey_menuy;LL6050
ld a,b
ld (menuy),a;(LL622c),a
ret
setkey_menux;LL6055
ld a,b
ld (menux),a;(LL622b),a
ret
setkey_cursory;LL605a
ld a,b
ld (cursory),a;(LL6234),a
ret
setkey_hinty;LL605f
ld a,b
ld (hinty),a;(LL621e),a
ret
setkey_hintx;LL6064
ld a,b
ld (hintx),a;(LL621d),a
ret
setkey_hintcolor;LL6069
ld a,b
ld (hintcolor),a;(LL6221),a
ret
setkey_cursorcolor;LL606e
ld a,b
ld (cursorcolor),a;(LL6233),a
ret
setkey_menucolor;LL6073
ld a,b
ld (menucolor),a;(LL622f),a
ret
LL6078
ld a,b
ld (LL6236),a
ret
LL607d
ld a,b
ld (LL6225),a
ret
setkey_hinthgt;LL6082
ld a,b
ld (hinthgt),a;(LL621f),a
ret
action;LL6087
DB #00
if NEDOOS
;mainmenupath;LL6088
;db "menu",0
else
mainmenupath;LL6088
;db #53,#3a,#53,#48,#45,#4c,#4c
;DB #5c,#0d,#6d,#65,#6e,#75,#20,#20
;DB #20,#20,#74,#78,#74
db "S:SHELL",'\\',13
endif
mainmenufilename;LL6091
if NEDOOS
db "menu/menu.mnu",0
;db "menu/resident.mnu",0
else
db "menu txt"
endif
LL609c
;e=тип строки
ld d,#01 ;db 0x16,0x01
LL609e ld hl,menutext;LL623a ;поиск строки типа e номер d в тексте menutext? ;out: z="(hl)==#03" (конец текста?) или error?
LL60a1 jp LL6179 ;поиск строки типа e номер d в тексте hl?
;z="(hl)==#03" (конец текста?) или error?
LL60a4 ;перепечатка окна?
ld a,(ix+MENU_flags);#0a)
bit 5,a
ret nz
set 5,a
ld (ix+MENU_flags),a;(ix+#0a),a
ld a,(ix+MENU_flags);#0a)
call LL6153 ;goto next menu
ld b,a
ld a,(hintspresent);LL6226)
or a
jr z,LL60c7 ;no hints ;goto next menu
ld a,(flags);(LL6235)
bit 4,a ;16 = подсказка без рамки
jr nz,_LL60c4
xor a
_LL60c4
if NEDOOS
call sR_WT
else
ld c,#61 ;97(61):wt - Вывод окна. Подфункция в рег. A: A=0 окно с одинарной рамкой, А=1 без рамки, А=2 с двойной рамкой, A=3..127 без рамки, A=128..255 только подкраска. IX= вектор окна
rst #10
endif
LL60c7 jp LL6153 ;goto next menu
cycleinmenu;LL60ca
call LL6165 ;печать текста в окне
call LL6115
call LL60a4 ;перепечатка окна?
call LL613d
if NEDOOS
push ix
OS_GETKEY
pop ix
else
ld c,#07 ;7(07):ttyin - Ввод символа. Выход: A - код нажатой клавиши
rst #10
endif
push af
ld b,(ix+MENU_menucolor);#04)
call printcursor;LL612d
pop af
ld hl,tkeyhandlers;LL60eb
if NEDOOS
call sanaly
else
ld c,#7e ;126(7E):analys - Передача управления подпрограмме по адресу из таблицы. HL - aдрес таблицы, А - код команды. Таблица состоит из записей по 3 байта: 0(1) код команды, 1(2) адрес процедуры. В последней записи должен лежать байт #FF и адрес отработки ситуации "код не найден"
rst #10
endif
ret nz
ret c
jr cycleinmenu;LL60ca
tkeyhandlers;LL60eb
DB #0d
dw handle_enter;LL61a8
db key_left;#09
dw handle_left;LL61bb
db key_up;#0b
dw handle_up;LL61d3
db key_down;#0a
dw handle_down;LL61fc
db key_right;#08
dw handle_right;LL61c9
db 'q';#71
dw handle_up;LL61d3
db 'a';#61
dw handle_down;LL61fc
db 'p';#70
dw handle_right;LL61c9
DB 'o';#6f
dw handle_left;LL61bb
db key_end;'A';#41
dw handle_end;LL61d9
db key_home;'Q';#51
dw handle_home;LL6205
DB key_esc;#10
dw xorascf;LL6112
db #ff
dw xora;LL61f6 ;xor a:ret
xorascf;LL6112
xor a
scf
ret
LL6115
ld d,(ix+MENU_cursory);#09)
ld e,'A';#41
call LL615d ;hl=ix+15
call LL6179 ;поиск строки типа 'A' номер d в тексте hl?
jp z,LL61f8 ;(hl)=#03 (конец текста?) или error? ;handle_down+jp LL6115
dec hl
ld a,(hl)
cp 'a';#61
jp z,LL61f8 ;handle_down+jp LL6115 ;'a' = строки меню, по которым не ходит курсор
ld b,(ix+MENU_cursorcolor);#08)
;b=color
printcursor;LL612d
ld a,(flags);(LL6235)
bit 2,a ;4 = короткий курсор
ld a,(ix+MENU_cursory);#09)
if NEDOOS
jr z,_LL6138
call sAWTC
jr _LL6138q
_LL6138
call sAWT
_LL6138q
else
ld c,#63 ;99(63):awt - Подкрашивает строку внутри окна, c рамкой. Вход: IX = адрес вектора окна, A = номер строки, которую необходимо подсветить (нумерация от 1), B = цвет
jr z,_LL6138
ld c,#64 ;100(64):awtc - Подкрашивает строку внутри окна, не затрагивая рамку, IX=вектор окна, A=номер строки, B=цвет
_LL6138 ;ld a,(ix+MENU_cursory);#09)
rst #10
endif
ret
LL613d call LL5fb4 ;поиск строки типа 'A' номер cursory в тексте menutext? ;out: z="(hl)==#03" (конец текста?) или error?
ld e,'H';#48 ;H - должен стоять текст ,который появляется в cтроке подсказке
call LL60a1 ;поиск строки типа e номер d в тексте hl? ;out: z="(hl)==#03" (конец текста?) или error?
ret z ;z=не найдено
call LL6153 ;goto next menu
ld b,#01
ld a,(ix+MENU_menuhgt);#02)
srl a ;???
if NEDOOS
call sLWT
else
ld c,#65 ;101(65):lwt - Распечатка заданного количества строк в окне; A - номер строки (начала), IX - вектор окна, HL - адрес строк текста для печати, B - количество строк, которое необходимо распечатать
rst #10
endif
;goto next menu
LL6153
ld e,(ix+MENU_nextmenuaddr);#0c)
ld d,(ix+MENU_nextmenuaddr+1);#0d)
push de
pop ix
ret
LL615d ;hl=ix+15
push ix
pop hl
ld bc,LL000f
add hl,bc
ret
;печать текста в окне
LL6165
ld d,#01
ld e,'A';#41
LL6169 call LL615d ;hl=ix+15
call LL6179 ;поиск строки типа 'A' номер d в тексте hl?
ret z ;(hl)=#03 (конец текста?) или error?
ld a,d
ld b,#01
if NEDOOS
push de
call sLWT
pop de
else
ld c,#65 ;101(65):lwt - Распечатка заданного количества строк в окне; A - номер строки (начала), IX - вектор окна, HL - адрес строк текста для печати, B - количество строк, которое необходимо распечатать
rst #10
endif
inc d
jr LL6169
LL6179
;поиск строки типа 'A' номер d в тексте hl?
;hl=text
;d=y?
;e='A'?
;out: hl, z=error?
push af
ld b,#00
LL617c pop af
call LL6191
ret z ;(hl)=#03 (конец текста?) или error?
inc b
push hl
call findCR;LL61a1
ld a,b
cp d
jr nz,LL617c
pop hl
inc hl
ld a,#fe
sub c
or a ;z="в предыдущей строке CR найден в первой же позиции (предыдущая строка пустая)"???
ret
;e=?
LL6191 ld a,(hl)
cp #03
ret z ;конец текста?
res 5,a
cp e
jr z,LL619f ;строка нужного типа
call findCR;LL61a1
jr LL6191
LL619f or a
ret
findCR;LL61a1
ld c,#ff
ld a,#0d
cpir
ret
handle_enter;LL61a8
ld a,#01
or a
LL61ab push af
ld a,(ix+MENU_flags);#0a)
bit 0,a
jr nz,_LL61b9
ld b,(ix+MENU_exitcursorcolor);#0e)
call printcursor;LL612d
_LL61b9 pop af
ret
handle_left;LL61bb
ld a,(ix+MENU_flags);#0a)
bit 3,a
ret z
set 6,a
LL61c3 ld (ix+MENU_flags),a;(ix+#0a),a
scf
jr LL61ab
handle_right;LL61c9
ld a,(ix+MENU_flags);#0a)
bit 3,a
ret z
set 7,a
jr LL61c3
handle_up;LL61d3
ld a,(ix+MENU_cursory);#09)
dec a
jr nz,LL61de
handle_end;LL61d9
ld a,(ix+MENU_menuhgt);#02)
dec a
dec a
LL61de ld (ix+MENU_cursory),a;(ix+#09),a
ld d,a
ld e,'A';#41
call LL615d ;hl=ix+15
call LL6179 ;поиск строки типа 'A' номер d в тексте hl?
jr z,handle_up;LL61d3 ;(hl)=#03 (конец текста?)
dec hl
ld a,(hl)
cp 'a';#61
jr z,handle_up;LL61d3 ;'a' = строки меню, по которым не ходит курсор
ld a,d
LL61f3 ld (ix+MENU_cursory),a;(ix+#09),a
xora;LL61f6
xor a
ret
LL61f8 ld hl,LL6115
push hl
handle_down;LL61fc
ld a,(ix+MENU_cursory);#09)
_LL61ff inc a
cp (ix+MENU_menuhgt);#02)
jr nz,LL61f3
handle_home;LL6205
xor a
jr _LL61ff
include "twind.asm" ;sR_WT
include "wtro.asm"
include "ttyp42.asm"
sATB42
incbin "Font42_f.cod"
;исходник не найден, пишем по догадке
;126(7E):analys - Передача управления подпрограмме по адресу из таблицы. HL - aдрес таблицы, А - код команды. Таблица состоит из записей по 3 байта: 0(1) код команды, 1(2) адрес процедуры. В последней записи должен лежать байт #FF и адрес отработки ситуации "код не найден" (возвращает NZ?)
sanaly
inc (hl)
jr z,sanaly_err
dec (hl)
cp (hl)
jr z,sanaly_ok
inc hl
inc hl
inc hl
jr sanaly
sanaly_err
dec (hl) ;NZ
sanaly_ok
inc hl
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
jp (hl)
sPRCHR
;a=chr
;in,out: de'=print addr
jp sTYP42
sPRAD
;out: de'=print addr
jp sADR42
;исходник не найден, пишем по догадке
;125(7D):a_d - преобразование строки ASCII-символов в 4-байтовое число. Ведущие пробелы игнорируются. HL - адрес ASCII - буфера, А - длина буфера ( если А=0, то до кода 13 ), В - основание системы счисления по умолчанию (не более 16, B=0 понимается как 10). Система счисления может также определяться по первому символу буфера: #,h,H - 16; .,d - 10; o,O - 8; %,b,B - 2. Выход: 32-разрядное число в DE'HL'. BC' - продолжение ASCII-буфера. Возможные ошибки (флаг C): нецифровой символ (A=0), переполнение (A=1)
sa_d
;dec only
;no overflow
;no leading spaces
exx
ld hl,0
ld d,h
ld e,l
exx
ld b,a ;длина буфера
sa_d_loop
ld a,(hl)
inc hl
sub '0'
cp 10
ccf
jr c,sa_d_loopq
exx
call sa_d_mul10
add a,l
ld l,a
ld a,h
adc a,0
ld h,a
jr nc,$+3
inc de
exx
djnz sa_d_loop
or a ;ok
sa_d_loopq
push hl
exx
pop bc
exx
ret
;de'hl'
sa_d_mul10
ld b,h
ld c,l
push de
add hl,hl
rl e
rl d ;*2
add hl,hl
rl e
rl d ;*4
add hl,bc
ex de,hl
pop bc
adc hl,bc
ex de,hl ;*5
add hl,hl
rl e
rl d ;*10
ret
skipword
;hl=string
;out: hl=terminator/space addr
getword0
ld a,(hl)
or a
ret z
cp ' '
ret z
inc hl
jr getword0
skipspaces
;hl=string
;out: hl=after last space
ld a,(hl)
cp ' '
ret nz
inc hl
jr skipspaces
strcopy
;hl->de
;out: hl,de after terminator
xor a
strcopy0
cp (hl)
ldi
jr nz,strcopy0
ret
keepdir
ld de,curdir
OS_GETPATH
ret
setolddir
ld de,curdir
OS_CHDIR
ret
loadandrun
;hl=rest of command line
;out: nz=error, e=id
;load file in fcb from system current dir with parameters in tcmd, then set curpaneldir and run
ld (loadandrun_restcmd),hl
ld de,cmd_filename
OS_OPENHANDLE
or a
ret nz ;error
ld a,b
ld (curhandle),a
ld hl,nv_closehandle
push hl
;set current drive and dir (will be copied into new app)
call setolddir
OS_NEWAPP
or a
ret nz ;error
;dehl=номера страниц в 0000,4000,8000,c000 нового приложения, b=id, a=error
push bc ;b=id
ld a,d
SETPGC000
push de
push hl
ld hl,filenametext
ld de,0xc000+COMMANDLINE
ld bc,4
ldir
loadandrun_restcmd=$+1
ld hl,0
call strcopy
xor a
ld (0xc000+COMMANDLINE+COMMANDLINE_sz-1),a
pop hl
pop de
call readfile_pages_dehl
pop de
ld e,d ;e=id
;run "cmd <commandline>"
push de
OS_RUNAPP
pop de
xor a
ret ;z
readfile_pages_dehl
ld a,d
SETPGC000
ld a,0xc100/256
call cmd_loadpage
ret nz
ld a,e
call cmd_loadfullpage
ret nz
ld a,h
call cmd_loadfullpage
ret nz
ld a,l
cmd_loadfullpage
SETPGC000
ld a,0xc000/256
cmd_loadpage
;out: a=error, bc=bytes read
;keeps hl,de
push de
push hl
ld d,a
xor a
ld l,a
ld e,a
sub d
ld h,a ;de=buffer, hl=size
call readcurhandle
ld b,h
ld c,l
pop hl
pop de
or a
ret
readcurhandle
curhandle=$+1
ld b,0
OS_READHANDLE
ret
nv_closehandle
;keep de and flags!!!
push af
push de
ld a,(curhandle)
ld b,a
OS_CLOSEHANDLE
pop de
pop af
ret
cmd_filename
db "cmd.com",0
filenametext
db "cmd "
tdotmnuz
db ".mnu",0
curdir
ds MAXPATH_sz
par1addr
dw 0
par2addr
dw 0
;curhandle
; db 0
;???
DB #55;'U'
db "ABCDEFGHIJ";#41,#42,#43,#44,#45,#46,#47,#48,#49,#4a
db "0123456789";#30,#31,#32,#33,#34,#35,#36,#37,#38,#39
HINTMENU
hintx;LL621d
db #00
hinty;LL621e
db #00
hinthgt;LL621f
db #01
LL6220 ;hintwid_chrs?
DB #20
hintcolor;LL6221
db #0f,#ff
LL6223 ;hinthgt_chrs?
db #01
hintwid;LL6224
db #1e
LL6225
db #00
hintspresent;LL6226
db #00
db #00
DB #00
dw MENU;#622b
MENU
menux;LL622b
db #ff
menuy;LL622c
db #ff
MENU_menuhgt=$-MENU;2
menuhgt;LL622d
db #00
menuwid_chrs;LL622e
db #00
MENU_menucolor=$-MENU;4
menucolor;LL622f
db #0f
shadowcolor;LL6230
DB #80
LL6231 ;menuhgt_chrs?
db #00
;MENU_menuwid=$-MENU;7
menuwid;LL6232
db #00
MENU_cursorcolor=$-MENU;8
cursorcolor;LL6233
db #39
MENU_cursory=$-MENU;9
cursory;LL6234
db #01
MENU_flags=$-MENU;10
flags;LL6235
;bit 0: не печатать курсор цветом exitcursorcolor по left, right, enter
;bit 3: enable left, right
;bit 5: LL60a4 already called (окно напечатано?)
;bit 6: left pressed
;bit 7: right pressed
db #10
LL6236
db #00 ;???
MENU_nextmenuaddr=$-MENU;12
dw HINTMENU;#621d
MENU_exitcursorcolor=$-MENU;14
exitcursorcolor;LL6239
db #20
;menu size = 15?
menutext;LL623a
end
savebin "menu.com",begin,end-begin
LABELSLIST "../../us/user.l"