|
|
@@ -120,9 +120,10 @@ CONST
|
|
|
not implemented yet is a loud ENoLib, never a silent no-op. *)
|
|
|
BI_ClrScr = 6 ; BI_GotoXY = 7 ; BI_LowVideo = 8 ;
|
|
|
BI_NormVideo = 9 ; BI_ClrEol = 10 ; BI_Delay = 11 ;
|
|
|
+ BI_KeyPressed = 12 ;
|
|
|
(* the sub-codes EmCrtSeq takes *)
|
|
|
CrtClr = 0 ; CrtDl = 1 ; CrtDh = 2 ; CrtCaret = 3 ; CrtEol = 4 ;
|
|
|
- CrtLow = 5 ; CrtNorm = 6 ; CrtDelay = 7 ;
|
|
|
+ CrtLow = 5 ; CrtNorm = 6 ; CrtDelay = 7 ; CrtKey = 8 ;
|
|
|
|
|
|
(* keyword tokens *)
|
|
|
TkNone = 0 ; TkProgram = 1 ; TkBegin = 2 ; TkEnd = 3 ;
|
|
|
@@ -3257,6 +3258,14 @@ BEGIN
|
|
|
fixture had ever exercised the fold. *)
|
|
|
ParseVar (r) ;
|
|
|
RETURN
|
|
|
+ ELSIF (symtab [idx].tag = KBuiltin) AND (symtab [idx].cls = BI_KeyPressed) THEN
|
|
|
+ (* KeyPressed: a boolean FUNCTION with no argument, and TP3 lets it be
|
|
|
+ written without a parameter list (`until KeyPressed'). *)
|
|
|
+ EmCrtSeq (CrtKey) ;
|
|
|
+ r.kind := 2 ;
|
|
|
+ r.cls := TBool ;
|
|
|
+ r.chr := FALSE ;
|
|
|
+ RETURN
|
|
|
ELSIF (symtab [idx].tag = KBuiltin) AND (symtab [idx].cls = BI_Length) THEN
|
|
|
(* LENGTH (s): the string's length byte, loaded inline. No runtime
|
|
|
entry, and no address is pushed - a string's value already carries its
|
|
|
@@ -3674,6 +3683,17 @@ BEGIN
|
|
|
Ebyte (0C6H) ; Ebyte (06H) ; Eword (crtAttrOff) ; Ebyte (07H)
|
|
|
ELSIF which = CrtNorm THEN
|
|
|
Ebyte (0C6H) ; Ebyte (06H) ; Eword (crtAttrOff) ; Ebyte (0FH)
|
|
|
+ ELSIF which = CrtKey THEN
|
|
|
+ (* KeyPressed: DOS AH=0Bh asks whether a character is waiting. AL is
|
|
|
+ 0FFh when one is, 0 when not; the boolean representation here is 0/1.
|
|
|
+ AND AX,1, not AND AL,1: the interrupt leaves AH = 0Bh, so the
|
|
|
+ comparison that follows (`CMP AX,0') would read 0B00h and call the
|
|
|
+ false case TRUE. bootcom happened to return AH=0 (it IRETs the
|
|
|
+ handler's whole AX) and hid this; hlt. No argument, no runtime
|
|
|
+ entry. *)
|
|
|
+ Ebyte (0B4H) ; Ebyte (0BH) ; (* MOV AH,0Bh *)
|
|
|
+ Ebyte (0CDH) ; Ebyte (21H) ; (* INT 21h *)
|
|
|
+ Ebyte (25H) ; Ebyte (01H) ; Ebyte (00H) (* AND AX,1 *)
|
|
|
ELSIF which = CrtDelay THEN
|
|
|
(* Delay(AX) milliseconds: TP3's xdelay, a calibrated busy loop. The
|
|
|
count 110 is TP3's default `delaycnt' for 1 ms (TPSRC1). AX = 0 does
|
|
|
@@ -5317,6 +5337,8 @@ BEGIN
|
|
|
symtab [i].defnd := TRUE ;
|
|
|
i := NewSym ("DELAY" , KBuiltin, BI_Delay , 0, 0, 0, 0, FALSE) ;
|
|
|
symtab [i].defnd := TRUE ;
|
|
|
+ i := NewSym ("KEYPRESSED", KBuiltin, BI_KeyPressed, 0, 0, 0, 0, FALSE) ;
|
|
|
+ symtab [i].defnd := TRUE ;
|
|
|
(* KBD: the console keyboard as a TEXT file. This runtime's read entries
|
|
|
already read the console, so `Read(Kbd, Ch)' drops the file argument and
|
|
|
reads a character exactly as `Read(Ch)' does. *)
|