| Z80 Line Editor
|
The Spectrum INPUT
command uses the bottom of the
screen. On most other platforms, you can use INPUT
anywhere on the screen. This Z80 code provides a simple line
editor to allow you to enter characters with the input
line displayed anywhere on the screen.
DELETE deletes the previous character, ENTER returns the
current line. If enabled, BREAK aborts the input. All
other control codes are ignored. All symbol characters can
be entered with the
"Symbol Shift"
layout by pressing
Symbol-Shift and the relevant key, and © is entered
with Symbol-Shift-I. The text is displayed where-ever the
current cursor is, so you can display a prompt before calling.
The code can be conditionally built to allow:
A specific cursor character
A CAPS/lower cursor
Keypress click
Maximum length checking
BREAK to abort
Download: input.asm (3K).
| |
; INPUT.ASM
; ZX Spectrum Text input routine - J.G.Harston
; --------------------------------------------
; On entry HL=address to enter text.
; B=if enabled, maximum line length, excluding <cr>.
; On exit HL=address of text, terminated with <cr>.
; B=length of text, excluding <cr>, up to 255 characters.
; Cy: clear=ok, set=BREAK.
; Alternate registers corrupted.
; Requires IY=>system variables, interupts on, IRQ routine at #38 running.
; Stand-alone routine, does not need external IORDCH.
; Size 121-163 bytes.
; Options:
;IOCURSR EQU 95 ; Cursor character, 1=show CAPS
IOCURSR EQU 1 ; Cursor character, 1=show CAPS
;IOCLICK EQU 0 ; Key click, 0=no click
IOBREAK EQU 1 ; Allow BREAK to stop input
;IOCURSR EQU 143 ; Cursor character, or 0=off, 1=show CAPS
IOCLICK EQU 1 ; Key click, 0=no click
IOMAXLN EQU 1 ; Enable maximum length
IOINPUT PUSH HL ; Save start of text
RES 5,(IY+1) ; Set 'no key pressed'
IF IOMAXLN
LD C,B ; C=maximum length
ENDIF
LD B,0 ; Initialise zero length
IORDLP
IF IOCURSR>31
LD A,IOCURSR
RST 16 ; Output cursor
ENDIF
IF IOCURSR=1
SET 7,(IY+85) ; Flashing
LD A,&43
BIT 3,(IY+48) ; Test CAPS
JR NZ,IORDNXT
LD A,&4C
IORDNXT RST 16 ; Output cursor
RES 7,(IY+85)
ENDIF
IF IOCURSR
LD A,8
RST 16 ; Back over cursor
ENDIF
IORDGET HALT ; Wait for interupt
IF IOBREAK
CALL &1F54 ; Test BREAK key
CCF
JR C,IORDBRK
ENDIF
BIT 5,(IY+1)
JR Z,IORDGET ; Loop until key pressed
LD A,(23560) ; Get keypress
RES 5,(IY+1) ; Set 'no key pressed'
CP 6
JR Z,IORDCAP ; CAPS pressed
IF IOCLICK
PUSH AF ; BEEPER corrupts all registers
PUSH BC
PUSH DE
PUSH HL
PUSH IX
LD D,0
LD E,(IY-1)
LD HL,&00C8
CALL &03B5 ; Keyclick
POP IX
POP HL
POP DE
POP BC
POP AF
ENDIF
CP 12
JR Z,IORDDEL ; DELETE pressed
CP 13
JR Z,IORDENT ; ENTER pressed, done
CP 128
JR C,IORDCHR ; Character pressed
SUB 194
JR NC,IORDSYM
LD A,2
IORDSYM AND 15
ADD A,IORDCNV & 255 ; Index into conversion table
PUSH HL
LD L,A
LD H,IORDCNV / 256
LD A,(HL)
POP HL
IORDCHR CP 32
JR C,IORDGET ; Not character, loop back
LD (HL),A ; Store character
IF IOMAXLN
LD A,B
CP C
JR NC,IORDGET ; Too long
INC B ; Increment length
LD A,(HL)
ELSE
INC B ; Increment length
JR Z,IORDBAK ; Too long, skip back
ENDIF
RST 16 ; Print character
INC HL ; Point to next location
JR IORDLP ; Loop for next
IORDCAP LD A,(23658)
XOR 8 ; Toggle CAPSLOCK
LD (23658),A
JR IORDLP
IORDDEL LD A,B
AND A
JR Z,IORDGET ; Nothing to delete
LD A,32 ; Overwrite cursor
RST 16
LD A,8 ; Backspace
RST 16
LD A,8 ; Backspace
RST 16
DEC HL ; Decrement pointer
IORDBAK DEC B ; Decrement length
IF IORDBAK-IORDLP<126
JR IORDLP ; Loop for next
ELSE
JP IORDLP ; Loop for next
ENDIF
IORDENT LD (HL),A ; Insert terminating <cr>
IORDBRK
IF IOCURSR
PUSH AF ; Save Ok/BREAK flag
LD A,32 ; Overwrite cursor
RST 16
POP AF
ENDIF
LD A,13
CALL NC,16 ; NEWL if not BREAK, returns NC
POP HL ; Get text pointer back
RET ; Exit
; *NB* Table must not wrap over page boundary
IORDCNV DB 126,124,127,93,91,0 ; ~ | (C) ] [ .
DB 0,0,0,125,123,92 ; . . . } { \
Authored by J.G.Harston
Last update: 19-Dec-2023