mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-25 17:34:06 +00:00
380 lines
11 KiB
Plaintext
380 lines
11 KiB
Plaintext
; **********************************************************************
|
||
; initdira - Provides BIOS (XIOS) assembler interface for INITDIR.PLI
|
||
; - Also provides examples of how to:
|
||
; 1. Call CCP/M-86 XIOS
|
||
; 2. Lock up disk system for direct disk I/O
|
||
; 3. Lock up console, to prevent a job from being switched out
|
||
; **********************************************************************
|
||
|
||
|
||
cseg
|
||
|
||
public bstdma ; sets DMA segment and offset
|
||
public rdsec ; reads a physical sector
|
||
public sectrn ; translates a sector
|
||
public seldsk ; selects a drive
|
||
public setsec ; sets the sector to be read/written
|
||
public settrk ; sets the track to be read/written
|
||
public wrsec ; writes a physical sector
|
||
|
||
public openvec ; returns open files vector
|
||
public syslock ; locks up the disk system
|
||
public sysunlock ; unlocks the disk system
|
||
public conlock ; locks the console into foreground mode
|
||
public conunlock ; unclocks the console
|
||
|
||
|
||
IO_SELDSK equ 9 ; XIOS function number
|
||
IO_READ equ 10 ; XIOS function number
|
||
IO_WRITE equ 11 ; XIOS function number
|
||
P_PRIORITY equ 145 ; BDOS function: set Process PRIORITY
|
||
S_SYSDAT equ 154 ; BDOS function: get SYStem DATa page address
|
||
P_PDADR equ 156 ; BDOS function: get Process Descriptor address
|
||
Q_OPEN equ 135 ; Open Queue
|
||
Q_READC equ 138 ; Read Queue Conditional
|
||
Q_WRITEC equ 139 ; Write Queue Conditional
|
||
|
||
XIOS_ptr equ dword ptr .28h ; loc of XIOS entry in SYSDAT
|
||
OPVEC equ word ptr .88h ; loc of Open_Files_on_Drives vector
|
||
UDA_seg equ word ptr 10h ; loc of UDA seg in Process Descriptor
|
||
|
||
|
||
|
||
;*****************************************************************
|
||
;*** PL/I Utility Functions ***
|
||
;*****************************************************************
|
||
getp1: ; get single byte parameter to register DL
|
||
mov bx,[bx] ;BX = .char
|
||
mov dl,[bx] ;to register DL
|
||
ret
|
||
|
||
getp2: ; get single word value to DX
|
||
getp2i: ; same as getp2
|
||
mov bx,[bx]
|
||
mov dx,[bx]
|
||
ret
|
||
|
||
|
||
getsu: ;get sysdat and uda addrs
|
||
;enters: DS=local data seg
|
||
;exits: DS=SYSDAT seg, ES=UDA seg (for call to XIOS)
|
||
mov cx,udaaddr ;get the saved value
|
||
or cx,cx ;set flags
|
||
jz getsu1 ;uninitialized, go do the OS call
|
||
mov es,cx ;we've been here before, just load regs
|
||
mov cx,sysaddr
|
||
mov ds,cx
|
||
ret
|
||
|
||
getsu1:
|
||
mov cl,P_PDADR ;get Process Descriptor
|
||
int 0E0h ;call BDOS
|
||
mov cx,es:UDA_seg[bx] ;grab UDA_seg
|
||
mov udaaddr,cx ;save for future calls
|
||
push cx ;save UDA_seg
|
||
mov cl,S_SYSDAT ;get address of SYStem DATa area
|
||
int 0E0h ;call BDOS
|
||
mov cx,es ;mov ds,es
|
||
mov sysaddr,cx ;save for future calls
|
||
mov ds,cx
|
||
pop es ;restore UDA_seg
|
||
ret
|
||
|
||
|
||
|
||
;*****************************************************************
|
||
;*** Simulate old XIOS style functions ***
|
||
;*****************************************************************
|
||
bstdma: ; sets DMA segment and offset
|
||
call getp2 ;dma address to DX
|
||
mov dmaoff,dx ;stuff addr in IOPB's offset field
|
||
mov dmaseg,ds ;assume all addresses relative to DS
|
||
ret ;no BDOS/XIOS call, just init the IOPB
|
||
|
||
|
||
sectrn: ; translates a sector
|
||
call getp2 ;get sector number to DX
|
||
mov bx,dx ;no translation: return (unchanged) value
|
||
ret
|
||
|
||
|
||
setsec: ; sets the sector to be read/written
|
||
call getp2i ;sector number to DX
|
||
mov sector,dx ;stuff sector into IOPB
|
||
ret
|
||
|
||
|
||
settrk: ; sets the track to be read/written
|
||
call getp2i ;track number to DX
|
||
mov track,dx ;stuff track into IOPB
|
||
ret
|
||
|
||
|
||
;*****************************************************************
|
||
;*** Physical I/O calls ***
|
||
;*****************************************************************
|
||
rdsec: ; reads a physical sector
|
||
mov ax,IO_READ
|
||
jmp xiosiopb ;jump around this code
|
||
|
||
wrsec: ; writes a physical sector
|
||
mov ax,IO_WRITE ;fall thru to xiosiopb
|
||
|
||
xiosiopb: ;put the IOPB on the stack, call XIOS
|
||
push ds ;ds will contain SYSDAT seg
|
||
push es ;es will contain UDA seg
|
||
;someday change this to a block move?
|
||
mov ch,mscnt
|
||
mov cl,drv
|
||
push cx ;1st word of IOPB
|
||
mov cx,track
|
||
push cx ;2nd word
|
||
mov cx,sector
|
||
push cx ;3rd word
|
||
mov cx,dmaseg
|
||
push cx ;4th word
|
||
mov cx,dmaoff
|
||
push cx ;5th word
|
||
|
||
push ax ;save XIOS_function
|
||
call getsu ;set up DS-SYSDAT and ES-UDA
|
||
pop ax ;restore XIOS_function
|
||
callf XIOS_ptr ;call indirect the XIOS
|
||
;bl contains return status
|
||
pop cx ;dma offset
|
||
pop cx ;dma segment
|
||
pop cx ;track
|
||
pop cx ;sector
|
||
pop cx ;drv & mscnt
|
||
pop es ;restore original es
|
||
pop ds ;ditto for ds
|
||
ret
|
||
|
||
|
||
;*****************************************************************
|
||
;*** XIOS Select Disk Routine ***
|
||
;*****************************************************************
|
||
seldsk: ; selects a drive
|
||
; also resets login sequence number of drive to 0,
|
||
; to force permanent media to be logged in again on disk reset
|
||
|
||
call getp1 ;drive to DL
|
||
mov drv,dl ;stuff drive into IOPB
|
||
push es ! push ds ;save context ************
|
||
;do the XIOS SELDSK call
|
||
push dx ;save drive
|
||
call getsu ;set up DS and ES
|
||
pop cx ;restore drive
|
||
mov ax,IO_SELDSK
|
||
mov dx,0 ;this better not be the first call
|
||
callf XIOS_ptr ;call indirect XIOS
|
||
;xfer DPH locally
|
||
pop es ! push es ;restore & save Data Segment into es
|
||
mov di,offset dph ;set up destination
|
||
mov si,bx ;ptr to dph returned from XIOS call
|
||
mov log_seqn[si],0 ;force disk reset: 0 login sequence number
|
||
mov cx,dphsiz
|
||
rep movsb ;move copy of DPH into local storage
|
||
;xfer DPB locally
|
||
mov di,offset dpb ;set up destination
|
||
mov si,es:dpbptr ;get this info from DPH
|
||
mov cx,dpbsiz
|
||
rep movsb ;move copy of DPB into local storage
|
||
;cleanup
|
||
pop ds ! pop es ;restore context ************
|
||
mov dpbptr,offset dpb ;set up local ptr in DPH
|
||
mov bx,offset dph ;return address of local copy of DPH
|
||
ret
|
||
|
||
|
||
;*****************************************************************
|
||
;*** Open Drives Vector ***
|
||
;*****************************************************************
|
||
openvec: ; returns vector of drives with open files
|
||
push es ;save extra seg
|
||
push ds ;save data seg
|
||
mov cl,S_SYSDAT ;look in the system data page
|
||
int 0E0h ;call bdos
|
||
mov ax,es:OPVEC ;get the vector of drives containing open files
|
||
mov bx,ax ;stuff both regs
|
||
pop ds ;restore data seg
|
||
pop es ;restore extra seg
|
||
ret
|
||
|
||
|
||
;*****************************************************************
|
||
;*** System Lock and Unlock Routines ***
|
||
;*****************************************************************
|
||
syslock: ; locks up the disk system
|
||
; returns 0 in ax,bx if everything ok, -1 o.w.
|
||
push es ;save extra seg
|
||
push ds ;save data seg
|
||
|
||
mov cl,S_SYSDAT ;look in the system data page
|
||
int 0E0h ;call bdos
|
||
mov cx,es:OPVEC ;get the vector of drives containing open files
|
||
test cx,0FFFFh ;check all drives
|
||
jnz syslfail ;fail if any open files
|
||
|
||
mov cx,Q_OPEN
|
||
mov dx,offset qpb ;mxdisk queue parm block
|
||
int 0E0h ;call bdos
|
||
or ax,ax ;test return
|
||
jnz sysltry2 ;if non zero, try kluge
|
||
mov cx,Q_READC ;see if we can read the queue
|
||
mov dx,offset qpb ;insurance
|
||
int 0E0h ;call bdos
|
||
or ax,ax ;test retrun
|
||
jnz syslfail ;fail if we can't read mxdisk queue
|
||
jmp syslokay ;okay, tell 'em so
|
||
|
||
sysltry2: ;kluge for old systems
|
||
mov cx,Q_OPEN
|
||
mov dx,offset qpb2 ;mxdisk queue parm block
|
||
int 0E0h ;call bdos
|
||
or ax,ax ;test return
|
||
jnz syslfail ;if non zero
|
||
mov cx,Q_READC ;see if we can read the queue
|
||
mov dx,offset qpb2 ;insurance
|
||
int 0E0h ;call bdos
|
||
or ax,ax ;test retrun
|
||
jnz syslfail ;fail if we can't read mxdisk queue
|
||
syslokay:
|
||
mov ax,0 ! jmp syslret ;return code 0, everything okay
|
||
syslfail:
|
||
mov ax,0FFFFh ;return code -1, failure
|
||
syslret:
|
||
mov bx,ax ;stuff both regs
|
||
pop ds ;restore data seg
|
||
pop es ;restore extra seg
|
||
ret
|
||
|
||
|
||
|
||
sysunlock: ;undoes a 'syslock' function
|
||
mov cx,Q_WRITEC ;conditionally write to mxdisk queue
|
||
mov dx,offset qpb
|
||
int 0E0h
|
||
mov cx,Q_WRITEC ;kluge to handle old systems
|
||
mov dx,offset qpb2
|
||
int 0E0h
|
||
ret
|
||
|
||
|
||
;*****************************************************************
|
||
;*** Console Lock and Unlock Routines ***
|
||
;*****************************************************************
|
||
|
||
CCB_BACKGRD equ 0002h ;Console in Background mode
|
||
CCB_NOSWITCH equ 0008h ;Console not allowed to switch mode
|
||
CCB_SIZE equ 2Ch ;size of CCB
|
||
CCB_STATE equ word ptr 0Eh ;addr of Console State word in CCB
|
||
CON_NUM equ byte ptr 020h ;addr of console number in PD
|
||
CCB_PTR equ word ptr .054h ;addr of CCB table in SYSDAT
|
||
|
||
PD_FLAG equ word ptr 06 ;addr of FLAGs word in PD
|
||
PD_KEEP equ 0002h ;Keep Process Flag
|
||
TOP_PRIOR equ 151 ;What we set to for Top Priority (arbitrary)
|
||
REG_PRIOR equ 200 ;Default Regular Priority
|
||
|
||
|
||
conlock: ;locks the console into the foreground, sets Keep Flag,
|
||
; and boosts priority
|
||
;returns 0 in ax,dx if everything okay, -1 o.w.
|
||
push es ;save extra seg
|
||
call concalc ;ES=SYSDAT, bx=CCB offset
|
||
test es:CCB_STATE[bx],CCB_BACKGRD ;is console in background?
|
||
jnz conlfail ;background operation not allowed!
|
||
or es:CCB_STATE[bx],CCB_NOSWITCH ;make sure they don't switch
|
||
mov cl,P_PDADR ;get Process Descriptor
|
||
int 0E0h ;call BDOS
|
||
or es:PD_FLAG[bx],PD_KEEP ;set Keep flag
|
||
mov dl,TOP_PRIOR ;let's be quick
|
||
mov cl,P_PRIORITY ;set Priority
|
||
int 0E0h ;call BDOS
|
||
|
||
conlokay:
|
||
mov ax,0 ! jmp conlret
|
||
conlfail:
|
||
mov ax,0FFFFh
|
||
conlret:
|
||
mov bx,ax
|
||
pop es ;restore extra seg
|
||
ret
|
||
|
||
|
||
|
||
conunlock: ;undoes the 'conlock' function
|
||
push es ;save extra seg
|
||
call concalc ;ES=sysdat, bx=CCB offset
|
||
and es:CCB_STATE[bx],NOT CCB_NOSWITCH ;let them switch now
|
||
mov cl,P_PDADR ;get Process Descriptor
|
||
int 0E0h ;call BDOS
|
||
and es:PD_FLAG[bx],NOT PD_KEEP ;reset Keep flag
|
||
mov dl,REG_PRIOR ;finished with quick
|
||
mov cl,P_PRIORITY ;set Priority
|
||
int 0E0h ;call BDOS
|
||
|
||
pop es ;restore extra seg
|
||
ret
|
||
|
||
|
||
|
||
concalc: ;put SYSDAT in ES, offset of CCB in bx
|
||
mov cx,P_PDADR ;get Process Descriptor Addr
|
||
int 0E0h ;call the bdos
|
||
xor ax,ax ;clear ax
|
||
mov al,es:CON_NUM[bx] ;grab the console number
|
||
mov cx,CCB_SIZE ;stuff cx with size
|
||
mul cx ;compute ccb address
|
||
push ax ;save ccb offset
|
||
mov cl,S_SYSDAT ;get the System Data Segment
|
||
int 0E0h ;call the bdos
|
||
pop bx ;restore ccb offset
|
||
add bx,es:CCB_PTR ;compute offset of ccb
|
||
ret
|
||
|
||
|
||
|
||
;*****************************************************************
|
||
;*** Data Segment ***
|
||
;*****************************************************************
|
||
|
||
dseg
|
||
|
||
sysaddr dw 0 ; save location for sysdat addr
|
||
udaaddr dw 0 ; save location for process uda addr
|
||
|
||
dphsiz equ 014h ; size of Disk Parm Header
|
||
dph rb dphsiz ; local save area
|
||
log_seqn equ byte ptr 6 ; byte to force reset of permanent media
|
||
dpbptr equ word ptr dph+8 ; word of interest: DPB offset
|
||
|
||
dpbsiz equ 011h ; size of Disk Parameter Buffer
|
||
dpb rb dpbsiz ; local save area
|
||
|
||
|
||
iopb rb 0 ; the iopb structure filled in by above rtns
|
||
mscnt db 1 ; multi sector count
|
||
drv rb 1 ; select drive
|
||
track rw 1 ; select track
|
||
sector rw 1 ; select sector
|
||
dmaseg rw 1 ; set dma address
|
||
dmaoff rw 1 ; set dma address
|
||
iopbsiz equ (offset $)-(offset iopb)
|
||
|
||
|
||
qpb rb 0 ; queue parameter block
|
||
dw 0 ; reserved
|
||
dw 0 ; queueid
|
||
dw 0 ; nmsgs
|
||
dw 0 ; buffer
|
||
db 'MXdisk ' ; queue name
|
||
|
||
qpb2 rb 0 ; queue parameter block number 2: be persistent
|
||
dw 0 ; reserved
|
||
dw 0 ; queueid
|
||
dw 0 ; nmsgs
|
||
dw 0 ; buffer
|
||
db 'mxdisk ' ; queue name
|
||
|