;***************************************************** ;* ;* BDOS Interface ;* ;***************************************************** MPM equ true CPM equ false cseg org 0 jmp init ;BDOS initialization jmp entry ;inter module entry pt. sysdat dw 0 ;seg address of sysdat supervisor equ offset $ dw 3 dw 0 ;SUP segment db 'COPYRIGHT (C) 1981,' db ' DIGITAL RESEARCH ' serial db '654321' ;==== init: ;==== ; initialize bdos/xios modules ; assume ds=system data area ; save sysdat segment mov sysdat,ds mov bx,offset supmod ! mov si,supervisor mov ax,[bx] ! mov cs:[si],ax mov ax,2[bx] ! mov cs:2[si],ax ; create disk mx queue mov dx,offset mxdiskqd ! mov cx,f_qmake call mpmif ; open mx disk queue mov dx,offset mxdiskqpb ! mov cx,f_qopen call mpmif ; write mx disk queue mov dx,offset mxdiskqpb ! mov cx,f_qwrite call mpmif retf ;***************************************************** ;* ;* BDOS function table ;* ;***************************************************** ; ; format of entry in functab ; btab_addr equ word ptr 0 btab_flag equ byte ptr (btab_addr + word) btablen equ btab_flag + byte bf_getmx equ 0001h ;get mxdisk queue BF_CSHELL EQU 0002H ;CONDITIONAL SHELL FUNCTION BF_TANDW EQU 0004H ;TEST & WRITE FUNCTION BF_FCB36 EQU 0008H ;SHELL 36 BYTE FCB FLAG ; ; bdos function table ; functab dw func13 ! db 1 ; 0: disk reset dw func14 ! db 1 ; 1: select disk dw func15 ! db 1 ; 2: open file dw func16 ! db 1 ; 3: close file dw func17 ! db 1 ; 4: search first dw func18 ! db 1 ; 5: search next dw func19 ! db 1 ; 6: delete file dw func20 ! db 3 ; 7: read sequential dw func21 ! db 3 ; 8: write sequential dw func22 ! db 1 ; 9: make file dw func23 ! db 1 ; 10: rename file dw func24 ! db 0 ; 11: return login vector dw func25 ! db 0 ; 12: return current disk dw func26 ! db 0 ; 13: set dma address dw func27 ! db 1 ; 14: get alloc addr dw func28 ! db 1 ; 15: write protect disk dw func29 ! db 0 ; 16: get r/o vector dw func30 ! db 1 ; 17: set file attributes dw func31 ! db 1 ; 18: get disk parm addr dw func32 ! db 0 ; 19: set/get user code RDRAN_OFF dw func33 ! db 11 ; 20: read random WRRAN_OFF dw func34 ! db 11 ; 21: write random dw func35 ! db 1 ; 22: compute file size dw func36 ! db 1 ; 23: set random record dw func37 ! db 1 ; 24: reset drive dw func38 ! db 1 ; 25: access drive dw func39 ! db 1 ; 26: free drive dw func40 ! db 3 ; 27: write random w/zero fill DW FUNC41 ! DB 13 ; 28: TEST & WRITE RECORD DW FUNC42 ! DB 1 ; 29: LOCK RECORD DW FUNC43 ! DB 1 ; 30: UNLOCK RECORD DW FUNC44 ! DB 0 ; 31: SET MULTI-SECTOR COUNT DW FUNC45 ! DB 0 ; 32: SET BDOS ERROR MODE DW FUNC46 ! DB 1 ; 33: GET DISK FREE SPACE DW FUNC47 ! DB 1 ; 34: CHAIN TO PROGRAM DW FUNC48 ! DB 1 ; 35: FLUSH BUFFERS dw func51 ! db 0 ; 36: set dma base dw func52 ! db 0 ; 37: get dma base DW FUNC100 ! DB 1 ; 38: SET DIRECTORY LABEL DW FUNC101 ! DB 1 ; 39: RETURN DIRECTORY LABEL DATA DW FUNC102 ! DB 1 ; 40: READ FILE XFCB DW FUNC103 ! DB 1 ; 41: WRITE OR UPDATE FILE XFCB DW FUNC104 ! DB 1 ; 42: SET CURRENT DATE AND TIME DW FUNC105 ! DB 1 ; 43: GET CURRENT DATE AND TIME DW FUNC106 ! DB 1 ; 44: SET DEFAULT PASSWORD DW FUNC107 ! DB 0 ; 45: RETURN SERIAL NUMBER DW PR_TERM ! DB 1 ; 46: TERMINATE PROCESS ;===== entry: ;===== mov ch,0 ! mov ax,btablen push dx ! mul cx ! pop dx mov si,offset functab ! add si,ax TEST cs:btab_flag[si],bf_getmx ! jz nomx call getdiskmx ! jmps exit nomx: call cs:btab_addr[si] exit: mov ax,bx ! retf ;========= getdiskmx: ;========= ; si = address of functab entry ; dx = argument push si! push dx MOV CX,F_CONSTAT CALL MPMIF pop dx! pop si ;do not allow ctrl c while in bdos mov bx,rlr mov ax,p_flag[bx] ! and ax,pf_tempkeep PUSH AX or p_flag[bx],pf_tempkeep push si! push dx mov cx,f_qread ! mov dx,offset mxdiskqpb call mpmif pop dx ! pop si mov bx,rlr! test p_flag[bx],pf_ctlc jz $+5 jmp retmonx ;switch to internal bdos stack pushf ! pop ax ! cli mov sssave,ss mov spsave,sp mov ss,sysdat mov sp,offset bdosstack push ax ! popf ;initialize bdos data area for user push si ! push dx mov ax,u_wrkseg mov parametersegment,ax mov ax,u_retseg mov returnseg,ax mov bx,rlr ! MOV PDADDR,BX ;set default user code mov al,p_user[bx] ! mov usrcode,al ;set default disk mov dl,p_dsk[bx] MOV SELDSK,DL ;set default dma mov setbf,false mov ax,u_dma_ofst cmp ax,dmaad ! je nodmaoch mov setbf,true nodmaoch: mov ax,u_dma_seg cmp ax,dmabase ! je nodmabch mov setbf,true nodmabch: ;copy uda bdos vars to local area push es ! push ds ! pop es ! pop ds mov si,offset u_dma_ofst ! mov di,offset dmaad mov cx,uda_ovl_len ! rep movs al,al push es ! push ds ! pop es ! pop ds TEST PDCNT,1! JZ PDCNT_OK ;RESET PDCNT IF LOW ORDER BIT SET MOV AL,PDCNT! CALL INC_PDCNT PDCNT_OK: pop dx ! push dx mov info,dx ;info=dx mov linfo,dl ;linfo = low(info) - don't equ call entryzero ;Set DMA buffer if needed cmp setbf,true ! jne nsetbf call setdata nsetbf: ;ready to go to the function pop dx ! pop si PUSH ES! PUSH DS! POP ES MOV AH,CS:BTABFLAG[SI] TEST AH,BF_TANDW ! JNZ SHELL CMP MULT_CNT,1 ! JE NOSHELL TEST AH,BF_CSHELL ! JNZ SHELL NOSHELL: CALL CALL_BDOS RETMON: POP ES mov si,offset dmaad ! mov di,offset u_dma_ofst mov cx,uda_ovl_len rep movs al,al ;setup return registers mov dx,returnseg mov u_retseg,dx mov bx,aret ;switch back to user's stack pushf ! pop dx ! cli mov ss,sssave mov sp,spsave push dx ! popf ;release mxdisk queue RETMONX: push bx mov cx,f_qwrite ! mov dx,offset mxdiskqpb call mpmif ;see if control c occured mov si,rlr pop bx! pop ax! not ax xor ax,pf_tempkeep! and p_flag[si],ax test p_flag[si],pf_ctlc jz mxdiskexit mov cx,f_terminate ! push bx sub dx,dx ! call mpmif pop bx mxdiskexit: ret ; SHELL: MOV SHELL_SI,SI MOV BX,DMAAD! MOV SHELL_DMA,BX MOV BX,OFFSET SHELL_RTN! PUSH BX TEST AH,BF_FCB36! JNZ SHELL01 CALL PARSAVE33! JMP SHELL02 SHELL01: CALL PARSAVE36! CALL SAVE_RR SHELL02: MOV SHELL_FLAG,TRUE TEST AH,BF_TANDW! JNZ TST_WRT JMP MULTIO ; CBDOS: MOV SI,SHELL_SI CBDOS1: MOV DX,INFO CALL CALL_BDOS! MOV AL,BYTE PTR ARET! RET ; SHELL_ERR: MOV BX,ARET MOV DL,MULT_CNT! POP AX! SUB DL,AL MOV CL,4! SHL DL,CL! OR BH,DL RET ; SHELL_RTN: MOV ARET,BX TEST AH,BF_FCB36! JZ $+5! CALL RESET_RR MOV BX,SHELL_DMA! MOV DMAAD,BX! CALL SET_DATA MOV SHELL_FLAG,FALSE! CALL PARUNSAVE JMP RETMON ; INCR_RR: CALL GET_RRA INC W[BX]! JNZ INCR_RR_RET INC BX! INC BX! INC B[BX] INCR_RR_RET: RET ; SAVE_RR: CALL SAVE_RR2! XCHG BX,DX SAVE_RR1: MOV CL,3! JMP MOVE SAVE_RR2: CALL GET_RRA! MOV DX,OFFSET SHELL_RR! RET ; RESET_RR: CALL SAVE_RR2! JMP SAVE_RR1 ; TST_WRT: MOV AL,MULT_CNT! PUSH AX CALL SET_DIR! POP AX TST_WRT1: PUSH AX! MOV SI,OFFSET RDRAN_OFF! CALL CBDOS1 OR AL,AL! JNZ SHELL_ERR CALL COMPARE_RECS CALL INCR_RR ADD DMAAD,80H POP AX! DEC AL! JNZ TST_WRT1 PUSH AX! CALL SET_DATA CALL RESET_RR MOV SHELL_SI,OFFSET WRRAN_OFF POP AX ; MULT_IO: MOV AL,MULT_CNT MULT_IO1: PUSH AX! CALL CBDOS OR AL,AL! JZ $+5! JMP SHELL_ERR POP AX! PUSH AX! TEST AH,BF_FCB36! JZ MULT_IO2 CALL INCR_RR MULT_IO2: ADD DMAAD,80H! CALL SET_DATA POP AX! DEC AL! JNZ MULT_IO1 XOR BX,BX RET ; COMPARE_RECS: PUSH ES! MOV ES,DMABASE! MOV DI,DMAAD MOV SI,BUFFA! MOV CL,64 REP CMPS AX,AX POP ES JNZ $+3! RET POP BX! MOV BX,7! JMP SHELL_ERR ; CALL_BDOS: MOV SAVESP,SP call cs:btab_addr[si] BDOS_RETURN: MOV AL,SELDSK cmp resel,0 JE RETMON5 CMP COMP_FCB_CKS,TRUE! JNE RETMON1 CALL SET_CHKSUM_FCB RETMON1: MOV AL,XFCB_READ_ONLY! OR AL,AL! JZ RETMON2 MOV BX,INFO! OR 7[BX],AL RETMON2: CALL GETEXTA! MOV AL,HIGHEXT! CMP AL,60H! JNE RETMON3 SUB BX,4! MOV AL,80H RETMON3: OR [BX],AL MOV AL,ACTUAL_RC! OR AL,AL! JZ RETMON4 CALL GETRCNTA! OR [BX],AL RETMON4: MOV AL,SELDSK mov cl,fcbdsk mov bx,info ! mov [bx],cl cmp cl,0 ! je RETMON5 mov al,olddsk RETMON5: cmp parcopfl,true jne RETMON6 call parunsave RETMON6: ;copy local vars to uda RET ; XCRLF: mov cx,F_CONPRINT mov dx,offset crlfstr XOR BX,BX jmp mpmif ; XPRINT: mov dx,cx ! mov cx,F_CONPRINT XOR BX,BX jmp mpmif ; parsave: ;copy parameterblock from user segment to bdos segment ;cl-reg = lenght of parameter block ; TEST SHELL_FLAG,TRUE JNZ PARRET push ds push ax mov parcopfl,true mov parlg,cl xor ch,ch mov si,info mov infosave,si mov di,offset loc_par_area mov info,di mov ds,parametersegment rep movs al,al pop ax pop ds parret: ret ; parsave33: ;copy 33 byte length parameterblock push cx mov cl,33 jmps pscommon ; parsave36: ;copy 36 byte length parameterblock push cx mov cl,36 pscommon: call parsave pop cx ret ; parunsave: ;copy local parameter block to user segment ; TEST SHELL_FLAG,TRUE JNZ PARRET push es push ax push cx mov cl,parlg xor ch,ch mov es,parametersegment mov si,offset loc_par_area mov di,infosave mov info,di rep movs al,al pop cx pop ax pop es ret ;these functions taken out of the ;bdosio.a86 module setlret1: mov al,1 staret: mov lret,al funcret: ret ;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 entryzero: ;--------- push cx ! push es mov cx,ds ! mov es,cx mov cx,zerolength ! mov al,0 mov di,offset fcbdsk rep stos al pop es ! pop cx ret ;***************************************************** ;* ;* bdos - xios interface ;* ;***************************************************** bootf: wbootf: mov cx,f_terminate ! jmp mpmif homef: mov al,io_home ! jmps xiosif seldskf:mov al,io_seldsk ! jmps xiosif settrkf:mov al,io_settrk ! jmps xiosif setsecf:mov al,io_setsec ! jmps xiosif setdmf: mov al,io_setdma ! jmps xiosif setdmbf:mov al,io_setdmab ! jmps xiosif readf: mov al,io_read ! jmps xiosif writef: mov al,io_write ! jmps xiosif sectran:mov al,io_sectran ! jmps xiosif flush: mov al,io_flush ! jmps xiosif ;====== ======================== xiosif: ; xios interface routine ;====== ======================== ; input: al = function number ; cx = argument 1 ; dx = argument 2 ; output: ax = bx = output MOV SI,RLR! PUSH ES! MOV ES,P_UDA[SI] callf dword ptr .xiosmod CLD! POP ES ret