mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 08:54:17 +00:00
820 lines
13 KiB
NASM
820 lines
13 KiB
NASM
title 'SAVE.RSX - CP/M 3.0 save routine. July 1982'
|
||
; *************************************************
|
||
; *
|
||
; * Title: SAVE.RSX Resident System eXtension
|
||
; * Date: 7/28/82
|
||
; * Author: Thomas J. Mason
|
||
; *
|
||
; * Modified:
|
||
; * 11/30/82 - Thomas J. Mason
|
||
; * Added trap for function 60 to fix PUT and SAVE
|
||
; * bios vector mods.
|
||
; *
|
||
; * Modified:
|
||
; * 17 May 1998 - John Elliott
|
||
; * Apply DRI patch 18 and "multiple calls" bug fix
|
||
; *
|
||
; *********************************************************
|
||
;
|
||
; Copyright (c) 1982
|
||
; Digital Research
|
||
; PO Box 579
|
||
; Pacific Grove, Ca. 93950
|
||
;
|
||
TRUE equ 0FFFFh
|
||
FALSE equ not TRUE
|
||
;
|
||
; BIOS and BDOS Jump vectors
|
||
;
|
||
WBOOT equ 0
|
||
WBTADR equ 1 ;address of boot in BIOS
|
||
BDOS equ 5 ;BDOS jump vector
|
||
BDOSAD equ 6 ;location of instructions
|
||
DFCB equ 05Ch ;default FCB
|
||
;
|
||
; BDOS Function calls
|
||
;
|
||
BDOSAD equ 6 ;BDOS jump address
|
||
PSTRING equ 9 ;print string
|
||
BUFIN equ 10 ;console buffer input
|
||
CFILE equ 16 ;file close
|
||
DFILE equ 19 ;file delete
|
||
WFILE equ 21 ;file write
|
||
MFILE equ 22 ;make file
|
||
SETDMA equ 26 ;set DMA function
|
||
BDOSER equ 45 ;Set BDOS error mode
|
||
GETSCB equ 49 ;get/set scb func #
|
||
LDRSX equ 59 ;function for RSX load
|
||
CALRSX equ 60 ;call rsx func #
|
||
CONMOD equ 109 ;GET/SET Console Mode
|
||
;
|
||
; Non Printable ASCII characters
|
||
;
|
||
CTL$C equ 03 ;CONTROL-C
|
||
CR equ 13 ;ASCII Carrige Return
|
||
LF equ 10 ;ASCII Line Feed
|
||
;
|
||
VERSION equ 31 ;[JCE] Version 3.1
|
||
;
|
||
; Buffer size
|
||
;
|
||
CONMAX equ 14 ;[JCE] Patch 18: console buffer maximum should be 14
|
||
STKSZE equ 010h ;size fo stack
|
||
SCBOST equ 068h ;page boundary + to jmp instr
|
||
RETDSP equ 0FEh ;RETurn and DiSPlay mode
|
||
JUMP equ 0C3h ;opcode for jump
|
||
LXIH equ 21h ;lxi instr to poke
|
||
BSNLY equ 07Fh ;restore bios jump table only
|
||
CMMON equ 0F9h ;offset of common memory base from pg. bound
|
||
;
|
||
; *********************************
|
||
; * *
|
||
; * The Save Program *
|
||
; * *
|
||
; *********************************
|
||
;
|
||
db 0,0,0,0,0,0
|
||
jmp PREFIX
|
||
NEXTJ:
|
||
db JUMP ;jump
|
||
NEXT:
|
||
db 0,0 ;next module in line
|
||
PREV:
|
||
dw 5 ;previous, initialized to 5
|
||
STKYBT: db 00h ;for warm start
|
||
db 0
|
||
db 'SAVE '
|
||
ds 3
|
||
;
|
||
;
|
||
; This is the check performed every time the BDOS is
|
||
; called to see if the RSX is to be invoked
|
||
;
|
||
PREFIX:
|
||
mov a,c ;set up for compare
|
||
cpi CALRSX
|
||
jnz GETGOING
|
||
|
||
push b
|
||
push d
|
||
push h
|
||
lxi h,0000h ;zero out HL
|
||
dad d ; <HL> -> RSXPB
|
||
mov a,m ;get the byte
|
||
cpi 160 ; sub function defined
|
||
|
||
pop h
|
||
pop d
|
||
pop b
|
||
jz GOODBYE ;remove this RSX
|
||
|
||
GETGOING:
|
||
;
|
||
cpi LDRSX ;do the compare
|
||
NOPME: jz START ;[JCE] For the bug fix, see below
|
||
lhld NEXT ;get address for continue
|
||
pchl ;get going.....
|
||
;
|
||
;
|
||
;
|
||
START:
|
||
;
|
||
;[JCE] Bug. This rewires the jump vectors every time the Loader is called,
|
||
; and some programs call the Loader more than once to load overlays.
|
||
; The second time it is called, SAVE is left pointing at itself rather
|
||
; than the real BIOS.
|
||
;
|
||
; They are equal so get the BIOS address to point here
|
||
; in case of a Func 0 call
|
||
;
|
||
push b ;save state
|
||
push d ; of registers
|
||
;
|
||
; check for jump byte before the SCB
|
||
call GETSET$SCB
|
||
shld SCBADR ;save address for later
|
||
;
|
||
mvi l,CMMON+1 ;offset into scb to check BIOS
|
||
mov a,m ;get byte
|
||
ora a ;check for zero
|
||
mvi a,FALSE ;store for insurance
|
||
sta CHGJMP ;non-banked = FALSE
|
||
jz NBNKED ;high byte zero if non-banked
|
||
;
|
||
lhld SCBADR ;restor SCB
|
||
mvi l,SCBOST ;offset from page for instr
|
||
mov a,m ;get byte
|
||
cpi JUMP ;is it a jump?
|
||
jnz MORRSX ;we are not alone
|
||
mvi a,TRUE
|
||
sta CHGJMP ;set flag
|
||
mvi m,LXIH ;put in lxi h,xxxx mnemonic
|
||
;
|
||
MORRSX:
|
||
; continue with processing
|
||
NBNKED:
|
||
;
|
||
;
|
||
lhld WBTADR ;get address at 01h
|
||
inx h ;now points to address of jmp xxxx
|
||
mov a,m ;get low order byte
|
||
sta BIOSAD
|
||
inx h ;next byte
|
||
mov a,m
|
||
sta BIOSAD+1 ;high order byte
|
||
;
|
||
; Now poke the BIOS address to point to
|
||
; the save routine.
|
||
;
|
||
lxi d,BEGIN ;begining of routine
|
||
mov m,d
|
||
dcx h ;point back to first byte
|
||
mov m,e ;low order
|
||
;
|
||
mvi c,BDOSER ;now set BDOS errormode
|
||
mvi e,RETDSP ;to trap any hard
|
||
call BDOS ;errors
|
||
;
|
||
;
|
||
; [JCE] Fix for the bug I mentioned earlier
|
||
;
|
||
lxi h,0 ;[JCE] Nop out the jump to this routine. Crude
|
||
shld NOPME ;[JCE] but effective!
|
||
shld NOPME+1 ;[JCE]
|
||
|
||
pop d
|
||
pop b
|
||
lhld NEXT
|
||
pchl ;continue on
|
||
;
|
||
BEGIN:
|
||
; Start of the save routine
|
||
; Notify the user which program is running
|
||
;
|
||
lxi sp,STACK ;initialize stack
|
||
lxi d,SIGNON ;prompt
|
||
call PSTR
|
||
;
|
||
; Get the file from the user
|
||
;
|
||
FLEGET:
|
||
lxi d,FLEPRMPT ;ask for file name
|
||
call PSTR
|
||
call GETBUF
|
||
; zero at end of string for parser
|
||
lxi h,CONBUF-1 ;address of #
|
||
mov a,m ;get it
|
||
cpi 0
|
||
jz REPLCE
|
||
inx h ;HL->CONBUF
|
||
mvi d,0 ;zero out high order
|
||
mov e,a ;fill low
|
||
dad d ;add to h
|
||
mvi m,00 ;zero out byte for parse
|
||
push h
|
||
;
|
||
;
|
||
call PARSE
|
||
mov a,h
|
||
cpi 0FFh
|
||
jz FLEGET
|
||
;
|
||
pop h ;get end of string address back
|
||
inx h
|
||
mvi m,'?' ;put in question mark
|
||
inx h ;bump
|
||
mvi m,' ' ;blank in string
|
||
inx h ;bump
|
||
mvi m,'$' ;end of string
|
||
;
|
||
mvi c,17 ;Search for first
|
||
lxi d,DFCB
|
||
call BDOS ;find it
|
||
inr a ;bump Acc
|
||
jz FLECLR ;file no present skip prompt
|
||
;
|
||
lxi d,DELFLE
|
||
call PSTR ;print out delete prompt
|
||
lxi d,CONBUF ;buffer address
|
||
call PSTR ;print out filename
|
||
call GETBUF ;get answer
|
||
call GNC ;get the next char
|
||
cpi 'Y' ;is it yes
|
||
jnz FLEGET ;another name if not
|
||
;
|
||
; Delete any existing file, then make a new one
|
||
FLECLR:
|
||
mvi c,DFILE ;file delete func
|
||
lxi d,DFCB ;default FCB
|
||
call BDOS ;real BDOS call
|
||
;
|
||
mvi a,0
|
||
lxi h,07ch ;M -> record count in FCB
|
||
mov m,a ;zero out record count
|
||
;
|
||
mvi c,MFILE ;make file function
|
||
lxi d,DFCB ;default FCB
|
||
call BDOS
|
||
; Get the address of start of write
|
||
;
|
||
STRADD:
|
||
lxi d,SPRMPT ;first address
|
||
call PSTR
|
||
call GETBUF
|
||
;
|
||
lda BUFFER+1 ;get # of chars read
|
||
cpi 0
|
||
jz STRADD
|
||
;
|
||
call SCANAD ;get address
|
||
jc STRADD
|
||
;
|
||
shld SADDR ;store in SADDR
|
||
;
|
||
; Get the finish address
|
||
ENDADD:
|
||
lxi d,FPRMPT ;load prompt
|
||
call PSTR ;print
|
||
call GETBUF ;read in
|
||
;
|
||
lda BUFFER+1
|
||
cpi 0
|
||
jz ENDADD
|
||
;
|
||
call SCANAD ;get finish address
|
||
jc ENDADD
|
||
;
|
||
shld FADDR ;store it
|
||
xchg
|
||
lhld SADDR
|
||
xchg
|
||
;
|
||
call CHECK
|
||
jc STRADD
|
||
;
|
||
;
|
||
lhld SADDR ;beginning DMA address
|
||
xchg ;DE=DMA address
|
||
;
|
||
; Write the first record then check the beginning address
|
||
; if DMA address ends up larger exit
|
||
;
|
||
WLOOP:
|
||
call WFLAG
|
||
push d ;save DMA address
|
||
mvi c,SETDMA
|
||
call BDOS ;set DMA address
|
||
;
|
||
mvi c,WFILE
|
||
lxi d,DFCB
|
||
call BDOS ;write
|
||
;
|
||
; Check for directory space on disk for extents
|
||
lxi d,NODIR
|
||
cpi 01h ;no more directory
|
||
jz FINIS
|
||
;
|
||
; CHECK data block error
|
||
lxi d,NOBLK
|
||
cpi 02h
|
||
jz FINIS ;out of disk space!
|
||
; final check
|
||
ora a ;if bad write occured...
|
||
jnz REPLCE ;restore BIOS address
|
||
;
|
||
; Write OK now check write address
|
||
pop d ;get DMA address
|
||
lxi h,080h
|
||
dad d
|
||
xchg
|
||
lhld FADDR ;HL=end of write
|
||
;
|
||
call CHECK
|
||
;
|
||
lda ONEFLG
|
||
cpi TRUE
|
||
jnz WLOOP ;WLOOP if not done
|
||
;
|
||
; Else, Close file and print out ending prompt
|
||
CLOSE:
|
||
mvi c,CFILE ;close function
|
||
lxi d,DFCB ;get filename
|
||
call BDOS
|
||
;
|
||
inr a ;check for close error
|
||
lxi d,CERROR
|
||
jz FINIS ;maybe write protected
|
||
;
|
||
;good copy
|
||
lxi d,ENDMSG
|
||
FINIS:
|
||
call PSTR
|
||
;
|
||
; Replace the BIOS Address to correct one
|
||
REPLCE:
|
||
lhld BIOSAD ;HL=BIOS warm jump
|
||
xchg ;DE=" " "
|
||
lhld WBTADR
|
||
inx h
|
||
mov m,e
|
||
inx h
|
||
mov m,d
|
||
;
|
||
GOODBYE:
|
||
mvi a,0FFh
|
||
sta STKYBT ;change sticky byte for
|
||
; ; removal of RSX
|
||
;
|
||
; check to see if JMP changed for BANKED system
|
||
lda CHGJMP
|
||
cpi TRUE ;has it been done?
|
||
jnz CHGBIOS
|
||
lhld SCBADR ;retreive SCB address
|
||
mvi l,SCBOST ;points to page + offset
|
||
mvi m,JUMP ;restore original code
|
||
;
|
||
CHGBIOS:
|
||
mvi c,13 ;reset the disk system
|
||
call BDOS
|
||
;
|
||
mvi c,0 ;set up for wboot
|
||
call BDOS
|
||
;****************************************
|
||
;* *
|
||
;* Logical end of the program *
|
||
;* *
|
||
;****************************************
|
||
;
|
||
GETSET$SCB:
|
||
mvi c,GETSCB
|
||
lxi d,SCBPB
|
||
call BDOS
|
||
ret
|
||
;
|
||
WFLAG:
|
||
mvi a,FALSE
|
||
sta ONEFLG
|
||
lda RSLT+1
|
||
cpi 00h
|
||
rnz
|
||
lda RSLT
|
||
cpi 080h
|
||
jc WFLAG1
|
||
jz WFLAG1
|
||
ret
|
||
;
|
||
WFLAG1:
|
||
mvi a,TRUE
|
||
sta ONEFLG
|
||
ret
|
||
;
|
||
;
|
||
;
|
||
CHECK:
|
||
; Subtract the two to find out if finished
|
||
mov a,l ;low order
|
||
sub e ;subtraction
|
||
sta RSLT
|
||
mov a,h ;now ...
|
||
sbb d ;high order subtraction
|
||
sta RSLT+1 ;saved
|
||
ret
|
||
;
|
||
GETBUF:
|
||
;buffer input routine
|
||
;
|
||
lxi h,CONBUF ;address of buffer
|
||
shld NEXTCOM ;store it
|
||
mvi c,BUFIN
|
||
lxi d,BUFFER
|
||
call BDOS
|
||
ret
|
||
;
|
||
PSTR:
|
||
; String output routine for messages
|
||
;
|
||
mvi c,PSTRING
|
||
call BDOS
|
||
ret
|
||
;
|
||
PARSE:
|
||
; General purpose parser
|
||
;
|
||
; Filename = [d:]file[.type][;password]
|
||
;
|
||
; FCB assignments
|
||
;
|
||
; 0 => drive, 0=default, 1=A, 2=B
|
||
; 1-8 => file, converted to upper case,
|
||
; padded with blanks
|
||
; 9-11 => type, converted to upper case,
|
||
; padded with blanks
|
||
; 12-15 => set to zero
|
||
; 16-23 => passwords, converted to upper case,
|
||
; padded with blanks
|
||
; 24-25 => address of password field in "filename",
|
||
; set to zero if password length=0.
|
||
; 26 => length of password (0-8)
|
||
;
|
||
; Upon return, HL is set to FFFFh if BC locates
|
||
; an invalid file name;
|
||
; otherwise, HL is set to 0000h if the delimiter
|
||
; following the file name is a 00h (null)
|
||
; or a 0Dh (CR);
|
||
; otherwise, HL is set to the address of the delimiter
|
||
; following the file name.
|
||
;
|
||
;
|
||
lxi h,0
|
||
push h
|
||
push h
|
||
lxi d,CONBUF ;set up source address
|
||
lxi h,DFCB ;set up dest address
|
||
call DEBLNK ;scan the blanks
|
||
call DELIM ;check for delimeter
|
||
jnz PARSE1
|
||
mov a,c
|
||
ora a
|
||
jnz PARSE9
|
||
mov m,a
|
||
jmp PARSE3
|
||
;
|
||
PARSE1:
|
||
mov b,a
|
||
inx d
|
||
ldax d
|
||
cpi ':'
|
||
jnz PARSE2
|
||
;
|
||
mov a,b
|
||
sui 'A'
|
||
jc PARSE9
|
||
cpi 16
|
||
jnc PARSE9
|
||
inr a
|
||
mov m,a
|
||
inx d
|
||
call DELIM
|
||
jnz PARSE3
|
||
cpi '.'
|
||
jz PARSE9
|
||
cpi ':'
|
||
jz PARSE9
|
||
cpi ';'
|
||
jz PARSE9
|
||
jmp PARSE3
|
||
;
|
||
PARSE2:
|
||
dcx d
|
||
mvi m,0
|
||
PARSE3:
|
||
mvi b,8
|
||
call SETFLD
|
||
mvi b,3
|
||
cpi '.'
|
||
jz PARSE4
|
||
call PADFLD
|
||
jmp PARSE5
|
||
;
|
||
PARSE4:
|
||
inx d
|
||
call SETFLD
|
||
PARSE5:
|
||
mvi b,4
|
||
PARSE6:
|
||
inx h
|
||
mvi m,0
|
||
dcr b
|
||
jnz PARSE6
|
||
mvi b,8
|
||
cpi ';'
|
||
jz PARSE7
|
||
call PADFLD
|
||
jmp PARSE8
|
||
PARSE7:
|
||
inx d
|
||
call PWFLD
|
||
PARSE8:
|
||
push d
|
||
call DEBLNK
|
||
call DELIM
|
||
jnz PARSE81
|
||
inx sp
|
||
inx sp
|
||
jmp PARSE82
|
||
PARSE81:
|
||
pop d
|
||
PARSE82:
|
||
mov a,c
|
||
ora a
|
||
pop b
|
||
mov a,c
|
||
pop b
|
||
inx h
|
||
mov m,c
|
||
inx h
|
||
mov m,b
|
||
inx h
|
||
mov m,a
|
||
xchg
|
||
rnz
|
||
lxi h,0
|
||
ret
|
||
PARSE9:
|
||
pop h
|
||
pop h
|
||
lxi h,0FFFFh
|
||
ret
|
||
;
|
||
SETFLD:
|
||
call DELIM
|
||
jz PADFLD
|
||
inx h
|
||
cpi '*'
|
||
jnz SETFD1
|
||
mvi m,'?'
|
||
dcr b
|
||
jnz SETFLD
|
||
jmp SETFD2
|
||
SETFD1:
|
||
mov m,a
|
||
dcr b
|
||
SETFD2:
|
||
inx d
|
||
jnz SETFLD
|
||
SETFD3:
|
||
call DELIM
|
||
rz
|
||
pop h
|
||
jmp PARSE9
|
||
;
|
||
PWFLD:
|
||
call DELIM
|
||
jz PADFLD
|
||
inx sp
|
||
inx sp
|
||
inx sp
|
||
inx sp
|
||
inx sp
|
||
inx sp
|
||
push d
|
||
push h
|
||
mvi l,0
|
||
xthl
|
||
dcx sp
|
||
dcx sp
|
||
PWFLD1:
|
||
inx sp
|
||
inx sp
|
||
xthl
|
||
inr l
|
||
xthl
|
||
dcx sp
|
||
dcx sp
|
||
inx h
|
||
mov m,a
|
||
inx d
|
||
dcr b
|
||
jz SETFD3
|
||
call DELIM
|
||
jnz PWFLD1
|
||
;
|
||
PADFLD:
|
||
inx h
|
||
mvi m,' '
|
||
dcr b
|
||
jnz PADFLD
|
||
ret
|
||
;
|
||
DELIM:
|
||
ldax d
|
||
mov c,a
|
||
ora a
|
||
rz
|
||
mvi c,0
|
||
cpi 0Dh
|
||
rz
|
||
mov c,a
|
||
cpi 09h
|
||
rz
|
||
cpi ' '
|
||
jc DELIM2
|
||
rz
|
||
cpi '.'
|
||
rz
|
||
cpi ':'
|
||
rz
|
||
cpi ';'
|
||
rz
|
||
cpi '='
|
||
rz
|
||
cpi ','
|
||
rz
|
||
cpi '/'
|
||
rz
|
||
cpi '['
|
||
rz
|
||
cpi ']'
|
||
rz
|
||
cpi '<'
|
||
rz
|
||
cpi '>'
|
||
rz
|
||
cpi 'a'
|
||
rc
|
||
cpi 'z'+1
|
||
jnc DELIM1
|
||
ani 05Fh
|
||
DELIM1:
|
||
ani 07Fh
|
||
ret
|
||
DELIM2:
|
||
pop h
|
||
jmp PARSE9
|
||
;
|
||
DEBLNK:
|
||
ldax d
|
||
cpi ' '
|
||
jz DBLNK1
|
||
cpi 09h
|
||
jz DBLNK1
|
||
ret
|
||
DBLNK1:
|
||
inx d
|
||
jmp DEBLNK
|
||
; End of the Parser
|
||
;
|
||
; GET a character from the console buffer
|
||
GNC:
|
||
push h
|
||
lxi h,CONBUF-1 ;get length
|
||
mov a,m
|
||
ora a ;zero?
|
||
mvi a,CR ;return with CR if so
|
||
jz GNCRET
|
||
dcr m ;lenght = length-1
|
||
lhld NEXTCOM ;next char address
|
||
mov a,m
|
||
inx h ;bump to next
|
||
shld NEXTCOM ;update
|
||
GNCRET:
|
||
pop h
|
||
TRANS:
|
||
cpi 7Fh ;Rubout?
|
||
rz
|
||
cpi ('A' or 0100000b)
|
||
rc
|
||
ani 1011111b ; clear upper case bit
|
||
ret
|
||
;
|
||
;
|
||
; Scan the buffer for the address read in ASCII from the terminal
|
||
;
|
||
SCANAD:
|
||
lxi d,00h ;zero out address
|
||
push d ;and save
|
||
;
|
||
lda CONBUF-1 ;get character count
|
||
cpi 05 ;5 is too many
|
||
jc SCAN0
|
||
stc ;set carry for routine
|
||
jmp SCNRET
|
||
SCAN0:
|
||
call GNC ;get a char
|
||
cpi CR ;end?
|
||
jz SCNRET ;to scnret if so
|
||
cpi '0' ;is it >0?
|
||
jnc SCAN01 ;bad character
|
||
jmp SCNRET
|
||
SCAN01:
|
||
cpi '@'
|
||
jnz SCAN02 ;bad character
|
||
stc
|
||
jmp SCNRET ;return on bad file
|
||
SCAN02:
|
||
jnc SCAN1 ;must be A-F
|
||
sui 030h ;normalize 0-9
|
||
jmp SCAN2
|
||
SCAN1:
|
||
cpi 'G' ;is it out of range?
|
||
jc SCAN11
|
||
stc
|
||
jmp SCNRET
|
||
SCAN11:
|
||
sui 037h ;normalize
|
||
SCAN2:
|
||
mov l,a ;character in low of DE
|
||
lda CONBUF-1 ;get # left
|
||
adi 1 ;readjust
|
||
mov c,a
|
||
mvi h,00 ;zero out high order
|
||
SCAN3:
|
||
dcr c ;dec to set flag
|
||
jz SCAN4 ;were done
|
||
dad h ;shift 1bit left
|
||
dad h ;same
|
||
dad h ;same
|
||
dad h ;finally
|
||
jmp SCAN3 ;back for more
|
||
;
|
||
SCAN4:
|
||
pop d ;ready for or
|
||
mov a,d ;high order
|
||
ora h ;
|
||
mov d,a
|
||
mov a,e ;low order
|
||
ora l ;ORed
|
||
mov e,a ;back
|
||
push d ;save
|
||
jmp SCAN0 ;get more characters
|
||
SCNRET:
|
||
pop d ;hl = address
|
||
xchg ;DE->HL
|
||
ret
|
||
;
|
||
;
|
||
; *********************************
|
||
; * *
|
||
; * Data Structures *
|
||
; * *
|
||
; *********************************
|
||
;
|
||
SCBPB:
|
||
db 03Ah ;SCB address
|
||
db 0
|
||
;
|
||
SADDR: dw 0 ;write start address
|
||
FADDR: dw 0 ;write finish address
|
||
BIOSAD: dw 0 ;WarmBOOT bios address
|
||
NEXTCOM: dw 0 ;address of next character to read
|
||
ONEFLG: db 0
|
||
RSLT: dw 0
|
||
CHGJMP db FALSE
|
||
;
|
||
SCBADR: dw 0 ;Scb address
|
||
;
|
||
BIOSMD: db 0 ;if non-zero change LXI @jmpadr to
|
||
;JUMP when removed.
|
||
;
|
||
BUFFER: db CONMAX
|
||
db 0 ;# of console characters read
|
||
CONBUF: ds CONMAX
|
||
;
|
||
SIGNON: db CR,LF,'CP/M 3 SAVE - Version ',VERSION/10+'0','.',VERSION mod 10+'0','$'
|
||
FLEPRMPT: db CR,LF,'Enter file '
|
||
db '(type RETURN to exit): $'
|
||
DELFLE: db CR,LF,'Delete $'
|
||
SPRMPT: db CR,LF,'Beginning hex address $'
|
||
FPRMPT: db CR,LF,'Ending hex address $'
|
||
ENDMSG: db CR,LF,'$'
|
||
;
|
||
; Error messages......
|
||
CERROR: db CR,LF,'ERROR: Bad close.$'
|
||
NODIR: db CR,LF,'ERROR: No directory space.$'
|
||
NOBLK: db CR,LF,'ERROR: No disk space.$'
|
||
;
|
||
; Stack for program
|
||
ds STKSZE
|
||
STACK:
|
||
end ;Physical end of program
|
||
|