DEVICE ZXSPECTRUM128
include "../_sdk/sys_h.asm"
NEDOOS=1
PRSTDIO=1
;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
if PRSTDIO
SCRHGT=25
else
SCRHGT=24
endif
MAXCMDSZ=COMMANDLINE_sz-1-4-4 ;not counting terminator (-4 for "cmd ")
org PROGSTART
begin
;0x5da4=23972
if NEDOOS
ld sp,0xc000
if PRSTDIO
call initstdio
ld a,(stdiohgt)
;ld (scrhgt),a
else
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
endif
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
WAITPID
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
ld a,(menuwid);(LL6232)
if PRSTDIO
ld c,80-1
else
ld c,#21
endif
dec a
cp c
jr c,_LL5e73
ld a,c
_LL5e73 ld (menuwid),a;(LL6232),a
if PRSTDIO
add a,2
else
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 ;чётное
endif
ld (menuwid_chrs),a;(LL622e),a
ld b,a
ld a,(menux);(LL622b)
cp #ff
jr nz,_LL5e96
if PRSTDIO
ld a,80
else
ld a,#20
endif
sub b
srl a
ld (menux),a;(LL622b),a
_LL5e96
if PRSTDIO
inc a
else
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
endif
ld (menux_chrs),a
ld a,(hintx);(LL621d)
if PRSTDIO
inc a;add a,2
else
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
endif
ld (LL6223),a ;??? NU hinthgt_chrs?
;
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
ld a,(hintwid);(LL6224)
if PRSTDIO
add a,2
else
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
endif
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
if PRSTDIO
call prwin
else
call sR_WT ;Вывод окна (без текста). Подфункция в рег. A: A=0 окно с одинарной рамкой, А=1 без рамки, А=2 с двойной рамкой, A=3..127 без рамки, A=128..255 только подкраска. IX= вектор окна
endif
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
if PRSTDIO
call prwin
else
call sR_WT ;Вывод окна (без текста). Подфункция в рег. A: A=0 окно с одинарной рамкой, А=1 без рамки, А=2 с двойной рамкой, A=3..127 без рамки, A=128..255 только подкраска. IX= вектор окна
endif
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
if PRSTDIO
call yieldgetkeyloop;getkey
else
YIELDGETKEYLOOP;OS_GETKEY
endif
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
if PRSTDIO
push af
ld a,b
call setcolor_a ;keep ix
pop af
ld e,(ix+MENU_menux)
ld b,(ix+MENU_menuwid_chrs)
jr z,$+5
inc e ;короткий курсор
dec b
dec b
push ix
push bc ;b=cursorwid
add a,(ix+MENU_menuy)
ld d,a
call setxy
call setcolor_invisible
ld a,' '
;printcursor_wid=$+1
pop bc ;ld b,0
;a=symbol
;b=count
call prNsymbol
call setcolor_visible
pop ix
else
jr z,_LL6138
call sAWTC ;100(64):awtc - Подкрашивает строку внутри окна, не затрагивая рамку, IX=вектор окна, A=номер строки, B=цвет
jr _LL6138q
_LL6138
call sAWT ;99(63):awt - Подкрашивает строку внутри окна, c рамкой. Вход: IX = адрес вектора окна, A = номер строки, которую необходимо подсветить (нумерация от 1), B = цвет
_LL6138q
endif
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
push af
push bc
push hl
call setmenucolor
pop hl
pop bc
pop af
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
push af
push bc
push hl
call setmenucolor
pop hl
pop bc
pop af
call sLWT ;101(65):lwt - Распечатка заданного количества строк в окне; A - номер строки (начала), IX - вектор окна, HL - адрес строк текста для печати, B - количество строк, которое необходимо распечатать
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"
if !PRSTDIO
include "ttyp42.asm"
sATB42
incbin "Font42_f.cod"
endif
;исходник не найден, пишем по догадке
;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
if PRSTDIO
push bc
push de
push hl
push ix
call sendchar
pop ix
pop hl
pop de
pop bc
ret
else
jp sTYP42
endif
sPRAD
;b=y
;out: de'=print addr, does exx
if PRSTDIO
exx
push bc
push de
push hl
push ix
exx
ld d,b
ld e,c
call setxy
pop ix
pop hl
pop de
pop bc
ret
else
jp sADR42
endif
;исходник не найден, пишем по догадке
;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
if PRSTDIO
include "../_sdk/stdio.asm"
setmenucolor
ld a,(ix+4) ;menucolor
setcolor_a
ld e,a
rra
rra
rra
and 15
ld d,a ;paper
ld a,e
and 7
ld e,a ;ink
push ix
call setcolor ;in: D=paper0..7, E=ink0..15
pop ix
ret
prwin
call setmenucolor
ld e,(ix+MENU_menux) ;x
ld d,(ix+MENU_menuy) ;y
ld b,(ix+MENU_menuhgt) ;hgt
ld c,(ix+MENU_menuwid_chrs) ;wid
;de=yx
;bc=hgt,wid
;de=yx
;bc=hgt,wid
ld a,c
sub 2
ld (winbeginstroka_wid),a
ld (winmidstroka_wid),a
ld (winendstroka_wid),a
ld a,b
cp 2
jr c,prwin_notopline
ld hl,winbeginstroka
call prtableline
dec b
prwin_notopline
ld a,b
cp 2
jr c,prwin_nobottomline
push bc
push de
ld a,d
add a,b
ld d,a ;bottom y
ld hl,winendstroka
call prtableline
pop de
pop bc
dec b
inc d
prwin_nobottomline
winlineN_0
ld hl,winmidstroka
call prtableline
inc d
djnz winlineN_0
ret
prtableline
;hl=tableline data
;de=yx
;b=hgt
;keeps bc,de,ix
push bc
call nv_setxy ;keeps de,hl
prtableline0
ld a,(hl)
or a
jr z,prtablelineq
inc hl
ld b,(hl)
inc hl
call prNsymbol
jr prtableline0
prtablelineq
pop bc
ret
prNsymbol
;a=symbol
;b=count
push de
push hl
push ix
ld c,a
prNsymbol0
push bc
ld a,c
call sendchar
pop bc
djnz prNsymbol0
pop ix
pop hl
pop de
ret
nv_setxy
;de=yx (kept)
;keeps de,hl,ix
push de
push hl
push ix
call setxy
pop ix
pop hl
pop de
ret
winbeginstroka
db 0xc9;'Ј'
db 1
db 0xcd;'='
winbeginstroka_wid=$
db 12;wdtcolumn1
db 0xbb;'ї'
db 1
db 0
winmidstroka
db 0xba;'і'
db 1
db ' '
winmidstroka_wid=$
db 12;wdtcolumn1
db 0xba;'і'
db 1
db 0
winendstroka
db 0xc8;'L'
db 1
db 0xcd;'='
winendstroka_wid=$
db 12;wdtcolumn1
db 0xbc;'-'
db 1
db 0
if 0
prwindow_text
;ld a,1
;prwindow_text0
;hl = window text
;out: ;de=YX of last line
push hl ;text
inc d
inc e
inc e
call nv_setxy ;keeps de,hl,ix
pop hl ;text
prwindow_waitkey_text0
ld a,(hl)
or a
ret z
;dec a;cp 1
;jr z,prwindow_waitkey_textnfiles
;dec a;cp 2
;jr z,prwindow_waitkey_textoutertext
;dec a;cp 3
;jr z,prwindow_waitkey_textnextline
push de
;ld c,0
call prtext
pop de
jr prwindow_waitkey_text0
if 0
prwindow_waitkey_textnfiles
inc hl
push de
push hl
call getmarkedfiles;countmarkedfiles
call prdword
pop hl
pop de
jr prwindow_waitkey_text0
prwindow_waitkey_textoutertext
inc hl
push de
ld e,(hl)
inc hl
ld d,(hl)
inc hl
push hl
ex de,hl
;ld c,0
call prtext
pop hl
pop de
jr prwindow_waitkey_text0
prwindow_waitkey_textnextline
inc hl
inc d
call nv_setxy ;keeps de,hl,ix
jr prwindow_waitkey_text0
endif
prtext
push hl
call strlen ;hl=length
pop de
ld a,h
or l
;de=buf
;hl=len
push de
push hl
call nz,sendchars
pop hl
pop de
add hl,de
inc hl
;hl=after terminator
ret
strlen
;hl=str
;out: hl=length
xor a
ld b,a
ld c,a ;чтобы точно найти терминатор
cpir ;найдём обязательно, если длина=0, то bc=-1 и т.д.
ld h,a
ld l,a
scf
sbc hl,bc
ret
endif
endif
cmd_filename
db "cmd.com",0
filenametext
db "cmd "
tdotmnuz
db ".mnu",0
curdir
ds MAXPATH_sz
par1addr
dw 0
par2addr
dw 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? из (ix+5) читается вроде атрибут shadowcolor
db #01
hintwid;LL6224
db #1e
LL6225
db #00
hintspresent;LL6226
db #00
db #00
DB #00
dw MENU;#622b
MENU
MENU_menux=$-MENU
menux;LL622b
db #ff
MENU_menuy=$-MENU
menuy;LL622c
db #ff
MENU_menuhgt=$-MENU;2
menuhgt;LL622d
db #00
MENU_menuwid_chrs=$-MENU
menuwid_chrs;LL622e
db #00
MENU_menucolor=$-MENU;4
menucolor;LL622f
db #0f
shadowcolor;LL6230
DB #80
menux_chrs;LL6231
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"