Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 3.X/CPM 3.0/SOURCE/resbdos.asm
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

713 lines
16 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

title 'CP/M 3 Banked BDOS Resident Module, Dec 1982'
;***************************************************************
;***************************************************************
;** **
;** B a s i c D i s k O p e r a t i n g S y s t e m **
;** **
;** R e s i d e n t M o d u l e - B a n k e d B D O S **
;** **
;***************************************************************
;***************************************************************
;/*
; Copyright (C) 1978,1979,1980,1981,1982
; Digital Research
; P.O. Box 579
; Pacific Grove, CA 93950
;
; December, 1982
;
;*/
;
ssize equ 30
diskfx equ 12
conoutfxx equ 2
printfx equ 9
constatfx equ 11
setdmafx equ 26
chainfx equ 47
ioloc equ 3
org 0000h
base equ $
bnkbdos$pg equ base+0fc00h
resbdos$pg equ base+0fd00h
scb$pg equ base+0fe00h
bios$pg equ base+0ff00h
bnkbdos equ bnkbdos$pg+6
error$jmp equ bnkbdos$pg+7ch
bios equ bios$pg
bootf equ bios$pg ; 00. cold boot function
wbootf equ bios$pg+3 ; 01. warm boot function
constf equ bios$pg+6 ; 02. console status function
coninf equ bios$pg+9 ; 03. console input function
conoutf equ bios$pg+12 ; 04. console output function
listf equ bios$pg+15 ; 05. list output function
punchf equ bios$pg+18 ; 06. punch output function
readerf equ bios$pg+21 ; 07. reader input function
homef equ bios$pg+24 ; 08. disk home function
seldskf equ bios$pg+27 ; 09. select disk function
settrkf equ bios$pg+30 ; 10. set track function
setsecf equ bios$pg+33 ; 11. set sector function
setdmaf equ bios$pg+36 ; 12. set dma function
readf equ bios$pg+39 ; 13. read disk function
writef equ bios$pg+42 ; 14. write disk function
liststf equ bios$pg+45 ; 15. list status function
sectran equ bios$pg+48 ; 16. sector translate
conoutstf equ bios$pg+51 ; 17. console output status function
auxinstf equ bios$pg+54 ; 18. aux input status function
auxoutstf equ bios$pg+57 ; 19. aux output status function
devtblf equ bios$pg+60 ; 20. return device table address fx
devinitf equ bios$pg+63 ; 21. initialize device function
drvtblf equ bios$pg+66 ; 22. return drive table address
multiof equ bios$pg+69 ; 23. multiple i/o function
flushf equ bios$pg+72 ; 24. flush function
movef equ bios$pg+75 ; 25. memory move function
timef equ bios$pg+78 ; 26. get/set system time function
selmemf equ bios$pg+81 ; 27. select memory function
setbnkf equ bios$pg+84 ; 28. set dma bank function
xmovef equ bios$pg+78 ; 29. extended move function
sconoutf equ conoutf ; 31. escape sequence decoded conout
screenf equ 0ffffh ; 32. screen function
serial: db '654321'
jmp bdos
jmp move$out ;A = bank #
;HL = dest, DE = srce
jmp move$tpa ;A = bank #
;HL = dest, DE = srce
jmp search$hash ;A = bank #
;HL = hash table address
; on return, Z flag set for eligible DCNTs
; Z flag reset implies unsuccessful search
; Additional variables referenced directly by bnkbdos
hashmx: dw 0 ;max hash search dcnt
rd$dir: db 0 ;read directory flag
make$xfcb: db 0 ;Make XFCB flag
find$xfcb: db 0 ;Search XFCB flag
xdcnt: dw 0 ;current xdcnt
xdmaadd: dw common$dma
curdma: dw 0
copy$cr$only: db 0
user$info: dw 0
kbchar: db 0
jmp qconinx
bdos: ;arrive here from user programs
mov a,c ; c = BDOS function #
;switch to local stack
lxi h,0! shld aret
dad sp! shld entsp ; save stack pointer
lxi sp,lstack! lxi h,goback! push h
cpi diskfx! jnc disk$func
sta fx ;[JCE] DRI patch 1
lxi h,functab! mvi b,0
dad b! dad b! mov a,m
inx h! mov h,m! mov l,a! pchl
maclib makedate ;[JCE] Dates all go in one file
@LCOPY
@BDATE
dw 0,0,0,0,0,0,0,0,0,0,0
functab:
dw wbootf, bank$bdos, bank$bdos, func3
dw func4, func5, func6, func7
dw func8, func9, func10, bank$bdos
func3:
call readerf! jmp sta$ret
func4:
mov c,e! jmp punchf
func5:
mov c,e! jmp listf
func6:
mov a,e! inr a! jz dirinp ;0ffh -> cond. input
inr a! jz dirstat ;0feh -> status
inr a! jz dirinp1 ;0fdh -> input
mov c,e! jmp conoutf ; output
dirstat:
call constx! jmp sta$ret
dirinp:
call constx! ora a! rz
dirinp1:
call conin! jmp sta$ret
constx:
lda kbchar! ora a! mvi a,0ffh! rnz
jmp constf
conin:
lxi h,kbchar! mov a,m! mvi m,0! ora a! rnz
jmp coninf
func7:
call auxinstf! jmp sta$ret
func8:
call auxoutstf! jmp sta$ret
func9:
mov b,d! mov c,e
print:
lxi h,outdelim
ldax b! cmp m! rz
inx b! push b! mov c,a
call blk$out0
pop b! jmp print
func10:
xchg
mov a,l! ora h! jnz func10a
lxi h,buffer+2! shld conbuffadd
lhld dmaad
func10a:
push h! lxi d,buffer! push d
mvi b,0! mov c,m! inx b! inx b! inx b
xchg! call movef! mvi m,0
pop d! push d! mvi c,10
call bank$bdos
lda buffer+1! mov c,a! mvi b,0
inx b! inx b
pop d! pop h! jmp movef
func111:
func112:
sta res$fx
xchg! mov e,m! inx h! mov d,m! inx h
mov c,m! inx h! mov b,m! xchg
; hl = addr of string
; bc = length of string
blk$out:
mov a,b! ora c! rz
push b! push h! mov c,m
lxi d,blk$out2! push d
lda res$fx! cpi 112! jz listf
blk$out0:
lda conmode! mov b,a! ani 2! jz blk$out1
mov a,b! ani 14h! jz blk$out1
ani 10h! jnz sconoutf
jmp conoutf
blk$out1:
mov e,c! mvi c,conoutfxx! jmp bank$bdos
blk$out2:
pop h! inx h! pop b! dcx b
jmp blk$out
qconinx:
; switch to bank 1
mvi a,1! call selmemf
; get character
mov b,m
; return to bank zero
xra a! call selmemf
; return with character in A
mov a,b! ret
switch1:
lxi d,switch0! push d
mvi a,1! call selmemf! pchl
switch0:
mov b,a! xra a! call selmemf
mov a,b! ret
disk$func:
cpi ndf! jc OKdf ;func < ndf
cpi 98! jc badfunc ;ndf < func < 98
cpi nxdf! jnc badfunc ;func >= nxdf
cpi 111! jz func111
cpi 112! jz func112
jmp disk$function
OKdf:
cpi 17! jz search
cpi 18! jz searchn
cpi setdmafx! jnz disk$function
; Set dma addr
xchg! shld dmaad! shld curdma! ret
search:
xchg! shld searcha
searchn:
lhld searcha! xchg
disk$function:
;
; Perform the required buffer tranfers from
; the user bank to common memory
;
lxi h,dfctbl-12
mov a,c! cpi 98! jc normalCPM
lxi h,xdfctbl-98
normalCPM:
mvi b,0! dad b! mov a,m
; **** SAVE DFTBL ITEM, INFO, & FUNCTION *****
mov b,a! push b! push d
rar! jc cpycdmain ;cdmain test
rar! jc cpyfcbin ;fcbin test
jmp nocpyin
cpycdmain:
lhld dmaad! xchg
lxi h,common$dma! lxi b,16
call movef
pop d! push d
cpyfcbin:
xra a! sta copy$cr$only
lxi h,commonfcb! lxi b,36
call movef
lxi d,commonfcb
pop h! pop b! push b! push h
shld user$info
nocpyin:
call bank$bdos
pop d ;restore FCB address
pop b! mov a,b ;restore fcbtbl byte & function #
ani 0fch! rz ;[JCE] DRI Patch 13: F8 -> FC
lxi h,commonfcb! xchg! lxi b,33
ral! jc copy$fcb$back ;fcbout test
mvi c,36! ral! jc copy$fcb$back ;pfcbout test
ral! jc cdmacpyout128 ;cdmaout128 test
mvi c,4! ral! jc movef ;timeout test
ral! jc cdmacpyout003 ;cdmaout003 test
mvi c,6! jmp movef ;seriout
copy$fcb$back:
lda copy$cr$only! ora a! jz movef
lxi b,14! dad b! xchg! dad b
mov a,m! stax d
inx h! inx d
mov a,m! stax d
inx b! inx b! inx b! dad b! xchg! dad b
ldax d! mov m,a! ret
cdmacpyout003:
lhld dmaad! lxi b,3! lxi d,common$dma
jmp movef
cdmacpyout128:
lhld dmaad! lxi b,128! lxi d,common$dma
jmp movef
parse:
xchg! mov e,m! inx h! mov d,m
inx h! mov c,m! inx h! mov b,m
lxi h,buffer+133! push h! push b! push d
shld buffer+2! lxi h,buffer+4! shld buffer
lxi b,128! call movef! mvi m,0
mvi c,152! lxi d,buffer! call bank$bdos
pop b! mov a,l! ora h! jz parse1
mov a,l! ana h! inr a! jz parse1
lxi d,buffer+4
mov a,l! sub e! mov l,a
mov a,h! sbb d! mov h,a
dad b! shld aret
parse1:
pop h! pop d! lxi b,36! jmp movef
bad$func:
cpi 152! jz parse
; A = 0 if fx >= 128, 0ffh otherwise
ral! mvi a,0! jc sta$ret
dcr a
sta$ret:
sta aret
goback:
lhld entsp! sphl ;user stack restored
lhld aret! mov a,l! mov b,h ;BA = HL = aret
ret
BANK$BDOS:
xra a! call selmemf
call bnkbdos
shld aret
mvi a,1! jmp selmemf ;ret
move$out:
ora a! jz move$f
call selmemf
move$ret:
call movef
xra a! jmp selmemf
move$tpa:
mvi a,1! call selmemf
jmp move$ret
search$hash: ; A = bank # , HL = hash table addr
; Hash format
; xxsuuuuu xxxxxxxx xxxxxxxx ssssssss
; x = hash code of fcb name field
; u = low 5 bits of fcb user field
; 1st bit is on for XFCB's
; s = shiftr(mod || ext,extshf)
shld hash$tbla! call selmemf
; Push return address
lxi h,search$h7! push h
; Reset read directory record flag
xra a! sta rd$dir
lhld hash$tbla! mov b,h! mov c,l
lhld hashmx! xchg
; Return with Z flag set if dcnt = hash$mx
lhld dcnt! push h! call subdh! pop d! ora l! rz
; Push hash$mx-dcnt (# of hash$tbl entries to search)
; Push dcnt+1
push h! inx d! xchg! push h
; Compute .hash$tbl(dcnt-1)
dcx h! dad h! dad h! dad b
search$h1:
; Advance hl to address of next hash$tbl entry
lxi d,4! dad d! lxi d,hash
; Do hash u fields match?
ldax d! xra m! ani 1fh! jnz search$h3 ; no
; Do hash's match?
call search$h6! jz search$h4 ; yes
search$h2:
xchg! pop h
search$h25:
; de = .hash$tbl(dcnt), hl = dcnt
; dcnt = dcnt + 1
inx h! xthl
; hl = # of hash$tbl entries to search
; decrement & test for zero
; Restore stack & hl to .hash$tbl(dcnt)
dcx h! mov a,l! ora h! xthl! push h
; Are we done?
xchg! jnz search$h1 ; no - keep searching
; Search unsuccessful - return with Z flag reset
inr a! pop h! pop h! ret
search$h3:
; Does xdcnt+1 = 0ffh?
lda xdcnt+1! inr a! jz search$h5 ; yes
; Does xdcnt+1 = 0feh?
inr a! jnz search$h2 ; no - continue searching
; Do hash's match?
push d! call search$h6! pop d! jnz search$h2 ; no
; Does find$xfcb = 0ffh?
lda find$xfcb! inr a! jz search$h45 ; yes
; Does find$xfcb = 0feh?
inr a! jz search$h35 ; yes
; xdcnt+1 = 0feh & find$xfcb < 0feh
; Open user 0 search
; Does hash u field = 0?
mov a,m! ani 1fh! jnz search$h2 ; no
; Search successful
jmp search$h4
search$h35:
; xdcnt+1 = 0feh & find$xfcb = 0feh
; Delete search to return matching fcb's & xfcbs
; Do hash user fields match?
ldax d! xra m! ani 0fh! jnz search$h2 ; no
; Exclude empty fcbs, sfcbs, and dir lbls
mov a,m! ani 30h! cpi 30h! jz search$h2
search$h4:
; successful search
; Set dcnt to search$hash dcnt-1
; dcnt gets incremented by read$dir
; Also discard search$hash loop count
lhld dcnt! xchg
pop h! dcx h! shld dcnt! pop b
; Does dcnt&3 = 3?
mov a,l! ani 03h! cpi 03h! rz ; yes
; Does old dcnt & new dcnt reside in same sector?
mov a,e! ani 0fch! mov e,a
mov a,l! ani 0fch! mov l,a
call subdh! ora l! rz ; yes
; Set directory read flag
mvi a,0ffh! sta rd$dir
xra a! ret
search$h45:
; xdcnt+1 = 0feh, find$xfcb = 0ffh
; Rename search to save dcnt of xfcb in xdcnt
; Is hash entry an xfcb?
mov a,m! ani 10h! jz search$h2 ; no
; Do hash user fields agree?
ldax d! xra m! ani 0fh! jnz search$h2 ; no
; set xdcnt
jmp search$h55
search$h5:
; xdcnt+1 = 0ffh
; Make search to save dcnt of empty fcb
; is hash$tbl entry empty?
mov a,m! cpi 0f5h! jnz search$h2 ; no
search$h55:
; xdcnt = dcnt
xchg! pop h! shld xdcnt! jmp search$h25
search$h6:
; hash compare routine
; Is hashl = 0?
lda hashl! ora a! rz ; yes - hash compare successful
; hash$mask = 0e0h if hashl = 3
; = 0c0h if hashl = 2
mov c,a! rrc! rrc! rar! mov b,a
; hash s field does not pertain if hashl ~= 3
; Does hash(0) fields match?
ldax d! xra m! ana b! rnz ; no
; Compare remainder of hash fields for hashl bytes
push h! inx h! inx d! call compare
pop h! ret
search$h7:
; Return to bnkbdos
push a! xra a! call selmemf! pop a! ret
subdh:
;compute HL = DE - HL
mov a,e! sub l! mov l,a
mov a,d! sbb h! mov h,a
ret
compare:
ldax d! cmp m! rnz
inx h! inx d! dcr c! rz
jmp compare
; Disk Function Copy Table
cdmain equ 00000001B ;copy 1ST 16 bytes of DMA to
;common$dma on entry
fcbin equ 00000010b ;fcb copy on entry
fcbout equ 10000000b ;fcb copy on exit
pfcbout equ 01000000b ;random fcb copy on exit
cdma128 equ 00100000b ;copy 1st 128 bytes of common$dma
;to DMA on exit
timeout equ 00010000b ;copy date & time on exit
cdma003 equ 00001000B ;copy 1ST 3 bytes of common$dma
;to DMA on exit
serout equ 00000100b ;copy serial # on exit
dfctbl:
db 0 ; 12=return version #
db 0 ; 13=reset disk system
db 0 ; 14=select disk
db fcbin+fcbout+cdmain ; 15=open file
db fcbin+fcbout ; 16=close file
db fcbin+cdma128 ; 17=search first
db fcbin+cdma128 ; 18=search next
db fcbin+cdmain ; 19=delete file
db fcbin+fcbout ; 20=read sequential
db fcbin+fcbout ; 21=write sequential
db fcbin+fcbout+cdmain ; 22=make file
db fcbin+cdmain ; 23=rename file
db 0 ; 24=return login vector
db 0 ; 25=return current disk
db 0 ; 26=set DMA address
db 0 ; 27=get alloc address
db 0 ; 28=write protect disk
db 0 ; 29=get R/O vector
db fcbin+fcbout+cdmain ; 30=set file attributes
db 0 ; 31=get disk param addr
db 0 ; 32=get/set user code
db fcbin+fcbout ; 33=read random
db fcbin+fcbout ; 34=write random
db fcbin+pfcbout ; 35=compute file size
db fcbin+pfcbout ; 36=set random record
db 0 ; 37=drive reset
db 0 ; 38=access drive
db 0 ; 39=free drive
db fcbin+fcbout ; 40=write random w/ zero fill
db fcbin+fcbout ; 41=test & write record
db 0 ; 42=record lock
db 0 ; 43=record unlock
db 0 ; 44=set multi-sector count
db 0 ; 45=set BDOS error mode
db cdma003 ; 46=get disk free space
db 0 ; 47=chain to program
db 0 ; 48=flush buffers
db fcbin ; 49=Get/Set system control block
db fcbin ; 50=direct BIOS call (CP/M)
ndf equ ($-dfctbl)+12
xdfctbl:
db 0 ; 98=reset allocation vectors
db fcbin+cdmain ; 99=truncate file
db fcbin+cdmain ; 100=set directory label
db 0 ; 101=return directory label data
db fcbin+fcbout+cdmain ; 102=read file xfcb
db fcbin+cdmain ; 103=write or update file xfcb
db fcbin ; 104=set current date and time
db fcbin+timeout ; 105=get current date and time
db fcbin ; 106=set default password
db fcbin+serout ; 107=return serial number
db 0 ; 108=get/set program return code
db 0 ; 109=get/set console mode
db 0 ; 110=get/set output delimiter
db 0 ; 111=print block
db 0 ; 112=list block
nxdf equ ($-xdfctbl)+98
res$fx: ds 1
hash$tbla:
ds 2
bank: ds 1
aret: ds 2 ;address value to return
buffer: ;function 10 256 byte buffer
commonfcb:
ds 36 ;fcb copy in common memory
common$dma:
ds 220 ;function 10 buffer cont.
ds ssize*2
lstack:
entsp: ds 2
; BIOS intercept vector
wbootfx: jmp wbootf
jmp switch1
constfx: jmp constf
jmp switch1
coninfx: jmp coninf
jmp switch1
conoutfx: jmp conoutf
jmp switch1
listfx: jmp listf
jmp switch1
dw 0,0,0
dw 0
dw 0
olog: dw 0
rlog: dw 0
patch$flgs: db 0,0,0,7 ;[JCE] Patchlevel 7
; Base of RESBDOS
dw base+6
; Reserved for use by non-banked BDOS
ds 2
; System Control Block
SCB:
; Expansion Area - 6 bytes
hashl: db 0 ;hash length (0,2,3)
hash: dw 0,0 ;hash entry
version: db 31h ;version 3.1
; Utilities Section - 8 bytes
util$flgs: dw 0,0
dspl$flgs: dw 0
dw 0
; CLP Section - 4 bytes
clp$flgs: dw 0
clp$errcde: dw 0
; CCP Section - 8 bytes
ccp$comlen: db 0
ccp$curdrv: db 0
ccp$curusr: db 0
ccp$conbuff: dw 0
ccp$flgs: dw 0
db 0
; Device I/O Section - 32 bytes
conwidth: db 0
column: db 0
conpage: db 0
conline: db 0
conbuffadd: dw 0
conbufflen: dw 0
conin$rflg: dw 0
conout$rflg: dw 0
auxin$rflg: dw 0
auxout$rflg: dw 0
lstout$rflg: dw 0
page$mode: db 0
pm$default: db 0
ctlh$act: db 0
rubout$act: db 0
type$ahead: db 0
contran: dw 0
conmode: dw 0
dw buffer+64
outdelim: db '$'
listcp: db 0
qflag: db 0
; BDOS Section - 42 bytes
scbadd: dw scb
dmaad: dw 0080h
seldsk: db 0
info: dw 0
resel: db 0
relog: db 0
fx: db 0
usrcode: db 0
dcnt: dw 0
searcha: dw 0
searchl: db 0
multcnt: db 1
errormode: db 0
searchchain: db 0,0ffh,0ffh,0ffh
temp$drive: db 0
errdrv: db 0
dw 0
media$flag: db 0
dw 0
bdos$flags: db 80h
stamp: db 0ffh,0ffh,0ffh,0ffh,0ffh
commonbase: dw 0
error: jmp error$jmp
bdosadd: dw base+6
end