[img] Z80 Line Editor
 MDFS::Info.Comp.Spectrum.ProgTips.Editors.editmc/htm Search  

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	; . .  .  } { \
    

    Best viewed with Any Browser Valid HTML 4.0! Authored by J.G.Harston
    Last update: 19-Dec-2023