Files
Digital-Research-Source-Code/MPM OPERATING SYSTEMS/MPM II/MPM II SOURCE/NUCLEUS/RESBDOS1.ASM
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

772 lines
17 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 'MP/M II V2.0 Resident Portion of Banked BDOS'
cseg
;***************************************************************
;***************************************************************
;** **
;** 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 P o r t i o n - B a n k e d B D O S **
;** **
;***************************************************************
;***************************************************************
;/*
; Copyright (C) 1978,1979,1980,1981
; Digital Research
; P.O. Box 579
; Pacific Grove, CA 93950
;
; Revised:
; 14 Sept 81 by David K. Brown
;*/
;
org 0000h
base equ $
;
; XDOS jump table below BDOS origin
pdisp equ $-3
xdos equ pdisp-3
; equates for non graphic characters
ctlc equ 03h ;control c, abort
ctld equ 04h ;control d, detach
ctle equ 05h ;physical eol
ctlh equ 08h ;backspace
ctlp equ 10h ;prnt toggle
ctlq equ 11h ;prnt owner toggle
ctlr equ 12h ;repeat line
ctls equ 13h ;stop/start screen
ctlu equ 15h ;line delete
ctlx equ 18h ;=ctl-u
ctlz equ 1ah ;end of file
rubout equ 7fh ;char delete
tab equ 09h ;tab char
cr equ 0dh ;carriage return
lf equ 0ah ;line feed
ctl equ 5eh ;up arrow
;
; XDOS call equates
makeque equ 134
readque equ 137
writeque equ 139
dispatch equ 142
terminate equ 143
setprior equ 145
attach equ 146
detach equ 147
asgncns equ 149
sendcli equ 150
ATTLST EQU 158
DETLST EQU 159
;
; Process Descriptor Offsets
pname equ 6
console equ 14
memseg equ 15
disksetDMA equ 20
diskselect equ 22
searcha equ 26
MULT$CNT EQU 50
;
; System Data Page Offsets
userstackflag equ 3
brkvctr equ 48
usrstkregion equ 80
LISTCPADR EQU 126
;
; MP/M Data Page Offsets
rlros equ 5
cnsatt equ 20
msegtbl equ 150
LSTATT EQU 599
;
;*****
;
; enter here from the user's program with function number
; in c, and information address in d,e
jmp xbdos ;to xbdos handler
jmp bios ;to bios jump table base address
JMP SYINIT
JMP REMOVE$FILES
JMP SWITCH$USER
JMP SWITCH$ZERO
XREMOVE$FILES:
JMP $-$
;
; bdos/xdos initialization code
syinit:
;HL = sysdat page address
shld sysdat
mvi l,14! lxi b,bnkbdos+1
mov a,m! mov d,a! stax b
xchg! mvi l,3
shld bnkbdosinit
MVI L,6! SHLD XREMOVE$FILES+1
MVI L,9! LXI D,COMMON$DMA
MOV M,E! INX H! MOV M,D! INX H
XCHG! LHLD SYSDAT! XCHG
MOV M,E! INX H! MOV M,D
INX H! PUSH H
bnkbdosinit equ $+1
call $-$ ;initialize the banked bdos
jmp syinitcontd
extjmptbl:
jmp extreboot
jmp rlr
jmp getrlradr
jmp dsplynm
jmp xprint
jmp xcrlf
jmp conoutx
jmp xgetmemseg
;
syinitcontd:
lhld sysdat! mov c,h
MVI L,LISTCPADR! LXI D,LISTCP ;PUT .LISTCP IN SYS DTA PG
MOV M,E! INX H! MOV M,D
mvi l,252! mov a,m! inx h! mov h,m
mov l,a! lxi d,0005! dad d! shld rlradr
lxi d,0091h! dad d! shld msegtadr
mov h,c! mvi l,userstackflag
mov a,m! sta usrstkflg
dcr l! mov l,m! mvi h,0 ;HL = RST #
mov c,l ;put RST # into C for use by SYSINITF
dad h! dad h! dad h ;HL = breakpoint address
mvi m,0C3h! inx h ;store jump to brkpt hndlr
lxi d,brkpt ;DE = brkpt entry address
mov m,e! inx h! mov m,d
;initialize jmp at 0000H to fake BIOS jump table
mvi a,0C3H! sta 0000H
lxi h,drctjmptbl! shld 0001H
;execute the XIOS SYSINIT function
call syinitf
ei ;in case it was not done in sysinit
;create disk mutual exclusion queue
mvi c,makeque! lxi d,diskcqcb! call xdos
mvi c,writeque! lxi d,MXDisk! call xdos
;create printer mutual exclusion queue
mvi c,makeque! lxi d,listcqcb! call xdos
;INHIBIT MXList EXCLUSION
LXI H,0FFFFH! SHLD LISTNMSGS! SHLD LISTMSGCNT
;get the directory buffer address
mvi c,0! call seldskf
lxi d,8! dad d! mov e,m! inx h! mov d,m
JMP SYINITEXTRA
;
CoNm:
db ' COPYRIGHT (C) 1981,'
db ' DIGITAL RESEARCH '
Serial:
db '654321'
lstack equ Serial+4
entsp equ lstack ;BDOS entry stack pointer
dtbl equ $
org ((dtbl-base)+0ffh) and 0ff00h
; *** this table is page aligned
; BIOS jump table for *.COM file support
jmp bootf
drctjmptbl:
jmp wbootf
jmp bconst
jmp bconin
jmp bconout
jmp blist
;
; Support for direct BIOS console & list device I/O
;
SYINITEXTRA:
xchg! shld dirbufa
XCHG! POP H! MOV M,E! INX H! MOV M,D
ret
bconst: mvi e,0feh! mvi c,6! jmp xbdos
bconin: mvi c,3! jmp xbdos
bconout:mov e,c! mvi c,4! jmp xbdos
blist: mov e,c! mvi c,5! jmp xbdos
; Disk and List data structures
diskcqcb:
;disk mutual exclusion circular que ctl blk
dw $-$ ;link
db 'MXDisk ' ;name
dw 0 ;message length
dw 1 ;number of messages
dw $-$ ;dq process head
dw $-$ ;nq process head
dw $-$ ;msgin
dw $-$ ;msgout
dw $-$ ;msgcnt
dw $-$ ;owner Process descriptor adr
MXDisk:
;disk user queue control block
dw diskcqcb
listcqcb:
;list mutual exclusion circular queue control block
dw $-$ ;link
db 'MXList ' ;name
dw 0 ;message length
LISTNMSGS:
dw 0FFFFH ;number of messages
dw $-$ ;dq process head
dw $-$ ;nq process head
dw $-$ ;msgin
dw $-$ ;msgout
LISTMSGCNT:
dw 0FFFFH ;msgcnt
dw listcqcb-4 ;owner Process Descriptor adr
xbdos: ;arrive here from user programs
mov a,c! ora c ; test function code
jz reboot ;zero terminates calling process
jp notXDOS ;jump if a BDOS call
call XDOS ;func >= 128 is a XDOS call
mov a,l ;XDOS returns address put low byte into A
ret
badfunc:
;invalid function code
lxi h,0ffffh! mov a,l! ret
brkpt: ;debugger breakpoint entry
di! shld svdhl! pop h! shld svdrt! push psw
;set HL = RLR
lhld rlradr! mov a,m! inx h! mov h,m! mov l,a
mvi a,memseg! add l! mov l,a
mvi a,0! adc h! mov h,a ;HL = .pd.memseg
mov a,m! add a! adi brkvctr
lhld sysdat! mov l,a ;HL = brkpt hndlr address
mov a,m! inx h! mov h,m! mov l,a
shld jmptobrk+1
pop psw! lhld svdrt! push h! lhld svdhl
jmptobrk:
jmp $-$
restore:
;restore user stack
xchg! pop h! sphl! xchg ;get user stack pointer
ret
tst$stk$swap:
lda usrstkflg! ora a
rz ; if flag set then change stack
; get memory segment index
lhld rlradr! mov a,m! inx h
mov h,m! mov l,a
mvi a,pname+2! add l! mov l,a
mvi a,0! adc h! mov h,a
mov a,m ; A = pd.name(2)
ani 80h! jz tst$stk$swap1 ;no stk chg if name(2) "on"
xra a! ret
tst$stk$swap1:
mvi a,memseg-(pname+2)! add l! mov l,a
mvi a,0! adc h! mov h,a
mov a,m ; A = memory segment index
ora a! rz
inr a! ret ;no stack change if system process call
notXDOS:
call tst$stk$swap! jz BDOS
dcr a! dcr a! add a! adi usrstkregion
lhld sysdat! mov l,a
mov a,d! mov b,e ;save DE in AB
mov e,m! inx h! mov d,m
lxi h,0! dad sp
xchg! sphl! push d ;set & save user SP
lxi h,restore! push h ; setup return address to restore stack
mov d,a! mov e,b ;restore DE
BDOS:
mov a,c! cpi diskf! jc cnsfunc ;jump if not disk i/o
cpi 26! jnz BDOS2
call rlr! mvi a,disksetDMA! add l! mov l,a
mvi a,0! adc h! mov h,a
inx d! mov a,e! ora d
jz BDOS1
dcx d
BDOS1:
mov m,e! inx h! mov m,d
ret
BDOS2:
cpi ndf+1! jc OKdf ;func <= ndf
cpi 100! jc badfunc ;ndf < func < 100
cpi nxdf+1! jnc badfunc ;func > nxdf
OKdf:
cpi chainf! jz chain
push d! push b ;save info & func
CALL TSTLIVEKBD ;TST FOR PD.NAME(3)' OFF
cz func11 ;simulate 'live console' with kbd status chk
;if not suppressing abort then set ctlc flg off, in BDOS on
call rlr! lxi d,(pname+7)! dad d
mov a,m! ani 80h! jnz noinbdosflg
dcx h! mov a,m! ani 7fh! mov m,a
dcx h! dcx h! dcx h! dcx h! dcx h
;DO NOT ALLOW ABORT WHEN IN BDOS
MOV A,M! ORI 80H! MOV M,A
noinbdosflg:
;obtain entry by getting disk mutual exclusion message
mvi c,readque! lxi d,MXDisk! call XDOS
;setup & jump to banked bdos
pop b! pop d ;restore info & func
lxi h,0! dad sp! shld entsp
lxi sp,lstack
;perform the required buffer transfers from
; the user in common memory
mov a,c! cpi 17 ;search ?
jnz skipsrch
call rlr! push d! lxi d,searcha! dad d! pop d
mov m,e! inx h! mov m,d
jmp skipsrchnxt
skipsrch:
cpi 18 ;search next ?
jnz skipsrchnxt
call rlr! lxi d,searcha! dad d
mov e,m! inx h! mov d,m
skipsrchnxt:
lxi h,dfctbl-12
mov a,c! cpi 100! jc normalCPM
lxi h,xdfctbl-100
normalCPM:
mvi b,0! dad b! mov a,m
;***** SAVE DFTBL ITEM, INFO, & FUNCTION *****
MOV B,A! PUSH B! PUSH D
rar! jc cpydmain
RAR! JC CPYCDMAIN
rar! jc cpyfcbin
jmp nocpyin
CPYCDMAIN:
LXI H,COMMON$DMA! PUSH H! MVI B,16! PUSH B
JMP CPYDMAIN1
cpydmain:
LHLD DIRBUFA! PUSH H! MVI B,128! PUSH B
CPYDMAIN1:
CALL SET$DMABUFA
XCHG! POP B! POP H
call move
pop d! push d
cpyfcbin:
lxi h,commonfcb! mvi b,36
call move
lxi d,commonfcb
nocpyin:
MOV A,C! MVI B,0! CPI 41! JZ SHELL
PUSH D! CALL GET$MULT$CNT$ADD! POP D
MOV A,M! DCR A! JZ BDOSE2
LXI H,MULT$FXS! INR B
BDOSE1:
MOV A,M! ORA A! JZ BDOSE2
CMP C! JZ SHELL
INX H! JMP BDOSE1
BDOSE2:
CALL BANK$BDOS
BDOSE3:
POP D ;RESTORE FCB ADDRESS
POP B! MOV A,B ;RESTORE DFCTBL BYTE & FUNCTION #
ral! jc dmacpyout
RAL! JC CDMACPYOUT
COPYOUT:
lxi h,commonfcb! xchg! mvi b,33
ral! jc cpyoutcmn
ral! jnc nocpyout
MOV A,C! CPI 105! MVI B,4! JZ CPYOUTCMN
CPI 107! MVI B,6! JZ CPYOUTCMN
mvi b,36! CPI 15! JZ CPYOUT1
CPI 22! JNZ CPYOUTCMN
CPYOUT1:
DCR B! PUSH H! LXI H,12! DAD D! MOV A,M! POP H
ANI 80H! JNZ CPYOUTCMN
MVI B,33! jmp cpyoutcmn
CDMACPYOUT:
PUSH D ;SAVE FCB ADDRESS FOR COPYOUT
CALL SET$DMA$BUFA
MVI B,3! CALL COPY$CDMA$OUT
POP D! JMP NOCPYOUT
dmacpyout:
lhld dirbufa! xchg! lhld dmabufa! mvi b,128
cpyoutcmn:
call move
nocpyout:
lhld entsp! sphl ;user stack restored
RELEASE:
lhld aret
push h
;release disk mutual exclusion message
mvi c,writeque! lxi d,MXDisk! call XDOS
;if in BDOS flag on, check for abt spc proc flg
call rlr! lxi d,(pname+1)! dad d
mov a,m! ani 7fh! cmp m! mov m,a
jz funcdone
inx h! inx h! inx h! inx h! inx h
mov a,m! ani 7fh! cmp m! mov m,a
CNZ REBOOT
funcdone:
;function done
pop h! mov a,l! mov b,h ;BA = HL = aret
ret
BANK$BDOS:
push d! push b ;save info & func
call getmemseg! sta usermemseg
xra a ;set memseg to 0 (memseg #0 must be bank zero)
call extbnkswt
pop b! pop d
bnkbdos equ $+1
call $-$
shld aret
call getmemseg! lda usermemseg
jmp extbnkswt ;ret
COPY$CDMA$OUT: ;B = 2 | 3
LHLD DMABUFA! LXI D,COMMON$DMA
;FALLS THROUGH TO MOVE
move:
;move data length of B from source DE to
;destination HL
inr b ;in case of length=0
move0:
dcr b! rz
ldax d! mov m,a
inx d! inx h
jmp move0
MULT$FXS: DB 20,21,33,34,40,0
;
getrlradr:
lhld rlradr! ret
rlr:
;set HL = contents of Ready List Root
lhld rlradr! mov a,m! inx h! mov h,m! mov l,a
ret
;
GET$MULT$CNT$ADD:
CALL RLR! LXI D,MULT$CNT! DAD D! RET
;
xgetmemseg:
lda usermemseg
ret
;
getmemseg:
;set A = memory segment #
call rlr ;HL = Ready List Root
mvi a,memseg! add l! mov l,a
mvi a,0! adc h! mov h,a ;HL = .pd.memseg
mov a,m! ret
;
REMOVE$FILES:
CALL GETMEMSEG! PUSH A! XRA A
PUSH B! CALL EXTBNKSWT! POP B
CALL XREMOVE$FILES
CALL GETMEMSEG! POP A! JMP EXTBNKSWT
;
;
; intercept bios boot to switch banks
extreboot:
call getmemseg! lda usermemseg
call extbnkswt
lxi h,0ffffh! shld aret
LHLD ENTSP! SPHL ;RESTORE USER'S STACK
CALL RELEASE ;RELEASE MXDisk
LDA USERMEMSEG
ORA A! RZ! INR A! RZ ;DON'T TERMINATE IF SYS PROCESS
xreboot:
call tst$stk$swap! jz reboot
lxi h,0! dad sp! lxi d,3fh! dad d
mov a,l! ani 0c0h! mov l,a! dcx h
mov d,m! dcx h! mov e,m! xchg! sphl
reboot:
call rlr! lxi d,memseg! dad d
mov a,m! ora a! rz
inr a! rz
dcx h! dcx h
mov a,m! ani 80h! rnz
;terminate the calling process
mvi c,terminate! lxi d,0
jmp xdos
SWITCH$USER:
call getmemseg! lda usermemseg
jmp extbnkswt
SWITCH$ZERO:
call getmemseg! xra a
;call extbnkswt
;ret
extbnkswt:
di
mov m,a! inr a! jz extbnkswt1 ;return if system process
dcr a! add a! add a! lhld msegtadr
add l! mov c,a
mvi a,0! adc h! mov b,a
call xiosms
extbnkswt1:
ei
ret
;
; Local Data Segment
msegtadr: ds 2 ;address of memory segment table
rlradr: ds 2 ;address of Ready List Root
sysdat: ds 2 ;address of system data page
usrstkflg: ds 1 ;user stack flag, 0ffh=users stack
svdhl: ds 2 ;saved HL at breakpoint entry
svdrt: ds 2 ;saved return address at breakpoint entry
;
dirbufa: ds 2 ;directory buffer address
dmabufa: ds 2 ;dma buffer address
usermemseg: ds 1 ;saved user mem seg index
aret: ds 2 ;address value to return
commonfcb:
ds 36 ;fcb copy in common memory
;
COMMON$DMA:
DS 16 ;LOCAL DMA FOR PASSWORDS, ETC.
;
; Disk Function Copy Table
;
dmain equ 00000001b ;dma copy on entry
CDMAIN EQU 00000010B ;COPY 1ST 16 BYTES OF DMA TO
fcbin equ 00000100b ;fcb copy on entry
;COMMON$DMA ON ENTRY
dmaout equ 10000000b ;dma copy on exit
CDMAOUT EQU 01000000B ;COPY 1ST 2 | 3 BYTES OF COMMON$DMA
;TO DMA ON EXIT
;2 IF UNLOCKED OPEN
;3 IF GET DISK FREE SPACE
fcbout equ 00100000b ;fcb copy on exit
pfcbout equ 00010000b ;random fcb copy on exit
dfctbl:
db 0 ; 12=return version #
db 0 ; 13=reset disk system
db 0 ; 14=select disk
db fcbin+PFCBOUT+CDMAIN ; 15=open file
db fcbin+fcbout ; 16=close file
db fcbin+dmain+dmaout ; 17=search first
db fcbin+dmain+dmaout ; 18=search next
db fcbin+CDMAIN ; 19=delete file
db fcbin+fcbout ; 20=read sequential
db fcbin+fcbout ; 21=write sequential
db fcbin+PFCBOUT+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+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 fcbin+fcbout+CDMAIN ; 42=record lock
db fcbin+fcbout+CDMAIN ; 43=record unlock
db 0 ; 44=set multi-sector count
db 0 ; 45=set BDOS error mode
db CDMAOUT ; 46=get disk free space
db fcbin ; 47=chain to program
db 0 ; 48=flush buffers
db 0 ; 49=CCP chain query (CP/M)
db 0 ; 50=direct BIOS call (CP/M)
ndf equ ($-dfctbl)+12
xdfctbl:
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+pfcbout ; 105=get current date and time
db fcbin ; 106=set default password
db fcbin+pfcbout ; 107=return serial number
nxdf equ ($-xdfctbl)+100
get$dma$add:
call rlr! lxi d,disksetdma! dad d! ret
set$dmabufa:
call get$dma$add
mov e,m! inx h! mov d,m
xchg! shld dmabufa! ret
shell:
sta fx! call set$dmabufa
shld shell$dma
call get$mult$cnt$add
mov a,m! sta shell$cnt
lxi h,shell$rtn! push h! push b
call save$rr! call save$dma
pop psw! ora a! jz tst$wrt
jmp mult$io ; HL = .DMA
;
shell$cnt: db 0
fx: db 0
shell$rr: db 0,0,0
;
hold$dma: dw 0
shell$dma: dw 0
;
cbdos:
lda fx! mov c,a
cbdos1:
lxi d,common$fcb! call bank$bdos! lda aret! ret
;
adv$dma:
lhld shell$dma
lxi d,80h! dad d! shld shell$dma
;
set$process$dma:
push h
call get$dma$add! pop d! mov m,e! inx h! mov m,d
ret
;
save$dma:
lhld shell$dma! shld hold$dma! ret
;
reset$dma:
lhld hold$dma! jmp set$process$dma
;
shell$err:
lhld aret
lda shell$cnt! pop b! sub b
add a! add a! add a! add a
ora h! mov h,a! ret
;
shell$rtn:
shld aret! lda fx! cpi 33! cnc reset$rr
call reset$dma! jmp bdose3
;
incr$rr:
call get$rra
inr m! rnz
inx h! inr m! rnz
inx h! inr m! ret
;
save$rr:
call save$rr2! xchg
save$rr1:
mvi b,3! jmp move ;ret
save$rr2:
call get$rra! lxi d,shell$rr! ret
;
reset$rr:
call save$rr2! jmp save$rr1
;
tst$wrt:
lhld dirbufa! xchg
mvi c,26! call bank$bdos
lda shell$cnt
tst$wrt1:
push a! mvi c,33! call cbdos1
ora a! jnz shell$err
call compare$recs
call incr$rr
lxi d,80h! lhld shell$dma! dad d! shld shell$dma
pop a! dcr a! jnz tst$wrt1
call set$process$dma
call reset$rr
mvi a,34! sta fx ; jmp mult$io
;
mult$io:
lda shell$cnt
mult$io1:
push a! call cbdos
ora a! jnz shell$err
lda fx! cpi 33! cnc incr$rr
call adv$dma
pop a! dcr a! jnz mult$io1
lxi h,0
ret
;
compare$recs:
lhld shell$dma! xchg! lhld dirbufa
mvi c,128
call compare! rz
pop h! lxi h,0007! jmp shell$err
;
compare:
ldax d! cmp m! rnz
inx h! inx d! dcr c! rz
jmp compare
;
get$rra:
lxi h,common$fcb! lxi d,33! dad d! ret
;******************************************************
;** **
;** C h a i n **
;** **
;******************************************************
;
chainf equ 47
chain:
call getmemseg! lhld rlradr
lxi b,msegtbl-rlros! dad b
add a! add a! mov e,a! mvi d,0! dad d
mov h,m! mvi l,5ch
push h! inx h! mvi c,8! lxi d,clipdname
moveclipdname:
ldax d! mov m,a! inx d! inx h
dcr c! jnz moveclipdname
mvi m,0
;set no user sys stacks
call rlr! lxi b,pname+2! dad b
mov a,m! ori 80h! mov m,a
lxi b,console-(pname+2)! dad b! mov a,m
pop d! push d! stax d! mvi e,7dh! stax d
lxi b,diskselect-console! dad b
dcx d! mov a,m! stax d
inx d! inx d! xra a! stax d! inx d
call getmemseg! stax d;
;assign the console to the cli
mvi c,asgncns! pop d! push d! call xdos
;raise process priority
mvi c,setprior! mvi e,0! call xdos
;send special form of send cli command
mvi c,sendcli! pop d! mvi e,7ch! call xdos
;terminate the calling process
mvi c,terminate! lxi d,0ff00h! jmp xdos
clipdname:
db 'cli '