mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-26 18:04:07 +00:00
284 lines
8.0 KiB
NASM
284 lines
8.0 KiB
NASM
; Figure 5-8
|
||
;
|
||
;--------------------------------------------------------------
|
||
; TESTBED CODE
|
||
; Because of the complexity of this subroutine, the actual
|
||
; testbed code has been left in this example. It assumes
|
||
; that DDT or ZSID will be used to checkout
|
||
IF 1 ;Change to IF 0 to disable testbed
|
||
ORG 100H
|
||
JMP START ;Bypass "variables" setup by DDT
|
||
OPTIONS: DB 0 ;Option Flags
|
||
TERMS: DB 'A','E','I',0 ;Terminators
|
||
BUFFER DB 5 ;Max. Characters in Buffer
|
||
DB 0 ;Actual Count
|
||
DB 99,99,99,99,99,99,99 ;Data Bytes
|
||
START:
|
||
LXI H,BUFFER ;Get address of buffer
|
||
LXI D,TERMS ;Address of terminator table
|
||
LDA OPTIONS ;Get options set by DDT
|
||
MOV B,A ;Put in correct register
|
||
CALL RCS ;Enter subroutine
|
||
CALL 38H ;Force DDT breakpoint
|
||
JMP START ;Test again
|
||
ENDIF ;End of testbed x`ce
|
||
;---------------------------------------------------------------
|
||
;
|
||
; RCS : Read Console String (using Raw Input)
|
||
;
|
||
; Reads a string of characters into a memory buffer using
|
||
; Raw Input. Supports options :
|
||
;
|
||
; * to echo characters or not (when echoing, a Carriage
|
||
; Return will be echoed followed by Line Feed)
|
||
; * warm boot on input of Control-C or not
|
||
; * terminating input either on :
|
||
; - max. no of chars input
|
||
; - matching terminator character
|
||
;
|
||
; Calling Sequence
|
||
;
|
||
; LXI H,BUFFER Buffer has structure
|
||
; BUFFER: DB 10 Max. size
|
||
; DB 0 Actual Read
|
||
; DS 10+1 Buffer area
|
||
; MVI B,OPTIONS Options required (see EQUates)
|
||
; LXI D,TERMS Pointer to 00H-byte terminated
|
||
; Chars, any one of which is a terminator.
|
||
; CALL RCS
|
||
;
|
||
; Exit Parameters
|
||
;
|
||
; BUFFER : Updated with data bytes and actual character count
|
||
; input. (Does not include the terminator).
|
||
; A = Terminating Code
|
||
; 0 = Maximum number of characters input.
|
||
; NZ = Terminator character found.
|
||
;
|
||
RCS$ECHO EQU 0000$0001B ;Input characters to be echoed
|
||
RCS$ABORT EQU 0000$0010B ;Abort on Control-C
|
||
RCS$FOLD EQU 0000$0100B ;Fold lower case to upper
|
||
RCS$TERM EQU 0000$1000B ;DE -> Term. char. set
|
||
;
|
||
B$DIRCONIO EQU 6 ;Direct console I/O
|
||
BDOS EQU 5 ;BDOS entry point
|
||
|
||
CTL$C EQU 03H ;Control-C
|
||
CR EQU 0DH ;Carriage Return
|
||
LF EQU 0AH ;Line Feed
|
||
BS EQU 08H ;Backspace
|
||
|
||
RCS$ST: ;Internal standard terminator table
|
||
DB 0DH ;Carriage return
|
||
DB 0AH ;Line feed
|
||
DB 0 ;End of table
|
||
;
|
||
RCS$BSS: ;Destructive backspace sequence
|
||
DB BS,' ',BS,0
|
||
;
|
||
RCS: ;<<<<< Main Entry
|
||
INX H ;HL -> Actual count
|
||
MVI M,0 ;Reset to initial state
|
||
DCX H ;HL -> Max. count
|
||
RCS$L:
|
||
PUSH H ;Save buffer pointer
|
||
CALL RCS$GC ;Get character and execute :
|
||
; ECHO, ABORT, and FOLD options
|
||
;C = character input
|
||
POP H ;Recover buffer pointer
|
||
MVI A,RCS$TERM ;Check if user-specified terminator
|
||
ANA B ;B = options
|
||
JNZ RCS$UST ;User specified terminators
|
||
LXI D,RCS$ST ;Standard terminators
|
||
RCS$UST:
|
||
CALL RCS$CT ;Check for terminator
|
||
JZ RCS$NOTT ;Not terminator
|
||
MOV B,A ;Preserve terminating char
|
||
RCS$MCI: ;(Max. char input shares this code)
|
||
MVI C,0 ;Terminate buffer
|
||
CALL RCS$SC ;Save character
|
||
MOV A,B ;Recover terminating char
|
||
ORA A ;Set flags
|
||
RET
|
||
RCS$NOTT: ;Not a terminator
|
||
MVI A,BS ;Check for backspace
|
||
CMP C
|
||
JZ RCS$BS ;Backspace entered
|
||
CALL RCS$SC ;Save character in buffer
|
||
CALL RCS$UC ;Update count
|
||
JNZ RCS$L ;Not max. so get another char
|
||
MVI B,0 ;Fake terminating char
|
||
JMP RCS$MCI ;A = 0 for max. chars input
|
||
;
|
||
RCS$BS: ;Backspace entered
|
||
PUSH H ;Save buffer pointer
|
||
INX H ;HL -> actual count
|
||
DCR M ;Backup one
|
||
JM RCS$NBS ;Check if count now -ve
|
||
LXI H,RCS$BSS ;HL -> Backspacing sequence
|
||
MVI A,RCS$ECHO ;No, check if echoing
|
||
ANA B ;(BS will have been echoed if so)
|
||
JZ RCS$BSNE ;No, input BS not echoed
|
||
INX H ;Bypass initial Backspace
|
||
RCS$BSNE:
|
||
PUSH B ;Save Options and character
|
||
PUSH D ;Save terminator table pointer
|
||
CALL WCS ;Write console string
|
||
POP D ;Recover terminator table pointer
|
||
POP B ;Recover options and character
|
||
JMP RCS$BSX ;Exit from Backspace logic
|
||
RCS$NBS:
|
||
INR M ;Reset count to 0
|
||
RCS$BSX:
|
||
POP H ;Recover buffer pointer
|
||
JMP RCS$L ;Get next character
|
||
|
||
RCS$SC: ;Save character in C in buffer
|
||
;HL -> buffer pointer
|
||
PUSH D ;Save terminator table pointer
|
||
PUSH H ;Save buffer pointer
|
||
INX H ;HL -> actual count in buffer
|
||
MOV E,M ;Get actual count
|
||
INR E ;Count of 0 points to first data byte
|
||
MVI D,0 ;Make word value of actual count
|
||
DAD D ;HL -> next free data byte
|
||
MOV M,C ;Save data byte away
|
||
POP H ;Recover buffer pointer
|
||
POP D ;Recover terminator table pointer
|
||
RET
|
||
;
|
||
RCS$UC: ;Update buffer count and check for max.
|
||
;Return Z set if = to max, NZ if not
|
||
;HL -> buffer on entry
|
||
PUSH H ;Save buffer pointer
|
||
MOV A,M ;Get max. count
|
||
INX H ;HL -> actual count
|
||
INR M ;Increase actual count
|
||
CMP M ;Compare max. to actual
|
||
POP H ;Recover buffer pointer
|
||
RET ;Z-flag set
|
||
;
|
||
RCS$GC: ;Get character and execute
|
||
; ECHO, ABORT and FOLD options
|
||
PUSH D ;Save terminator table pointer
|
||
PUSH H ;Save buffer pointer
|
||
PUSH B ;Save option flags
|
||
RCS$WT:
|
||
MVI C,B$DIRCONIO ;Function code
|
||
MVI E,0FFH ;Specify input
|
||
CALL BDOS
|
||
ORA A ;Check if data waiting
|
||
JZ RCS$WT ;Go back and wait
|
||
POP B ;Recover option flags
|
||
MOV C,A ;Save data byte
|
||
MVI A,RCS$ABORT ;Check if abort option enabled
|
||
ANA B
|
||
JZ RCS$NA ;No abort
|
||
MVI A,CTL$C ;Check for control-C
|
||
CMP C
|
||
JZ 0 ;Warm boot
|
||
RCS$NA:
|
||
MVI A,RCS$FOLD ;Check if folding enabled
|
||
ANA B
|
||
CNZ TOUPPER ;Fold to UPPER CASE
|
||
MVI A,RCS$ECHO ;Check if echo required
|
||
ANA B
|
||
JZ RCS$NE ;No echo required
|
||
PUSH B ;Save options and character
|
||
MOV E,C ;Move character for output
|
||
MVI C,B$DIRCONIO ;Function code
|
||
CALL BDOS ;Echo character
|
||
POP B ;Recover options and character
|
||
MVI A,CR ;Check if Carriage Return
|
||
CMP C
|
||
JNZ RCS$NE ;No
|
||
PUSH B ;Save options and character
|
||
MVI C,B$DIRCONIO ;Function code
|
||
MVI E,LF ;Output line feed
|
||
CALL BDOS
|
||
POP B ;Recover options and character
|
||
RCS$NE:
|
||
POP H ;Recover buffer pointer
|
||
POP D ;Recover terminator table
|
||
RET ;Character in C
|
||
;
|
||
RCS$CT: ;Check for terminator
|
||
;C = character just input
|
||
;DE -> 00-byte character string of Term. Chars
|
||
;Returns Z status if no match found, NZ if found
|
||
; (with A = C = Terminating character)
|
||
PUSH D ;Save table pointer
|
||
RCS$CTL:
|
||
LDAX D ;Get next terminator character
|
||
ORA A ;Check for end of table
|
||
JZ RCS$CTX ;No terminator matched
|
||
CMP C ;Compare to input character
|
||
JZ RCS$CTX ;Terminator matched
|
||
INX D ;Move to next terminator
|
||
JMP RCS$CTL ;loop to try next character in table
|
||
RCS$CTX: ;Check terminator exit
|
||
ORA A ;At this point, A will either be 0
|
||
; if the end of the table has been
|
||
; reached, or NZ if a match has been
|
||
; found. The Z-flag will be set.
|
||
POP D ;Recover table pointer
|
||
RET
|
||
|
||
;
|
||
; TOUPPER - Fold lower case letters to upper
|
||
;
|
||
; C = Character on entry and exit
|
||
;
|
||
TOUPPER:
|
||
MVI A,'a'-1 ;Check if folding needed
|
||
CMP C ;Compare to input char
|
||
JNC TOUPX ;No, char is < or = 'a'-1
|
||
MVI A,'z' ;Maybe, char is = or > 'a'
|
||
CMP C
|
||
JC TOUPX ;No, char is > 'z'
|
||
MVI A,0DFH ;Fold character
|
||
ANA C
|
||
MOV C,A ;Return folded character
|
||
TOUPX:
|
||
RET
|
||
;
|
||
;
|
||
; WCS - Write Console String (Using Raw I/O)
|
||
;
|
||
; Output terminates when a 00H byte is encountered.
|
||
; A Carriage Return is output when a Line Feed is
|
||
; encountered.
|
||
;
|
||
; Calling sequence
|
||
;
|
||
; LXI H,BUFFER
|
||
; CALL WCS
|
||
;
|
||
; Exit Parameters
|
||
;
|
||
; HL -> 00H byte terminator
|
||
;
|
||
;
|
||
WCS:
|
||
PUSH H ;Save buffer pointer
|
||
MOV A,M ;Get next character
|
||
ORA A ;Check if 00H
|
||
JZ WCSX ;Yes, exit
|
||
CPI LF ;Check if Line Feed
|
||
CZ WCSLF ;Yes, O/P CR
|
||
MOV E,A ;Character to be output
|
||
MVI C,B$DIRCONIO ;Function Code
|
||
CALL BDOS ;Output character
|
||
POP H ;Recover Buffer pointer
|
||
INX H ;Update to next char.
|
||
JMP WCS ;Output next char
|
||
WCSLF: ;Line Feed encountered
|
||
MVI C,B$DIRCONIO ;Function Code
|
||
MVI E,CR ;Output a CR
|
||
CALL BDOS
|
||
MVI A,LF ;Recreate Line Feed
|
||
RET ;Output LF
|
||
WCSX: ;Exit
|
||
POP H ;Balance the stack
|
||
RET
|
||
|