Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 86/CONCURRENT/CCPM-86 3.1 SOURCE/D2/BDOSIF.BDO
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

637 lines
15 KiB
Plaintext
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.

;*****************************************************
;*
;* BDOS interface
;*
;*****************************************************
BMPM equ true
BCPM equ false
CSEG
if PCMODE
EXTRN bdosrw:NEAR
EXTRN compfs:NEAR
EXTRN closef:NEAR
EXTRN deletef:NEAR
EXTRN getspace:NEAR
EXTRN makef:NEAR
EXTRN openf:NEAR
EXTRN chk_pcfcb:NEAR
EXTRN pc_chkrec:NEAR
EXTRN pcsearch:NEAR
EXTRN renamef:NEAR
EXTRN setattsf:NEAR
EXTRN setstamp:NEAR
EXTRN truncatef:NEAR
EXTRN xfcb:NEAR
PUBLIC check_fcb1
PUBLIC check_fcb3
PUBLIC checkwrite
PUBLIC chk_olist
PUBLIC chk_wild
PUBLIC chk_wild0
PUBLIC ckrofile
PUBLIC close021
PUBLIC conv_rr
PUBLIC copy_user_no
PUBLIC dblockio
PUBLIC directio
PUBLIC discard_data
PUBLIC flush
PUBLIC flushx
PUBLIC fxi40
PUBLIC get_atts
PUBLIC init_wzf
PUBLIC lret_eq_ff
PUBLIC openx1a
PUBLIC pack_sdcnt
PUBLIC pc_make_test
PUBLIC rd_pcdir
PUBLIC reset_checksum_fcb
PUBLIC roferror
PUBLIC search_olist
PUBLIC seek;
PUBLIC setcdr
PUBLIC setenddir
PUBLIC set_aret
PUBLIC set_lret1
PUBLIC test_lock
PUBLIC tst_olist
PUBLIC update_fat
PUBLIC wrbuff;
PUBLIC wrdir
endif
org 0000h
jmp init ;bdos initialization
jmp entry ;inter module entry pt.
sysdat dw 0 ;seg address of sysdat
supervisor rw 2 ;supervisor offset and segment
dev_ver dw 6 ; chk'd by GENSYS
db 'COPYRIGHT(C)1983,84,'
db 'DIGITAL RESEARCH(02/07/84)'
db 'XXXX-0000-654321'
;====
init: ; initialize bdos/xios modules
;====
; entry: DS = system data area
; code segment values setup by gensys
; mov sysdat,ds
; mov ax,supmod
; mov cs:supervisor,ax
; mov ax,supmod+2
; mov cs:supervisor+2,ax
retf
;*****************************************************
;*
;* bdos function table
;*
;*****************************************************
; structure of entry in functab
btab_addr equ word ptr 0
btab_flag equ byte ptr (btab_addr + word)
bf_getmx equ 00001b ;get mxdisk queue
bf_cshell equ 00010b ;conditional shell function
bf_fcb33 equ 00100b ;33 byte fcb flag
bf_fcb36 equ 01000b ;36 byte fcb flag
bf_resel equ 10000b ;disk reselect flag
; bdos function table
functab dw func13 ! db 00001b ; fxi13 equ 00h ;disk reset
dw func14 ! db 00001b ; fxi14 equ 01h ;select disk
dw func15 ! db 10101b ! fxi15 equ 02h ;open file
ftab16 dw func16 ! db 10101b ! fxi16 equ 03h ;close file
dw func17 ! db 00101b ! fxi17 equ 04h ;search first
dw func18 ! db 00001b ! fxi18 equ 05h ;search next
dw func19 ! db 10101b ! fxi19 equ 06h ;delete file
dw func20 ! db 10111b ! fxi20 equ 07h ;read sequential
dw func21 ! db 10111b ! fxi21 equ 08h ;write sequential
dw func22 ! db 00101b ! fxi22 equ 09h ;make file
dw func23 ! db 10101b ! fxi23 equ 0Ah ;rename file
dw func24 ! db 00000b ; fxi24 equ 0Bh ;return login vector
dw func25 ! db 00000b ; fxi25 equ 0Ch ;return current disk
dw func26 ! db 00000b ; fxi26 equ 0Dh ;set dma address
dw func27 ! db 00001b ! fxi27 equ 0Eh ;get alloc addr
dw func28 ! db 00001b ; fxi28 equ 0Fh ;write protect disk
dw func29 ! db 00000b ; fxi29 equ 10h ;get r/o vector
dw func30 ! db 00101b ! fxi30 equ 11h ;set file attributes
dw func31 ! db 00001b ! fxi31 equ 12h ;get disk parm addr
dw func32 ! db 00000b ; fxi32 equ 13h ;set/get user code
dw func33 ! db 11011b ! fxi33 equ 14h ;read random
dw func34 ! db 11011b ! fxi34 equ 15h ;write random
dw func35 ! db 11001b ! fxi35 equ 16h ;compute file size
dw func36 ! db 01001b ; fxi36 equ 17h ;set random record
dw func37 ! db 00001b ; fxi37 equ 18h ;reset drive
dw func38 ! db 00001b ; fxi38 equ 19h ;access drive
dw func39 ! db 00001b ! fxi39 equ 1Ah ;free drive
dw func40 ! db 11011b ! fxi40 equ 1Bh ;write random w/zero fill
dw func42 ! db 11001b ! fxi42 equ 1Ch ;lock record
dw func43 ! db 11001b ! fxi43 equ 1Dh ;unlock record
dw func44 ! db 00000b ; fxi44 equ 1Eh ;set multi-sector count
dw func45 ! db 00000b ; fxi45 equ 1Fh ;set bdos error mode
dw func46 ! db 00001b ; fxi46 equ 20h ;get disk free space
dw func48 ! db 00001b ! fxi48 equ 21h ;flush buffers
dw func51 ! db 00000b ; fxi51 equ 22h ;set dma base
dw func52 ! db 00000b ; fxi52 equ 23h ;get dma base
dw func98 ! db 00001b ! fxi98 equ 24h ;reset alloc vector
dw func99 ! db 01001b ! fxi99 equ 25h ;truncate file
dw func100 ! db 00101b ! fxi100 equ 26h ;set directory label
dw func101 ! db 00001b ; fxi101 equ 27h ;return directory label data
dw func102 ! db 00101b ! fxi102 equ 28h ;read file xfcb
dw func103 ! db 00101b ! fxi103 equ 29h ;write or update file xfcb
dw func104 ! db 00000b ; fxi104 equ 2Ah ;set current date and time
dw func105 ! db 00000b ; fxi105 equ 2Bh ;get current date and time
dw func106 ! db 00001b ; fxi106 equ 2Ch ;set default password
dw func116 ! db 10101b ; fxi113 equ 2Dh ;set file date and time
dw pr_term ! db 00001b ! fxi143 equ 2Eh ;terminate process
dw funcdio ! db 00001b ; fxi??? equ 2Fh ;direct disk I/O
;=====
entry: ; bdos module entry point
;=====
; entry: CL = internal bdos function number
; DX = argument
; DS = system data area
; ES = user data area
; exit: AX = BX = return code
xor ch,ch! mov si,cx
shl si,1! add si,cx ; multiply by 3
add si,offset functab
test cs:btab_flag[si],bf_getmx
jz nomx
call getdiskmx
jmps exit
nomx:
xor bx,bx ;initialize return parameter
call cs:btab_addr[si]
exit:
mov ax,bx
retf
restart: ;restart entry point for media changes
;-------
mov cl,fx_intrn ;CX = internal function #
xor ch,ch ;SI = offset of BDOS functab entry
mov si,cx
shl si,1
add si,cx
add si,offset functab
mov bx,rlr ;BX = PD addr
mov dx,info ;DX = argument addr
mov es,uda_save ;ES = UDA addr
cli
jmps setup_stack
getdiskmx:
;---------
; entry: SI = offset of bdos functab entry
; CX = internal bdos function number
; DX = argument
mov bx,rlr
mov ax,p_flag[bx] ! and ax,pf_tempkeep
push ax ;save tempkeep flag
or p_flag[bx],pf_tempkeep ;do not allow ctrl c while in bdos
push si! push dx! push cx
mov cx,f_qread ! mov dx,offset mxdiskqpb
call mpmif ;get mxdisk queue
pop cx! pop dx! pop si
or ax,ax! jz $+5 ;was MXQ read successful?
jmp retmonx1 ;no
mov fx_intrn,cl ;save internal bdos func #
mov bx,rlr
test p_flag[bx],pf_ctlc
jz not_ctlc
xor al,al ;AL = no error message to print
mov bx,0ffffh
jmp retmonxa
not_ctlc:
cli ;switch to internal bdos stack
mov ss_save,ss
mov sp_save,sp
setup_stack:
mov ss,sysdat
mov sp,offset bdosstack
sti
mov pdaddr,bx ;BX = rlr
mov ax,word ptr p_dsk[bx]
mov word ptr seldsk,ax ;set default disk and user code
mov ax,u_wrkseg ;initialize bdos data area for user
mov parametersegment,ax
mov ax,u_retseg
mov returnseg,ax
mov u_ioexerr,0FFh ;initialize IOS extended error byte
push es
mov uda_save,es ;save uda segment
push si
mov ax,ds! mov bx,es ;copy uda bdos vars to local area
mov ds,bx! mov es,ax
mov si,offset u_dma_ofst
mov di,offset dma_ofst
mov cx,uda_ovl_len
rep movsb
mov ds,ax
mov ax,dma_ofst
mov cl,4! shr ax,cl
add dma_seg,ax
and dma_ofst,000fh
mov cx,zerolength ! xor al,al ;zero local variables
mov di,offset fcbdsk
rep stosb
mov info,dx ;info=dx
mov linfo,dl ;linfo = low(info) - don't equ
pop si! push si
mov ah,cs:btab_flag[si]
test ah,bf_fcb33! jz notfcb33 ;if 33 byte fcb
call parsave33! jmps notfcb36 ; copy 33 bytes to local FCB
notfcb33:
test ah,bf_fcb36! jz notfcb36 ;else if 36 byte fcb
call parsave36! call save_rr ; copy 36 bytes to local FCB
notfcb36: ; and save random record bytes
pop si
cmp mult_cnt,1 ! je noshell ;if mult_cnt <> 1 and
test cs:btab_flag[si],bf_cshell ; func uses mult_cnt then
jz noshell
call shell ; use bdos multi sector shell
jmps retmon
noshell:
call call_bdos
retmon:
mov cl,parlg
or cl,cl! jz retmon6
xor ch,ch ;copy local FCB back to user segment?
mov si,offset info_fcb
mov di,info
mov es,parametersegment
rep movsb
retmon6:
pop es ;restore uda segment
mov si,offset dma_ofst+4 ! mov di,offset u_dma_ofst+4
mov cx,uda_ovl_len-4
rep movsb
mov ax,returnseg ;setup return registers
mov u_retseg,ax
mov bx,aret
pushf ! pop ax ! cli ;switch back to user's stack
mov ss,ss_save
mov sp,sp_save
push ax ! popf
mov al,err_type
retmonxa:
push bx ;save return code
test al,true
jz retmonx
js denied_typ
push parametersegment ;fcb segment
mov bx,0ffffh ;0ffffh => no fcb to print in message
test resel,true
jz no_fcb
mov bx,info ;fcb offset
no_fcb:
push bx
jmps comn_dat
denied_typ:
push err_pd_addr ;denied error pd address
comn_dat:
mov ah,err_drv
retmonx:
push ax ;AL = error message type to print
mov cx,f_qwrite ! mov dx,offset mxdiskqpb
call mpmif ;release mxdisk queue
pop ax
test al,0ffh
jnz $+5! jmp retmonx1a
push ax
mov bx,offset msg_spb
mov cx,f_sync
call mpmif
cmp word ptr err_intercept+2,0 ;check if error interception
je ret_err0 ; no
callf dword ptr err_intercept ;call intercept routine
jmp free_spb
ret_err0:
pop ax
add ah,'A'
test al,0ffh
jns $+5! jmp denied_err
push ax
mov dskerr,ah ;set D: field
mov dx,offset dskmsg
call xprint ;print "CP/M Error On D:"
pop ax
mov bl,al
xor bh,bh
shl bx,1
mov dx,xerr_list[bx] ;compute extended error message offset
call xprint ;print error message
mov al,u_func ;convert func# to character
mov ch,30h
mov bx,offset pr_fx1
cmp al,100! jb ret_err1
mov b[bx],31h
inc bx
sub al,100
ret_err1:
sub al,10! jb ret_err2
inc ch
jmps ret_err1
ret_err2:
mov [bx],ch
inc bx
add al,3ah
mov [bx],al
inc bx
mov b[bx],20h
mov bx,offset pr_fcb ;0 = message delimiter
mov b[bx],0
pop si! pop dx ;DX,SI = offset of fcb
inc si ;was reselect called?
jz ret_err3 ;no - don't print fcb
mov b[bx],20h ;remove delimiter
mov di,offset pr_fcb1
mov ax,ds! mov bx,es
mov es,ax ;ES = DS
mov ds,dx ;DS = parametersegment
mov cx,4 ;move file name to message
rep movsw
mov es:b[di],'.' ;move '.' to message
inc di
mov cl,3 ;move file type to message
rep movsb
mov ds,ax! mov es,bx ;restore DS,ES
ret_err3:
mov dx,offset pr_fx ;print "bdos function = ### "
call xprint ; + "file = ffffffff.ttt"
jmps free_spb
denied_err:
mov denieddrv,ah
pop si
mov al,p_cns[si]
add al,'0'
mov deniedcns,al
add si,p_name
mov di,offset deniedprc
push es! push ds! pop es ;ES = DS
mov cx,4 ;copy process name to message
rep movsw
pop es ;restore ES
mov dx,offset deniedmsg
call xprint
free_spb:
mov dx,offset crlf_str
call xprint
mov bx,offset msg_spb
mov cx,f_unsync
call mpmif
retmonx1a:
pop bx ;restore retcode
retmonx1:
mov si,rlr
pop ax ;restore tempkeep flag
or ax,not pf_tempkeep
and p_flag[si],ax
test p_flag[si],pf_ctlc ;see if control C occured
jz mxdiskexit
mov cx,f_terminate! xor dx,dx
push bx! call mpmif! pop bx
mxdiskexit:
ret
call_bdos:
;---------
; entry: DX = argument
; SI = offset of bdos functab entry
mov save_sp,sp
test cs:btab_flag[si],bf_resel
jz cbdos1
push si
call reselect
pop si
cbdos1:
call cs:btab_addr[si]
bdos_return:
cmp resel,0
je retmon5
cmp comp_fcb_cks,true! jne retmon1
call set_chksum_fcb
retmon1:
mov al,xfcb_read_only
mov bx,offset info_fcb
or f7[bx],al
mov al,high_ext
cmp al,60h! jne retmon3
or byte ptr f8[bx],80h
jmps retmon4
retmon3:
or extnum[bx],al
retmon4:
mov al,actual_rc
or reccnt[bx],al
mov al,fcbdsk
mov drv[bx],al
retmon5:
ret
shell:
;-----
; entry: SI = offset of functab entry
mov shell_si,si
mov ah,cs:btab_flag[si]
mov al,mult_cnt
mult_io1:
MOV MULT_NUM,AL
push ax
mov si,shell_si
mov dx,info
call call_bdos
mov bl,byte ptr aret
or bl,bl
pop ax
jz no_shell_err
cmp bl,0ffh! je shell04
mov bh,mult_cnt
sub bh,al ;BH = # of successfull records
jmps shell03
no_shell_err:
test ah,bf_fcb36! jz mult_io2 ;AH = entry functab flags
call incr_rr
mult_io2:
add dma_ofst,80h
dec al
jnz mult_io1
xor bx,bx
shell03:
mov aret,bx
test info_fcb+modnum,80h
jnz shell04
test high_ext,80h
jz shell04
push ax! push bx
mov si,offset ftab16
or info_fcb+f5,80h
mov aret,0
call call_bdos
pop ax
cmp lret+1,0
jnz shell03b
cmp lret,0
jz shell03a
mov al,11
shell03a:
mov aret,ax
shell03b:
pop ax
shell04:
test ah,bf_fcb36! jz parret
;jmps reset_rr
reset_rr:
;--------
call save_rr2! jmps save_rr1
save_rr:
;-------
call save_rr2! xchg bx,dx
save_rr1:
mov cl,3! jmp move
save_rr2:
mov bx,offset info_fcb+ranrec
mov dx,offset shell_rr
ret
parsave33: ;copy 33 byte length FCB
;---------
mov cl,33
jmps parsave
parsave36: ;copy 36 byte length FCB
;---------
mov cl,36
parsave: ;copy FCB from user segment to bdos segment
;-------
; entry: CL = length of FCB to save
mov parlg,cl
xor ch,ch
mov si,info
mov di,offset info_fcb
push ds
mov ds,parametersegment
rep movsb
pop ds
parret:
ret
incr_rr:
;-------
; exit: AX = preserved
mov bx,offset info_fcb+ranrec
inc w[bx]! jnz incr_rr_ret
inc byte ptr 2[bx]
incr_rr_ret:
ret
xprint: ;print message at DX
;------
; entry: DX = offset of message to print
push dx
mov cx,f_cconattch ;make sure we own console before
call mpmif ; attempting to print message
pop dx
or al,al! jnz parret
mov cx,f_conprint
;jmps mpmif
;these functions added for mpm interface
;=====
mpmif: ;call mpm function
;=====
mov si,rlr
push es! mov es,p_uda[si]
callf cs:dword ptr supervisor
pop es
ret
;*****************************************************
;*
;* bdos - xios interface
;*
;*****************************************************
;====== ========================
xiosif: ; xios interface routine
;====== ========================
; entry: AL = function number
; CX = argument 1
; DX = argument 2
; exit: AX = BX = output
push es! mov es,uda_save
callf dword ptr xiosmod
cld! pop es
ret
;======== ================================
rwxiosif: ; disk read/write xios interface
;======== ================================
; entry: AL = function number
; exit: AX = BX = output
mov dx,arecord
mov ch,byte ptr arecord+2
mov bl,curdsk
mov bh,1
xchg bh,mult_sec ;BH = multi sector count
; stack on entry to the xios
push bx ; +C | DRV | MCNT |
push track ; +A | TRACK |
push sector ; +8 | SECTOR |
push cur_dma_seg ; +6 | DMA_SEG |
push cur_dma ; +4 | DMA_OFF |
; +2 | RET_SEG |
; SP+0 | RET_OFF |
mov es,uda_save
callf dword ptr xiosmod
add sp,10 ;remove parameters from stack
cld! push ds! pop es
ret
;************* end of BDOS interface ****************