Subversion Repositories Spectranet

[/] [branches/] [gnubinutils/] [rom/] [ui_input.asm] - Diff between revs 371 and 384

Show entire file | Details | Blame | View Log

Rev 371 Rev 384
Line 25... Line 25...
; They are designed to hopefully work without needing the ZX ROM itself to
; They are designed to hopefully work without needing the ZX ROM itself to
; have initialized (and so can work when the Spectranet has run its RESET
; have initialized (and so can work when the Spectranet has run its RESET
; routine, but before the ZX ROM has done the same).
; routine, but before the ZX ROM has done the same).
; The routines are designed to work regardless of the maskable interrupt
; The routines are designed to work regardless of the maskable interrupt
; state.
; state.
 
.include        "sysdefs.inc"
 
.include        "sysvars.inc"
 
.include        "page1.xinc"
 
 
;===========================================================================
;===========================================================================
; Definitions - special keys returned by K_DECODE (and therefore F_getkey)
; Definitions - special keys returned by K_DECODE (and therefore F_getkey)
KEY_TRUEVID     equ 0x04
KEY_TRUEVID:    equ 0x04
KEY_INVVID      equ 0x05
KEY_INVVID:     equ 0x05
KEY_CAPSLOCK    equ 0x06
KEY_CAPSLOCK:   equ 0x06
KEY_EDIT        equ 0x07
KEY_EDIT:       equ 0x07
KEY_LEFT        equ 0x08
KEY_LEFT:       equ 0x08
KEY_RIGHT       equ 0x09
KEY_RIGHT:      equ 0x09
KEY_DOWN        equ 0x0A
KEY_DOWN:       equ 0x0A
KEY_UP          equ 0x0B
KEY_UP:         equ 0x0B
KEY_BACKSPACE   equ 0x0C
KEY_BACKSPACE:  equ 0x0C
KEY_ENTER       equ 0x0D
KEY_ENTER:      equ 0x0D
KEY_EXTEND      equ 0x0E
KEY_EXTEND:     equ 0x0E
KEY_GRAPH       equ 0x0F
KEY_GRAPH:      equ 0x0F
 
 
;===========================================================================
;===========================================================================
; F_getkey:
; F_getkey:
; Waits for a key to be pressed, and returns the key in A.
; Waits for a key to be pressed, and returns the key in A.
; The routine returns the key on keydown. The calling routine should then
; The routine returns the key on keydown. The calling routine should then
; wait for keyup before getting the next key.
; wait for keyup before getting the next key.
F_getkey
.globl F_getkey
 
F_getkey:
        ld a, DATAROM           ; key scan routines live here
        ld a, DATAROM           ; key scan routines live here
        call F_pushpageA
        call F_pushpageA
.loop
.loop1:
        call key_scan
        call F_key_scan
        call key_test
        call F_key_test
        jr nc, .loop
        jr nc, .loop1
        ld e, a                 ; partially decoded key is in A, copy it to E
        ld e, a                 ; partially decoded key is in A, copy it to E
        ld d, 8                 ; not in 'K' cursor mode
        ld d, 8                 ; not in 'K' cursor mode
        ld c, 0                 ; FLAGS = 0
        ld c, 0                 ; FLAGS = 0
        call key_code           ; decode keypress into actual ascii value
        call F_key_code         ; decode keypress into actual ascii value
        ld c, a
        ld c, a
        call F_poppageA         ; restore original page A
        call F_poppageA         ; restore original page A
        ld a, c
        ld a, c
        ret
        ret
 
 
;===========================================================================
;===========================================================================
; F_keyup:
; F_keyup:
; Waits for the keyboard not being pressed anywhere that will generate
; Waits for the keyboard not being pressed anywhere that will generate
; a character.
; a character.
F_keyup
.globl F_keyup
 
F_keyup:
        ld a, DATAROM           ; key scan routines live here
        ld a, DATAROM           ; key scan routines live here
        call F_pushpageA
        call F_pushpageA
.loop
.loop2:
        call key_scan
        call F_key_scan
        call key_test
        call F_key_test
        jr c, .loop             ; carry set = key being pressed
        jr c, .loop2            ; carry set = key being pressed
        call F_poppageA
        call F_poppageA
        ret
        ret
 
 
;===========================================================================
;===========================================================================
; F_inputstring:
; F_inputstring:
; Get a string from the keyboard, and null terminate.
; Get a string from the keyboard, and null terminate.
; Parameters: DE = pointer to memory to store the string.
; Parameters: DE = pointer to memory to store the string.
;              C = size of buffer (string length + 1, for the null terminator)
;              C = size of buffer (string length + 1, for the null terminator)
F_inputstring
.globl F_inputstring
 
F_inputstring:
        ld b, c                 ; save length in b
        ld b, c                 ; save length in b
        ld (v_stringptr), de    ; save the pointer
        ld (v_stringptr), de    ; save the pointer
        ld (v_stringlen), bc    ; save the string lengths
        ld (v_stringlen), bc    ; save the string lengths
