Как раз по теме ТС - ввод строки (с обработкой всяких символов и т.д.). Чтобы стало выглядеть красиво, надо TAB c 8 на 10 заменить.
;-----------------------------------------------------------
; Крутая подпрограмма ввода строки
;
; [hl] - Адрес буфера
; +0 - Максимальная длина строки
; +1 - Текущая длина строки
; +2 - Размер окна
; +3 - Координаты окна (y*80+x) or 4000h
; +5 - Позиция курсора в строке
; +6 - Отступ слева
; +7 - строка
InpString:
xor a ; курсор ┬
ld (CStyle),a
ISInit: push hl
push hl
pop ix
ld de,0005h ; Устанавливаем указатель на позицию курсора
add hl,de
ld a,(hl) ; позиция курсора
inc hl
add a,(hl) ; + отступ слева
ld e,a
ld d,0
add hl,de ; Получаем адрес текущего символа
;---------
ISOutStr: ex (sp),hl
push hl ; Адрес буфера
ld de,DMA1+22 ; Временный буфер
push de
ld bc,0006
add hl,bc
ld a,(hl) ; Смещение
inc hl ; Адрес первого символа в строке
ld c,a
ld b,0
add hl,bc
and a
ld a,' '
jr z,$+4
ld a,'░'
ld (de),a
inc de
ld b,(ix+2) ; Берем размер окна
IS004: ld a,(hl) ; Если это последний символ
cp cr
jr z,IS003
ld (de),a
inc de
inc hl ; Ставим указатель на следующий
djnz IS004
jr IS006 ; И обходим забивание пробелами
IS003: ex de,hl
call Fill32
ex de,hl
IS006: ld a,(ix+2) ; Берем размер окна
add a,(ix+6) ; отступ слева
sub (ix+1) ; длина строки
ld a,' '
jr nc,$+4
ld a,'▐'
ld (de),a
pop hl
push hl
ld e,(ix+5) ; Позиция курсора
ld d,0
add hl,de
ld (hl),255
pop hl
ld e,(ix+3)
ld d,(ix+4)
ld b,(ix+2)
inc b
inc b
call LdrVM
pop hl
ex (sp),hl
push hl
ld a,(hl)
cp cr
jr nz,$+4
ld a,' '
ld h,0
ld b,3
rlca
rl h
djnz $-3
and 11111000b
ld l,a
ld de,(CgpBasic)
add hl,de
ld de,DMA1+22
ld b,8
push de
call LdrMV
pop hl
push hl
ld a,(CStyle)
ld c,a
ld b,0
add hl,bc
ld a,8
sub c
ld b,a
ld a,(hl)
cpl
ld (hl),a
inc hl
djnz $-4
ld hl,(CgpBasic)
ld de,255*8
add hl,de
ex de,hl
pop hl
ld b,8
call LdrVM
pop hl
ISInputKey:
push hl
call Inputs
ld b,a
ld hl,ISOnKeyGoTo
call OnKeyGoToFunction
pop hl
ld a,b ; Это случаем не управляющий символ?
cp 32
jr c,ISInputKey ; Тогда игнорируем его!
;----------------------------------------
ld a,(hl)
cp cr
jr z,IS008 ; Добавляем символ к строке
;-
ld a,(CStyle) ; Вставка или надпечатка?
and a
jr z,IS009 ; Надпечатка
;-
ld a,(ix+1) ; Текущая длина
cp (ix+0) ; Сравниваем с максимальной длиной
jr z,ISInputKey ; Если равны, то ничего не делаем
push bc ; Сохраним символ
push hl ; Куда записать
inc (ix+1) ; Увеличиваем текущую длину строки
ld a,(ix+1) ; Текущая длина
sub (ix+6) ; Отступ слева
sub (ix+5) ; Берем текущую позицию курсора
ld c,a
ld b,0
add hl,bc ; Получаем: откуда сдвигать
ld d,h
ld e,l
inc de ; Куда сдвигать
inc bc ; Сколько сдвигать
lddr
pop hl ; Куда записать символ
pop bc ; [a] - какой символ
;-
IS009: ld (hl),b ; Новый символ
inc hl
jr IS010
;-
IS008: ld a,(ix+1) ; Текущая длина
cp (ix+0) ; Сравниваем с максимальной длиной
jr z,ISInputKey ; Если равны, то ничего не делаем
ld (hl),b ; Добавляем символ к строке
inc hl
ld (hl),cr
inc (ix+1) ; Увеличиваем текущую длину строки
IS010: ld a,(ix+5) ; Берем Позицию курсора
cp (ix+2) ; Сравниваем с размером окна
jr z,IS017 ; Если равна
inc (ix+5) ; Увеличиваем позицию курсора
jp ISOutStr ; И выводим стоку
IS017: inc (ix+6) ; Отступ слева
jp ISOutStr
;----------------------------------------
ISEsc: scf
;-
ISEnter: ex af,af'
pop hl ; Адрес текущего символа
ld a,(hl)
cp cr
jr nz,$+4
ld a,' '
ld l,(ix+3) ; Адрес окна
ld h,(ix+4)
ld e,(ix+5) ; Позиция курсора
ld d,0
add hl,de ; Адрес символа с курсором
call WrVrHL ; Затираем курсор символом
ex af,af'
pop hl ; Извлекаем указатель на буфер
ret
;--
ISRight: pop hl
ld a,(hl) ; Текущий символ
cp cr ; Последний?
jp z,ISInputKey
inc hl ; Увеличиваем указатель на текущий символ
ld a,(ix+5) ; Позиция курсора
cp (ix+2) ; Сравниваем с размером окна
jr nz,IS015 ; Если не последняя возможная позиция
inc (ix+6) ; Если последняя, то увеличиваем отступ слева
jp ISOutStr
IS015: inc (ix+5) ; Иначе увеличиваем позицию курсора
jp ISOutStr
;--
ISLeft: pop hl
;
ISLeft_: ld a,(ix+6) ; Слева от окна что-нибудь есть?
and a
jr z,IS013 ; Если нет
ld b,a
ld a,(ix+2) ; Берем размер окна
srl a ; Делим пополам
cp (ix+5)
jr c,IS013 ; Если курсор правее, то сдвигаем его ; Если курсор левее
ld a,b
dec (ix+6) ; Иначе уменьшаем отступ слева
dec hl ; Уменьшаем указатель на текущий символ
jp ISOutStr ; и выводим строку
IS013: ld a,(ix+5)
dec a
jp z,ISInputKey
ld (ix+5),a ; Устанавливаем новую позицию курсора
dec hl ; Уменьшаем указатель на текущий символ
jp ISOutStr ; И выводим строку
;--
ISBackStep:
pop hl
ld a,(ix+6)
add a,(ix+5) ; Мы не на первом символе стоим?
dec a
jp z,ISOutStr ; Если да, то ничего не делаем
;-
ld a,(hl) ; Тогда может за последним?
cp cr
jr nz,IS002
dec (ix+1) ; Уменьшаем текущую длину строки
dec hl ; Возвращаемся на один символ назад
ld (hl),cr ; И устанавливаем указатель конца строки
inc hl
jr ISLeft_
;-
IS002: ld d,h ; Ставим указатель на следующий символ
ld e,l
push hl ; Это будет новый указатель
dec de
ld a,(ix+1)
sub (ix+6) ; Отступ слева
sub (ix+5) ; Добавляем позицию курсора
add a,2 ; + текущий символ + cr
ld c,a
ld b,0
ldir
dec (ix+1) ; Уменьшаем текущую длину строки
pop hl
jr ISLeft_
;--
ISIns: pop hl
ld a,(CStyle)
xor 0 xor 5
ld (CStyle),a
jp ISOutStr
;--
ISDel: pop hl
ld a,(hl)
cp cr
jp z,ISInputKey
ld d,h
ld e,l
push hl
inc hl
ld a,(ix+1) ; Текущая длина строки
sub (ix+6) ; Отступ слева
sub (ix+5) ; Добавляем позицию курсора
inc a
ld c,a
ld b,0
ldir
dec (ix+1) ; Уменьшаем текущую длину строки
pop hl
jp ISOutStr
;--
ISDelToEndOfLine:
pop hl
ld (hl),cr
ld a,(ix+6) ; Отступ слева
add a,(ix+5) ; Позиция курсора в окне
dec a
ld (ix+1),a ; Новая длина строки
jp ISOutStr
;--
ISDelAllLine:
pop hl
ld (ix+1),0 ; Текущая длина строки
ld (ix+5),1 ; Позиция курсора в строке
ld (ix+6),0 ; Отступ слева
ld (ix+7),cr ; Пустая строка
pop hl ; Указатель на блок
jp ISInit ; Переходим на инициализацию буфера
;--
ISBeginOfLine:
pop hl
ld (ix+5),1 ; Позиция курсора в строке
ld (ix+6),0 ; Отступ слева
pop hl
jp ISInit
;--
ISEndOfLine:
pop hl
ld a,(hl) ; Текущий символ
cp cr ; Последний?
jp z,ISOutStr
inc hl ; Увеличиваем указатель на текущий символ
ld a,(ix+5) ; Позиция курсора
cp (ix+2) ; Сравниваем с размером окна
jr nz,IS0151 ; Если не последняя возможная позиция
inc (ix+6) ; Если последняя, то увеличиваем отступ слева
jr ISEndOfLine+1
IS0151: inc (ix+5) ; Иначе увеличиваем позицию курсора
jr ISEndOfLine+1
;------------------------------------------------------------
ISOnKeyGoTo:
db esc
dw ISEsc
db cr
dw ISEnter
db 28
dw ISRight
db 29
dw ISLeft
db 30
dw ISBeginOfLine
db 31
dw ISEndOfLine
db 8
dw ISBackStep
db 18
dw ISIns
db 127
dw ISDel
db 5
dw ISDelToEndOfLine
db 21
dw ISDelAllLine
db 0
;---------------------------------------------------------------------
OnKeyGoToFunction:
ld a,(hl) ; Проверяем
inc hl ; Адрес перехода по клавише
and a ; Конец меню?
ret z ; если да, то возвращаемся
ld e,(hl)
inc hl
ld d,(hl)
inc hl
xor b ; Эта клавиша нажата?
jr nz,OnKeyGoToFunction; Если нет, то продолжаем проверку
pop hl ; Удаляем из стека адрес возврата
ex de,hl ; [hl] - адрес перехода
jp (hl) ; Переходим к функции
;---------------------------------------------------------------------
[свернуть]