Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

View File

@@ -0,0 +1,674 @@
;***************************************************************
;***************************************************************
;** **
;** B a s i c D i s k O p e r a t i n g S y s t e m **
;** **
;** C o n s o l e P o r t i o n **
;** **
;***************************************************************
;***************************************************************
cnsfunc:
mov a,c! mov c,e! mov b,d
lxi h,functab! mov e,a! mvi d,0 ;DE=func, HL=.functab
dad d! dad d! mov e,m! inx h! mov d,m ;DE=functab(func)
xchg! pchl ;dispatched
;
; dispatch table for functions
functab:
dw bootf,func1,func2,func3
dw func4,func5,func6,func7
dw cmnret,func9,func10,func11
diskf equ ($-functab)/2
nfuncs equ 41 ;must match with banked bdos # fns
;
func1:
;return console character with echo
call conech
mov l,a! ret
;
func2:
;write console character with tab expansion
call attcns! jmp tabout
;
func3:
;return raw unattached console character
call rawattcns
jmp dirinp
;
func4:
;write raw unattached console character
call rawattcns
jmp conoutf
;
func5:
;write list character
call testlstatt
;write to list device if already attached
jz listf
;else must attach list device first
push b! push d
mvi c,attlst! call xdos
pop d! pop b
jmp listf
;
func6:
;direct console i/o - 0ffh = read/status
; 0feh = status
; 0fdh = read
call rawattcns
mov a,c! inr a! jz stsdirinp
inr a! jz stsinp
inr a! jz dirinp
;direct output function
jmp conoutf
stsdirinp:
push d! call constf! pop d
ora a! jnz dirinp
mvi c,dispatch! call xdos
xra a! mov l,a! ret
stsinp:
;direct console status input
call constf ;to A
mov l,a! ret
dirinp:
lxi h,kbchar! call ofsthl
mov a,m! mvi m,0! ora a
cz coninf ;to A
mov l,a! ret
;
func7:
;return io byte
;*** Not implemented in MP/M ***
xra a
mov l,a! ret
;
;func8:
;set i/o byte
;*** Not implemented in MP/M ***
;ret
;
func9:
;write line until $ encountered
;BC = string address
call attcns! jmp print ;out to console
;
func10:
;read a buffered console line
call attcns! jmp read
;
func11:
;check console status
call testcnsatt
jz doconbrk
mvi c,dispatch! call xdos
xra a! mov l,a! ret
doconbrk:
call conbrk
mov l,a
;
cmnret:
ret
;
tstlivekbd:
;test for simulated 'live keyboard'
;pd.name(3)' = off
call rlr! lxi b,pname+3! dad b! mov a,m! ani 80h
ret
;
testlstatt:
;test to determine if list is attached
;Zero = attached, D = List #
di
call rlr! xchg ;DE = Ready List Root
lxi h,console! dad d! mov a,m! ani 0f0h
rrc! rrc! rrc! rrc! push psw! push b
lxi b,lstatt-rlros! jmp attcmn
;ret
;
testcnsatt:
;test to determine if console is attached
;Zero = attached, D = Console #
di
call rlr! xchg ;DE = Ready List Root
lxi h,console! dad d! mov a,m! ani 0fh
push psw! push b
lxi b,cnsatt-rlros
attcmn:
lhld rlradr! dad b
add a! mov c,a! mvi b,0! dad b
mov a,m! cmp e! inx h! jnz notatt
mov a,m! cmp d! jz testext
notatt:
mov a,m! dcx h! ora m! jnz testext
mov m,e! inx h! mov m,d! xra a ;attach ok
testext:
ei! pop b! pop d
mvi e,0 ;cns req'd flag false
ret
;
rawattcns:
push b! mvi b,80h! jmp attcns0
attcns:
push b! mvi b,0
attcns0:
call rlr
inx h! inx h! inx h! inx h! inx h! inx h
mov a,m! ani 7fh! ora b! mov m,a ;set/reset direct i/o
inx h! inx h! inx h
mov a,m! ani 7fh! ora b! mov m,a ;set/reset simul. live kbd
pop b
;attach console if req'd
call testcnsatt
mvi e,0ffh! rz ;cns req'd flag true
push b! push d!
mvi c,attach! call xdos
pop d! push d ;restore DE
call dsplyatchmsg
pop d! pop b
ret
;
ofsthl:
;offset HL by console # (in D)
push psw
mov a,d! add l! mov l,a
mvi a,0! adc h! mov h,a
pop psw
ret
;
; console handlers
constx:
push d! call constf! pop d! ret
coninx:
;returns char & cond code = NZ if raw input
push d! call rlr! lxi d,pname! dad d
pop d! push d! ;restore console #
mov a,m! ani 80h! push psw
call coninf
mov b,a! pop psw! mov a,b
pop d! ret
conoutx:
mov a,c! ani 7fh! mov c,a
push d! call conoutf! pop d! ret
conin:
;read console character to A
;attach console first
call attcns
lxi h,kbchar! call ofsthl
mov a,m! mvi m,0! ora a! rnz
;no previous keyboard character ready
call getchr ;get character externally and test it
jmp conin ;only exit is with kbchar <> 0
;ret
;
conech:
;read character with echo
call conin! call echoc! rc ;echo character?
;character must be echoed before return
push psw! mov c,a! call tabout! pop psw
ret ;with character in A
;
echoc:
;echo character if graphic
;cr, lf, tab, or backspace
cpi cr! rz ;carriage return?
cpi lf! rz ;line feed?
cpi tab! rz ;tab?
cpi ctlh! rz ;backspace?
cpi ' '! ret ;carry set if not graphic
;
conbrk: ;check for character ready
call constx! ani 1
lxi h,kbchar! call ofsthl
jnz pgetchr ;jump if char to be read in
mov a,m! ora a! rz ;return if no char in kbchar either
jmp conb1 ;active kbchar
pgetchr:
mvi m,0 ;clear kbchar to prepare for new char
;character ready, read it
getchr: ;entry point used by conin
call coninx ;to A
jnz conb0; skip char testing if pd.pname.f0 is "on"
cpi ctls! jnz notcts ;check stop screen function
;found ctls, read next character
getctlq:
call coninx ;to A
cpi ctlc! jz controlc ;ctlc implies re-boot
cpi ctlq! jz gotctlq
mvi c,7! call conoutx ;send bell character
jmp getctlq
gotctlq:
;resume after ^Q
xra a! ret ;with zero in accumulator
notcts:
;not a control s, control q?
cpi ctlq! jz gotctlq
;ignore control Q's
notctq:
;not a control s, control d?
cpi ctld! jnz notctd
;found ctld, detach console
;^D is ignored if submit in progress
lhld sysdat! mvi l,128! call ofsthl
mov a,m! ora a! mvi a,0! rnz
push d! lxi h,listcp! call ofsthl
;if ^D and ^P then detach list
mov a,m! ora a! jz notctlp
mvi c,detlst! call XDOS
notctlp:
mvi c,detach! call XDOS
;then attach console back
; unless cns not req'd
pop d! mov a,e! ora a
rz! push d ;return if cns not req'd
mvi c,attach! call XDOS! pop d
dsplyatchmsg:
;print console attach message
lxi b,atchmsg! call xprint
call rlr
dsplynm:
call pdsplynm
xcrlf:
;output crlf without CONBRK calls
mvi c,cr! call conoutx
mvi c,lf! call conoutx
xra a! ret ;with zero in A
pdsplynm:
lxi b,pname! dad b! mvi e,8
dsploop:
mov c,m! push h! push d! call conoutx
pop d! pop h! inx h! dcr e
jnz dsploop
inr e ;cns req'd set true
ret
notctd:
;not a control d, control c?
cpi ctlc! jnz conb0
controlc: ;entry point
lhld sysdat! mvi l,128! call ofsthl
mov a,m! ora a! jz ctlcnt
push h! lxi b,submsg! call query
pop h! jnz ctlcnt
mvi m,0
ctlcnt:
;test for suppress abort flag
call rlr! lxi b,(pname+7)! dad b
mov a,m! ani 80h! jz notctlcsupr
dcx h! mov a,m! ori 80h! mov m,a
xra a! ret
notctlcsupr:
;test to see if this is a user process
inx h! inx h
mov a,m! ora a! rz
inr a! rz ;ignore ^C if system process running
;print Abort (Y/N) ?
lxi b,abtmsg1! call xprint
call rlr! call pdsplynm
lxi b,abtmsg2! call query! jz xreboot
xra a! ret ;with zero in A
conb0:
;character in accum, save it
lxi h,kbchar! call ofsthl! mov m,a
conb1:
;return with true set in accumulator
mvi a,1! ret
;
query:
call xprint
eatctlc:
call coninx! ani 7fh
cpi ctlc! jz eatctlc! push psw
mov c,a! call conoutx
mvi c,cr! call conoutx
mvi c,lf! call conoutx
pop psw
ani 5fh! cpi 'Y'
ret
;
conout:
;compute character position/write console char from C
;compcol = true if computing column position
lxi h,compcol! call ofsthl
mov a,m! ora a! jnz compout
;write the character, then compute the column
;write console character from C
push b! call conoutx ;externally, to console
call tstlivekbd ;conbrk only if simulated 'live kbd'
cz conbrk ;check for screen stop function
pop b! push b! push d ;recall/save character & con #
;may be copying to the list device
lxi h,listcp! call ofsthl
mov a,m! ani 01h! cnz func5 ;to printer, if so
pop d! pop b ;recall the character & con #
compout:
mov a,c ;recall the character
;and compute column position
lxi h,column! call ofsthl ;A = char, HL = .column
cpi rubout! rz ;no column change if nulls
inr m ;column = column + 1
cpi ' '! rnc ;return if graphic
;not graphic, reset column position
dcr m ;column = column - 1
mov a,m! ora a! rz ;return if at zero
;not at zero, may be backspace or end line
mov a,c ;character back to A
cpi ctlh! jnz notbacksp
;backspace character
dcr m ;column = column - 1
ret
notbacksp:
;not a backspace character, eol?
cpi lf! rnz ;return if not
;end of line, column = 0
mvi m,0 ;column = 0
ret
;
ctlout:
;send C character with possible preceding up-arrow
mov a,c! call echoc ;cy if not graphic (or special case)
jnc tabout ;skip if graphic, tab, cr, lf, or ctlh
;send preceding up arrow
push psw! mvi c,ctl! call conout ;up arrow
pop psw! ori 40h ;becomes graphic letter
mov c,a ;ready to print
;(drop through to tabout)
;
tabout:
;expand tabs to console
mov a,c! cpi tab! jnz conout ;direct to conout if not
;tab encountered, move to next tab position
tab0:
mvi c,' '! call conout ;another blank
call ldacolumn! ani 111b ;column mod 8 = 0 ?
jnz tab0 ;back for another if not
ret
;
backup:
;back-up one screen position
call pctlh! mvi c,' '! call conoutx ;jmp pctlh
;
pctlh:
;send ctlh to console without affecting column count
mvi c,ctlh! jmp conoutx
;ret
;
crlfp:
;print #, cr, lf for ctlx, ctlu, ctlr functions
;then move to strtcol (starting column)
mvi c,'#'! call conout
call crlf
;column = 0, move to position strtcol
crlfp0:
call ldacolumn! lxi h,strtcol! call ofsthl
cmp m! rnc ;stop when column reaches strtcol
mvi c,' '! call conout ;print blank
jmp crlfp0
;;
;
crlf:
;carriage return line feed sequence
mvi c,cr! call conout! mvi c,lf! jmp conout
;ret
;
xprint:
;print routine which does not CONBRK
;BC = string address, string terminated with a '$'
ldax b! ORA A! rz
push b! mov c,a! call conoutx! pop b
inx b! jmp xprint
;
print:
;print message until M(BC) = '$'
ldax b! cpi '$'! rz ;stop on $
;more to print
inx b! push b! mov c,a ;char to C
call tabout ;another character printed
pop b! jmp print
;
pread: ;entry to read, restores buffer address
pop b
read: ;BC = address (max length, current length, buffer)
push b ;save buffer address for possible ^X or ^U
call ldacolumn
lxi h,strtcol! call ofsthl
mov m,a ;save start for ctl-x, ctl-h
mov h,b! mov l,c! mov c,m! inx h! push h! mvi b,0
;B = current buffer length,
;C = maximum buffer length,
;HL= next to fill - 1
readnx:
;read next character, BC, HL active
push b! push h ;blen, cmax, HL saved
readn0:
call conin ;next char in A
ani 7fh ;mask parity bit
pop h! pop b ;reactivate counters
cpi cr! jz readen ;end of line?
cpi lf! jz readen ;also end of line
cpi ctlh! jnz noth ;backspace?
;do we have any characters to back over?
mov a,b! ora a! jz readnx
;characters remain in buffer, backup one
dcr b ;remove one character
call ldacolumn
lxi h,compcol! call ofsthl
mov m,a ;col > 0
;compcol > 0 marks repeat as length compute
jmp linelen ;uses same code as repeat
noth:
;not a backspace
cpi rubout! jnz notrub ;rubout char?
;rubout encountered, rubout if possible
mov a,b! ora a! jz readnx ;skip if len=0
;buffer has characters, resend last char
mov a,m! dcr b! dcx h ;A = last char
;blen=blen-1, next to fill - 1 decremented
jmp rdech1 ;act like this is an echo
;
notrub:
;not a rubout character, check end line
cpi ctle! jnz note ;physical end line?
;yes, save active counters and force eol
push b! push h! call crlf
lxi h,strtcol! call ofsthl
xra a! mov m,a ;start position = 00
jmp readn0 ;for another character
note:
;not end of line, list toggle?
cpi ctlp! jnz notp ;skip if not ctlp
lda kbproc! ora a! jnz notp
;list toggle - change parity
push h ;save next to fill - 1
push b! push d
lxi h,listcp! call ofsthl ;HL=.listcp flag
mvi a,01h! xra m! mov m,a ;listcp=-listcp
push h ;save address of listcp
jnz prntron ; jump if printer to be turned on
prntroff:
;return list mutex queue message
mvi m,0! ;zero listcp(console)
mvi c,detlst! call XDOS
pop h! jmp ctlpxit
prntron:
call testlstatt
pop h! jz ctlpxit
;printer busy, could not ^p
mvi m,0! lxi b,pbsymsg
;D = console #
pop d! push d
call xprint
ctlpxit:
pop d! pop b
pop h! jmp readnx ;for another char
notp:
;not a ctlp, line delete?
cpi ctlx! jnz notx
pop h ;discard start position
;loop while column > strtcol
backx:
lxi h,strtcol! call ofsthl
mov a,m! lxi h,column! call ofsthl
cmp m! jnc pread ;start again
dcr m ;column = column - 1
call backup ;one position
jmp backx
notx:
;not a control x, control u?
cpi ctlu! jnz notu ;skip if not
;delete line (ctlu)
call crlfp ;physical eol
pop h ;discard starting position
jmp pread ;to start all over
notu:
;not line delete, repeat line?
cpi ctlr! jnz notr
linelen:
;repeat line, or compute line len (ctlh)
;if compcol > 0
push b! call crlfp ;save line length
pop b! pop h! push h! push b
;bcur, cmax active, beginning buff at HL
rep0:
mov a,b! ora a! jz rep1 ;count len to 00
inx h! mov c,m ;next to print
dcr b! push b! push h ;count length down
call ctlout ;character echoed
pop h! pop b ;recall remaining count
jmp rep0 ;for the next character
rep1:
;end of repeat, recall lengths
;original BC still remains pushed
push h ;save next to fill
lxi h,compcol! call ofsthl
mov a,m! ora a ;>0 if computing length
jz readn0 ;for another char if so
;column position computed for ctlh
lxi h,column! call ofsthl! sub m ;diff > 0
lxi h,compcol! call ofsthl
mov m,a ;count down below
;move back compcol-column spaces
backsp:
;move back one more space
call backup ;one space
lxi h,compcol! call ofsthl! dcr m
jnz backsp
jmp readn0 ;for next character
notr:
;not a ctlr, place into buffer
rdecho:
inx h! mov m,a ;character filled to mem
inr b ;blen = blen + 1
rdech1:
;look for a random control character
push b! push h ;active values saved
mov c,a ;ready to print
call ctlout ;may be up-arrow C
pop h! pop b! mov a,b ;len to A
;are we at end of buffer?
cmp c! jc readnx ;go for another if not
readen:
;end of read operation, store blen
pop h! mov m,b ;M(current len) = B
pop h ;discard buffer address
mvi c,cr! jmp conout ;return carriage
;ret
;
ldacolumn:
lxi h,column! call ofsthl! mov a,m! ret
pbsymsg:
db cr,lf,'Printer Busy.',cr,lf,0
abtmsg1:
db cr,lf,'Abort ',0
abtmsg2:
db ' (Y/N) ?',0
atchmsg:
db cr,lf,'Attach:',0
submsg:
db cr,lf,'Terminate Submit ?',0
;
; data areas
;
nmbcns equ 16
compcol:db 0 ;true if computing column position
rept nmbcns-1
db 0
endm
strtcol:db 0 ;starting column position after read
rept nmbcns-1
db 0
endm
column: db 0 ;column position
rept nmbcns-1
db 0
endm
kbchar: db 0 ;initial key char = 00
rept nmbcns-1
db 0
endm
listcp: db 0 ;listing toggle
rept nmbcns-1
db 0
endm
kbproc: db 0 ;kb proc resident flag
;
patch$size equ 80
ds patch$size
patch:
org (((patch-base)+255) AND 0ff00h)-patch$size
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0
;
; bios external jump table
;
bios equ $ ;base of the bios jump table
bootf equ bios ;cold boot function
wbootf equ bootf+3 ;warm boot function
constf equ wbootf+3 ;console status function
coninf equ constf+3 ;console input function
conoutf equ coninf+3 ;console output function
listf equ conoutf+3 ;list output function
punchf equ listf+3 ;punch output function
readerf equ punchf+3 ;reader input function
homef equ readerf+3 ;disk home function
seldskf equ homef+3 ;select disk function
settrkf equ seldskf+3 ;set track function
setsecf equ settrkf+3 ;set sector function
setdmaf equ setsecf+3 ;set dma function
readf equ setdmaf+3 ;read disk function
writef equ readf+3 ;write disk function
liststf equ writef+3 ;list status function
sectran equ liststf+3 ;sector translate
;
; xios access table
xiosms equ sectran+3 ;memory select / protect
xiospl equ xiosms+3 ;device poll
strclk equ xiospl+3 ;start clock
stpclk equ strclk+3 ;stop clock
exitr equ stpclk+3 ;exit critical region
maxcns equ exitr+3 ;max console #
syinitf equ maxcns+3 ;MP/M system initialization
;
end