.inputloop
.inputloop3:
        ld a, '_'               ; cursor - possible TODO - flashing cursor?
        ld a, '_'               ; cursor - possible TODO - flashing cursor?
        call F_putc_5by8        ; display it
        call F_putc_5by8        ; display it
.keyloop
.keyloop3:
        call F_keyup            ; wait for keyup before doing anything
        call F_keyup            ; wait for keyup before doing anything
        call F_getkey           ; wait for a key to be pressed.
        call F_getkey           ; wait for a key to be pressed.
        push hl
        push hl
        ld hl, 0x1000           ; wait some more time so that
        ld hl, 0x1000           ; wait some more time so that
.loop                           ; multi key contacts on Spectrum + / 128
.loop3:                         ; multi key contacts on Spectrum + / 128
        dec hl                  ; membranes all make. Use a delay loop
        dec hl                  ; membranes all make. Use a delay loop
        ld a, h                 ; rather than halt so this routine works
        ld a, h                 ; rather than halt so this routine works
        or l                    ; with interrupts disabled.
        or l                    ; with interrupts disabled.
        jr nz, .loop
        jr nz, .loop3
        pop hl
        pop hl
 
 
        call F_getkey           ; closed.
        call F_getkey           ; closed.
        cp KEY_ENTER            ; enter pressed?
        cp KEY_ENTER            ; enter pressed?
        jr z, .enter            ; handle enter
        jr z, .enter3           ; handle enter
        cp KEY_BACKSPACE        ; backspace pressed?
        cp KEY_BACKSPACE        ; backspace pressed?
        jr z, .backspace        ; handle it
        jr z, .backspace3       ; handle it
        cp ' '                  ; space - lowest printable character
        cp ' '                  ; space - lowest printable character
        jp m, .keyloop          ; do nothing for non-printable char
        jp m, .keyloop3         ; do nothing for non-printable char
        ex af, af'
        ex af, af'
        ld a, (v_stringlen)     ; get remaining buffer size back
        ld a, (v_stringlen)     ; get remaining buffer size back
        cp 1                    ; and if only one byte is left,
        cp 1                    ; and if only one byte is left,
        jr z, .keyloop          ; don't accept more input.
        jr z, .keyloop3         ; don't accept more input.
        call F_backspace        ; backspace over the cursor
        call F_backspace        ; backspace over the cursor
        ex af, af'              ; get keypress back
        ex af, af'              ; get keypress back
        ld hl, (v_stringptr)    ; get current string pointer
        ld hl, (v_stringptr)    ; get current string pointer
        ld (hl), a              ; save entered key
        ld (hl), a              ; save entered key
        inc hl                  ; update pointer
        inc hl                  ; update pointer
        ld (v_stringptr), hl    ; save pointer
        ld (v_stringptr), hl    ; save pointer
        call F_putc_5by8        ; and print the char
        call F_putc_5by8        ; and print the char
        ld a, (v_stringlen)     ; get the remaining byte count
        ld a, (v_stringlen)     ; get the remaining byte count
        dec a                   ; decrement it
        dec a                   ; decrement it
        ld (v_stringlen), a     ; save remaining length
        ld (v_stringlen), a     ; save remaining length
        jr .inputloop           ; and wait for the next key.
        jr .inputloop3          ; and wait for the next key.
.backspace
.backspace3:
        ld bc, (v_stringlen)    ; is the cursor at the start
        ld bc, (v_stringlen)    ; is the cursor at the start
        ld a, c                 ; of the string?
        ld a, c                 ; of the string?
        cp b
        cp b
        jr z, .keyloop          ; yes - so just wait for another key.
        jr z, .keyloop3         ; yes - so just wait for another key.
 
 
        ; To update the screen, the cursor and the character behind
        ; To update the screen, the cursor and the character behind
        ; it must be removed, hence two calls to F_backspace.
        ; it must be removed, hence two calls to F_backspace.
        inc a                   ; increase the remaining byte count
        inc a                   ; increase the remaining byte count
        ld (v_stringlen), a     ; and save it
        ld (v_stringlen), a     ; and save it
        ld hl, (v_stringptr)    ; get the string pointer
        ld hl, (v_stringptr)    ; get the string pointer
        dec hl                  ; rewind the string pointer
        dec hl                  ; rewind the string pointer
        ld (v_stringptr), hl    ; save it
        ld (v_stringptr), hl    ; save it
        call F_backspace        ; remove cursor
        call F_backspace        ; remove cursor
        call F_backspace        ; remove last character
        call F_backspace        ; remove last character
        jr .inputloop
        jr .inputloop3
.enter
.enter3:
        call F_keyup            ; wait until keyup
        call F_keyup            ; wait until keyup
        call F_backspace        ; erase the cursor
        call F_backspace        ; erase the cursor
        ld hl, (v_stringptr)    ; get the string pointer
        ld hl, (v_stringptr)    ; get the string pointer
        ld (hl), 0              ; put the null terminator on the string
        ld (hl), 0              ; put the null terminator on the string
        ret
        ret