mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-27 02:14:19 +00:00
Upload
Digital Research
This commit is contained in:
284
CONTRIBUTIONS/cpm-handbook/cpmsrc/FIG5-8.ASM
Normal file
284
CONTRIBUTIONS/cpm-handbook/cpmsrc/FIG5-8.ASM
Normal file
@@ -0,0 +1,284 @@
|
||||
; 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
|
||||
|
||||
Reference in New Issue
Block a user