collapseos/arch/z80/trs80/blk.fs
Virgil Dupras 475caf35f4 Make KEY non-blocking
... and rename it to KEY?. Then, add KEY from KEY? for its blocking
version.

I need this for an upcoming Remote Shell feature. If a Collapse OS
system remotely controls another shell, it needs to be able to poll
both the remote system and the local keyboard at the same time. A
blocking KEY is incompatible with this.

In some places, the polling mechanism doesn't make sense, so this
new KEY? always returns a character. In some places, I just haven't
implemented the mechanism yet, so I kept the old blocking code and
added a "always 1" flag as a temporary shim.

I have probably broken something, but in emulators, Collapse OS runs
fine. It's an important reminder of what will be lost with the new
"dogfooding" approach (see recent mailing list message): without
emulators, it's much harder to to sweeping changes like this without
breaking stuff.

It's fine, I don't expect many more of these core changes to the
system. It's nearly feature-complete.
2021-01-01 08:23:59 -05:00

140 lines
3.6 KiB
Forth

( ----- 600 )
TRS-80 Recipe
Support code for the TRS-80 recipe. Contains drivers for the
keyboard, video and floppy. At the moment, they are thin layer
over the drivers provided by TRSDOS' SVC.
Load with "602 LOAD".
There is also the RECV program at B612.
( ----- 602 )
1 8 LOADR+
( ----- 603 )
CODE (key?) ( -- c? f ) ( TODO: make non-blocking )
A 0x01 LDri, ( @KEY )
0x28 RST,
PUSHA, PUSH1,
;CODE
CODE (emit) EXX, ( protect BC )
BC POP, ( c == @DSP arg ) chkPS,
A 0x02 LDri, ( @DSP )
0x28 RST,
EXX, ( unprotect BC ) ;CODE
CODE AT-XY EXX, ( protect BC )
DE POP, H E LDrr, ( Y )
DE POP, L E LDrr, ( X ) chkPS,
A 0x0f LDri, ( @VDCTL ) B 3 LDri, ( setcur )
0x28 RST,
EXX, ( unprotect BC ) ;CODE
( ----- 604 )
: LINES 24 ; : COLS 80 ;
: XYMODE 0x70 RAM+ ;
: CELL! COLS /MOD AT-XY (emit) ;
CODE BYE
HL 0 LDdi,
A 0x16 LDri, ( @EXIT )
0x28 RST,
CODE @DCSTAT ( drv -- f ) EXX, ( protect BC )
BC POP,
chkPS,
A 0x28 LDri, ( @DCSTAT )
0x28 RST,
PUSHZ,
EXX, ( unprotect BC ) ;CODE
( ----- 605 )
CODE @RDSEC ( drv cylsec addr -- f ) EXX, ( protect BC )
HL POP,
DE POP,
BC POP,
chkPS,
A 0x31 LDri, ( @RDSEC )
0x28 RST,
PUSHZ,
EXX, ( unprotect BC ) ;CODE
( ----- 606 )
CODE @WRSEC ( drv cylsec addr -- f ) EXX, ( protect BC )
HL POP,
DE POP,
BC POP,
chkPS,
A 0x35 LDri, ( @WRSEC )
0x28 RST,
PUSHZ,
EXX, ( unprotect BC ) ;CODE
CODE @GET ( a -- c f )
DE POP,
chkPS,
A 0x03 LDri, ( @GET )
0x28 RST,
PUSHA, PUSHZ,
;CODE
( ----- 607 )
CODE @PUT ( c a -- f ) EXX, ( protect BC )
DE POP,
BC POP,
chkPS,
A 0x04 LDri, ( @PUT )
0x28 RST,
PUSHZ,
EXX, ( unprotect BC ) ;CODE
( ----- 609 )
: _err LIT" FDerr" ERR ;
: _cylsec ( sec -- cs, return sector/cylinder for given secid )
( 4 256b sectors per block, 10 sec per cyl, 40 cyl max )
10 /MOD ( sec cyl )
DUP 39 > IF _err THEN
8 LSHIFT + ( cylsec )
;
: FD@! ( wref blk -- )
1 @DCSTAT NOT IF _err THEN
2 LSHIFT ( 4 * -- wr sec )
4 0 DO ( wr sec )
DUP I + _cylsec ( wr sec cs )
I 8 LSHIFT BLK( + ( wr sec cs addr )
1 ROT ROT ( wr sec drv cs addr )
4 PICK EXECUTE NOT IF _err THEN
LOOP 2DROP ;
( ----- 610 )
: FD@ ['] @RDSEC SWAP FD@! ;
: FD! ['] @WRSEC SWAP FD@! ;
: FD$ ['] FD@ BLK@* ! ['] FD! BLK!* ! ;
: CL$ 0x02 0xe8 PC! ( UART RST ) 0xee 0xe9 PC! ( 9600 bauds )
0b01101100 0xea PC! ( word8 no parity RTS ) ;
: CL> BEGIN 0xea PC@ 0x40 AND UNTIL 0xeb PC! ;
: CL< BEGIN 0xea PC@ 0x80 AND UNTIL 0xeb PC@ ;
( ----- 612 )
( We process the 0x20 exception by pre-putting a mask in the
(HL) we're going to write to. If it wasn't a 0x20, we put a
0xff mask. If it was a 0x20, we put a 0x7f mask. )
: @GET,
A 0x03 LDri, ( @GET )
DE COM_DRV_ADDR LDdi,
0x28 RST, JRNZ, L2 FWR ( maybeerror )
A ORr,
CZ RETc, ( Sending a straight NULL ends the comm. ) ;
: @PUT, ( @PUT that char back )
C A LDrr,
A 0x04 LDri, ( @PUT )
0x28 RST, JRNZ, L3 FWR ( error )
A C LDrr, ;
H@ ORG !
HL DEST_ADDR LDdi, ( cont. )
( ----- 613 )
BEGIN,
A 0xff LDri, (HL) A LDrr, ( default mask )
L1 BSET ( loop2 ) @GET, @PUT,
0x20 CPi, JRZ, L4 FWR ( escapechar )
( not an escape char, just apply the mask and write )
(HL) ANDr, (HL) A LDrr,
HL INCd,
JR, AGAIN,
L4 FSET ( escapechar, adjust by setting (hl) to 0x7f )
7 (HL) RES, JR, L1 BWR ( loop2 )
L2 FSET ( maybeerror, was it an error? )
A ORr, JRZ, L1 BWR ( loop2, not an error )
L3 FSET ( error )
C A LDrr, ( error code from @GET/@PUT )
A 0x1a LDri, ( @ERROR ) 0x28 RST, RET,