;EXPORT:
;initstdio
;receivechar (macro GETCHAR_) - read char from stdin (out: A=char, CY=error)
;receivekey (macro GETKEY_) - read key from stdin (out: A=keylang, C=keynolang(???TODO), CY=error)
;yieldgetkeyloop - wait key from stdin (out: A=keylang, C=keynolang(???TODO), CY=error)
;setcolor (macro SETCOLOR_) - set color attribute (in: d=paper, e=ink)
;setcolor_invisible
;setcolor_visible
;scrolldown ;de=topyx, hl=hgt,wid ;x, wid even
;scrollup ;de=topyx, hl=hgt,wid ;x, wid even
;setxy (macro SETXY_) - set cursor position (in: de=YX, top left is 0;0)
;sendchar (macro PRCHAR_) - send char to stdout (in: A=char)
;sendchars - send chars to stdout (in: de=buf, hl=size, out: A=error)
;setstdouthandle - in: A=handle
;setstdinhandle - in: A=handle
;clearterm - print 25 lines of spaces except one
STDINBUF_SZ=255
initstdio
OS_GETSTDINOUT ;e=stdin, d=stdout, h=stderr
ld a,e
ld (stdinhandle),a
ld a,d
setstdouthandle
ld (stdouthandle),a
ret
setstdinhandle
ld (stdinhandle),a
ret
yieldgetkeyloop
;wait key from stdin (out: A=keylang, C=keynolang(???TODO), CY=error)
;т юфэюь ЇЁхщьх ьюцхЄ яЁшщЄш ьэюую ъэюяюъ (єяЁрты ■∙шщ esc-ъюф)!
YIELDKEEP
jr yieldgetkey_afteryield
yieldgetkey_nokey
;ьюцхЄ с√Є№, ь√ т ёхЁхфшэх esc-ъюфр? Єюуфр эрфю yieldgetkeyloop
ld a,(term_prfsm_curstate)
dec a
jr nz,yieldgetkeyloop
;ld a,7
;out (0xfe),a
YIELD ;хёыш т яЁю°ы√щ Ёрч эшўхую эх с√ыю, Єю YIELD, р эх YIELDKEEP
yieldgetkey_afteryield
;ld a,5
;out (0xfe),a
xor a
ld (wasmouseevent),a
call receivekey
ret c ;error
;с√ы mouse event? ёўшЄрхь чр эрцрЄшх, р яЁшыюцхэшх сєфхЄ ёьюЄЁхЄ№ ъююЁфшэрЄ√ ш ъэюяъє ь√°ш
stdio_mousebuttons=$+1
ld l,0
stdio_mousex=$+1
stdio_mousey=$+2
ld de,0
wasmouseevent=$
ret ;NC=no error
or a ;cp NOKEY ;keylang==0?
jr nz,$+3
cp c ;keynolang==0?
jr z,yieldgetkey_nokey
scf
ccf ;no error
ret
;яюёыхфютрЄхы№эюёЄш ёырЄ№ юфэшь ъєёъюь!
setcolor
;set color attribute (in: d=paper, e=ink)
;CSI Pm m Character Attributes (SGR)
;Ps = 30 Set foreground color to Black.
;Ps = 31 Set foreground color to Red.
;Ps = 32 Set foreground color to Green.
;Ps = 33 Set foreground color to Yellow.
;Ps = 34 Set foreground color to Blue.
;Ps = 35 Set foreground color to Magenta.
;Ps = 36 Set foreground color to Cyan. (Grey?)
;Ps = 37 Set foreground color to White.
;Ps = 39 Set foreground color to default, ECMA-48 3rd.
;Ps = 40 Set background color to Black.
;Ps = 41 Set background color to Red.
;Ps = 42 Set background color to Green.
;Ps = 43 Set background color to Yellow.
;Ps = 44 Set background color to Blue.
;Ps = 45 Set background color to Magenta.
;Ps = 46 Set background color to Cyan.
;Ps = 47 Set background color to White.
;Ps = 49 Set background color to default, ECMA-48 3rd.
;Ps = 8 Invisible, i.e., hidden, ECMA-48 2nd, VT300.
;Ps = 28 Visible, i.e., not hidden, ECMA-48 3rd, VT300.
;Assume that xtermТs resources are set so that the ISO color codes are the first 8 of a set of 16. Then the aixterm colors are the bright versions of the ISO colors:
;Ps = 90 Set foreground color to Black.
;Ps = 91 Set foreground color to Red.
;Ps = 92 Set foreground color to Green.
;Ps = 93 Set foreground color to Yellow.
;Ps = 94 Set foreground color to Blue.
;Ps = 95 Set foreground color to Magenta.
;Ps = 96 Set foreground color to Cyan.
;Ps = 97 Set foreground color to White.
;TODO 1 - BRIGHT ON: ┬ъы■ўхэшх ЁъюёЄш INK. (Bold, VT100.)
;TODO 22 - Normal (neither bold nor faint), ECMA-48 3rd. [21 - BRIGHT OFF: ┬√ъы■ўхэшх ЁъюёЄш INK. (Doubly-underlined, ECMA-48 3rd.)]
ld hl,stdoutbuf
push hl
;push de
;ld a,0x1b
;call sendchar_byte_a
ld (hl),0x1b
inc hl
;ld a,'['
;call sendchar_byte_a
ld (hl),'['
inc hl
;pop de
;push de
ld a,e ;a=ink
cp 8
jr c,$+4
add a,90-30-8
add a,30
call sendchar_num
;ld a,';'
;call sendchar_byte_a
ld (hl),';'
inc hl
;pop de
ld a,d ;a=paper
and 7
add a,40
setcolorq
call sendchar_num
;ld a,'m'
;call sendchar_byte_a
ld (hl),'m'
setcolorqq
inc hl
pop de
or a
sbc hl,de ;de=buf, hl=size
jp sendchars
setcolor_invisible
ld hl,stdoutbuf
push hl
ld (hl),0x1b
inc hl
ld (hl),'['
inc hl
ld a,8
jr setcolorq
setcolor_visible
ld hl,stdoutbuf
push hl
ld (hl),0x1b
inc hl
ld (hl),'['
inc hl
ld a,28
jr setcolorq
scrolldown
;de=topyx, hl=hgt,wid
;x, wid even
ld b,h ;hgt
ld c,l ;wid
ld hl,stdoutbuf
push hl
ld (hl),0x1b
inc hl
ld (hl),'['
inc hl
ld a,c ;wid
call sendchar_num
ld (hl),';'
inc hl
ld a,b ;hgt
call sendchar_num
ld (hl),';'
inc hl
ld a,e ;topx
call sendchar_num
ld (hl),';'
inc hl
ld a,d ;topy
call sendchar_num
ld (hl),'d' ;NON-STANDARD!!!
jr setcolorqq
scrollup
;de=topyx, hl=hgt,wid
;x, wid even
ld b,h ;hgt
ld c,l ;wid
ld hl,stdoutbuf
push hl
ld (hl),0x1b
inc hl
ld (hl),'['
inc hl
ld a,c ;wid
call sendchar_num
ld (hl),';'
inc hl
ld a,b ;hgt
call sendchar_num
ld (hl),';'
inc hl
ld a,e ;topx
call sendchar_num
ld (hl),';'
inc hl
ld a,d ;topy
call sendchar_num
ld (hl),'u' ;NON-STANDARD!!!
jr setcolorqq
clearterm
ld b,24
clearterm0
push bc
ld de,clearterm_data
ld hl,80
call sendchars
pop bc
djnz clearterm0
ld de,clearterm_data
ld hl,79
call sendchars
ld de,0
jp setxy
clearterm_data
ds 80,' '
setxy
;set cursor position (in: de=YX, top left is 0;0)
ld hl,stdoutbuf
push hl
;push de
;ld a,0x1b
;call sendchar_byte_a
ld (hl),0x1b
inc hl
;ld a,'['
;call sendchar_byte_a
ld (hl),'['
inc hl
;pop de
;push de
ld a,d ;y
inc a
call sendchar_num
;ld a,';'
;call sendchar_byte_a
ld (hl),';'
inc hl
;pop de
ld a,e ;x
inc a
call sendchar_num
;ld a,'H'
ld (hl),'H'
jp setcolorqq
sendchar_num
;a=num
push bc
ld c,'0'-1
inc c
sub 10
jr nc,$-3
;push af
;ld a,c
;call sendchar_byte_a
;pop af
ld (hl),c
inc hl
add a,'0'+10
;jr sendchar_byte_a
ld (hl),a
inc hl
pop bc
ret
sendchar
;cp 0x80
;jr nc,sendchar_rustoutf8
;sendchar_byte_a
ld (stdoutbuf),a
ld hl,1
ld de,stdoutbuf
sendchars
;send chars to stdout (in: de=buf, hl=size, out: A=error)
;ld a,6
;out (0xfe),a
sendchars0
push de
push hl
stdouthandle=$+1
ld b,0
OS_WRITEHANDLE ;1436t ;[2718t (1225 before BDOS_writehandle + 195 before BDOS_writehandle_pipe + 477 ..findpipe_byhandle + 301 pipe + 192 end BDOS_writehandle + 326 end BDOS)]
;push af
;push hl
;YIELDKEEP ;2158t
;pop bc ;bytes actually written
;pop af
ld b,h
ld c,l ;bytes actually written
pop hl
pop de
or a
ret nz ;error ;TODO юсЁрсюЄрЄ№? р Єръ яюър яЁюёЄю шчсхурхь чрЎшъыштрэш
sbc hl,bc ;datasize-byteswritten
ret z
ex de,hl
add hl,bc ;dataaddr+byteswritten
ex de,hl
;hl=remaining data size
;de=remaining data addr
push de
push hl
;ld a,5
;out (0xfe),a
YIELDKEEP ;2158t
pop hl
pop de
jr sendchars0
receivechar
;read char from stdin (out: A=char, CY=error)
stdindatacount=$+1
ld a,0
or a
jr z,receivechar_doreceive
dec a
ld (stdindatacount),a
stdindatapointer=$+1
ld hl,0
ld a,(hl)
inc hl
ld (stdindatapointer),hl
or a ;NC=no error
ret
receivechar_doreceive
ld hl,STDINBUF_SZ
ld de,stdinbuf
ld (stdindatapointer),de
stdinhandle=$+1
ld b,0
OS_READHANDLE ;hl=size actually received
or a
scf
ret nz ;error
ld a,h
or l
;ld c,a
ret z ;NC=no error
;ld a,l
ld (stdindatacount),a
jr receivechar
receivekey
;read key from stdin (out: A=keylang, C=keynolang(???TODO), CY=error)
call receivechar
ret c ;error
;a=char
TERM_ST_SINGLE=1 ;1: wait for single symbol
TERM_ST_AFTERESC=2 ;2: after 0x1b
TERM_ST_AFTERESCBRACKET=3 ;3: after 0x1b [ [number] (might be more digits)
TERM_ST_AFTERMOUSE=4
TERM_ST_AFTERMOUSEb=5
TERM_ST_AFTERMOUSEbx=6
term_prfsm_curstate=$+1
ld b,TERM_ST_SINGLE
djnz term_prfsm_nosingle
;cp 0x0a
;ld c,0x0d
;jp z,term_prfsm_keycok
cp 0x1b
ld c,a
jp nz,term_prfsm_keycok
ld hl,term_prfsm_curstate
inc (hl) ;TERM_ST_AFTERESC
jr term_prfsm_nokey
term_prfsm_nosingle
djnz term_prfsm_noafteresc
cp '['
ld c,0x1b
jp nz,term_prfsm_keycok ;esc esc -> esc_key
ld hl,term_prfsm_curstate
inc (hl) ;TERM_ST_AFTERESCBRACKET
term_prfsm_0curnumber_nokey
xor a
ld (term_prfsm_curnumber),a
;xor a ;no key, no error
ld c,a
ret
term_prfsm_noafteresc
djnz term_prfsm_noafterescbracket
sub '0'
cp 10
jr nc,term_prfsm_afterescbracket_nonumber
ld e,a
ld hl,term_prfsm_curnumber
ld a,(hl)
add a,a
add a,a
add a,(hl)
add a,a ;*10
add a,e
ld (hl),a
jr term_prfsm_nokey
term_prfsm_afterescbracket_nonumber
add a,'0'
cp ';'
jr nz,term_prfsm_afterescbracket_nosemicolon
ld a,(term_prfsm_curnumber)
ld (term_prfsm_curnumber1),a
jr term_prfsm_0curnumber_nokey
term_prfsm_afterescbracket_nosemicolon
ld hl,term_prfsm_curstate
ld (hl),TERM_ST_SINGLE
;cp 'H'
cp '~'
jr z,term_prfsm_afterescbracket_tilde
cp 'A'
ld c,key_up
jr z,term_prfsm_keycok
cp 'B'
ld c,key_down
jr z,term_prfsm_keycok
cp 'C'
ld c,key_right
jr z,term_prfsm_keycok
cp 'D'
ld c,key_left
jr z,term_prfsm_keycok
cp 'M'
jr z,term_prfsm_mouse
term_prfsm_nokey
xor a ;no key, no error
ld c,a
ret
term_prfsm_noafterescbracket
djnz term_prfsm_noaftermouse
ld hl,term_prfsm_curstate
inc (hl) ;TERM_ST_AFTERMOUSEb
ld l,0xff
dec a
jr nz,$+3
dec l
dec a
jr nz,$+4
res 1,l
dec a
jr nz,$+4
res 2,l
ld a,l
ld (stdio_mousebuttons),a
xor a ;no key, no error
ld c,a
ret
term_prfsm_noaftermouse
djnz term_prfsm_aftermousebx;term_prfsm_noaftermouseb
ld hl,term_prfsm_curstate
inc (hl) ;TERM_ST_AFTERMOUSEbx
ld (stdio_mousex),a
xor a ;no key, no error
ld c,a
ret
term_prfsm_aftermousebx
ld hl,term_prfsm_curstate
ld (hl),TERM_ST_SINGLE
ld (stdio_mousey),a
ld a,0xc9
ld (wasmouseevent),a
xor a ;no key, no error
ld c,a
ret
term_prfsm_afterescbracket_tilde
ld a,(term_prfsm_curnumber)
cp 3
ld c,key_del
jr z,term_prfsm_keycok
cp 1
ld c,key_home
jr z,term_prfsm_keycok
cp 4
ld c,key_end
jr z,term_prfsm_keycok
cp 2
ld c,key_ins
jr z,term_prfsm_keycok
jr term_prfsm_nokey
term_prfsm_keycok
ld hl,term_prfsm_curstate
ld (hl),TERM_ST_SINGLE
xor a
or c ;NC=no error
ret
term_prfsm_mouse
ld hl,term_prfsm_curstate
ld (hl),TERM_ST_AFTERMOUSE
xor a ;no key, no error
ld c,a
ret
term_prfsm_curnumber
db 0
term_prfsm_curnumber1
db 0
stdoutbuf
db "-[00;00m"
stdinbuf
ds STDINBUF_SZ