.export _timed_getch, _set_jiffy_timer, _agetc, _numgetc .export _yngetc, _lcgetc, _jsleep .import _cgetc, _cblank, _cursor .include "atari.inc" ; keyboard and timer functions for taipan. ; sleep for j jiffies. ; extern void __fastcall__ jsleep(unsigned int j); _jsleep: jsr _set_jiffy_timer jiffy_wait: lda CDTMV3 ora CDTMV3+1 bne jiffy_wait rts ; extern void __fastcall__ set_jiffy_timer(unsigned int jiffies); _set_jiffy_timer: ; called by jsleep() also. sei ; disable IRQ while setting timer (probably overkill) sta CDTMV3 stx CDTMV3+1 cli rts ; like curses timeout(5000) followed by getch(): sleep until either ; a key is pressed or the timer expires. returns 0 if no key pressed. ; extern char __fastcall__ timed_getch(void); _timed_getch: lda #$2c ; $012c jiffies = 5 sec (NTSC) or 6 sec (PAL) ldx #$01 jsr _set_jiffy_timer @wait4key: lda CDTMV3 ; has timer counted down to 0? ora CDTMV3+1 beq @done ; yes, return(0) lda CH ; no, check for a keypress ; ...but don't let the capslock or inverse keys count ; as a keypress, here. cmp #$ff ; no key pressed beq @wait4key and #$3f ; mask shift/control bits cmp #$3c ; caps-lock beq @wait4key cmp #$27 ; inverse (atari) key beq @wait4key jmp _agetc ; user hit a key, read it. @done: ;lda #$00 ; return(0), A is already 0 here tax rts ; _agetc removes the inverse-video bit, and if ; a control key is pressed, it turns it into the non-control version ; (e.g. ^A = lowercase a). Keys that can't be mapped to regular ASCII ; (such as clear, delete, escape) are replaced with a space. ; extern unsigned char agetc(void); _agetc: lda #1 ; show cursor jsr _cursor sta FR1+2 ; save old cursor status lda #1 jsr _cblank jsr _cgetc ; get ATASCII code of keypress ; special cases cmp #$9b ; enter key, return as-is beq ok cmp #$9c ; delete key, return as-is beq ok cmp #$7e ; backspace beq ok ; everything else and #$7f ; strip bit 7 (inverse) bne notnull lda #$20 ; map null (heart, ctrl-,) to space notnull: cmp #$20 bcs notcontrol ora #$60 ; 1 - 31 map to 96 - 127 notcontrol: cmp #$7c ; | (pipe, vertical bar) allowed as-is. beq ok cmp #$7b ; rest of range $7b - $7f is unmappable. bcc ok ; (remember, $7e, backspace, was handled above) lda #$20 ok: pha ldx #0 lda FR1+2 jsr _cursor pla ldx #0 rts ; extern unsigned char lcgetc(void); _lcgetc: jsr _agetc cmp #'A' bcc ok cmp #'Z'+1 bcs ok eor #$20 ; lowercase it bcc ok ; extern unsigned char numgetc(void); _numgetc: jsr _agetc cmp #$9b beq ok cmp #$7e ; backspace beq ok cmp #$61 ; allow 'a' for "all" beq ok cmp #$6b ; allow 'k' for 1000 beq ok cmp #$6d ; allow 'm' for 1 million beq ok cmp #$9c ; shift-del beq ok cmp #'0' bcc _numgetc cmp #'9'+1 bcc ok bcs _numgetc ; extern unsigned char __fastcall__ yngetc(char dflt); _yngetc: sta FR0 ; stash default arg jsr _lcgetc cmp #'y' ; return y or n immediately beq ok cmp #'n' beq ok lda FR0 ; otherwise, check for default arg beq _yngetc ; no default, get another keypress rts ; else return the default