mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-26 18:04:07 +00:00
Upload
Digital Research
This commit is contained in:
350
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/DEBLOCK.LIB
Normal file
350
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/DEBLOCK.LIB
Normal file
@@ -0,0 +1,350 @@
|
||||
;*****************************************************
|
||||
;* *
|
||||
;* Sector Blocking / Deblocking *
|
||||
;* *
|
||||
;* This algorithm is a direct translation of the *
|
||||
;* CP/M-80 Version, and is included here for refer- *
|
||||
;* ence purposes only. The file DEBLOCK.LIB is in- *
|
||||
;* cluded on your MP/M-86 disk, and should be used *
|
||||
;* for actual applications. You may wish to contact *
|
||||
;* Digital Research for notices of updates. *
|
||||
;* *
|
||||
;*****************************************************
|
||||
;
|
||||
;*****************************************************
|
||||
;* *
|
||||
;* CP/M to host disk constants *
|
||||
;* *
|
||||
;* (This example is setup for CP/M block size of 16K *
|
||||
;* with a host sector size of 512 bytes, and 12 sec- *
|
||||
;* tors per track. Blksiz, hstsiz, hstspt, hstblk *
|
||||
;* and secshf may change for different hardware.) *
|
||||
;*****************************************************
|
||||
una equ byte ptr [BX] ;name for byte at BX
|
||||
;
|
||||
blksiz equ 16384 ;CP/M allocation size
|
||||
hstsiz equ 512 ;host disk sector size
|
||||
hstspt equ 12 ;host disk sectors/trk
|
||||
hstblk equ hstsiz/128 ;CP/M sects/host buff
|
||||
;
|
||||
;*****************************************************
|
||||
;* *
|
||||
;* secshf is log2(hstblk), and is listed below for *
|
||||
;* values of hstsiz up to 2048. *
|
||||
;* *
|
||||
;* hstsiz hstblk secshf *
|
||||
;* 256 2 1 *
|
||||
;* 512 4 2 *
|
||||
;* 1024 8 3 *
|
||||
;* 2048 16 4 *
|
||||
;* *
|
||||
;*****************************************************
|
||||
secshf equ 2 ;log2(hstblk)
|
||||
cpmspt equ hstblk * hstspt ;CP/M sectors/track
|
||||
secmsk equ hstblk-1 ;sector mask
|
||||
;
|
||||
;*****************************************************
|
||||
;* *
|
||||
;* BDOS constants on entry to write *
|
||||
;* *
|
||||
;*****************************************************
|
||||
wrall equ 0 ; deferred write
|
||||
wrdir equ 1 ; non-deferred write
|
||||
wrual equ 2 ; def wrt 1st sect unalloc blk
|
||||
wrdal equ 3 ; non-def 1st sect unalloc blk
|
||||
;
|
||||
;*****************************************************
|
||||
;* *
|
||||
;* The BIOS entry points given below show the *
|
||||
;* code which is relevant to deblocking only. *
|
||||
;* *
|
||||
;*****************************************************
|
||||
seldsk:
|
||||
;select disk
|
||||
;is this the first activation of the drive?
|
||||
test DL,1 ;lsb = 0?
|
||||
jnz selset
|
||||
;this is the first activation, clear host buff
|
||||
mov hstact,0
|
||||
mov unacnt,0
|
||||
selset:
|
||||
mov al,cl ! cbw ;put in AX
|
||||
mov sekdsk,al ;seek disk number
|
||||
mov cl,4 ! shl al,cl ;times 16
|
||||
add ax,offset dpbase
|
||||
mov bx,ax
|
||||
ret
|
||||
;
|
||||
home:
|
||||
;home the selected disk
|
||||
mov al,hstwrt ;check for pending write
|
||||
test al,al
|
||||
jnz homed
|
||||
mov hstact,0 ;clear host active flag
|
||||
homed:
|
||||
mov cx,0 ;now, set track zero
|
||||
; (continue HOME routine)
|
||||
ret
|
||||
;
|
||||
settrk:
|
||||
;set track given by registers CX
|
||||
mov sektrk,CX ;track to seek
|
||||
ret
|
||||
;
|
||||
setsec:
|
||||
;set sector given by register cl
|
||||
mov seksec,cl ;sector to seek
|
||||
ret
|
||||
;
|
||||
setdma:
|
||||
;set dma address given by CX
|
||||
mov dma_off,CX
|
||||
ret
|
||||
;
|
||||
setdmab:
|
||||
;set segment address given by CX
|
||||
mov dma_seg,CX
|
||||
ret
|
||||
;
|
||||
sectran:
|
||||
;translate sector number CX with table at [DX]
|
||||
test DX,DX ;test for hard skewed
|
||||
jz notran ;(blocked must be hard skewed)
|
||||
mov BX,CX
|
||||
add BX,DX
|
||||
mov BL,[BX]
|
||||
ret
|
||||
no_tran:
|
||||
;hard skewed disk, physical = logical sector
|
||||
mov BX,CX
|
||||
ret
|
||||
;
|
||||
read:
|
||||
;read the selected CP/M sector
|
||||
mov unacnt,0 ;clear unallocated counter
|
||||
mov readop,1 ;read operation
|
||||
mov rsflag,1 ;must read data
|
||||
mov wrtype,wrual ;treat as unalloc
|
||||
jmp rwoper ;to perform the read
|
||||
;
|
||||
write:
|
||||
;write the selected CP/M sector
|
||||
mov readop,0 ;write operation
|
||||
mov wrtype,cl
|
||||
and cl,wrual ;write unallocated?
|
||||
jz chkuna ;check for unalloc
|
||||
;
|
||||
; write to unallocated, set parameters
|
||||
;
|
||||
mov unacnt,(blksiz/128) ;next unalloc recs
|
||||
mov al,sekdsk ;disk to seek
|
||||
mov unadsk,al ;unadsk = sekdsk
|
||||
mov ax,sektrk
|
||||
mov unatrk,ax ;unatrk = sektrk
|
||||
mov al,seksec
|
||||
mov unasec,al ;unasec = seksec
|
||||
;
|
||||
chkuna:
|
||||
;check for write to unallocated sector
|
||||
;
|
||||
mov bx,offset unacnt ;point "UNA" at UNACNT
|
||||
mov al,una ! test al,al ;any unalloc remain?
|
||||
jz alloc ;skip if not
|
||||
;
|
||||
; more unallocated records remain
|
||||
dec al ;unacnt = unacnt-1
|
||||
mov una,al
|
||||
mov al,sekdsk ;same disk?
|
||||
mov BX,offset unadsk
|
||||
cmp al,una ;sekdsk = unadsk?
|
||||
jnz alloc ;skip if not
|
||||
;
|
||||
; disks are the same
|
||||
mov AX, unatrk
|
||||
cmp AX, sektrk
|
||||
jnz alloc ;skip if not
|
||||
;
|
||||
; tracks are the same
|
||||
mov al,seksec ;same sector?
|
||||
;
|
||||
mov BX,offset unasec ;point una at unasec
|
||||
;
|
||||
cmp al,una ;seksec = unasec?
|
||||
jnz alloc ;skip if not
|
||||
;
|
||||
; match, move to next sector for future ref
|
||||
inc una ;unasec = unasec+1
|
||||
mov al,una ;end of track?
|
||||
cmp al,cpmspt ;count CP/M sectors
|
||||
jb noovf ;skip if below
|
||||
;
|
||||
; overflow to next track
|
||||
mov una,0 ;unasec = 0
|
||||
inc unatrk ;unatrk=unatrk+1
|
||||
;
|
||||
noovf:
|
||||
;match found, mark as unnecessary read
|
||||
mov rsflag,0 ;rsflag = 0
|
||||
jmps rwoper ;to perform the write
|
||||
;
|
||||
alloc:
|
||||
;not an unallocated record, requires pre-read
|
||||
mov unacnt,0 ;unacnt = 0
|
||||
mov rsflag,1 ;rsflag = 1
|
||||
;drop through to rwoper
|
||||
;
|
||||
;*****************************************************
|
||||
;* *
|
||||
;* Common code for READ and WRITE follows *
|
||||
;* *
|
||||
;*****************************************************
|
||||
rwoper:
|
||||
;enter here to perform the read/write
|
||||
mov erflag,0 ;no errors (yet)
|
||||
mov al, seksec ;compute host sector
|
||||
mov cl, secshf
|
||||
shr al,cl
|
||||
mov sekhst,al ;host sector to seek
|
||||
;
|
||||
; active host sector?
|
||||
mov al,1
|
||||
xchg al,hstact ;always becomes 1
|
||||
test al,al ;was it already?
|
||||
jz filhst ;fill host if not
|
||||
;
|
||||
; host buffer active, same as seek buffer?
|
||||
mov al,sekdsk
|
||||
cmp al,hstdsk ;sekdsk = hstdsk?
|
||||
jnz nomatch
|
||||
;
|
||||
; same disk, same track?
|
||||
mov ax,hsttrk
|
||||
cmp ax,sektrk ;host track same as seek track
|
||||
jnz nomatch
|
||||
;
|
||||
; same disk, same track, same buffer?
|
||||
mov al,sekhst
|
||||
cmp al,hstsec ;sekhst = hstsec?
|
||||
jz match ;skip if match
|
||||
nomatch:
|
||||
;proper disk, but not correct sector
|
||||
mov al, hstwrt
|
||||
test al,al ;"dirty" buffer ?
|
||||
jz filhst ;no, don't need to write
|
||||
call writehst ;yes, clear host buff
|
||||
; (check errors here)
|
||||
;
|
||||
filhst:
|
||||
;may have to fill the host buffer
|
||||
mov al,sekdsk ! mov hstdsk,al
|
||||
mov ax,sektrk ! mov hsttrk,ax
|
||||
mov al,sekhst ! mov hstsec,al
|
||||
mov al,rsflag
|
||||
test al,al ;need to read?
|
||||
jz filhst1
|
||||
;
|
||||
call readhst ;yes, if 1
|
||||
; (check errors here)
|
||||
;
|
||||
filhst1:
|
||||
mov hstwrt,0 ;no pending write
|
||||
;
|
||||
match:
|
||||
;copy data to or from buffer depending on "readop"
|
||||
mov al,seksec ;mask buffer number
|
||||
and ax,secmsk ;least signif bits are masked
|
||||
mov cl, 7 ! shl ax,cl ;shift left 7 (* 128 = 2**7)
|
||||
;
|
||||
; ax has relative host buffer offset
|
||||
;
|
||||
add ax,offset hstbuf ;ax has buffer address
|
||||
mov si,ax ;put in source index register
|
||||
mov di,dma_off ;user buffer is dest if readop
|
||||
;
|
||||
push DS ! push ES ;save segment registers
|
||||
;
|
||||
mov ES,dma_seg ;set destseg to the users seg
|
||||
;SI/DI and DS/ES is swapped
|
||||
;if write op
|
||||
mov cx,128/2 ;length of move in words
|
||||
mov al,readop
|
||||
test al,al ;which way?
|
||||
jnz rwmove ;skip if read
|
||||
;
|
||||
; write operation, mark and switch direction
|
||||
mov hstwrt,1 ;hstwrt = 1 (dirty buffer now)
|
||||
xchg si,di ;source/dest index swap
|
||||
mov ax,DS
|
||||
mov ES,ax
|
||||
mov DS,dma_seg ;setup DS,ES for write
|
||||
;
|
||||
rwmove:
|
||||
cld ! rep movs AX,AX ;move as 16 bit words
|
||||
pop ES ! pop DS ;restore segment registers
|
||||
;
|
||||
; data has been moved to/from host buffer
|
||||
and wrtype,wrdir ;write type to directory?
|
||||
mov al,erflag ;in case of errors
|
||||
jz return_rw ;no further processing
|
||||
;
|
||||
; clear host buffer for directory write
|
||||
test al,al ;errors?
|
||||
jnz return_rw ;skip if so
|
||||
mov hstwrt,0 ;buffer written
|
||||
call writehst
|
||||
mov al,erflag
|
||||
return_rw:
|
||||
ret
|
||||
;
|
||||
;*****************************************************
|
||||
;* *
|
||||
;* WRITEHST performs the physical write to the host *
|
||||
;* disk, while READHST reads the physical disk. *
|
||||
;* *
|
||||
;*****************************************************
|
||||
writehst:
|
||||
ret
|
||||
;
|
||||
readhst:
|
||||
ret
|
||||
;
|
||||
;*****************************************************
|
||||
;* *
|
||||
;* Use the GENDEF utility to create disk def tables *
|
||||
;* *
|
||||
;*****************************************************
|
||||
dpbase equ offset $
|
||||
; disk parameter tables go here
|
||||
;
|
||||
;*****************************************************
|
||||
;* *
|
||||
;* Uninitialized RAM areas follow, including the *
|
||||
;* areas created by the GENDEF utility listed above. *
|
||||
;* *
|
||||
;*****************************************************
|
||||
sek_dsk rb 1 ;seek disk number
|
||||
sek_trk rw 1 ;seek track number
|
||||
sek_sec rb 1 ;seek sector number
|
||||
;
|
||||
hst_dsk rb 1 ;host disk number
|
||||
hst_trk rw 1 ;host track number
|
||||
hst_sec rb 1 ;host sector number
|
||||
;
|
||||
sek_hst rb 1 ;seek shr secshf
|
||||
hst_act rb 1 ;host active flag
|
||||
hst_wrt rb 1 ;host written flag
|
||||
;
|
||||
una_cnt rb 1 ;unalloc rec cnt
|
||||
una_dsk rb 1 ;last unalloc disk
|
||||
una_trk rw 1 ;last unalloc track
|
||||
una_sec rb 1 ;last unalloc sector
|
||||
;
|
||||
erflag rb 1 ;error reporting
|
||||
rsflag rb 1 ;read sector flag
|
||||
readop rb 1 ;1 if read operation
|
||||
wrtype rb 1 ;write operation type
|
||||
dma_seg rw 1 ;last dma segment
|
||||
dma_off rw 1 ;last dma offset
|
||||
hstbuf rb hstsiz ;host buffer
|
||||
end
|
||||
|
||||
132
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LBDOSDAT.A86
Normal file
132
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LBDOSDAT.A86
Normal file
@@ -0,0 +1,132 @@
|
||||
;******************* BDOS data area ********************
|
||||
;
|
||||
;
|
||||
; 8086 variables that must recide in code segment
|
||||
;
|
||||
cseg $
|
||||
;
|
||||
axsave dw 0 ; register saves
|
||||
SS_save dw 0
|
||||
SP_save dw 0
|
||||
;
|
||||
; Variables in data segment:
|
||||
;
|
||||
dseg cpmsegment
|
||||
org bdosoffset+bdoscodesize
|
||||
;
|
||||
; byte I/O variables:
|
||||
;
|
||||
compcol db 0 ;true if computing column position
|
||||
strtcol db 0 ;starting column position after read
|
||||
column db 0 ;column position
|
||||
listcp db 0 ;listing toggle
|
||||
kbchar db 0 ;initial key char = 00
|
||||
;
|
||||
; common values shared between bdosi and bdos
|
||||
;
|
||||
usrcode db 0 ;current user number
|
||||
curdsk db 0 ;current disk number
|
||||
info dw 0 ;information address
|
||||
aret dw 0 ;address value to return
|
||||
lret EQU byte ptr aret ;low(aret)
|
||||
;
|
||||
; data areas for file system:
|
||||
;
|
||||
; initialized data
|
||||
;
|
||||
efcb db empty ;0e5=available dir entry
|
||||
rodsk dw 0 ;read only disk vector
|
||||
dlog dw 0 ;logged-in disks
|
||||
dmaad dw 0 ;dma address
|
||||
;
|
||||
; curtrka - alloca are set upon disk select
|
||||
; (data must be adjacent, do not insert variables)
|
||||
; (address of translate vector, not used)
|
||||
;
|
||||
cdrmaxa dw 0 ;pointer to cur dir max value
|
||||
curtrka dw 0 ;current track address
|
||||
curreca dw 0 ;current record address
|
||||
buffa dw 0 ;pointer to directory dma address
|
||||
dpbaddr dw 0 ;current disk parameter block address
|
||||
checka dw 0 ;current checksum vector address
|
||||
alloca dw 0 ;current allocation vector address
|
||||
addlist EQU 8 ;"$-buffa" = address list size
|
||||
;
|
||||
; sectpt - offset obtained from disk parm block at dpbaddr
|
||||
; (data must be adjacent, do not insert variables)
|
||||
sectpt dw 0 ;sectors per track
|
||||
blkshf db 0 ;block shift factor
|
||||
blkmsk db 0 ;block mask
|
||||
extmsk db 0 ;extent mask
|
||||
maxall dw 0 ;maximum allocation number
|
||||
dirmax dw 0 ;largest directory number
|
||||
dirblk dw 0 ;reserved allocation bits for direct.
|
||||
chksiz dw 0 ;size of checksum vector
|
||||
offsetv dw 0 ;offset tracks at beginning
|
||||
endlist rs 0 ;end of list
|
||||
dpblist equ (offset endlist)-(offset sectpt) ;size
|
||||
;
|
||||
; local variables
|
||||
tranv dw 0 ;address of translate vector
|
||||
fcbcopied db 0 ;set true if copy$fcb called
|
||||
rmf db 0 ;read mode flag for open$reel
|
||||
dirloc db 0 ;directory flag in rename, etc.
|
||||
seqio db 0 ;1 if sequential i/o
|
||||
linfo db 0 ;low(info)
|
||||
dminx db 0 ;local for diskwrite
|
||||
srchl db 0 ;search length
|
||||
srcha dw 0 ;search address
|
||||
tinfo dw 0 ;temp for info in "make"
|
||||
single db 0 ;set true if single byte
|
||||
;allocation map
|
||||
resel db 0 ;reselection flag
|
||||
olddsk db 0 ;disk on entry to bdos
|
||||
fcbdsk db 0 ;disk named in fcb
|
||||
rcount db 0 ;record count in current fcb
|
||||
extval db 0 ;extent number and extmsk
|
||||
vrecord dw 0 ;current virtual record
|
||||
lvrecord equ byte ptr vrecord ;low (vrecord)
|
||||
arecord dw 0 ;current actual record
|
||||
ablock dw 0 ;current actual block# * blkmsk
|
||||
;
|
||||
; local variables for directory access
|
||||
dptr db 0 ;directory pointer 0,1,2,3
|
||||
dcnt dw 0 ;directory counter 0,1,...,dirmax
|
||||
ldcnt equ byte ptr dcnt ;low(dcnt)
|
||||
drec dw 0 ;directory record 0,1,...,dirmax/4
|
||||
;
|
||||
; Special 8086 variables:
|
||||
;
|
||||
ioloc db 0 ;iobyte
|
||||
dmabase dw 0 ;segment base for disk I/O
|
||||
infosave dw 0 ;save for FCB address
|
||||
parametersegment dw 0 ;user parameter segment
|
||||
parcopfl db 0 ;true if parameter block copied
|
||||
parlg db 0 ;length of parameter block
|
||||
nallocmem db 0 ;no. of allocated memory segments
|
||||
ncrmem db 0 ;no. of available memory segments
|
||||
crmem dw 0,0 ;memory table (16 elements)
|
||||
dw 0,0,0,0,0,0
|
||||
dw 0,0,0,0,0,0,0,0
|
||||
dw 0,0,0,0,0,0,0,0
|
||||
dw 0,0,0,0,0,0,0,0
|
||||
;
|
||||
;
|
||||
; error messages
|
||||
;
|
||||
dskmsg db 'Bdos Err On '
|
||||
dskerr db ' : $' ;filled in by errflg
|
||||
permsg db 'Bad Sector$'
|
||||
selmsg db 'Select$'
|
||||
rofmsg db 'File '
|
||||
rodmsg db 'R/O$'
|
||||
;
|
||||
; Local buffer area:
|
||||
;
|
||||
loc_par_area rb 258 ;local user parameter (FCB,...)
|
||||
stackarea rw ssize ;stack size
|
||||
endstack rb 0 ;top of stack
|
||||
;
|
||||
;******************** end BDOS data area *******************
|
||||
end
|
||||
|
||||
212
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LBDOSENT.A86
Normal file
212
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LBDOSENT.A86
Normal file
@@ -0,0 +1,212 @@
|
||||
;******************** BDOS entry module ********************
|
||||
;
|
||||
; Perform branching, error handling and special
|
||||
; 8086 stuff.
|
||||
;
|
||||
;
|
||||
cseg cpmsegment
|
||||
org bdosoffset
|
||||
;
|
||||
db 0,0,0,0,0,0
|
||||
;
|
||||
; enter here from the user's program with function number in cl,
|
||||
; and information address in dx
|
||||
;
|
||||
JMP bdose ;past parameter block
|
||||
;
|
||||
; ************************************************
|
||||
; *** relative locations 0009 - 000e ***
|
||||
; ************************************************
|
||||
pererr dw persub ;permanent error subroutine
|
||||
seler dw selsub ;select error subroutine
|
||||
roderr dw rodsub ;ro disk error subroutine
|
||||
rofer dw rofsub ;ro file error subroutine
|
||||
;
|
||||
;
|
||||
bdose: ;arrive here from user progs
|
||||
mov axsave,ax ;switch stack segment
|
||||
mov SS_save,ss
|
||||
mov SP_save,sp
|
||||
mov ax,cs
|
||||
; add ax,(bdosoffset+bdoscodesize)/16
|
||||
mov ss,ax
|
||||
lea sp,endstack
|
||||
;
|
||||
;pick up parameter segment
|
||||
mov ax,ds
|
||||
;
|
||||
push ds ;save registers
|
||||
push es
|
||||
push bp
|
||||
push di
|
||||
push si
|
||||
;
|
||||
push ss ;switch to local segment registers
|
||||
push ss
|
||||
pop es
|
||||
pop ds
|
||||
;
|
||||
mov parametersegment,ax
|
||||
mov ax,axsave
|
||||
;
|
||||
call oldbdos ;call 8080 BDOS
|
||||
;
|
||||
pop si ;unsave 8086 registers
|
||||
pop di
|
||||
pop bp
|
||||
pop es
|
||||
pop ds
|
||||
;
|
||||
;switch back to entry stack
|
||||
mov sp,SP_save
|
||||
mov ss,SS_save
|
||||
iret ; return from interrupt
|
||||
;
|
||||
;
|
||||
oldbdos: ;8080 bdos entry point
|
||||
MOV info,dx ;info=dx
|
||||
MOV linfo,dl ;linfo = low(info) - don't equ
|
||||
MOV aret,0 ;return value defaults to 0000
|
||||
mov parcopfl,false ;set true if parameter
|
||||
;block copied from user
|
||||
; MOV entsp,sp ;entsp = stackptr
|
||||
; LEA sp,lstack ;local stack setup
|
||||
XOR AL,AL
|
||||
MOV fcbdsk,AL
|
||||
MOV resel,AL ;fcbdsk,resel=false
|
||||
MOV BX,offset goback ;common return point
|
||||
PUSH BX ;jmp goback equivalent to ret
|
||||
CMP cl,nfuncs80
|
||||
jb branch
|
||||
sub cl,sfunc86-nfuncs80
|
||||
cmp cl,nfuncs
|
||||
jb branch
|
||||
RET
|
||||
; ;skip if invalid #
|
||||
branch: MOV bl,cl
|
||||
mov bh,0
|
||||
MOV CL,DL ;possible output char. to CL
|
||||
add bx,bx ;branch
|
||||
jmp cs:functab[bx]
|
||||
;
|
||||
; dispatch table for functions
|
||||
;
|
||||
functab dw wbootf,func1,func2,func3
|
||||
dw punchf,listf,func6,func7
|
||||
dw func8,func9,func10,func11
|
||||
diskf equ 12 ;beginning of disk functions
|
||||
dw func12,func13,func14,func15
|
||||
dw func16,func17,func18,func19
|
||||
dw func20,func21,func22,func23
|
||||
dw func24,func25,func26,func27
|
||||
dw func28,func29,func30,func31
|
||||
dw func32,func33,func34,func35
|
||||
dw func36,func37,func38,func39
|
||||
dw func40
|
||||
dw func50,func51,func52,func53 ;8086 functions
|
||||
dw func54,func55,func56,func57
|
||||
|
||||
nfuncs80 equ 41 ;number of 8080 functions
|
||||
sfunc86 equ 50 ;start number for 8086 functions
|
||||
nfuncs equ 49 ;total number of BDOS functions
|
||||
;
|
||||
;
|
||||
; error subroutines
|
||||
persub: ;report permanent error
|
||||
LEA BX,permsg
|
||||
CALL errflg ;to report the error
|
||||
CMP AL,ctlc
|
||||
jnz parret ;rnz
|
||||
JMP wbootf
|
||||
;reboot if response is ctlc
|
||||
;and ignore the error
|
||||
;
|
||||
selsub: ;report select error
|
||||
LEA BX,selmsg
|
||||
JMPS waiterr ;wait console before boot
|
||||
;
|
||||
rodsub: ;report write to R/O disk
|
||||
LEA BX,rodmsg
|
||||
JMPS waiterr
|
||||
;
|
||||
rofsub: ;report read/only file
|
||||
LEA BX,rofmsg ;wait for console
|
||||
;
|
||||
waiterr:
|
||||
;wait for response before boot
|
||||
CALL errflg
|
||||
JMP wbootf
|
||||
;
|
||||
errflg:
|
||||
;report error to console,
|
||||
;message address in BX
|
||||
PUSH BX
|
||||
CALL crlf ;stack mssg address, new line
|
||||
MOV AL,curdsk
|
||||
ADD AL,'A'
|
||||
MOV dskerr,AL ;current disk name
|
||||
LEA CX,dskmsg
|
||||
CALL print ;the error message
|
||||
POP CX
|
||||
CALL print ;error mssage tail
|
||||
jmp coninf ;jump to input character
|
||||
;note: conin is now coninf for cpm loader, goes to bios
|
||||
;
|
||||
parsave:
|
||||
;copy parameterblock from user segment to BDOS segment
|
||||
;CL-reg = lenght of parameter block
|
||||
;
|
||||
push ds
|
||||
push ax
|
||||
push cx
|
||||
mov parcopfl,true
|
||||
mov parlg,cl
|
||||
xor ch,ch
|
||||
mov si,info
|
||||
mov infosave,si
|
||||
lea di,loc_par_area
|
||||
mov info,di
|
||||
mov ds,parametersegment
|
||||
rep movs al,al
|
||||
pop cx
|
||||
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
|
||||
;
|
||||
push es
|
||||
push ax
|
||||
push cx
|
||||
mov cl,parlg
|
||||
xor ch,ch
|
||||
mov es,parametersegment
|
||||
lea si,loc_par_area
|
||||
mov di,infosave
|
||||
mov info,di
|
||||
rep movs al,al
|
||||
pop cx
|
||||
pop ax
|
||||
pop es
|
||||
ret
|
||||
;
|
||||
;
|
||||
;***************** end BDOS entry module ****************
|
||||
end
|
||||
|
||||
114
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LBDOSEQU.A86
Normal file
114
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LBDOSEQU.A86
Normal file
@@ -0,0 +1,114 @@
|
||||
;**************************************************************
|
||||
; *
|
||||
; BDOS symbols: *
|
||||
; *
|
||||
;**************************************************************
|
||||
;
|
||||
;
|
||||
dvers EQU 22h ;version 2.2
|
||||
;
|
||||
on EQU 0ffffh
|
||||
off EQU 00000h
|
||||
testf EQU off
|
||||
;
|
||||
; Special 8086 symbols:
|
||||
;
|
||||
b equ byte ptr 0
|
||||
w equ word ptr 0
|
||||
;
|
||||
; bios value defined at end of module
|
||||
;
|
||||
ssize EQU 96 ;96 level stack
|
||||
;
|
||||
;
|
||||
cseg cpmsegment
|
||||
;
|
||||
; BIOS routines
|
||||
;
|
||||
org biosoffset
|
||||
bios:
|
||||
bootf EQU BIOS+3*0 ;cold boot function
|
||||
wbootf EQU BIOS+3*1 ;warm boot function
|
||||
constf EQU BIOS+3*2 ;console status function
|
||||
coninf EQU BIOS+3*3 ;console input function
|
||||
conouf EQU BIOS+3*4 ;console output function
|
||||
listf EQU BIOS+3*5 ;list output function
|
||||
punchf EQU BIOS+3*6 ;punch output function
|
||||
readerf EQU BIOS+3*7 ;reader input function
|
||||
homef EQU BIOS+3*8 ;disk home function
|
||||
seldskf EQU BIOS+3*9 ;select disk function
|
||||
settrkf EQU BIOS+3*10 ;set track function
|
||||
setsecf EQU BIOS+3*11 ;set sector function
|
||||
setdmf EQU BIOS+3*12 ;set dma function
|
||||
readf EQU BIOS+3*13 ;read disk function
|
||||
writef EQU BIOS+3*14 ;write disk function
|
||||
liststf EQU BIOS+3*15 ;list status function
|
||||
sectran EQU BIOS+3*16 ;sector translate
|
||||
setdmbf EQU BIOS+3*17 ;set base for disk I/O
|
||||
getsegtabf EQU BIOS+3*18 ;get segment table address
|
||||
nbiosfuncs equ 19 ;number of BIOS functions
|
||||
;
|
||||
; equates for non graphic characters
|
||||
ctlc EQU 03h ;control c
|
||||
ctle EQU 05h ;physical eol
|
||||
ctlh EQU 08h ;backspace
|
||||
ctlp EQU 10h ;prnt 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
|
||||
;
|
||||
;
|
||||
; module addresses
|
||||
;
|
||||
; literal constants
|
||||
true EQU 0ffh ;constant true
|
||||
false EQU 000h ;constant false
|
||||
enddir EQU 0ffffh ;end of directory
|
||||
;
|
||||
;
|
||||
; file control block (fcb) constants
|
||||
empty EQU 0e5h ;empty directory entry
|
||||
lstrec EQU 127 ;last record# in extent
|
||||
recsiz EQU 128 ;record size
|
||||
fcblen EQU 32 ;file control block size
|
||||
dirrec EQU recsiz/fcblen ;directory elts / record
|
||||
dskshf EQU 2 ;log2(dirrec)
|
||||
dskmsk EQU dirrec-1
|
||||
fcbshf EQU 5 ;log2(fcblen)
|
||||
;
|
||||
extnum EQU 12 ;extent number field
|
||||
maxext EQU 31 ;largest extent number
|
||||
ubytes EQU 13 ;unfilled bytes field
|
||||
modnum EQU 14 ;data module number
|
||||
maxmod EQU 15 ;largest module number
|
||||
fwfmsk EQU 80h ;file write flag is high
|
||||
;order modnum
|
||||
namlen EQU 15 ;name length
|
||||
reccnt EQU 15 ;record count field
|
||||
dskmap EQU 16 ;disk map field
|
||||
lstfcb EQU fcblen-1
|
||||
nxtrec EQU fcblen
|
||||
ranrec EQU nxtrec+1 ;random record field (2 bytes)
|
||||
;
|
||||
; reserved file indicators
|
||||
rofile EQU 9 ;high order of first type char
|
||||
invis EQU 10 ;invisible file in dir command
|
||||
; equ 11 ;reserved
|
||||
;
|
||||
; Memory management symbols:
|
||||
;
|
||||
membase equ word ptr 0
|
||||
memlg equ word ptr 2
|
||||
memdescrlg equ 4
|
||||
;
|
||||
;
|
||||
;********************* end of BDOS symbols ***********************
|
||||
end
|
||||
|
||||
602
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LBDOSF1.A86
Normal file
602
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LBDOSF1.A86
Normal file
@@ -0,0 +1,602 @@
|
||||
;
|
||||
;*****************************************************************
|
||||
;*****************************************************************
|
||||
;** **
|
||||
;** B a s i c D i s k O p e r a t i n g S y s t e m **
|
||||
;** **
|
||||
;*****************************************************************
|
||||
;*****************************************************************
|
||||
;
|
||||
selerror:
|
||||
;report select error
|
||||
LEA BX,seler ;
|
||||
;
|
||||
;
|
||||
goerr:
|
||||
;BX = .errorhandler,call subr.
|
||||
JMP w[bx] ;to subroutine
|
||||
;
|
||||
;
|
||||
;
|
||||
; local subroutines for bios interface
|
||||
;
|
||||
move:
|
||||
;move data length of length CL from source DX to
|
||||
;destination given by BX
|
||||
push cx
|
||||
mov ch,0
|
||||
mov si,dx
|
||||
mov di,bx
|
||||
rep movs al,al
|
||||
pop cx
|
||||
ret
|
||||
;
|
||||
;
|
||||
selectdisk:
|
||||
;select the disk drive given by curdsk, and fill
|
||||
;the base addresses curtrka - alloca, then fill
|
||||
;the values of the disk parameter block
|
||||
;
|
||||
MOV cl,curdsk ;current disk# to CL
|
||||
;lsb of DL = 0 if not yet
|
||||
;logged in
|
||||
CALL seldskf ;BX filled by call
|
||||
;BX = 0000 if error,
|
||||
;otherwise disk headers
|
||||
cmp bx,0
|
||||
jz ret4 ;rz
|
||||
MOV DX,[bx]
|
||||
add bx,2
|
||||
MOV cdrmaxa,BX
|
||||
add bx,2
|
||||
MOV curtrka,BX
|
||||
add bx,2
|
||||
MOV curreca,BX
|
||||
add bx,2
|
||||
;DX still contains .tran
|
||||
xchg bx,dx
|
||||
MOV tranv,bx ;.tran vector
|
||||
LEA BX,buffa ;DX= source for move, BX=dest
|
||||
MOV CL,addlist
|
||||
CALL move ;addlist filled
|
||||
;now fill the disk
|
||||
;parameter block
|
||||
MOV dx,dpbaddr
|
||||
LEA BX,sectpt ;BX is destination
|
||||
MOV CL,dpblist
|
||||
CALL move ;data filled
|
||||
;set single/double map mode
|
||||
MOV al,byte ptr maxall+1 ;largest allocation number
|
||||
LEA BX,single
|
||||
MOV b[bx],true ;assume a=00
|
||||
OR AL,AL
|
||||
JZ retselect
|
||||
;high order of maxall not
|
||||
;zero, use double dm
|
||||
MOV b[bx],false
|
||||
retselect:
|
||||
MOV AL,true
|
||||
OR AL,AL
|
||||
ret4: RET ;select disk function ok
|
||||
;
|
||||
home:
|
||||
;move to home position, then offset to start of dir
|
||||
CALL homef
|
||||
;first directory pos. selected
|
||||
XOR AX,AX ;constant zero to accumulator
|
||||
MOV BX,curtrka
|
||||
MOV [bx],ax ;curtrk=0000
|
||||
;curtrk, currec both set to 0
|
||||
RET
|
||||
;
|
||||
rdbuff:
|
||||
;read buffer and check if ok
|
||||
CALL readf ;current drive, track,....
|
||||
jmps diocomp ;check for i/o errors
|
||||
;
|
||||
wrbuff:
|
||||
;write buffer and check condition
|
||||
;write type (wrtype) is in register CL
|
||||
;wrtype = 0 => normal write operation
|
||||
;wrtype = 1 => directory write operation
|
||||
;wrtype = 2 => start of new block
|
||||
CALL writef ;current drive, track, ...
|
||||
diocomp: ;check for disk errors
|
||||
OR AL,AL
|
||||
jz ret4 ;rz
|
||||
LEA BX,pererr
|
||||
JMP goerr
|
||||
;
|
||||
seekdir:
|
||||
;seek the record containing the current dir entry
|
||||
MOV BX,dcnt ;directory counter to BX
|
||||
MOV CL,dskshf
|
||||
shr bx,cl ;value to BX
|
||||
MOV arecord,BX
|
||||
MOV drec,BX ;ready for seek
|
||||
; jmp seek
|
||||
;ret
|
||||
;
|
||||
seek:
|
||||
;seek the track given by arecord (actual record)
|
||||
;
|
||||
;
|
||||
mov ax,arecord ;compute track/sector
|
||||
mov dx,0
|
||||
div sectpt ;dx=sector, ax=track
|
||||
push dx
|
||||
mov cx,ax ;update curtrk
|
||||
mov si,curtrka
|
||||
mov [si],cx
|
||||
add cx,offsetv ;set BIOS track
|
||||
call settrkf
|
||||
pop cx ;set BIOS sector
|
||||
mov dx,tranv
|
||||
call sectran
|
||||
mov cx,bx
|
||||
jmp setsecf
|
||||
;ret
|
||||
;
|
||||
;
|
||||
; utility functions for file access
|
||||
;
|
||||
dmposition:
|
||||
;compute disk map position for vrecord to BX
|
||||
lea bx,blkshf
|
||||
MOV CL,[bx] ;shift count to CL
|
||||
MOV AL,lvrecord ;current virtual record to A
|
||||
shr al,cl
|
||||
;A = shr(vrecord,blkshf) = vrecord/2**(sect/block)
|
||||
MOV CH,AL ;save it for later addition
|
||||
MOV cl,7
|
||||
SUB cl,[bx]
|
||||
MOV AL,extval ;extent value ani extmsk
|
||||
;
|
||||
;blkshf = 3,4,5,6,7
|
||||
;CL=4,3,2,1,0
|
||||
;shift is 4,3,2,1,0
|
||||
shl al,cl
|
||||
;arrive here with A = shl(ext and extmsk,7-blkshf)
|
||||
ADD AL,CH ;add the previous
|
||||
;shr(vrecord,blkshf) value
|
||||
;AL is one of the following
|
||||
;values, depending upon alloc
|
||||
;bks blkshf
|
||||
;1k 3 v/8 + extval * 16
|
||||
;2k 4 v/16+ extval * 8
|
||||
;4k 5 v/32+ extval * 4
|
||||
;8k 6 v/64+ extval * 2
|
||||
;16k 7 v/128+extval * 1
|
||||
RET ;with dm$position in A
|
||||
;
|
||||
getdm:
|
||||
;return disk map value from position given by CX
|
||||
MOV BX,info ;base address of file
|
||||
;file control block
|
||||
ADD BX,dskmap ;bx=.diskmap
|
||||
ADD BX,CX ;index by asingle byte value
|
||||
cmp single,0 ;single byte/map entry?
|
||||
JZ getdmd ;get disk map single byte
|
||||
MOV BL,[bx]
|
||||
MOV BH,0
|
||||
RET ;with BX=00bb
|
||||
getdmd:
|
||||
ADD BX,CX ;bx=.fcb(dm+1*2)
|
||||
;return double precision value
|
||||
MOV bx,[bx]
|
||||
RET
|
||||
;
|
||||
index:
|
||||
;compute disk block number from current FCB
|
||||
CALL dmposition ;0...15 in register AL
|
||||
MOV CL,AL
|
||||
MOV CH,0
|
||||
CALL getdm ;value to BX
|
||||
MOV arecord,BX
|
||||
RET
|
||||
;
|
||||
alloct:
|
||||
;called following index to see if block allocated
|
||||
MOV BX,arecord
|
||||
or bx,bx
|
||||
RET
|
||||
;
|
||||
atran:
|
||||
;compute actual record address, assuming index called
|
||||
MOV cl,blkshf ;shift count to reg AL
|
||||
MOV BX,arecord
|
||||
shl bx,cl
|
||||
MOV ablock,BX ;save shifted block #
|
||||
MOV AL,lvrecord
|
||||
AND AL,blkmsk ;masked value in AL
|
||||
OR bl,al
|
||||
MOV arecord,BX ;arecord=BX or
|
||||
;(vrecord and blkmsk)
|
||||
RET
|
||||
;
|
||||
getexta:
|
||||
;get current extent field address to AL
|
||||
MOV BX,info
|
||||
add bx,extnum ;bx=.fcb(extnum)
|
||||
mov al,[bx]
|
||||
RET
|
||||
;
|
||||
gtfcba:
|
||||
;compute reccnt and nxtrec addresses for get/setfcb
|
||||
MOV DX,reccnt
|
||||
add dx,info ;DX=.fcb(reccnt)
|
||||
MOV BX,(nxtrec-reccnt)
|
||||
ADD BX,DX ;bx=.fcb(nxtrec)
|
||||
RET
|
||||
;
|
||||
getfcb:
|
||||
;set variables from currently addressed FCB
|
||||
CALL gtfcba ;addresses in DX, BX
|
||||
MOV AL,[bx]
|
||||
MOV lvrecord,al ;vrecord=fcb(nxtrec)
|
||||
XCHG BX,DX
|
||||
MOV AL,[bx]
|
||||
MOV rcount,AL ;rcount=fcb(reccnt)
|
||||
CALL getexta ;BX=.fcb(extnum)
|
||||
MOV AL,extmsk ;extent mask to a
|
||||
AND AL,[bx] ;fcb(extnum) and extmsk
|
||||
MOV extval,AL
|
||||
RET
|
||||
;
|
||||
setfcb:
|
||||
;place values back into current fcb
|
||||
CALL gtfcba ;addresses to DX, BX
|
||||
MOV AL,seqio
|
||||
CMP AL,02
|
||||
JNZ setfc1
|
||||
XOR AL,AL ;check ranfill
|
||||
setfc1:
|
||||
;=1 if sequential i/o
|
||||
add AL,lvrecord
|
||||
MOV [bx],al ;fcb(nxtrec)=vrecord+seqio
|
||||
XCHG BX,DX
|
||||
MOV AL,rcount
|
||||
MOV [bx],al ;fcb(reccnt)=rcount
|
||||
RET
|
||||
;
|
||||
;
|
||||
cmpecs:
|
||||
;compute checksum for current directory buffer
|
||||
MOV cx,recsiz ;size of directory buffer
|
||||
MOV BX,buffa ;current directory buffer
|
||||
XOR AL,AL ;clear checksum value
|
||||
cmpec0:
|
||||
ADD AL,[bx]
|
||||
INC BX
|
||||
loop cmpec0
|
||||
RET ;with checksum in A
|
||||
;
|
||||
setcdisk:
|
||||
;set a "1" value in curdsk position of CX
|
||||
PUSH CX ;save input parameter
|
||||
MOV cl,curdsk
|
||||
MOV BX,1 ;number to shift
|
||||
shl bx,cl ;BX = mask to integrate
|
||||
POP CX ;original mask
|
||||
or bx,cx ;BX = mask or rol(1,curdsk)
|
||||
RET
|
||||
;
|
||||
nowrite:
|
||||
;return true if dir checksum difference occurred
|
||||
MOV ax,rodsk
|
||||
MOV cl,curdsk
|
||||
shr ax,cl
|
||||
AND AL,1
|
||||
RET ;non zero if nowrite
|
||||
;
|
||||
setro:
|
||||
;set current disk to read only
|
||||
mov cx,rodsk
|
||||
CALL setcdisk ;sets bit to 1
|
||||
MOV rodsk,BX
|
||||
;high water mark in directory
|
||||
;goes to max
|
||||
MOV dx,dirmax
|
||||
INC dx
|
||||
MOV BX,cdrmaxa ;BX = .cdrmax
|
||||
MOV [bx],dx ;cdrmax = dirmax
|
||||
RET
|
||||
;
|
||||
ckrodir:
|
||||
;check current directory element for read/only status
|
||||
CALL getdptra ;address of element
|
||||
;
|
||||
ckrofile:
|
||||
;check current buff(dptr) or fcb(0) for r/o status
|
||||
MOV DX,rofile
|
||||
ADD BX,DX ;offset to r/o bit
|
||||
MOV AL,[bx]
|
||||
RCL AL,1
|
||||
jae ret5 ;rnc
|
||||
LEA BX,rofer
|
||||
JMP goerr ;
|
||||
; jmp roferror ;exit to read only disk message
|
||||
;
|
||||
;
|
||||
checkwrite:
|
||||
;check for write protected disk
|
||||
CALL nowrite
|
||||
jz ret5 ;rz
|
||||
LEA BX,roderr
|
||||
JMP goerr
|
||||
; jmp roderror ;read only disk error
|
||||
;
|
||||
getdptra:
|
||||
;compute the address of a directory element at
|
||||
;positon dptr in the buffer
|
||||
MOV BX,buffa
|
||||
MOV AL,dptr
|
||||
addh:
|
||||
;BX = BX + AL
|
||||
mov ah,0
|
||||
add bx,ax
|
||||
ret5: ret
|
||||
;
|
||||
;
|
||||
getmodnum:
|
||||
;compute the address of the module number
|
||||
;bring module number to accumulator
|
||||
;(high order bit is fwf (file write flag)
|
||||
MOV BX,info
|
||||
add bx,modnum
|
||||
MOV AL,[bx]
|
||||
RET ;AL=fcb(modnum)
|
||||
;
|
||||
clrmodnum:
|
||||
;clear the module number field for user open/make
|
||||
CALL getmodnum
|
||||
MOV b[bx],0 ;fcb(modnum)=0
|
||||
RET
|
||||
;
|
||||
setfwf:
|
||||
CALL getmodnum ;BX=.fcb(modnum),
|
||||
;AL=fcb(modnum)
|
||||
;set fwf(file write flag) to 1
|
||||
OR AL,fwfmsk
|
||||
MOV [bx],al ;fcb(modnum)=fcb(modnum) + 80h
|
||||
;also returns non zero
|
||||
;in accumulator
|
||||
RET
|
||||
;
|
||||
;
|
||||
compcdr:
|
||||
;return cy if cdrmax > dcnt
|
||||
MOV dx,dcnt ;DX = directory counter
|
||||
MOV BX,cdrmaxa ;BX=.cdrmax
|
||||
cmp dx,[bx]
|
||||
;condition dcnt - cdrmax
|
||||
;produces cy if cdrmax>dcnt
|
||||
ret6: RET
|
||||
;
|
||||
setcdr:
|
||||
;if not (cdrmax > dcnt) then cdrmax = dcnt+1
|
||||
CALL compcdr
|
||||
jb ret6 ;return if cdrmax > dcnt
|
||||
;otherwise, BX = .cdrmax+1,
|
||||
;DX = dcnt
|
||||
INC DX
|
||||
MOV [bx],dx
|
||||
RET
|
||||
;
|
||||
subdh:
|
||||
;compute BX = DX - BX
|
||||
push dx
|
||||
sub dx,bx
|
||||
mov bx,dx
|
||||
pop dx
|
||||
RET
|
||||
;
|
||||
newchecksum:
|
||||
;drop through to compute new checksum
|
||||
MOV CL,true
|
||||
checksum:
|
||||
;compute current checksum record and update the
|
||||
;directory element if CL=true, or check for = if not
|
||||
;drec < chksiz?
|
||||
MOV DX,drec
|
||||
MOV BX,chksiz
|
||||
CALL subdh ;DX-BX
|
||||
jae ret6 ;skip checksum if past
|
||||
;checksum vector size
|
||||
;drec < chksiz, so continue
|
||||
PUSH CX ;save init flag
|
||||
CALL cmpecs ;check sum value to AL
|
||||
MOV BX,drec ;value of drec
|
||||
ADD BX,checka ;bx=.check(drec)
|
||||
POP CX ;recall true or false to CL
|
||||
INC CL ;true produces zero flag
|
||||
JZ initcs
|
||||
;not initializing, compare
|
||||
CMP AL,[bx] ;compute$cs=check(drec)?
|
||||
jz ret7 ;no message if ok
|
||||
;checksum error, are we beyond
|
||||
;the end of the disk?
|
||||
CALL compcdr
|
||||
jae ret7 ;no message if so
|
||||
CALL setro ;read/only disk set
|
||||
RET
|
||||
initcs:
|
||||
;initializing the checksum
|
||||
MOV [bx],al
|
||||
ret7: RET
|
||||
;
|
||||
;
|
||||
wrdir:
|
||||
;write the current directory entry, set checksum
|
||||
CALL newchecksum ;initialize entry
|
||||
CALL setdir ;directory dma
|
||||
MOV CL,1 ;indicates a write directory
|
||||
CALL wrbuff ;write the buffer
|
||||
JMP setdata ;to data dma address
|
||||
;ret
|
||||
;
|
||||
rddirbuf:
|
||||
;read a directory entry into the directory buffer
|
||||
CALL setdir ;directory dma
|
||||
CALL rdbuff ;directory record loaded
|
||||
; jmp setdata
|
||||
; ret
|
||||
;
|
||||
setdata:
|
||||
;set data dma address
|
||||
mov cx,dmabase
|
||||
call setdmbf ;set BIOS disk I/O base
|
||||
LEA BX,dmaad
|
||||
jmps setdma ;to complete the call
|
||||
;
|
||||
setdir:
|
||||
;set directory dma address
|
||||
mov cx,ds
|
||||
call setdmbf ;set BIOS disk I/O base
|
||||
LEA BX,buffa ;jmp setdma to complete call
|
||||
;
|
||||
setdma:
|
||||
;BX=.dma address to set (i.e., buffa or dmaad)
|
||||
MOV CX,[bx] ;parameter ready
|
||||
JMP setdmf
|
||||
;
|
||||
;
|
||||
dirtouser:
|
||||
;copy the directory entry to the user buffer
|
||||
;after call to search or searchn by user code
|
||||
MOV DX,buffa ;source is directory buffer
|
||||
MOV BX,dmaad ;destination is user dma addr.
|
||||
MOV CL,recsiz ;copy entire record
|
||||
push es ;move to user segment
|
||||
mov es,parametersegment
|
||||
call move
|
||||
pop es
|
||||
ret
|
||||
;ret
|
||||
;
|
||||
endofdir:
|
||||
;return zero flag if at end of director, non zero
|
||||
;if not at end (end of dir if dcnt = 0ffffh)
|
||||
LEA BX,dcnt
|
||||
MOV AL,[bx] ;may be 0ffh
|
||||
INC BX
|
||||
CMP AL,[bx] ;low(dcnt) = high(dcnt)?
|
||||
jnz ret8 ;return non zero if different
|
||||
;high and low the same,= 0ffh?
|
||||
INC AL ;0ffh becomes 00 if so
|
||||
ret8: RET
|
||||
;
|
||||
setenddir:
|
||||
;set dcnt to the end of the directory
|
||||
MOV BX,enddir
|
||||
MOV dcnt,bx
|
||||
RET
|
||||
;
|
||||
rddir:
|
||||
;read next directory entry, with CL=true if initializing
|
||||
MOV DX,dirmax ;in preparation for subtract
|
||||
MOV BX,dcnt
|
||||
INC BX
|
||||
MOV dcnt,bx ;dcnt=dcnt+1
|
||||
;continue while dirmax >= dcnt
|
||||
;(dirmax-dcnt no cy)
|
||||
CALL subdh ;DX-BX
|
||||
JAE rddir0
|
||||
;yes, set dcnt to end
|
||||
;of directory
|
||||
jmps setenddir
|
||||
; ret
|
||||
rddir0:
|
||||
;not at end of directory, seek next element
|
||||
;CL=initialization flag
|
||||
MOV AL,ldcnt
|
||||
AND AL,dskmsk ;low(dcnt) and dskmsk
|
||||
push cx
|
||||
MOV cl,fcbshf ;to multiply by fcb size
|
||||
shl al,cl
|
||||
pop cx
|
||||
;A = (low(dcnt) and dskmsk)
|
||||
;shl fcbshf
|
||||
MOV dptr,AL ;ready for next dir operation
|
||||
OR AL,AL
|
||||
jnz ret71 ;return if not a new record
|
||||
PUSH CX ;save initialization flag CL
|
||||
CALL seekdir ;seek proper record
|
||||
CALL rddirbuf ;read the directory record
|
||||
POP CX ;recall initialization flag
|
||||
JMP checksum ;checksum the directory elt
|
||||
;ret
|
||||
;
|
||||
;
|
||||
getallocbit:
|
||||
;given allocation vector
|
||||
;position on CX, return byte
|
||||
;containing CX shifted so that the least significant
|
||||
;bit is in the low order accumulator position. BX is
|
||||
;the address of the byte for
|
||||
;possible replacement in
|
||||
;memory upon return, and DH contains the number of shifts
|
||||
;required to place the returned value back into position
|
||||
;
|
||||
MOV dl,CL
|
||||
AND dl,111b
|
||||
INC dl
|
||||
MOV DH,dl
|
||||
;dh and dl both contain the
|
||||
;number of bit positions to
|
||||
;shift
|
||||
MOV AL,CL
|
||||
mov cl,3
|
||||
ror al,cl
|
||||
AND AL,11111b
|
||||
MOV CL,AL ;CL shr 3 to CL
|
||||
push cx
|
||||
mov cl,5
|
||||
shl al,cl
|
||||
pop cx
|
||||
or CL,AL ;bbbccccc to CL
|
||||
MOV AL,CH
|
||||
ROR AL,1
|
||||
ROR AL,1
|
||||
ROR AL,1
|
||||
AND AL,11111b
|
||||
MOV CH,AL ;CX shr 3 to CX
|
||||
MOV BX,alloca ;base addr. of alloc. vector
|
||||
ADD BX,CX
|
||||
;byte to A, hl =
|
||||
MOV AL,[bx] ;.alloc(CX shr 3)
|
||||
;now move the bit to the
|
||||
;low order position of AL
|
||||
push cx
|
||||
mov cl,dl
|
||||
rol al,cl
|
||||
pop cx
|
||||
ret71: RET
|
||||
;
|
||||
;
|
||||
setallocbit:
|
||||
;CX is the bit position of ALLOC to set or reset. The
|
||||
;value of the bit is in register DL.
|
||||
PUSH DX
|
||||
CALL getallocbit ;shifted val AL,count in DL
|
||||
AND AL,11111110b ;mask low bit to zero
|
||||
;(may be set)
|
||||
POP CX
|
||||
OR AL,CL ;low bit of CL masked into AL
|
||||
; jmp rotr
|
||||
; ret
|
||||
rotr:
|
||||
;byte value from ALLOC is in register AL, with shift count
|
||||
;in register CH (to place bit back into position), and
|
||||
;target ALLOC position in registers BX, rotate and replace
|
||||
;
|
||||
push cx
|
||||
mov cl,ch
|
||||
ror al,cl
|
||||
mov [bx],al
|
||||
pop cx
|
||||
ret
|
||||
;
|
||||
;************* end BDOS filesystem part 1 **************
|
||||
end
|
||||
|
||||
666
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LBDOSF2.A86
Normal file
666
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LBDOSF2.A86
Normal file
@@ -0,0 +1,666 @@
|
||||
;***************** BDOS file system part 2 *****************
|
||||
;
|
||||
scndm:
|
||||
;scan the disk map addressed by dptr for non-zero
|
||||
;entries, the allocation vector entry corresponding
|
||||
;to a non-zero entry is set to the value of CL (0,1)
|
||||
;BX addresses the beginning of the directory entry
|
||||
;
|
||||
CALL getdptra ;BX = buffa + dptr
|
||||
ADD BX,dskmap ;BX = diskmap address
|
||||
PUSH CX ;save the 0/1 bit to set
|
||||
MOV CL,fcblen-dskmap+1 ;size of single byte diskmap+1
|
||||
scndm0:
|
||||
;loop for each diskmap entry
|
||||
POP DX ;recall bit parity
|
||||
DEC CL
|
||||
JNZ L_41
|
||||
RET
|
||||
L_41: ;all done scanning?
|
||||
;no, get next entry for scan
|
||||
PUSH DX ;replace bit parity
|
||||
cmp single,0
|
||||
JZ scndm1
|
||||
;single byte scan operation
|
||||
PUSH CX ;save counter
|
||||
PUSH BX ;save map address
|
||||
MOV CL,[bx]
|
||||
MOV CH,0 ;CX=block#
|
||||
jmps scndm2
|
||||
scndm1:
|
||||
;double byte scan operation
|
||||
DEC CL ;count for double byte
|
||||
PUSH CX ;save counter
|
||||
MOV cx,[bx] ;CX=block
|
||||
INC BX
|
||||
PUSH BX ;save map address
|
||||
scndm2:
|
||||
;arrive here with CX=block#,
|
||||
;DL= 0/1
|
||||
OR cx,cx ;skip if = 0000
|
||||
JZ scan3
|
||||
MOV BX,maxall ;check invalid index
|
||||
cmp bx,cx
|
||||
JNAE L_42
|
||||
CALL setallocbit
|
||||
L_42: ;
|
||||
;bit set to 0/1
|
||||
scan3: ;
|
||||
POP BX
|
||||
INC BX ;to next bit position
|
||||
POP CX ;recall counter
|
||||
jmps scndm0 ;for another item
|
||||
;
|
||||
initialize:
|
||||
;initialize the current disk
|
||||
;lret = false ;set to true if $ file exists
|
||||
;compute the length of the allocation vector - 2
|
||||
MOV BX,maxall
|
||||
MOV CL,3 ;perform maxall/8
|
||||
shr bx,cl
|
||||
INC BX
|
||||
mov cx,bx
|
||||
MOV BX,alloca ;base of allocation vector
|
||||
;fill the allocation vector
|
||||
;with zeros
|
||||
init0:
|
||||
MOV b[bx],0
|
||||
INC BX ;alloc(i)=0
|
||||
loop init0
|
||||
;set the reserved space for
|
||||
;the directory
|
||||
MOV DX,dirblk
|
||||
MOV BX,alloca ;BX=.alloc()
|
||||
MOV [bx],dx ;sets reserved directory blks
|
||||
;allocation vector initialized
|
||||
CALL home ;home disk
|
||||
;cdrmax = 3 (scans at least
|
||||
;one directory record)
|
||||
MOV BX,cdrmaxa
|
||||
mov w[bx],3
|
||||
;cdrmax = 0000
|
||||
CALL setenddir ;dcnt = enddir
|
||||
;read directory entries and
|
||||
;check for allocated storage
|
||||
init2:
|
||||
MOV CL,true
|
||||
CALL rddir
|
||||
CALL endofdir
|
||||
jz ret8b ;rz
|
||||
;not end of directory,
|
||||
;valid entry ?
|
||||
CALL getdptra ;BX = buffa + dptr
|
||||
cmp b[bx],empty
|
||||
JZ init2 ;go get another item
|
||||
;not empty,user code the same?
|
||||
MOV AL,usrcode
|
||||
CMP AL,[bx]
|
||||
JNZ pdollar
|
||||
;same user code,
|
||||
;check for '$' submit
|
||||
INC BX
|
||||
MOV AL,[bx] ;first character
|
||||
SUB AL,'$' ;dollar file?
|
||||
JNZ pdollar
|
||||
;$ file found, mark in lret
|
||||
DEC AL
|
||||
MOV lret,al ;lret = 255
|
||||
pdollar:
|
||||
;now scan the disk map for
|
||||
;allocated blocks
|
||||
MOV CL,1 ;set to allocated
|
||||
CALL scndm
|
||||
CALL setcdr ;set cdrmax to dcnt
|
||||
jmps init2 ;for another entry
|
||||
;
|
||||
cpydirloc:
|
||||
;copy directory location to lret following
|
||||
;delete, rename, ... ops
|
||||
MOV AL,dirloc
|
||||
JMP staret
|
||||
; ret
|
||||
;
|
||||
compext:
|
||||
;compare extent# in AL with that in CL, return nonzero
|
||||
;if they do not match
|
||||
PUSH CX ;save CL's original value
|
||||
MOV ch,extmsk
|
||||
NOT ch
|
||||
;CH has negated form of
|
||||
;extent mask
|
||||
and cl,ch ;low bits removed from CL
|
||||
AND AL,CH ;low bits removed from AL
|
||||
SUB AL,CL
|
||||
AND AL,maxext ;set flags
|
||||
POP CX ;restore original values
|
||||
ret8b: RET
|
||||
;
|
||||
srch:
|
||||
;search for directory element
|
||||
;of lenght
|
||||
MOV dirloc,0ffh ;changed if actually found
|
||||
MOV srchl,cl ;searchl = CL
|
||||
MOV BX,info
|
||||
MOV srcha,BX ;searcha = info
|
||||
CALL setenddir ;dcnt = enddir
|
||||
CALL home ;to start at the beginning
|
||||
;(drop through to searchn) ;
|
||||
;
|
||||
srchn:
|
||||
;search for the next directory element, assuming
|
||||
;a previous call on search which sets searcha and searchhl
|
||||
MOV CL,false
|
||||
CALL rddir ;read next dir element
|
||||
CALL endofdir
|
||||
jz srchfin
|
||||
;skip to end if so
|
||||
;not end of directory,
|
||||
;scan for match
|
||||
MOV dx,srcha ;DX=beginning of user fcb
|
||||
MOV SI,DX
|
||||
LODS al ;first character
|
||||
CMP AL,empty ;keep scanning if empty
|
||||
JZ srchnext
|
||||
;not empty, may be end of
|
||||
;logical directory
|
||||
PUSH DX ;save search address
|
||||
CALL compcdr ;past logical end?
|
||||
POP DX ;recall address
|
||||
jnb srchfin
|
||||
;artificial stop
|
||||
srchnext:
|
||||
CALL getdptra ;BX = buffa+dptr
|
||||
MOV AL,srchl
|
||||
MOV CL,AL ;length of search to CL
|
||||
MOV CH,0 ;CH counts up, CL counts down
|
||||
srchloop:
|
||||
or cl,cl
|
||||
JZ endsearch
|
||||
MOV SI,DX
|
||||
LODS al
|
||||
CMP AL,'?'
|
||||
JZ srchok ;? matches all
|
||||
;scan next character if not
|
||||
;ubytes
|
||||
CMP ch,ubytes
|
||||
JZ srchok
|
||||
;not the ubytes field,
|
||||
;extent field
|
||||
CMP ch,extnum ;may be extent field
|
||||
MOV SI,DX
|
||||
LODS al ;fcb character
|
||||
JZ srchext ;skip to search extent
|
||||
SUB AL,[bx]
|
||||
AND AL,7fh ;mask-out flags/extent modulus
|
||||
jnz srchn
|
||||
jmps srchok ;matched character
|
||||
srchext:
|
||||
;A has fcb character
|
||||
;attempt an extent # match
|
||||
PUSH CX ;save counters
|
||||
MOV CL,[bx] ;directory character to c
|
||||
CALL compext ;compare user/dir char
|
||||
POP CX ;recall counters
|
||||
jnz srchn ;skip if no match
|
||||
srchok:
|
||||
;current character matches
|
||||
INC DX
|
||||
INC BX
|
||||
INC CH
|
||||
DEC CL
|
||||
jmps srchloop
|
||||
endsearch:
|
||||
;entire name matches, return dir position
|
||||
MOV AL,ldcnt
|
||||
AND AL,dskmsk
|
||||
MOV lret,al
|
||||
;lret = low(dcnt) and 11b
|
||||
LEA BX,dirloc
|
||||
MOV AL,[bx]
|
||||
RCL AL,1
|
||||
jae ret9 ;rnc
|
||||
;yes, change it to 0 to
|
||||
;mark as found
|
||||
XOR AL,AL
|
||||
MOV [bx],al ;dirloc=0
|
||||
ret9: RET
|
||||
srchfin:
|
||||
;end of directory, or empty name
|
||||
CALL setenddir ;may be artifical end
|
||||
MOV AL,255
|
||||
JMP staret
|
||||
;
|
||||
;
|
||||
delet:
|
||||
;delete the currently addressed file
|
||||
CALL checkwrite ;write protected?
|
||||
MOV CL,extnum
|
||||
CALL srch ;search through file type
|
||||
delet0:
|
||||
;loop while directory matches
|
||||
CALL endofdir
|
||||
jz ret9
|
||||
;set each non zero disk map
|
||||
;entry to 0
|
||||
;in the allocation vector
|
||||
;may be r/o file
|
||||
CALL ckrodir ;ro disk error if found
|
||||
CALL getdptra ;BX=.buff(dptr)
|
||||
MOV b[bx],empty
|
||||
MOV CL,0
|
||||
CALL scndm ;alloc elts set to 0
|
||||
CALL wrdir ;write the directory
|
||||
CALL srchn ;to next element
|
||||
jmps delet0 ;for another record
|
||||
;
|
||||
getblock:
|
||||
;given allocation vector position CX, find the zero bit
|
||||
;closest to this position by searching left and right.
|
||||
;if found, set the bit to 1 and return the bit position
|
||||
;in BX. if not found (i.e., we pass 0 on the left, or
|
||||
;maxall on the right), return 0000 in BX
|
||||
;
|
||||
MOV dx,cx ;copy start pos. to DX
|
||||
lefttst:
|
||||
or cx,cx
|
||||
JZ righttst ;skip if left=0000
|
||||
;left not at position zero,
|
||||
;bit zero ?
|
||||
DEC CX
|
||||
PUSH DX
|
||||
PUSH CX ;left,right pushed
|
||||
CALL getallocbit
|
||||
RCR AL,1
|
||||
JAE rblok ;return block number if zero
|
||||
;bit is one, so try the right
|
||||
POP CX
|
||||
POP DX ;left, right restored
|
||||
righttst:
|
||||
cmp dx,maxall ;value of maximum allocation#
|
||||
JAE rblok0 ;return block 0000 if so
|
||||
INC DX
|
||||
PUSH CX
|
||||
PUSH DX ;left, right pushed
|
||||
MOV cx,dx ;ready right for call
|
||||
CALL getallocbit
|
||||
RCR AL,1
|
||||
JAE rblok ;return block number if zero
|
||||
POP DX
|
||||
POP CX ;restore left and right ptr
|
||||
jmps lefttst ;for another attempt
|
||||
rblok:
|
||||
RCL AL,1
|
||||
INC AL ;bit back into position
|
||||
;and set to 1
|
||||
;DL contains the number of
|
||||
;shifts required to reposition
|
||||
CALL rotr ;move bit back to position
|
||||
;and store
|
||||
POP BX
|
||||
POP DX ;BX returned value,
|
||||
;DX discarded
|
||||
RET
|
||||
rblok0:
|
||||
;cannot find an available
|
||||
;bit, return 0000
|
||||
or cx,cx
|
||||
jnz lefttst
|
||||
MOV BX,0000h
|
||||
RET
|
||||
;
|
||||
copyfcb:
|
||||
;copy the entire FCB
|
||||
MOV CL,0
|
||||
MOV DL,fcblen ;start at 0, to fcblen-1
|
||||
; jmp copydir ;
|
||||
;
|
||||
copydir:
|
||||
;copy fcb information starting
|
||||
;into the currently addressed directory entry
|
||||
PUSH DX ;save length for later
|
||||
MOV CH,0 ;double index to CX
|
||||
MOV dx,info ;BX = source for data
|
||||
ADD dx,CX ;DX=.fcb(CL), source for copy
|
||||
CALL getdptra ;BX=.buff(dptr), destination
|
||||
POP CX ;DX=source, BX=dest, C=length
|
||||
CALL move ;data moved
|
||||
seekcopy:
|
||||
;enter from close to seek and copy current element
|
||||
CALL seekdir ;to the directory element
|
||||
JMP wrdir ;write the directory element
|
||||
;ret
|
||||
;
|
||||
;
|
||||
rename:
|
||||
;rename the file described by the first half of
|
||||
;the currently addressed file control block. the
|
||||
;new name is contained in the last half of the
|
||||
;currently addressed file conrol block. the file
|
||||
;name and type are changed, but the reel number
|
||||
;is ignored. the user number is identical.
|
||||
;
|
||||
CALL checkwrite ;may be write protected
|
||||
;search up to the extent field
|
||||
MOV CL,extnum
|
||||
CALL srch
|
||||
;copy position 0
|
||||
MOV BX,info
|
||||
MOV AL,[bx] ;BX=.fcb(0), A=fcb(0)
|
||||
ADD BX,dskmap ;bx=.fcb(diskmap)
|
||||
MOV [bx],al ;fcb(dskmap)=fcb(0)
|
||||
;assume the same disk
|
||||
;for new named file
|
||||
renam0:
|
||||
CALL endofdir
|
||||
JNZ L_51
|
||||
ret10: RET
|
||||
L_51: ;stop at end of dir
|
||||
;not end of directory,
|
||||
;rename next element
|
||||
CALL ckrodir ;may be read-only file
|
||||
MOV CL,dskmap
|
||||
MOV DL,extnum
|
||||
CALL copydir
|
||||
;element renamed, move to next
|
||||
CALL srchn
|
||||
jmps renam0
|
||||
;
|
||||
indicators:
|
||||
;set file indicators for current fcb
|
||||
MOV CL,extnum
|
||||
CALL srch ;through file type
|
||||
indic0:
|
||||
CALL endofdir
|
||||
jz ret10 ;stop at end of dir
|
||||
;not end of directory,
|
||||
;continue to change
|
||||
MOV CL,0
|
||||
MOV DL,extnum ;copy name
|
||||
CALL copydir
|
||||
CALL srchn
|
||||
jmps indic0
|
||||
;
|
||||
open:
|
||||
;search for the directory entry, copy to FCB
|
||||
MOV CL,namlen
|
||||
CALL srch
|
||||
CALL endofdir
|
||||
jz ret10 ;return with lret=255 if end
|
||||
;not end of directory,copy fcb
|
||||
opencopy:
|
||||
;(referenced below to copy fcb
|
||||
CALL getexta
|
||||
|
||||
PUSH AX
|
||||
PUSH BX ;save extent#
|
||||
CALL getdptra
|
||||
XCHG BX,DX ;DX = .buff(dptr)
|
||||
MOV BX,info ;BX=.fcb(0)
|
||||
MOV CL,nxtrec ;length of move operation
|
||||
PUSH DX ;save .buff(dptr)
|
||||
CALL move ;from .buff(dptr) to .fcb(0)
|
||||
;note that entire fcb is
|
||||
;copied, including indicators
|
||||
CALL setfwf ;sets file write flag
|
||||
POP DX
|
||||
MOV BX,extnum
|
||||
ADD BX,DX ;bx=.buff(dptr+extnum)
|
||||
mov cl,[bx]
|
||||
|
||||
MOV BX,reccnt
|
||||
ADD BX,DX
|
||||
mov ch,[bx]
|
||||
|
||||
POP BX
|
||||
POP AX
|
||||
MOV [bx],al ;restore extent number
|
||||
;
|
||||
;BX = .user extent#, CH = dir rec cnt, CL = dir extent#
|
||||
;if user ext < dir ext then user := 128 records
|
||||
;if user ext = dir ext then user := dir records
|
||||
;if user ext > dir ext then user := 0 records
|
||||
;
|
||||
CMP cl,[bx]
|
||||
MOV AL,CH ;ready dir reccnt
|
||||
JZ openrcnt ;if same, user gets dir reccnt
|
||||
MOV AL,0
|
||||
JB openrcnt ;user is larger
|
||||
MOV AL,128 ;directory is larger
|
||||
openrcnt: ;A has record count to fill
|
||||
MOV BX,info
|
||||
MOV DX,reccnt
|
||||
ADD BX,DX
|
||||
MOV [bx],al
|
||||
ret11: RET
|
||||
;
|
||||
mergezero:
|
||||
;BX = .fcb1(i), DX = .fcb2(i),
|
||||
;if fcb1(i) = 0
|
||||
;then fcb1(i) := fcb2(i)
|
||||
cmp w[bx],0
|
||||
jnz ret11 ;rnz
|
||||
MOV SI,DX
|
||||
LODS ax
|
||||
mov [bx],ax
|
||||
ret12: RET
|
||||
;
|
||||
close:
|
||||
;locate the directory element and re-write it
|
||||
XOR AX,AX
|
||||
MOV lret,al
|
||||
MOV dcnt,ax
|
||||
CALL nowrite
|
||||
jnz ret12 ;skip close if r/o disk
|
||||
;check file write flag -
|
||||
;0 indicates written
|
||||
CALL getmodnum ;fcb(modnum) in A
|
||||
AND AL,fwfmsk
|
||||
jnz ret12 ;return if bit remains set
|
||||
MOV CL,namlen
|
||||
CALL srch ;locate file
|
||||
CALL endofdir
|
||||
jz ret12 ;return if not found
|
||||
;merge the disk map at info
|
||||
MOV CX,dskmap
|
||||
CALL getdptra
|
||||
ADD BX,CX
|
||||
XCHG BX,DX ;DX is .buff(dptr+16)
|
||||
MOV BX,info
|
||||
ADD BX,CX ;dx=.buff(dptr+16),
|
||||
;bx=.fcb(16)
|
||||
MOV CL,(fcblen-dskmap) ;length of single byte dm
|
||||
merge0:
|
||||
cmp single,0
|
||||
JZ merged ;skip to double
|
||||
;
|
||||
;this is a single byte map
|
||||
;if fcb(i) = 0 then fcb(i) = buff(i)
|
||||
;if buff(i) = 0 then buff(i) = fcb(i)
|
||||
;if fcb(i) <> buff(i) then error
|
||||
;
|
||||
MOV AL,[bx]
|
||||
OR AL,AL
|
||||
MOV SI,DX
|
||||
LODS al
|
||||
JNZ fcbnzero
|
||||
;fcb(i) = 0
|
||||
MOV [bx],al ;fcb(i) = buff(i)
|
||||
fcbnzero:
|
||||
OR AL,AL
|
||||
JNZ buffnzero
|
||||
;buff(i) = 0
|
||||
MOV AL,[bx]
|
||||
MOV DI,DX
|
||||
stos al ;buff(i)=fcb(i)
|
||||
buffnzero:
|
||||
CMP AL,[bx]
|
||||
jnz mergerr ;fcb(i) = buff(i)?
|
||||
jmps dmset ;if merge ok
|
||||
merged:
|
||||
;this is a double byte merge
|
||||
CALL mergezero ;buff = fcb if buff 0000
|
||||
XCHG BX,DX
|
||||
CALL mergezero
|
||||
XCHG BX,DX ;fcb = buff if fcb 0000
|
||||
;they should be identical
|
||||
;at this point
|
||||
MOV SI,DX
|
||||
mov ax,[si]
|
||||
cmp ax,[bx]
|
||||
jnz mergerr
|
||||
inc dx
|
||||
inc bx
|
||||
;merge ok for this pair
|
||||
DEC CL ;extra count for double byte
|
||||
dmset:
|
||||
INC DX
|
||||
INC BX
|
||||
DEC CL
|
||||
JNZ merge0 ;for more
|
||||
;end of disk map merge,
|
||||
;check record count
|
||||
;DX = .buff(dptr)+32,
|
||||
;BX = .fcb(32)
|
||||
MOV CX,-(fcblen-extnum)
|
||||
ADD BX,CX
|
||||
XCHG BX,DX
|
||||
ADD BX,CX
|
||||
;DX = .fcb(extnum),
|
||||
;BX = .buff(dptr+extnum)
|
||||
MOV SI,DX
|
||||
LODS al ;current user extent number
|
||||
;if fcb(ext) >= buff(fcb) then
|
||||
;buff(ext) := fcb(ext),
|
||||
;buff(rec) := fcb(rec)
|
||||
CMP AL,[bx]
|
||||
JB endmerge
|
||||
;fcb extent number >=
|
||||
;dir extent number
|
||||
MOV [bx],al ;buff(ext) = fcb(ext)
|
||||
;update dir. rec count field
|
||||
MOV CX,(reccnt-extnum)
|
||||
ADD BX,CX
|
||||
XCHG BX,DX
|
||||
ADD BX,CX
|
||||
;DX=.buff(reccnt),
|
||||
;BX=.fcb(reccnt)
|
||||
MOV AL,[bx]
|
||||
MOV DI,DX
|
||||
stos al ;buff(reccnt)=fcb(reccnt)
|
||||
endmerge:
|
||||
MOV fcbcopied,true ;mark as copied
|
||||
JMP seekcopy ;ok to "wrdir" here -
|
||||
;1.4 compatible
|
||||
; ret
|
||||
mergerr:
|
||||
;elements did not merge ok
|
||||
dec lret ;=255 non zero flag set
|
||||
ret13: RET
|
||||
;
|
||||
make:
|
||||
;create a new file by creating a directory entry
|
||||
;then opening the file
|
||||
CALL checkwrite ;may be write protected
|
||||
push info
|
||||
MOV info,offset efcb ;info = .empty
|
||||
MOV CL,1
|
||||
CALL srch ;length 1 match on empty entry
|
||||
CALL endofdir ;zero flag set if no space
|
||||
pop info ;recall word ptr info address
|
||||
jz ret13 ;return with error condition
|
||||
;255 if not found
|
||||
XCHG BX,DX ;DX = word ptr info address
|
||||
;clear the remainder of fcb
|
||||
MOV BX,namlen
|
||||
ADD BX,DX ;bx=.fcb(namlen)
|
||||
MOV CL,fcblen-namlen ;number of bytes to fill
|
||||
XOR AL,AL ;clear AL for fill
|
||||
make0:
|
||||
MOV [bx],al
|
||||
INC BX
|
||||
DEC CL
|
||||
JNZ make0
|
||||
MOV BX,ubytes
|
||||
ADD BX,DX ;bx=.fcb(ubytes)
|
||||
MOV [bx],al ;fcb(ubytes) = 0
|
||||
CALL setcdr ;may have extended dir
|
||||
;now copy entry to dir
|
||||
CALL copyfcb
|
||||
;set file write flag to "1"
|
||||
JMP setfwf
|
||||
;ret
|
||||
;
|
||||
openreel:
|
||||
;close the current extent, and open the next one
|
||||
;if possible. RMF is true if in read mode.
|
||||
XOR AL,AL
|
||||
MOV fcbcopied,AL ;set true if actually copied
|
||||
CALL close ;close current extent
|
||||
;lret remains at enddir
|
||||
;if we cannot open next ext
|
||||
CALL endofdir
|
||||
jz ret13 ;return if end
|
||||
;increment extent number
|
||||
MOV BX,info
|
||||
ADD BX,extnum ;BX=.fcb(extnum)
|
||||
MOV AL,[bx]
|
||||
INC AL
|
||||
AND AL,maxext
|
||||
MOV [bx],al ;fcb(extnum)=++1
|
||||
JZ openmod ;move to next module if 0
|
||||
;may be in same extent group
|
||||
MOV CH,AL
|
||||
MOV AL,extmsk
|
||||
AND AL,CH
|
||||
;if 0, then not in same group
|
||||
and al,fcbcopied ;true if fcb was copied to dir
|
||||
;puts 0 in AL if not written
|
||||
JZ openr0 ;go to next physical extent
|
||||
;result is non zero,
|
||||
;so we must be in same extent
|
||||
jmps openr1 ;to copy fcb info
|
||||
openmod:
|
||||
;extent number overflow, go to next module
|
||||
ADD BX,(modnum-extnum) ;bx=.fcb(modnum)
|
||||
INC b[bx] ;fcb(modnum)=++1
|
||||
;module number incremented,
|
||||
;check for overflow
|
||||
MOV AL,[bx]
|
||||
AND AL,maxmod ;mask high order bits
|
||||
JZ openerr ;cannot overflow to 0
|
||||
;otherwise, ok to continue
|
||||
;with new module
|
||||
openr0:
|
||||
MOV CL,namlen
|
||||
CALL srch ;next extent found?
|
||||
CALL endofdir
|
||||
JNZ openr1
|
||||
;end of file encountered
|
||||
MOV AL,rmf
|
||||
INC AL ;0ffh becomes 00 if read
|
||||
JZ openerr ;sets lret = 1
|
||||
;try to extend current file
|
||||
CALL make
|
||||
;cannot be end of directory
|
||||
CALL endofdir
|
||||
JZ openerr ;with lret = 1
|
||||
jmps openr2
|
||||
openr1:
|
||||
;not end of file, open
|
||||
CALL opencopy
|
||||
openr2:
|
||||
CALL getfcb ;set parameters
|
||||
XOR AL,AL
|
||||
JMP staret ;lret = 0
|
||||
; ret
|
||||
openerr:
|
||||
;cannot move to next extent
|
||||
;of this file
|
||||
CALL setlret1 ;lret = 1
|
||||
JMP setfwf ;ensure that it will not
|
||||
;be closed
|
||||
;ret
|
||||
;
|
||||
;*************** end BDOS file system part 2 ***************
|
||||
end
|
||||
|
||||
477
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LBDOSF3.A86
Normal file
477
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LBDOSF3.A86
Normal file
@@ -0,0 +1,477 @@
|
||||
;******************** BDOS filesystem part 3 ****************
|
||||
;
|
||||
;
|
||||
sqread:
|
||||
;sequential disk read operation
|
||||
MOV seqio,1
|
||||
;drop through to diskread
|
||||
;
|
||||
diskread: ;(may enter from seqdiskread)
|
||||
MOV rmf,true ;read mode flag =
|
||||
;true (open$reel)
|
||||
;read the next record from
|
||||
;the current FCB
|
||||
CALL getfcb ;sets parameters for the read
|
||||
MOV AL,lvrecord
|
||||
CMP AL,rcount ;vrecord-rcount
|
||||
;skip if rcount > vrecord
|
||||
JB recordok
|
||||
;not enough records in extent
|
||||
;record count must be 128
|
||||
;to continue
|
||||
CMP AL,128 ;vrecord = 128?
|
||||
JNZ diskeof ;skip if vrecord<>128
|
||||
CALL openreel ;go to next extent if so
|
||||
MOV vrecord,0 ;vrecord=00
|
||||
;now check for open ok
|
||||
cmp lret,0 ;stop at eof
|
||||
JNZ diskeof
|
||||
recordok:
|
||||
;arrive with fcb addressing a record to read
|
||||
CALL index
|
||||
;error 2 if reading
|
||||
;unwritten data
|
||||
;(returns 1 to be compatible
|
||||
;with 1.4)
|
||||
CALL alloct ;arecord=0000?
|
||||
JZ diskeof
|
||||
;record has been allocated,
|
||||
;read it
|
||||
CALL atran ;arecord now a disk address
|
||||
CALL seek ;to proper track,sector
|
||||
CALL rdbuff ;to dma address
|
||||
JMP setfcb ;replace parameter
|
||||
; ret
|
||||
diskeof:
|
||||
JMP setlret1 ;lret = 1
|
||||
;ret
|
||||
;
|
||||
slect:
|
||||
;select disk word ptr info for subsequent input or output ops
|
||||
MOV BX,dlog
|
||||
MOV cl,curdsk
|
||||
ror bx,cl
|
||||
PUSH BX
|
||||
XCHG BX,DX ;save it for test below,
|
||||
;send to seldsk
|
||||
CALL selectdisk
|
||||
POP BX ;recall dlog vector
|
||||
JNZ L_67
|
||||
CALL selerror
|
||||
L_67: ;returns true if select ok
|
||||
;is the disk logged in?
|
||||
RCR bl,1
|
||||
jb ret20 ;rc
|
||||
;return if bit is set
|
||||
;disk not logged in,
|
||||
;set bit and initialize
|
||||
mov cx,dlog
|
||||
CALL setcdisk
|
||||
MOV dlog,BX ;dlog=set$cdisk(dlog)
|
||||
JMP initialize
|
||||
;ret
|
||||
;
|
||||
curselect:
|
||||
MOV AL,linfo
|
||||
mov curdsk,al ;curdsk=info
|
||||
jmps slect
|
||||
;ret
|
||||
;
|
||||
reselect:
|
||||
;check current fcb to see if reselection necessary
|
||||
MOV resel,true ;mark possible reselect
|
||||
MOV BX,info
|
||||
MOV AL,[bx] ;drive select code
|
||||
AND AL,00011111b ;non zero is auto drive select
|
||||
dec AL ;drive code normalized to
|
||||
;0...30, or 255
|
||||
MOV linfo,AL ;save drive code
|
||||
CMP AL,30
|
||||
JAE noselect
|
||||
;auto select function,
|
||||
;save curdsk
|
||||
MOV AL,curdsk
|
||||
MOV olddsk,AL ;olddsk=curdsk
|
||||
MOV AL,[bx]
|
||||
MOV fcbdsk,AL ;save drive code
|
||||
AND AL,11100000b
|
||||
MOV [bx],al ;preserve hi bits
|
||||
CALL curselect
|
||||
noselect:
|
||||
;set user code
|
||||
MOV AL,usrcode ;0...31
|
||||
MOV BX,info
|
||||
OR AL,[bx]
|
||||
MOV [bx],al
|
||||
ret20: RET
|
||||
;
|
||||
; individual function handlers
|
||||
|
||||
func12 equ return
|
||||
func13:
|
||||
;
|
||||
;reset disk system - initialize to disk 0
|
||||
;
|
||||
xor bx,bx
|
||||
MOV rodsk,BX
|
||||
MOV dlog,BX
|
||||
MOV curdsk,bl ;note that usrcode remains
|
||||
;unchanged
|
||||
JMP slect
|
||||
;ret ;jmp goback
|
||||
;
|
||||
func14 EQU curselect ;
|
||||
;
|
||||
;select disk info
|
||||
;
|
||||
;
|
||||
func15:
|
||||
;
|
||||
;open file
|
||||
;
|
||||
CALL parsave33 ;copy FCB from user seg.
|
||||
CALL clrmodnum ;clear the module number
|
||||
CALL reselect
|
||||
jmp open
|
||||
;ret ;jmp goback
|
||||
;
|
||||
func16 equ return
|
||||
func17 equ return
|
||||
func18 equ return
|
||||
func19 equ return
|
||||
;
|
||||
func20:
|
||||
;
|
||||
;read a file
|
||||
;
|
||||
CALL parsave33
|
||||
CALL reselect
|
||||
jmp sqread
|
||||
;jmp goback
|
||||
;
|
||||
func21 equ return
|
||||
func22 equ return
|
||||
func23 equ return
|
||||
func24 equ return
|
||||
func25 equ return
|
||||
;
|
||||
func26:
|
||||
;
|
||||
;set the subsequent dma address to info
|
||||
;
|
||||
;was MOV BX,INFO
|
||||
MOV dmaad,dx ;dmaad = info
|
||||
JMP setdata ;to data dma address
|
||||
;ret ;jmp goback
|
||||
;
|
||||
func27 equ return
|
||||
func28 equ return
|
||||
func29 equ return
|
||||
func30 equ return
|
||||
func31 equ return
|
||||
func32 equ return
|
||||
func33 equ return
|
||||
func34 equ return
|
||||
func35 equ return
|
||||
func36 equ return
|
||||
func37 equ return
|
||||
;
|
||||
goback:
|
||||
|
||||
;arrive here at end of processing to return to user
|
||||
|
||||
cmp resel,0
|
||||
JZ retmon
|
||||
;reselection may have
|
||||
;taken place
|
||||
MOV BX,info
|
||||
MOV b[bx],0 ;fcb(0)=0
|
||||
MOV AL,fcbdsk
|
||||
OR AL,AL
|
||||
JZ retmon
|
||||
;restore disk number
|
||||
MOV [bx],al ;fcb(0)=fcbdsk
|
||||
MOV AL,olddsk
|
||||
MOV linfo,AL
|
||||
CALL curselect
|
||||
;
|
||||
; return from the disk monitor
|
||||
retmon:
|
||||
cmp parcopfl,true ;test if parameter block
|
||||
jnz retm1 ;to be copied back to user
|
||||
call parunsave
|
||||
retm1: MOV BX,aret
|
||||
MOV AL,BL
|
||||
MOV CH,BH ;BA = BX = aret
|
||||
RET
|
||||
func38 EQU funcret
|
||||
func39 EQU funcret
|
||||
func40 equ return
|
||||
;
|
||||
;******************* end BDOS filesystem part 3 ***************
|
||||
end
|
||||
BX
|
||||
; MOV arecord,BX
|
||||
; CALL setdata
|
||||
;dskw11:
|
||||
; CALL seek ;to proper file position
|
||||
; POP CX
|
||||
; PUSH CX ;restore/save write flag
|
||||
; ;(CL=2 if new block,0 if not)
|
||||
; CALL wrbuff ;written to disk
|
||||
; POP CX
|
||||
;increment record count
|
||||
;if rcount <= vrecord
|
||||
; MOV AL,lvrecord
|
||||
; LEA BX,rcount
|
||||
; CMP AL,[bx] ;vrecord-rcount
|
||||
; JB dskwr2
|
||||
;rcount <= vrecord
|
||||
; MOV [bx],al
|
||||
; INC b[bx] ;rcount = vrecord+1
|
||||
; MOV CL,2 ;mark as record count
|
||||
;incremented
|
||||
;dskwr2:
|
||||
;AL has vrecord,
|
||||
;CL=2 if new block or record#
|
||||
; dec CL
|
||||
; dec CL
|
||||
; JNZ noupdate
|
||||
; PUSH AX ;save vrecord value
|
||||
; CALL getmodnum ;BX=.fcb(modnum),
|
||||
;AL=fcb(modnum)
|
||||
;reset the file write flag to
|
||||
;mark as written FCB
|
||||
; AND AL,not fwfmsk ;bit reset
|
||||
; MOV [bx],al ;fcb(modnum) = fcb(modnum)
|
||||
;and 7fh
|
||||
; POP AX ;restore vrecord
|
||||
;noupdate:
|
||||
;check for end of extent, if found attempt to open
|
||||
;next extent in preparation for next write
|
||||
; CMP AL,lstrec ;vrecord=lstrec?
|
||||
; JNZ dskwr3 ;skip if not
|
||||
;may be random access write,
|
||||
;if so we are done
|
||||
;change next
|
||||
; cmp seqio,1
|
||||
; JNZ dskwr3 ;skip next extent open op
|
||||
;update current fcb before
|
||||
;going to next extent
|
||||
; CALL setfcb
|
||||
; CALL openreel ;rmf=false
|
||||
;vrecord remains at lstrec
|
||||
;causing eof if no more dir
|
||||
;space is available
|
||||
; LEA BX,lret
|
||||
; MOV AL,[bx]
|
||||
; OR AL,AL
|
||||
; JNZ nospace
|
||||
;space available,
|
||||
;set vrecord = 255
|
||||
; dec AL
|
||||
; MOV lvrecord,al ;goes to 00 next time
|
||||
;nospace:
|
||||
; MOV b[bx],0 ;lret = 00 for returned value
|
||||
;dskwr3:
|
||||
; JMP setfcb ;replace parameters
|
||||
;ret
|
||||
;
|
||||
;rseek:
|
||||
;random access seek operation, C=0ffh if read mode
|
||||
;fcb is assumed to address an active FCB
|
||||
;(modnum has been set to 1100$0000b if previous bad seek)
|
||||
;
|
||||
; MOV seqio,0 ;marked as random access op.
|
||||
;rseek1:
|
||||
; PUSH CX ;save r/w flag
|
||||
; MOV DX,info
|
||||
;dx will hold base of fcb
|
||||
; MOV BX,ranrec
|
||||
; ADD BX,DX ;bx=.fcb(ranrec)
|
||||
; MOV AL,[bx]
|
||||
; AND AL,7fh
|
||||
; PUSH AX ;record number
|
||||
; MOV AL,[bx]
|
||||
; RCL AL,1 ;cy=lsb of extent#
|
||||
; INC BX
|
||||
; MOV AL,[bx]
|
||||
; RCL AL,1
|
||||
; AND AL,11111b ;AL=ext#
|
||||
; MOV CL,AL ;CL holds extent number,
|
||||
;record stacked
|
||||
; MOV AL,[bx]
|
||||
; RCR AL,1
|
||||
; RCR AL,1
|
||||
; RCR AL,1
|
||||
; RCR AL,1
|
||||
; AND AL,1111b ;mod#
|
||||
; MOV CH,AL ;CH = module#,CL = ext#
|
||||
; POP AX ;recall sought record #
|
||||
;check to insure high byte
|
||||
; INC BX
|
||||
; MOV BL,[bx] ;l=high byte (must be 00)
|
||||
; or bl,bl
|
||||
; MOV BL,6 ;zero flag, l=6
|
||||
;produce error 6,
|
||||
;seek past physical eod
|
||||
; jnz seekerr
|
||||
;otherwise, high byte = 0
|
||||
; MOV BX,nxtrec
|
||||
; ADD BX,DX ;bx=.fcb(nxtrec)
|
||||
; MOV [bx],al ;sought rec# stored away
|
||||
;
|
||||
;arrive here with CH=mod#, CL=ext#, DX=.fcb, rec stored
|
||||
;the r/w flag is still stacked. compare fcb values
|
||||
;
|
||||
; MOV BX,extnum
|
||||
; ADD BX,DX
|
||||
; MOV AL,CL ;A=seek ext#
|
||||
; SUB AL,[bx]
|
||||
; JNZ ranclose ;tests for = extents
|
||||
;extents match, check mod#
|
||||
; MOV BX,modnum
|
||||
; ADD BX,DX
|
||||
; MOV AL,CH ;B=seek mod#
|
||||
;could be overflow at eof,
|
||||
;producing module# of 90h
|
||||
;or 10h, so compare all
|
||||
;but fwf
|
||||
; SUB AL,[bx]
|
||||
; AND AL,7fh
|
||||
; JZ seekok ;same?
|
||||
;ranclose:
|
||||
; PUSH CX
|
||||
; PUSH DX ;save seek mod#,ext#, .fcb
|
||||
; CALL close ;current extent closed
|
||||
; POP DX
|
||||
; POP CX ;recall parameters and fill
|
||||
; MOV BL,3 ;cannot close error #3
|
||||
; MOV AL,lret
|
||||
; INC AL
|
||||
; JZ badseek
|
||||
; MOV BX,extnum
|
||||
; ADD BX,DX
|
||||
; MOV [bx],cl ;fcb(extnum)=ext#
|
||||
; MOV BX,modnum
|
||||
; ADD BX,DX
|
||||
; MOV [bx],ch ;fcb(modnum)=mod#
|
||||
; CALL open ;is the file present?
|
||||
; MOV AL,lret
|
||||
; INC AL
|
||||
; JNZ seekok ;open successful?
|
||||
;cannot open file, read mode?
|
||||
; POP CX ;r/w flag to c (=0ffh if read)
|
||||
; PUSH CX ;everyone expects this
|
||||
;item stacked
|
||||
; MOV BL,4 ;seek to unwritten extent #4
|
||||
; INC CL ;becomes 00 if read operation
|
||||
; JZ badseek ;error if read operation
|
||||
;write, make new extent
|
||||
; CALL make
|
||||
; MOV BL,5 ;cannot create new extent #5
|
||||
; MOV AL,lret
|
||||
; INC AL
|
||||
; JZ badseek ;no dir space
|
||||
;file make successful
|
||||
;seekok:
|
||||
; POP CX ;discard r/w flag
|
||||
; XOR AL,AL
|
||||
; JMP staret ;with zero set
|
||||
;badseek:
|
||||
;
|
||||
;fcb no longer contains a valid fcb, mark
|
||||
;with 1100$000b in modnum field so that it
|
||||
;appears as overflow with file write flag set
|
||||
;
|
||||
; PUSH BX ;save error flag
|
||||
; CALL getmodnum ;BX = .modnum
|
||||
; MOV b[bx],11000000b
|
||||
; POP BX ;and drop through
|
||||
;seekerr:
|
||||
; POP CX ;discard r/w flag
|
||||
; MOV AL,BL
|
||||
; MOV lret,al ;lret=#, nonzero
|
||||
;setfwf returns <> 0 if error
|
||||
; JMP setfwf ;flag set, so subsequent
|
||||
;close ok
|
||||
;ret
|
||||
;
|
||||
;rdread:
|
||||
;
|
||||
;random disk read operation
|
||||
;
|
||||
; MOV CL,true ;marked as read operation
|
||||
; CALL rseek
|
||||
; JNZ L_65
|
||||
; CALL diskread
|
||||
;L_65: ;if seek successful
|
||||
; RET
|
||||
;
|
||||
;rdwrite:
|
||||
;random disk write operation
|
||||
; MOV CL,false ;marked as write operation
|
||||
; CALL rseek
|
||||
; JNZ L_66
|
||||
; CALL diskwite
|
||||
;L_66: ;if seek successful
|
||||
; RET
|
||||
;
|
||||
;cmperr:
|
||||
;compute random record position for getfilesize/setrandom
|
||||
; XCHG BX,DX
|
||||
; ADD BX,DX
|
||||
;DX=.buf(dptr) or .fcb(0),
|
||||
;BX=.f(nxtrec/reccnt)
|
||||
; MOV CL,[bx] ;pick up record no.
|
||||
; MOV CH,0 ;CX = 0000 0000 ?rrr rrrr
|
||||
; MOV BX,extnum
|
||||
; ADD BX,DX
|
||||
; MOV ah,[bx]
|
||||
; mov al,0
|
||||
; shr ax,1
|
||||
; and ah,0fh
|
||||
; add cx,ax
|
||||
;CX = 000? eeee errrr rrrr
|
||||
; MOV BX,modnum
|
||||
; ADD BX,DX
|
||||
; MOV AL,[bx] ;A=XXX? mmmm
|
||||
; mov ah,16
|
||||
; mul ah
|
||||
; PUSH AX
|
||||
; ADD ch,al
|
||||
;cy=?,CX = mmmm eeee errr rrrr
|
||||
; pushf ;possible second carry
|
||||
; POP BX ;cy = lsb of L
|
||||
; MOV AL,BL ;cy = lsb of A
|
||||
; POP BX ;cy = lsb of L
|
||||
; OR AL,BL ;cy/cy = lsb of A
|
||||
; AND AL,1 ;Al=0? possible carry-out
|
||||
; RET
|
||||
;
|
||||
;getfilesize:
|
||||
;compute logical file size for current fcb
|
||||
; MOV CL,extnum
|
||||
; CALL srch
|
||||
;zero receiving ranrec field
|
||||
; MOV BX,info
|
||||
; MOV DX,ranrec
|
||||
; ADD BX,DX
|
||||
; PUSH BX ;save position
|
||||
; MOV [bx],dh
|
||||
; INC BX
|
||||
; MOV [bx],dh
|
||||
; INC BX
|
||||
; MOV [bx],dh ;=00 00 00
|
||||
;getsize:
|
||||
; CALL endofdir
|
||||
; JZ setsize
|
||||
;current fcb addressed by dptr
|
||||
; CALL getdptra
|
||||
; MOV DX,reccnt ;ready for compute size
|
||||
; CALL cmperr
|
||||
;AL=0000 000?,
|
||||
;CX = mmmm eeee errr rrrr
|
||||
;compare with memory, larger?
|
||||
; POP BX
|
||||
; PUSH BX
|
||||
169
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LBDOSIO.A86
Normal file
169
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LBDOSIO.A86
Normal file
@@ -0,0 +1,169 @@
|
||||
;***************** BDOS byte I/O module ****************
|
||||
;
|
||||
; console handlers
|
||||
ret0: RET ;carry set if not graphic
|
||||
;
|
||||
conbrk: ;check for character ready
|
||||
MOV AL,kbchar
|
||||
OR AL,AL
|
||||
JNZ conb1 ;skip if active kbchar
|
||||
;no active kbchar,
|
||||
;check external break
|
||||
CALL constf
|
||||
AND AL,1
|
||||
jz ret0 ;rz
|
||||
;character ready, read it
|
||||
CALL coninf ;to A
|
||||
CMP AL,ctls
|
||||
JNZ conb0 ;check stop screen function
|
||||
;found ctls, read next char
|
||||
CALL coninf ;to A
|
||||
CMP AL,ctlc
|
||||
JNZ L_10
|
||||
JMP wbootf
|
||||
L_10: ;ctlc implies re-boot
|
||||
;not a reboot,
|
||||
;act as if nothing happened
|
||||
XOR AL,AL
|
||||
RET ;with zero in accumulator
|
||||
conb0:
|
||||
;character in accum, save it
|
||||
MOV kbchar,AL
|
||||
conb1:
|
||||
;return with true set
|
||||
MOV AL,1
|
||||
RET
|
||||
;
|
||||
conout:
|
||||
;compute character position/write conso
|
||||
;compcol = true if computing
|
||||
;column position
|
||||
MOV AL,compcol
|
||||
OR AL,AL
|
||||
JNZ compout
|
||||
;write the character,
|
||||
;then compute column
|
||||
;write console char from CL
|
||||
PUSH CX
|
||||
CALL conbrk ;check for screen stop func.
|
||||
POP CX
|
||||
PUSH CX ;recall/save character
|
||||
CALL conouf ;externally, to console
|
||||
POP CX
|
||||
PUSH CX ;recall/save character
|
||||
;may be copying to list dev.
|
||||
cmp listcp,0
|
||||
JZ L_11
|
||||
CALL listf
|
||||
L_11: ;to printer, if so
|
||||
POP CX ;recall the character
|
||||
compout:
|
||||
MOV AL,CL ;recall the character
|
||||
;and compute column position
|
||||
LEA BX,column ;A = char, BX = .column
|
||||
CMP AL,rubout
|
||||
jz ret1 ;no column change if nulls
|
||||
INC b[bx] ;column = column + 1
|
||||
CMP AL,' '
|
||||
jae ret1 ;rnc
|
||||
;not graphic, reset column
|
||||
DEC b[bx] ;column = column - 1
|
||||
MOV AL,[bx]
|
||||
OR AL,AL
|
||||
jz ret1 ;return if at zero
|
||||
;not at zero, may be
|
||||
;bacspace or end of line
|
||||
MOV AL,CL ;character back to A
|
||||
CMP al,ctlh
|
||||
JNZ notbacksp
|
||||
;backspace character
|
||||
DEC b[bx] ;column = column - 1
|
||||
ret1: RET
|
||||
notbacksp:
|
||||
;not backspace, eol ?
|
||||
CMP AL,lf
|
||||
jnz ret1 ;return if not
|
||||
;end of line, column = 0
|
||||
MOV b[bx],0 ;column = 0
|
||||
RET
|
||||
;
|
||||
tabout:
|
||||
;expand tabs to console
|
||||
CMP cl,tab
|
||||
jnz conout ;direct to conout if not
|
||||
;tab encountered, move to
|
||||
;next tab position
|
||||
tab0:
|
||||
MOV CL,' '
|
||||
CALL conout ;another blank
|
||||
MOV AL,column
|
||||
AND AL,111b ;column mod 8 = 0 ?
|
||||
JNZ tab0 ;back for another if not
|
||||
ret2: RET
|
||||
;
|
||||
crlf:
|
||||
;carriage return line feed sequence
|
||||
MOV CL,cr
|
||||
CALL conout
|
||||
MOV CL,lf
|
||||
JMP conout
|
||||
;ret
|
||||
;
|
||||
print:
|
||||
;print message until M(BC) = '$'
|
||||
MOV SI,CX
|
||||
LODS al
|
||||
CMP AL,'$'
|
||||
jz ret2 ; rz
|
||||
;more to print
|
||||
INC CX
|
||||
PUSH CX
|
||||
MOV CL,AL ;char to C
|
||||
push ds ;restore data segment
|
||||
push ss
|
||||
pop ds
|
||||
CALL tabout ;another character printed
|
||||
pop ds
|
||||
POP CX
|
||||
jmps print
|
||||
|
||||
return: ret
|
||||
func1 equ return
|
||||
func2 EQU tabout
|
||||
func3 equ return
|
||||
func6 equ return
|
||||
func7 equ return
|
||||
func8 equ return
|
||||
;
|
||||
func9:
|
||||
;write line until $ encountered
|
||||
;
|
||||
MOV CX,DX ;CX=string address
|
||||
push ds ;read from user segment
|
||||
mov ds,parametersegment
|
||||
call print ;out to console
|
||||
pop ds
|
||||
ret
|
||||
;
|
||||
func10 equ return
|
||||
|
||||
func11 equ return
|
||||
;check console status
|
||||
;(drop through to sta$ret)
|
||||
staret:
|
||||
;store the A register to aret
|
||||
MOV lret,al
|
||||
funcret: ;
|
||||
RET ;jmp goback
|
||||
;(pop stack for non CP/M func)
|
||||
;
|
||||
setlret1:
|
||||
;set lret = 1
|
||||
MOV AL,1
|
||||
jmps staret
|
||||
;
|
||||
; end of Basic I/O System
|
||||
;
|
||||
;*****************************************************************
|
||||
end
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
;******************* New BDOS functions for 8086 ****************
|
||||
|
||||
|
||||
func51: ;set segment base for disk I/O
|
||||
mov dmabase,dx
|
||||
func50:
|
||||
func52:
|
||||
func53:
|
||||
func54:
|
||||
func55:
|
||||
func56:
|
||||
func57:ret
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
; title 'Bdos Interface, Bdos, Version 2.2 Feb, 1980'
|
||||
;*****************************************************************
|
||||
;*****************************************************************
|
||||
;** **
|
||||
;** L o a d e r **
|
||||
;** B a s i c D i s k O p e r a t i n g S y s t e m **
|
||||
;** I n t e r f a c e M o d u l e **
|
||||
;** **
|
||||
;*****************************************************************
|
||||
;*****************************************************************
|
||||
;
|
||||
; Copyright (c) 1978, 1979, 1980
|
||||
; Digital Research
|
||||
; Box 579, Pacific Grove
|
||||
; California
|
||||
;
|
||||
;
|
||||
; 5 september, 1980
|
||||
; smaller version of BDOS for CP/M-86 Loader
|
||||
;
|
||||
;**********************************************
|
||||
;
|
||||
cpmsegment equ 0 ; base of CP/M-86
|
||||
ldroffset equ 0 ; offset of CPMLDR
|
||||
bdosoffset equ 400H ; offset of LBDOS-86
|
||||
biosoffset equ 1200H ; offset of LBIOS-86
|
||||
bdoscodesize equ 0B00H ; size of BDOS code
|
||||
;
|
||||
eject ! include lbdosequ.a86 ; symbol definition
|
||||
eject ! include lbdosent.a86 ; entry module
|
||||
eject ! include lbdosnew.a86 ; new 8086 BDOS functions
|
||||
eject ! include lbdosio.a86 ; byte I/O module
|
||||
eject ! include lbdosf1.a86 ; file system part 1
|
||||
eject ! include lbdosf2.a86 ; file system part 2
|
||||
eject ! include lbdosf3.a86 ; file system part 3
|
||||
eject ! include lbdosdat.a86 ; data area
|
||||
eject
|
||||
;********************** end of BDOS ********************
|
||||
end
|
||||
|
||||
110
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LDBDOS.H86
Normal file
110
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LDBDOS.H86
Normal file
@@ -0,0 +1,110 @@
|
||||
:02000085000079
|
||||
:02000085000079
|
||||
:0400000300000400F5
|
||||
:1B040081000000000000E90800E804F604FC0402052EA3CD0D2E8C16CF0D2EFD
|
||||
:1B041B818926D10D8CC88ED08D2685118CD81E065557561616071FA3520F2EAF
|
||||
:1B043681A1CD0DE810005E5F5D071F2E8B26D10D2E8E16CF0DCF8916070F8800
|
||||
:1B04518116350FC706090F0000C606540F0032C0A23F0FA23D0FBB9A0D53809C
|
||||
:1B046C81F929720980E90980F9317201C38AD9B7008ACA03DB2EFFA786040358
|
||||
:1B048781121F06EE051F0612120F121F061F061F0620061F061F061F066D0DC7
|
||||
:1B04A281310D7E0D1F061F061F061F068A0D1F061F061F061F061F06930D1F52
|
||||
:1B04BD81061F061F061F061F061F061F061F061F061F061F062F062F061F069C
|
||||
:1B04D8817E057A057E057E057E057E057E057E058D1EA80FE81D003C03755AFF
|
||||
:1B04F381E90D0D8D1EB30FEB0A8D1EBF0FEB048D1EBA0FE80300E9F70C53E81A
|
||||
:1B050E81F000A0060F0441A2A40F8D0E980FE8EB0059E8E700E9E30C1E50513E
|
||||
:1B052981C606540FFF880E550F32ED8B36070F8936500F8D3EC30F893E070F80
|
||||
:1B0544818E1E520FF3A459581FC351B121EB0351B124E8CDFF59C30650518AAC
|
||||
:1B055F810E550F32ED8E06520F8D36C30F8B3E500F893E070FF3A4595807C3CE
|
||||
:1B057A8189164E0FC3C3A0040F0AC0751EE87C0C240174F1E8780C3C13750D1C
|
||||
:1B059581E8710C3C037503E9640C32C0C3A2040FB001C3A0000F0AC075165122
|
||||
:1B05B081E8CDFF5951E8540C5951803E030F007403E84B0C598AC18D1E020F79
|
||||
:1B05CB813C7F7416FE073C207310FE0F8A070AC074088AC13C087503FE0FC3B0
|
||||
:1B05E6813C0A75FBC60700C380F90975B5B120E8B0FFA0020F240775F4C3B166
|
||||
:1B0601810DE8A3FFB10AE99EFF8BF1AC3C2474EE41518AC81E161FE8D3FF1F8B
|
||||
:1B061C8159EBEBC38BCA1E8E1E520FE8E0FF1FC3A2090FC3B001EBF88D1E0B60
|
||||
:1B06378104FF2751B5008BF28BFBF3A459C38A0E060FE8CF0B83FB00744B8B0A
|
||||
:1B0652811783C302891E120F83C302891E140F83C302891E160F83C30287DA16
|
||||
:1B066D81891E2F0F8D1E180FB108E8C0FF8B161A0F8D1E200FB10FE8B3FFA03C
|
||||
:1B068881260F8D1E3C0FC607FF0AC07403C60700B0FF0AC0C3E8780B33C08BAC
|
||||
:1B06A3811E140F8907C3E87B0BEB03E8790B0AC074E78D1E0904E97CFF8B1E75
|
||||
:1B06BE81490FB102D3EB891E440F891E4B0FA1440FBA0000F736200F528BC82D
|
||||
:1B06D9818B36140F890C030E2D0FE8380B598B162F0FE8420B8BCBE92E0B8D22
|
||||
:1B06F4811E220F8A0FA0420FD2E88AE8B1072A0FA0410FD2E002C5C38B1E0798
|
||||
:1B070F810F83C31003D9803E3C0F0074058A1FB700C303D98B1FC3E8CAFF8AE4
|
||||
:1B072A81C8B500E8DCFF891E440FC38B1E440F0BDBC38A0E220F8B1E440FD3F9
|
||||
:1B074581E3891E460FA0420F2206230F0AD8891E440FC38B1E070F83C30C8AB4
|
||||
:1B07608107C3BA0F000316070FBB110003DAC3E8F0FF8A07A2420F87DA8A0782
|
||||
:1B077B81A2400FE8D7FFA0240F2207A2410FC3E8D5FFA0340F3C02750232C03C
|
||||
:1B0796810206420F880787DAA0400F8807C3B980008B1E180F32C0020743E214
|
||||
:1B07B181FBC3518A0E060FBB0100D3E3590BD9C3A10C0F8A0E060FD3E8240135
|
||||
:1B07CC81C38B0E0C0FE8DFFF891E0C0F8B16270F428B1E120F8917C3E81E0046
|
||||
:1B07E781BA090003DA8A07D0D0731E8D1E0F04E93FFEE8C5FF74128D1E0D0442
|
||||
:1B080281E933FE8B1E180FA0480FB40003D8C38B1E070F83C30E8A07C3E8F3E5
|
||||
:1B081D81FFC60700C3E8ECFF0C808807C38B16490F8B1E120F3B17C3E8F2FF4E
|
||||
:1B08388172FA428917C3522BD38BDA5AC3B1FF8B164B0F8B1E2B0FE8ECFF736D
|
||||
:1B085381E051E84CFF8B1E4B0F031E1C0F59FEC1740D3A07740BE8BEFF7306DF
|
||||
:1B086E81E85CFFC38807C3E8CDFFE81B00B101E82EFEE90600E81000E820FE2C
|
||||
:1B0889818B0E4E0FE8A3098D1E100FEB098CD9E898098D1E180F8B0FE98009BF
|
||||
:1B08A4818B16180F8B1E100FB180068E06520FE884FD07C38D1E490F8A0743F2
|
||||
:1B08BF813A077502FEC0C3BBFFFF891E490FC38B16270F8B1E490F43891E49DE
|
||||
:1B08DA810FE860FF7302EBE4A0490F240351B105D2E059A2480F0AC0754051EE
|
||||
:1B08F581E8C4FDE888FF59E948FF8AD180E207FEC28AF28AC1B103D2C8241FEA
|
||||
:1B0910818AC851B105D2E0590AC88AC5D0C8D0C8D0C8241F8AE88B1E1E0F0370
|
||||
:1B092B81D98A07518ACAD2C059C352E8C6FF24FE590AC1518ACDD2C888075904
|
||||
:1B094681C3E8BBFE83C31051B1115AFEC97501C352803E3C0F00740851538AE9
|
||||
:1B0961810FB500EB07FEC9518B0F43530BC9740B8B1E250F3BD97203E8B9FFA3
|
||||
:1B097C815B4359EBCF8B1E250FB103D3EB438BCB8B1E1E0FC6070043E2FA8BF9
|
||||
:1B09978116290F8B1E1E0F8917E8FAFC8B1E120FC7070300E818FFB1FFE81BD5
|
||||
:1B09B281FFE802FF743BE84AFE803FE574EEA0050F3A07750C438A072C2475CD
|
||||
:1B09CD8105FEC8A2090FB101E86FFFE85AFEEBD1A0330FE949FC518A2E240FB9
|
||||
:1B09E881F6D522CD22C52AC1241F59C3C606330FFF880E370F8B1E070F891E39
|
||||
:1B0A0381380FE8BEFEE892FCB100E8BEFEE8A5FE74648B16380F8BF2AC3CE50C
|
||||
:1B0A1E81740752E806FE5A7352E8DBFDA0370F8AC8B5000AC9742D8BF2AC3CDE
|
||||
:1B0A39813F741E80FD0D741980FD0C8BF2AC74082A07247F75BCEB09518A0F28
|
||||
:1B0A5481E88CFF5975B14243FEC5FEC9EBCFA0490F2403A2090F8D1E330F8AFB
|
||||
:1B0A6F8107D0D0730432C08807C3E84AFEB0FFE9ABFBE875FDB10CE86BFFE8CA
|
||||
:1B0A8A812CFE74EAE853FDE871FDC607E5B100E8ABFEE8D6FDE869FFEBE58B60
|
||||
:1B0AA581D10BC9740C495251E84FFED0D87318595A3B16250F731A4251528B07
|
||||
:1B0AC081CAE83BFED0D873045A59EBDAD0D0FEC0E86BFE5B5AC30BC975CCBB21
|
||||
:1B0ADB810000C3B100B22052B5008B16070F03D1E817FD59E848FBE8C7FBE994
|
||||
:1B0AF6817DFDE8FEFCB10CE8F4FE8B1E070F8A0783C3108807E8AAFD7501C374
|
||||
:1B0B1181E8D0FCB110B20CE8C7FFE8EDFEEBEBB10CE8CFFEE890FD74E6B100CC
|
||||
:1B0B2C81B20CE8B1FFE8D7FEEBEFB10FE8B9FEE87AFD74D0E815FC5053E8BDFD
|
||||
:1B0B4781FC87DA8B1E070FB12052E8E6FAE8CBFC5ABB0C0003DA8A0FBB0F00FB
|
||||
:1B0B628103DA8A2F5B5888073A0F8AC57406B0007202B0808B1E070FBA0F0031
|
||||
:1B0B7D8103DA8807C3833F0075FA8BF2AD8907C333C0A2090FA3490FE829FC4A
|
||||
:1B0B988175F2E874FC248075EBB10FE84EFEE80FFD74E1B91000E854FC03D9E4
|
||||
:1B0BB38187DA8B1E070F03D9B110803E3C0F00741A8A070AC08BF2AC750288CF
|
||||
:1B0BCE81070AC075058A078BFAAA3A077546EB16E8A1FF87DAE89CFF87DA8B2B
|
||||
:1B0BE981F28B043B0775324243FEC94243FEC975C3B9ECFF03D987DA03D98BEE
|
||||
:1B0C0481F2AC3A0772108807B9030003D987DA03D98A078BFAAAC606310FFFC4
|
||||
:1B0C1F81E9D0FEFE0E090FC3E8CFFBFF36070FC706070F0B0FB101E8BBFDE867
|
||||
:1B0C3A817CFC8F06070F74E487DABB0F0003DAB11132C0880743FEC975F9BB25
|
||||
:1B0C55810D0003DA8807E8D7FBE87DFEE9BEFB32C0A2310FE821FFE849FC744E
|
||||
:1B0C7081B58B1E070F83C30C8A07FEC0241F8807740F8AE8A0240F22C522062A
|
||||
:1B0C8B81310F740DEB2683C302FE078A07240F7426B10FE853FDE814FC7511DA
|
||||
:1B0CA681A0320FFEC07415E877FFE805FC740DEB03E886FEE8B2FA32C0E96A8F
|
||||
:1B0CC181F9E86BF9E95AFBC606340F01C606320FFFE89AFAA0420F3A06400FFC
|
||||
:1B0CDC8172143C807524E87FFFC706420F0000803E090F007514E831FAE83D86
|
||||
:1B0CF781FA740CE83FFAE8CCF9E8A6F9E984FAE927F98B1E0E0F8A0E060FD3DC
|
||||
:1B0D1281CB5387DAE82CF95B7503E815F9D0DB72498B0E0E0FE889FA891E0EB4
|
||||
:1B0D2D810FE950FCA0350FA2060FEBD0C6063D0FFF8B1E070F8A07241FFEC820
|
||||
:1B0D4881A2350F3C1E7312A0060FA23E0F8A07A23F0F24E08807E8D0FFA00536
|
||||
:1B0D63810F8B1E070F0A078807C333DB891E0C0F891E0E0F881E060FE98BFF01
|
||||
:1B0D7E81E8CDF7E897FAE8B2FFE9ACFDE8C1F7E8A9FFE935FF8916100FE9EFA6
|
||||
:1B0D9981FA803E3D0F0074198B1E070FC60700A03F0F0AC0740B8807A03E0FEE
|
||||
:190DB481A2350FE877FF803E540FFF7503E897F78B1E090F8AC38AEFC309
|
||||
:02000085000079
|
||||
:060DCD810000000000009F
|
||||
:02000086000078
|
||||
:1B0F00820000000000000000000000E50000000000000000000000000000006F
|
||||
:1B0F1B8200000000000000000000000000000000000000000000000000000039
|
||||
:1B0F36820000000000000000000000000000000000000000000000000000001E
|
||||
:1B0F518200000000000000000000000000000000000000000000000000000003
|
||||
:1B0F6C82000000000000000000000000000000000000000000000000000000E8
|
||||
:1B0F8782000000000000000000000000000000000042646F7320457272204F8D
|
||||
:1B0FA2826E20203A202442616420536563746F722453656C6563742446696C2C
|
||||
:060FBD826520522F4F2433
|
||||
:00000001FF
|
||||
78
|
||||
:1B0F00820000000000000000000000E500000000000000000000000000
|
||||
618
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LDBIOS.A86
Normal file
618
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LDBIOS.A86
Normal file
@@ -0,0 +1,618 @@
|
||||
title '8086 Disk I/O Drivers'
|
||||
|
||||
;*********************************************
|
||||
;* *
|
||||
;* Loader Basic Input/Output System (LDBIOS) *
|
||||
;* for LDMPM Configured for iSBC 86/12 with *
|
||||
;* the iSBC 204 Floppy Disk Controller *
|
||||
;* *
|
||||
;* The only modifications of the CP/M-86 *
|
||||
;* LDBIOS for this MP/M-86 LDBIOS are the *
|
||||
;* CCP offset and the contents of the signon *
|
||||
;* message, which is printed by LDMPM.A86 *
|
||||
;* in place of the INIT routine. *
|
||||
;* *
|
||||
;* (Note: this file contains both embedded *
|
||||
;* tabs and blanks to minimize the list file *
|
||||
;* width for printing purposes. You may wish*
|
||||
;* to expand the blanks before performing *
|
||||
;* major editing.) *
|
||||
;*********************************************
|
||||
|
||||
; Copyright (C) 1980,1981
|
||||
; Digital Research, Inc.
|
||||
; Box 579, Pacific Grove
|
||||
; California, 93950
|
||||
;
|
||||
; (Permission is hereby granted to use
|
||||
; or abstract the following program in
|
||||
; the implementation of CP/M, MP/M or
|
||||
; CP/NET for the 8086 or 8088 Micro-
|
||||
; processor)
|
||||
|
||||
|
||||
true equ -1
|
||||
false equ not true
|
||||
|
||||
;*********************************************
|
||||
;* *
|
||||
;* Bdos_int is interrupt used for earlier *
|
||||
;* versions. *
|
||||
;* *
|
||||
;*********************************************
|
||||
|
||||
bdos_int equ 224 ;reserved BDOS Interrupt
|
||||
|
||||
bios_code equ 1200h ;start of LDBIOS
|
||||
ccp_offset equ 0103h ;base of MPMLOADER
|
||||
bdos_ofst equ 0406h ;stripped BDOS entry
|
||||
|
||||
csts equ 0DAh ;i8251 status port
|
||||
cdata equ 0D8h ; " data port
|
||||
|
||||
;*********************************************
|
||||
;* *
|
||||
;* Intel iSBC 204 Disk Controller Ports *
|
||||
;* *
|
||||
;*********************************************
|
||||
|
||||
base204 equ 0a0h ;SBC204 assigned address
|
||||
|
||||
fdc_com equ base204+0 ;8271 FDC out command
|
||||
fdc_stat equ base204+0 ;8271 in status
|
||||
fdc_parm equ base204+1 ;8271 out parameter
|
||||
fdc_rslt equ base204+1 ;8271 in result
|
||||
fdc_rst equ base204+2 ;8271 out reset
|
||||
dmac_adr equ base204+4 ;8257 DMA base address out
|
||||
dmac_cont equ base204+5 ;8257 out control
|
||||
dmac_scan equ base204+6 ;8257 out scan control
|
||||
dmac_sadr equ base204+7 ;8257 out scan address
|
||||
dmac_mode equ base204+8 ;8257 out mode
|
||||
dmac_stat equ base204+8 ;8257 in status
|
||||
fdc_sel equ base204+9 ;FDC select port (not used)
|
||||
fdc_segment equ base204+10 ;segment address register
|
||||
reset_204 equ base204+15 ;reset entire interface
|
||||
|
||||
max_retries equ 10 ;max retries on disk i/o
|
||||
;before perm error
|
||||
cr equ 0dh ;carriage return
|
||||
lf equ 0ah ;line feed
|
||||
|
||||
cseg
|
||||
org ccpoffset
|
||||
ccp:
|
||||
org bios_code
|
||||
|
||||
;*********************************************
|
||||
;* *
|
||||
;* BIOS Jump Vector for Individual Routines *
|
||||
;* *
|
||||
;*********************************************
|
||||
|
||||
jmp INIT ;Enter from BOOT ROM or LOADER
|
||||
jmp WBOOT ;Arrive here from BDOS call 0
|
||||
jmp CONST ;return console keyboard status
|
||||
jmp CONIN ;return console keyboard char
|
||||
jmp CONOUT ;write char to console device
|
||||
jmp LISTOUT ;write character to list device
|
||||
jmp PUNCH ;write character to punch device
|
||||
jmp READER ;return char from reader device
|
||||
jmp HOME ;move to trk 00 on cur sel drive
|
||||
jmp SELDSK ;select disk for next rd/write
|
||||
jmp SETTRK ;set track for next rd/write
|
||||
jmp SETSEC ;set sector for next rd/write
|
||||
jmp SETDMA ;set offset for user buff (DMA)
|
||||
jmp READ ;read a 128 byte sector
|
||||
jmp WRITE ;write a 128 byte sector
|
||||
jmp LISTST ;return list status
|
||||
jmp SECTRAN ;xlate logical->physical sector
|
||||
jmp SETDMAB ;set seg base for buff (DMA)
|
||||
jmp GETSEGT ;return offset of Mem Desc Table
|
||||
jmp GETIOBF ;return I/O map byte (IOBYTE)
|
||||
jmp SETIOBF ;set I/O map byte (IOBYTE)
|
||||
|
||||
;*********************************************
|
||||
;* *
|
||||
;* INIT Entry Point, Differs for LDBIOS and *
|
||||
;* BIOS, according to "Loader_Bios" value *
|
||||
;* *
|
||||
;*********************************************
|
||||
|
||||
INIT: ;initialize hardware
|
||||
mov ax,cs ;we entered with a JMPF so use
|
||||
mov ss,ax ; CS: as the initial value of SS:,
|
||||
mov ds,ax ; DS:,
|
||||
mov es,ax ; and ES:
|
||||
;use local stack during initialization
|
||||
mov sp,offset stkbase
|
||||
cld ;set forward direction
|
||||
|
||||
push ds ;save data segment
|
||||
mov ax,0
|
||||
mov ds,ax ;point to segment zero
|
||||
;BDOS interrupt offset
|
||||
mov bdos_offset,bdos_ofst
|
||||
mov bdos_segment,CS ;bdos interrupt segment
|
||||
pop ds ;restore data segment
|
||||
|
||||
mov cl,0 ;default to dr A: on coldstart
|
||||
jmp ccp ;jump to cold start entry of CCP
|
||||
|
||||
WBOOT: jmp ccp+6 ;direct entry to CCP at command level
|
||||
|
||||
;*********************************************
|
||||
;* *
|
||||
;* CP/M Character I/O Interface Routines *
|
||||
;* Console is Usart (i8251a) on iSBC 86/12 *
|
||||
;* at ports D8/DA *
|
||||
;* *
|
||||
;*********************************************
|
||||
|
||||
CONST: ;console status
|
||||
in al,csts
|
||||
and al,2
|
||||
jz const_ret
|
||||
or al,255 ;return non-zero if RDA
|
||||
const_ret:
|
||||
ret ;Receiver Data Available
|
||||
|
||||
CONIN: ;console input
|
||||
call const
|
||||
jz CONIN ;wait for RDA
|
||||
in al,cdata
|
||||
and al,7fh ;read data and remove parity bit
|
||||
ret
|
||||
|
||||
CONOUT: ;console output
|
||||
in al,csts
|
||||
and al,1 ;get console status
|
||||
jz CONOUT ;wait for TBE
|
||||
mov al,cl
|
||||
out cdata,al ;Transmitter Buffer Empty
|
||||
ret ;then return data
|
||||
|
||||
LISTOUT: ;list device output
|
||||
LISTST: ;poll list status
|
||||
|
||||
ret
|
||||
|
||||
PUNCH: ;not implemented in this configuration
|
||||
READER:
|
||||
mov al,1ah
|
||||
ret ;return EOF for now
|
||||
|
||||
GETIOBF:
|
||||
mov al,0 ;TTY: for consistency
|
||||
ret ;IOBYTE not implemented
|
||||
|
||||
SETIOBF:
|
||||
ret ;iobyte not implemented
|
||||
|
||||
zero_ret:
|
||||
and al,0
|
||||
ret ;return zero in AL and flags
|
||||
|
||||
; Routine to get and echo a console character
|
||||
; and shift it to upper case
|
||||
|
||||
uconecho:
|
||||
call CONIN ;get a console character
|
||||
push ax
|
||||
mov cl,al ;save and
|
||||
call CONOUT
|
||||
pop ax ;echo to console
|
||||
cmp al,'a'
|
||||
jb uret ;less than 'a' is ok
|
||||
cmp al,'z'
|
||||
ja uret ;greater than 'z' is ok
|
||||
sub al,'a'-'A' ;else shift to caps
|
||||
uret:
|
||||
ret
|
||||
|
||||
; utility subroutine to print messages
|
||||
|
||||
pmsg:
|
||||
mov al,[BX] ;get next char from message
|
||||
test al,al
|
||||
jz return ;if zero return
|
||||
mov CL,AL
|
||||
call CONOUT ;print it
|
||||
inc BX
|
||||
jmps pmsg ;next character and loop
|
||||
|
||||
;*********************************************
|
||||
;* *
|
||||
;* Disk Input/Output Routines *
|
||||
;* *
|
||||
;*********************************************
|
||||
|
||||
SELDSK: ;select disk given by register CL
|
||||
mov bx,0000h
|
||||
cmp cl,2 ;this BIOS only supports 2 disks
|
||||
jnb return ;return w/ 0000 in BX if bad drive
|
||||
mov al, 80h
|
||||
cmp cl,0
|
||||
jne sel1 ;drive 1 if not zero
|
||||
mov al, 40h ;else drive is 0
|
||||
sel1: mov sel_mask,al ;save drive select mask
|
||||
;now, we need disk parameter address
|
||||
mov ch,0
|
||||
mov bx,cx ;BX = word(CL)
|
||||
mov cl,4
|
||||
shl bx,cl ;multiply drive code * 16
|
||||
;create offset from Disk Parameter Base
|
||||
add bx,offset dp_base
|
||||
return:
|
||||
ret
|
||||
|
||||
HOME: ;move selected disk to home position (Track 0)
|
||||
mov trk,0 ;set disk i/o to track zero
|
||||
mov bx,offset hom_com
|
||||
call execute
|
||||
jz return ;home drive and return if OK
|
||||
mov bx,offset bad_hom ;else print
|
||||
call pmsg ;"Home Error"
|
||||
jmps home ;and retry
|
||||
|
||||
SETTRK: ;set track address given by CX
|
||||
mov trk,cl ;we only use 8 bits of track address
|
||||
ret
|
||||
|
||||
SETSEC: ;set sector number given by cx
|
||||
mov sect,cl ;we only use 8 bits of sector address
|
||||
ret
|
||||
|
||||
SECTRAN: ;translate sector CX using table at [DX]
|
||||
mov bx,cx
|
||||
add bx,dx ;add sector to tran table address
|
||||
mov bl,[bx] ;get logical sector
|
||||
ret
|
||||
|
||||
SETDMA: ;set DMA offset given by CX
|
||||
mov dma_adr,CX
|
||||
ret
|
||||
|
||||
SETDMAB: ;set DMA segment given by CX
|
||||
mov dma_seg,CX
|
||||
ret
|
||||
;
|
||||
GETSEGT: ;return address of physical memory table
|
||||
mov bx,offset seg_table
|
||||
ret
|
||||
|
||||
;*********************************************
|
||||
;* *
|
||||
;* All disk I/O parameters are setup: the *
|
||||
;* Read and Write entry points transfer one *
|
||||
;* sector of 128 bytes to/from the current *
|
||||
;* DMA address using the current disk drive *
|
||||
;* *
|
||||
;*********************************************
|
||||
|
||||
READ:
|
||||
mov al,12h ;basic read sector command
|
||||
jmps r_w_common
|
||||
|
||||
WRITE:
|
||||
mov al,0ah ;basic write sector command
|
||||
|
||||
r_w_common:
|
||||
mov bx,offset io_com ;point to command string
|
||||
mov byte ptr 1[BX],al ;put command into string
|
||||
; fall into execute and return
|
||||
|
||||
execute: ;execute command string.
|
||||
;[BX] points to length,
|
||||
; followed by Command byte,
|
||||
; followed by length-1 parameter bytes
|
||||
|
||||
mov last_com,BX ;save command address for retries
|
||||
outer_retry:
|
||||
;allow some retrying
|
||||
mov rtry_cnt,max_retries
|
||||
retry:
|
||||
mov BX,last_com
|
||||
call send_com ;transmit command to i8271
|
||||
; check status poll
|
||||
|
||||
mov BX,last_com
|
||||
mov al,1[bx] ;get command op code
|
||||
mov cx,0800h ;mask if it will be "int req"
|
||||
cmp al,2ch
|
||||
jb exec_poll ;ok if it is an interrupt type
|
||||
mov cx,8080h ;else we use "not command busy"
|
||||
and al,0fh
|
||||
cmp al,0ch ;unless there isn't
|
||||
mov al,0
|
||||
ja exec_exit ; any result
|
||||
;poll for bits in CH,
|
||||
exec_poll: ; toggled with bits in CL
|
||||
|
||||
in al,fdc_stat ;read status
|
||||
and al,ch
|
||||
xor al,cl ; isolate what we want to poll
|
||||
jz exec_poll ;and loop until it is done
|
||||
|
||||
;Operation complete,
|
||||
in al,fdc_rslt ; see if result code indicates error
|
||||
and al,1eh
|
||||
jz exec_exit ;no error, then exit
|
||||
;some type of error occurred . . .
|
||||
cmp al,10h
|
||||
je dr_nrdy ;was it a not ready drive ?
|
||||
;no,
|
||||
dr_rdy: ; then we just retry read or write
|
||||
dec rtry_cnt
|
||||
jnz retry ; up to 10 times
|
||||
|
||||
; retries do not recover from the
|
||||
; hard error
|
||||
|
||||
mov ah,0
|
||||
mov bx,ax ;make error code 16 bits
|
||||
mov bx,errtbl[BX]
|
||||
call pmsg ;print appropriate message
|
||||
in al,cdata ;flush usart receiver buffer
|
||||
call uconecho ;read upper case console character
|
||||
cmp al,'C'
|
||||
je wboot_l ;cancel
|
||||
cmp al,'R'
|
||||
je outer_retry ;retry 10 more times
|
||||
cmp al,'I'
|
||||
je z_ret ;ignore error
|
||||
or al,255 ;set code for permanent error
|
||||
exec_exit:
|
||||
ret
|
||||
|
||||
dr_nrdy: ;here to wait for drive ready
|
||||
call test_ready
|
||||
jnz retry ;if it's ready now we are done
|
||||
call test_ready
|
||||
jnz retry ;if not ready twice in row,
|
||||
mov bx,offset nrdymsg
|
||||
call pmsg ;"Drive Not Ready"
|
||||
nrdy01:
|
||||
call test_ready
|
||||
jz nrdy01 ;now loop until drive ready
|
||||
jmps retry ;then go retry without decrement
|
||||
zret:
|
||||
and al,0
|
||||
ret ;return with no error code
|
||||
|
||||
wboot_l: ;can't make it w/ a short leap
|
||||
jmp WBOOT
|
||||
|
||||
;*********************************************
|
||||
;* *
|
||||
;* The i8271 requires a read status command *
|
||||
;* to reset a drive-not-ready after the *
|
||||
;* drive becomes ready *
|
||||
;* *
|
||||
;*********************************************
|
||||
|
||||
test_ready:
|
||||
mov dh, 40h ;proper mask if dr 1
|
||||
test sel_mask,80h
|
||||
jnz nrdy2
|
||||
mov dh, 04h ;mask for dr 0 status bit
|
||||
nrdy2:
|
||||
mov bx,offset rds_com
|
||||
call send_com
|
||||
dr_poll:
|
||||
in al,fdc_stat ;get status word
|
||||
test al,80h
|
||||
jnz dr_poll ;wait for not command busy
|
||||
in al,fdc_rslt ;get "special result"
|
||||
test al,dh ;look at bit for this drive
|
||||
ret ;return status of ready
|
||||
|
||||
;*********************************************
|
||||
;* *
|
||||
;* Send_com sends a command and parameters *
|
||||
;* to the i8271: BX addresses parameters. *
|
||||
;* The DMA controller is also initialized *
|
||||
;* if this is a read or write *
|
||||
;* *
|
||||
;*********************************************
|
||||
|
||||
send_com:
|
||||
in al,fdc_stat
|
||||
test al,80h ;insure command not busy
|
||||
jnz send_com ;loop until ready
|
||||
|
||||
;see if we have to initialize for a DMA operation
|
||||
|
||||
mov al,1[bx] ;get command byte
|
||||
cmp al,12h
|
||||
jne write_maybe ;if not a read it could be write
|
||||
mov cl,40h
|
||||
jmps init_dma ;is a read command, go set DMA
|
||||
write_maybe:
|
||||
cmp al,0ah
|
||||
jne dma_exit ;leave DMA alone if not read or write
|
||||
mov cl,80h ;we have write, not read
|
||||
init_dma:
|
||||
;we have a read or write operation, setup DMA controller
|
||||
; (CL contains proper direction bit)
|
||||
mov al,04h
|
||||
out dmac_mode,al ;enable dmac
|
||||
mov al,00
|
||||
out dmac_cont,al ;send first byte to control port
|
||||
mov al,cl
|
||||
out dmac_cont,al ;load direction register
|
||||
mov ax,dma_adr
|
||||
out dmac_adr,al ;send low byte of DMA
|
||||
mov al,ah
|
||||
out dmac_adr,al ;send high byte
|
||||
mov ax,dma_seg
|
||||
out fdc_segment,al ;send low byte of segment address
|
||||
mov al,ah
|
||||
out fdc_segment,al ;then high segment address
|
||||
dma_exit:
|
||||
mov cl,[BX] ;get count
|
||||
inc BX
|
||||
mov al,[BX] ;get command
|
||||
or al,sel_mask ;merge command and drive code
|
||||
out fdc_com,al ;send command byte
|
||||
parm_loop:
|
||||
dec cl
|
||||
jz exec_exit ;no (more) parameters, return
|
||||
inc BX ;point to (next) parameter
|
||||
parm_poll:
|
||||
in al,fdc_stat
|
||||
test al,20h ;test "parameter register full" bit
|
||||
jnz parm_poll ;idle until parm reg not full
|
||||
mov al,[BX]
|
||||
out fdc_parm,al ;send next parameter
|
||||
jmps parm_loop ;go see if there are more parameters
|
||||
|
||||
;*********************************************
|
||||
;* *
|
||||
;* Data Areas *
|
||||
;* *
|
||||
;*********************************************
|
||||
data_offset equ offset $
|
||||
|
||||
dseg
|
||||
org data_offset ;contiguous with code segment
|
||||
|
||||
signon db cr,lf,cr,lf
|
||||
db 'MP/M-86 Loader 2.0',cr,lf,0
|
||||
|
||||
bad_hom db cr,lf,'Home Error',cr,lf,0
|
||||
int_trp db cr,lf,'Interrupt Trap Halt',cr,lf,0
|
||||
|
||||
errtbl dw er0,er1,er2,er3
|
||||
dw er4,er5,er6,er7
|
||||
dw er8,er9,erA,erB
|
||||
dw erC,erD,erE,erF
|
||||
|
||||
er0 db cr,lf,'Null Error ??',0
|
||||
er1 equ er0
|
||||
er2 equ er0
|
||||
er3 equ er0
|
||||
er4 db cr,lf,'Clock Error :',0
|
||||
er5 db cr,lf,'Late DMA :',0
|
||||
er6 db cr,lf,'ID CRC Error :',0
|
||||
er7 db cr,lf,'Data CRC Error :',0
|
||||
er8 db cr,lf,'Drive Not Ready :',0
|
||||
er9 db cr,lf,'Write Protect :',0
|
||||
erA db cr,lf,'Trk 00 Not Found :',0
|
||||
erB db cr,lf,'Write Fault :',0
|
||||
erC db cr,lf,'Sector Not Found :',0
|
||||
erD equ er0
|
||||
erE equ er0
|
||||
erF equ er0
|
||||
nrdymsg equ er8
|
||||
|
||||
rtry_cnt db 0 ;disk error retry counter
|
||||
last_com dw 0 ;address of last command string
|
||||
dma_adr dw 0 ;dma offset stored here
|
||||
dma_seg dw 0 ;dma segment stored here
|
||||
sel_mask db 40h ;select mask, 40h or 80h
|
||||
|
||||
; Various command strings for i8271
|
||||
|
||||
io_com db 3 ;length
|
||||
rd_wr db 0 ;read/write function code
|
||||
trk db 0 ;track #
|
||||
sect db 0 ;sector #
|
||||
|
||||
hom_com db 2,29h,0 ;home drive command
|
||||
rds_com db 1,2ch ;read status command
|
||||
|
||||
; System Memory Segment Table
|
||||
|
||||
segtable db 1 ;1 segment
|
||||
dw tpa_seg ;seg starts after BIOS
|
||||
dw tpa_len ;and extends to 20000
|
||||
|
||||
; DISKS 2
|
||||
dpbase equ $ ;Base of Disk Parameter Blocks
|
||||
dpe0 dw xlt0,0000h ;Translate Table
|
||||
dw 0000h,0000h ;Scratch Area
|
||||
dw dirbuf,dpb0 ;Dir Buff, Parm Block
|
||||
dw csv0,alv0 ;Check, Alloc Vectors
|
||||
dpe1 dw xlt1,0000h ;Translate Table
|
||||
dw 0000h,0000h ;Scratch Area
|
||||
dw dirbuf,dpb1 ;Dir Buff, Parm Block
|
||||
dw csv1,alv1 ;Check, Alloc Vectors
|
||||
; DISKDEF 0,1,26,6,1024,243,64,64,2
|
||||
;
|
||||
; 1944: 128 Byte Record Capacity
|
||||
; 243: Kilobyte Drive Capacity
|
||||
; 64: 32 Byte Directory Entries
|
||||
; 64: Checked Directory Entries
|
||||
; 128: Records / Extent
|
||||
; 8: Records / Block
|
||||
; 26: Sectors / Track
|
||||
; 2: Reserved Tracks
|
||||
; 6: Sector Skew Factor
|
||||
;
|
||||
dpb0 equ offset $ ;Disk Parameter Block
|
||||
dw 26 ;Sectors Per Track
|
||||
db 3 ;Block Shift
|
||||
db 7 ;Block Mask
|
||||
db 0 ;Extnt Mask
|
||||
dw 242 ;Disk Size - 1
|
||||
dw 63 ;Directory Max
|
||||
db 192 ;Alloc0
|
||||
db 0 ;Alloc1
|
||||
dw 16 ;Check Size
|
||||
dw 2 ;Offset
|
||||
xlt0 equ offset $ ;Translate Table
|
||||
db 1,7,13,19
|
||||
db 25,5,11,17
|
||||
db 23,3,9,15
|
||||
db 21,2,8,14
|
||||
db 20,26,6,12
|
||||
db 18,24,4,10
|
||||
db 16,22
|
||||
als0 equ 31 ;Allocation Vector Size
|
||||
css0 equ 16 ;Check Vector Size
|
||||
; DISKDEF 1,0
|
||||
;
|
||||
; Disk 1 is the same as Disk 0
|
||||
;
|
||||
dpb1 equ dpb0 ;Equivalent Parameters
|
||||
als1 equ als0 ;Same Allocation Vector Size
|
||||
css1 equ css0 ;Same Checksum Vector Size
|
||||
xlt1 equ xlt0 ;Same Translate Table
|
||||
; ENDEF
|
||||
;
|
||||
; Uninitialized Scratch Memory Follows:
|
||||
;
|
||||
begdat equ offset $ ;Start of Scratch Area
|
||||
dirbuf rs 128 ;Directory Buffer
|
||||
alv0 rs als0 ;Alloc Vector
|
||||
csv0 rs css0 ;Check Vector
|
||||
alv1 rs als1 ;Alloc Vector
|
||||
csv1 rs css1 ;Check Vector
|
||||
enddat equ offset $ ;End of Scratch Area
|
||||
datsiz equ offset $-begdat ;Size of Scratch Area
|
||||
db 0 ;Marks End of Module
|
||||
|
||||
loc_stk rw 32 ;local stack for initialization
|
||||
stkbase equ offset $
|
||||
|
||||
lastoff equ offset $
|
||||
tpa_seg equ (lastoff+0400h+15) / 16
|
||||
tpa_len equ 2000h - tpa_seg
|
||||
db 0 ;fill last address for GENCMD
|
||||
|
||||
;*********************************************
|
||||
;* *
|
||||
;* Dummy Data Section *
|
||||
;* *
|
||||
;*********************************************
|
||||
dseg 0 ;absolute low memory
|
||||
org 0 ;(interrupt vectors)
|
||||
int0_offset rw 1
|
||||
int0_segment rw 1
|
||||
; pad to system call vector
|
||||
rw 2*(bdos_int-1)
|
||||
|
||||
bdos_offset rw 1
|
||||
bdos_segment rw 1
|
||||
END
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
:0400000300001200E7
|
||||
:1B120081E93C00E95B00E95B00E96100E96800E97000E96E00E96B00E9B60067
|
||||
:1B121B81E99200E9C500E9C700E9D000E9DB00E9DC00E95200E9BD00E9C6008C
|
||||
:1B123681E9C800E94A00E94A008CC88ED08ED88EC0BC8A16FC1EB800008ED80B
|
||||
:1B125181C706800306048C0E82031FB100E9A2EEE9A5EEE4DA240274020CFF5E
|
||||
:1B126C81C3E8F4FF74FBE4D8247FC3E4DA240174FA8AC1E6D8C3C3B01AC3B09A
|
||||
:1B12878100C3C32400C3E8DDFF508AC8E8E1FF583C6172063C7A77022C20C385
|
||||
:1B12A2818A0784C074288AC8E8CAFF43EBF2BB000080F9027318B08080F900B2
|
||||
:1B12BD817502B040A21315B5008BD9B104D3E381C32215C3C606161500BB18D8
|
||||
:1B12D88115E8350074F2BB1414E8BEFFEBEB880E1615C3880E1715C38BD90314
|
||||
:1B12F381DA8A1FC3890E0F15C3890E1115C3BB1D15C3B012EB02B00ABB14151E
|
||||
:1B130E81884701891E0D15C6060C150A8B1E0D15E889008B1E0D158A4701B921
|
||||
:1B13298100083C2C720BB98080240F3C0CB0007736E4A022C532C174F8E4A15B
|
||||
:1B134481241E74283C107425FE0E0C1575C8B4008BD88B9F3B14E845FFE4D868
|
||||
:1B135F81E82BFF3C4374253C5274AB3C49741A0CFFC3E81A0075A4E8150075AD
|
||||
:1B137A819FBBAC14E821FFE80A0074FBEB922400C3E9D3FEB640F6061315809C
|
||||
:1B1395817502B604BB1B15E80B00E4A0A88075FAE4A184C6C3E4A0A88075FAE5
|
||||
:1B13B0818A47013C127504B140EB063C0A7520B180B004E6A8B000E6A58AC152
|
||||
:1B13CB81E6A5A10F15E6A48AC4E6A4A11115E6AA8AC4E6AA8A0F438A070A0622
|
||||
:1513E6811315E6A0FEC9748243E4A0A82075FA8A07E6A1EBEF16
|
||||
:1B13FB820D0A0D0A4D502F4D2D3836204C6F6164657220322E300D0A000D0A1E
|
||||
:1B141682486F6D65204572726F720D0A000D0A496E74657272757074205472A5
|
||||
:1B14318261702048616C740D0A005B145B145B145B146B147B1488149914ACCE
|
||||
:1B144C8214C014D214E714F7145B145B145B140D0A4E756C6C204572726F7206
|
||||
:1B146782203F3F000D0A436C6F636B204572726F72203A000D0A4C6174652006
|
||||
:1B148282444D41203A000D0A494420435243204572726F72203A000D0A4461C5
|
||||
:1B149D82746120435243204572726F72203A000D0A4472697665204E6F7420DF
|
||||
:1B14B8825265616479203A000D0A57726974652050726F74656374203A000DBE
|
||||
:1B14D3820A54726B203030204E6F7420466F756E64203A000D0A5772697465D8
|
||||
:1B14EE82204661756C74203A000D0A536563746F72204E6F7420466F756E64F7
|
||||
:1B150982203A00000000000000004003000000022900012C01A901571E5115CA
|
||||
:1B1524820000000000006B1542150A16EB1551150000000000006B15421539BD
|
||||
:1B153F82161A161A00030700F2003F00C0001000020001070D1319050B111729
|
||||
:11155A8203090F1502080E141A060C1218040A101618
|
||||
:01164982001E
|
||||
:01168A8200DD
|
||||
:02000086000078
|
||||
:00000001FF
|
||||
|
||||
:1B14B8825265616479203A000D0A577269746520
|
||||
321
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LDMPM.A86
Normal file
321
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LDMPM.A86
Normal file
@@ -0,0 +1,321 @@
|
||||
title 'MP /M-86 Loader'
|
||||
|
||||
; The MPMLDR consists of this module along with the
|
||||
; LDBDOS and LDBIOS. The LDBDOS is the same as for
|
||||
; for CP/M-86, and the LDBIOS has only the login message
|
||||
; changed.
|
||||
|
||||
; MPMLDR resides on the first two tracks of a
|
||||
; MP/M-86 system diskette and is brought into memory
|
||||
; by the ROM bootstrap loader to load initiate MP/M-86
|
||||
|
||||
; It opens the file 'MPM.SYS' using the LDBDOS and LDBIOS
|
||||
; and then reads it into memory. The DS register is set
|
||||
; to the start of the MPM DATA area, and a JMPF to the
|
||||
; first byte of the MPM code is executed.
|
||||
|
||||
; The first 128 byte record of the MPM.SYS file is a header
|
||||
; with the following format:
|
||||
|
||||
; ty rb 1 ;seg type
|
||||
; len rw 1 ;length
|
||||
; abs dw 1 ;absolute segment address for LOADER
|
||||
; min rw 1 ;minimum mem
|
||||
; max rw 1 ;max mem needed
|
||||
|
||||
; The code is expected first and then the data within MPM.SYS
|
||||
; This header record is constructed automatically by the
|
||||
; GENSYS-86 utility. See the variables declared at 'SEC1:'
|
||||
; where the first sector of MPM.SYS will be read
|
||||
|
||||
; MPMLDR may be read into any segment that does not
|
||||
; overlap the desired system load segment as it makes
|
||||
; all memory references using copies of the CS: register
|
||||
; it is entered with.
|
||||
;
|
||||
; For debugging under CP/M and DDT a 'IB' can be used to force a
|
||||
; break to DDT just before 'Far Jumping' to MPM.
|
||||
;
|
||||
false equ 0
|
||||
true equ not false
|
||||
|
||||
cr equ 0dh
|
||||
lf equ 0ah
|
||||
|
||||
ldbdos_offset equ 406H ;offset of LDBDOS
|
||||
mldbios_offset equ 1200h ;offset of LDBIOS
|
||||
bdos_int equ 224 ;lbdos interrupt number
|
||||
|
||||
bootdrv equ 0 ; boot drive always zero
|
||||
codetype equ 1 ; code type CMD header
|
||||
datatype equ 2 ; data type CMD header
|
||||
|
||||
; dummy section for interrupt vectors
|
||||
|
||||
dseg 0
|
||||
org 0
|
||||
abs_zero rw 2*bdosint
|
||||
bdos_offset rw 1
|
||||
bdos_segment rw 1
|
||||
|
||||
fcb1 equ 5dh ; look here for 'B' to break
|
||||
ddt_int equ 3 ; DDT interrupt
|
||||
|
||||
; bdos function numbers
|
||||
|
||||
coutf equ 2
|
||||
pstrf equ 9
|
||||
seldsk equ 14
|
||||
openf equ 15
|
||||
readsf equ 20
|
||||
dmaf equ 26
|
||||
dmabf equ 51
|
||||
|
||||
|
||||
;*******************************
|
||||
;*
|
||||
;* MPMLDR starts here
|
||||
;*
|
||||
;*******************************
|
||||
|
||||
cseg ; JMPF to here from boot ROM
|
||||
org 0
|
||||
jmp start ; if loaded under DDT this
|
||||
; gets overlayed and IP = 100H
|
||||
; want 100h byte header for
|
||||
; 'IB' option
|
||||
|
||||
db 'COPYRIGHT (C) 1981,' ; found by serial program
|
||||
db ' DIGITAL RESEARCH '
|
||||
db '654321'
|
||||
db ' MP/M-86 Loader V2.0 (9/21/81)'
|
||||
|
||||
org 80H ; read first sector of MPM.SYS
|
||||
sec1 rb 128 ; here
|
||||
|
||||
org offset sec1 ;CMD header fields
|
||||
ctype rb 1 ;type
|
||||
clen rw 1 ;length
|
||||
cldseg rw 1 ;abs
|
||||
cmin rw 1 ;minimum
|
||||
cmax rw 1 ;maximum
|
||||
dtype rb 1
|
||||
dlen rw 1
|
||||
dldseg rw 1
|
||||
dmin rw 1
|
||||
dmax rw 1
|
||||
|
||||
org 100H
|
||||
start: ; execution begins here if DDT
|
||||
jmp mldbios ; initialize mldbios
|
||||
; mldbios returns here: 103H
|
||||
xor ax,ax ! mov ds,ax ; temp DS at absolute zero
|
||||
mov bdos_offset,offset ldbdos_offset ; to patch in interrupt table
|
||||
mov bdos_segment,cs ; offset and segment
|
||||
mov ax,cs ! mov ss,ax ; make ss, ds, es = cs
|
||||
mov ds,ax ! mov es,ax
|
||||
mov sp,offset(stack) ; set up local stack
|
||||
|
||||
mov dx,offset signon
|
||||
call msg
|
||||
call initlbdos ; warm up lbdos and lbios
|
||||
call openfnc ; open MPM.SYS
|
||||
cmp al,255 ! jne perr ; insure good file
|
||||
mov dx,offset nofile ! call msg ; no MPM.SYS file
|
||||
jmp stop ; then halt the machine
|
||||
perr:
|
||||
mov dx,cs ! call setdmab
|
||||
mov dx,offset sec1 ! call setdma ; read first sector of MPM.SYS
|
||||
call read
|
||||
cmp ctype,codetype ; code should be first
|
||||
jnz badhdr
|
||||
cmp dtype,datatype ; then data
|
||||
jnz badhdr
|
||||
mov ax,cldseg ; code abs + code length
|
||||
add ax,clen ; should be = to data abs
|
||||
cmp ax,dldseg ! jnz badhdr
|
||||
add ax,dlen ! cmp ax,cldseg ; check for wrap around
|
||||
ja hdrok
|
||||
badhdr:
|
||||
mov dx,offset hdrerr ! call msg
|
||||
jmp stop
|
||||
hdrok:
|
||||
mov dx,offset csegment ! call msg ; put memory map on console
|
||||
mov ax,cldseg ! call phex ; print base code segment
|
||||
mov dx,offset dsegment ! call msg ; print base data segment
|
||||
mov ax,dldseg ! call phex
|
||||
;
|
||||
mov dx,cldseg
|
||||
mov dmab,dx ; initial DMA segment
|
||||
readit1:
|
||||
call setdmab ; set DMA segment for disk IO
|
||||
mov dx,0 ; offset of MPM in segment
|
||||
readit2:
|
||||
call setdma ; set DMA offset for
|
||||
push dx ! call read ; next sector read
|
||||
cmp al,01H ! je done ; check for EOF
|
||||
cmp al,0 ! je prerr ; check for good write
|
||||
mov dx,offset rerr ! call msg ; print READ ERROR message
|
||||
jmp stop ; hard stop on any error
|
||||
|
||||
prerr: pop dx ! add dx,80H
|
||||
cmp dx,0 ; more than 64K ?
|
||||
jnz readit2
|
||||
add dmab,1000h ; add 64K to base
|
||||
mov dx,dmab
|
||||
jmp readit1
|
||||
done:
|
||||
pop ax ; number of bytes read
|
||||
mov cl,4
|
||||
shr ax,cl ; number of paragraphs read
|
||||
add ax,dmab ; number of 64K segments read
|
||||
sub ax,cldseg ; (dmab - cldseg)
|
||||
mov cx,clen
|
||||
add cx,dlen
|
||||
cmp ax,cx
|
||||
jae lenok ; MPM.SYS at least as long
|
||||
mov dx,offset shortmsg ; as header claims ?
|
||||
call msg ! jmp stop
|
||||
lenok:
|
||||
push cx ; clen + dlen in cx
|
||||
mov dx,offset lenmsg ! call msg ; print length message
|
||||
pop ax
|
||||
add ax,cldseg
|
||||
dec ax ; last paragraph
|
||||
call phex
|
||||
call pcrlf ; and a crlf
|
||||
|
||||
mov ax,cldseg
|
||||
mov mpmcseg,ax
|
||||
mov ds,dldseg ; MP/M data segment
|
||||
|
||||
mov al, cs:.fcb1 ; must use CS over-ride
|
||||
cmp al,'B'
|
||||
jnz gompm
|
||||
int ddt_int ; break to mpm
|
||||
gompm:
|
||||
jmpf mpm ; leap to MPM initialization
|
||||
|
||||
;*****************************
|
||||
;*
|
||||
;* subroutines
|
||||
;*
|
||||
;*****************************
|
||||
|
||||
;******
|
||||
phex: ;print 4 hex characters from ax
|
||||
mov cx,0404h ; 4 in both CH and CL
|
||||
lhex:
|
||||
rol ax,cl ; rotate left 4
|
||||
push cx ! push ax ; save crucial registers
|
||||
call pnib ; print hex nibble
|
||||
pop ax ! pop cx ; restore registers
|
||||
dec ch ! jnz lhex ; and loop four times
|
||||
ret
|
||||
pnib: ;print low nibble in AL as hex char
|
||||
and al,0fh ! cmp al,9
|
||||
ja p10 ;above 9 ?
|
||||
add al,'0' ;digit
|
||||
jmp prn
|
||||
p10: add al,'A'-10 ;char a-e
|
||||
prn: mov dl,al
|
||||
|
||||
;******
|
||||
putchar:
|
||||
mov cl,coutf
|
||||
jmp sys_vec
|
||||
|
||||
;******
|
||||
initlbdos:
|
||||
mov cl,seldsk ! mov dx,bootdrv ; select boot disk
|
||||
jmp sys_vec
|
||||
|
||||
;******
|
||||
openfnc:
|
||||
mov cl,openf ! mov dx,offset fcb ; fcb already initialized
|
||||
mov cl,openf
|
||||
jmp sys_vec
|
||||
|
||||
;********
|
||||
;
|
||||
setdma: ;set new dma addr in dx
|
||||
mov cl,dmaf
|
||||
jmp sys_vec
|
||||
|
||||
;********
|
||||
;
|
||||
setdmab: ; set new dma segment base from DX
|
||||
mov cl,dmabf
|
||||
jmp sys_vec
|
||||
|
||||
;******
|
||||
;
|
||||
pcrlf: mov dx,offset crlf ;print carriage return, line feed
|
||||
|
||||
;******
|
||||
;
|
||||
msg: ;print msg starting at dx until $
|
||||
mov cl,pstrf ;print string function
|
||||
jmp sys_vec
|
||||
|
||||
;*****
|
||||
;
|
||||
read:
|
||||
mov dx,offset fcb ! mov cl,readsf
|
||||
; jmp sys_vec
|
||||
|
||||
;******
|
||||
;
|
||||
sys_vec:
|
||||
int bdos_int
|
||||
ret
|
||||
|
||||
;******
|
||||
;
|
||||
stop: mov ax,0 ; hard stop 8086 for error
|
||||
mov ds,ax
|
||||
mov word ptr .8h,ax
|
||||
mov word ptr .0ah,cs
|
||||
stop2:
|
||||
jmp stop2
|
||||
|
||||
;********************************
|
||||
;*
|
||||
;* DATA AREA
|
||||
;*
|
||||
;********************************
|
||||
|
||||
signon db cr,lf,lf,'MP/M-86 V2.0 Loader',cr,lf,'$'
|
||||
nofile db cr,lf,'The File MPM.SYS Not Found On This Disk$'
|
||||
rerr db cr,lf,'Error In Reading MPM.SYS$'
|
||||
hdrerr db cr,lf,'Bad Header Record in MPM.SYS$'
|
||||
shortmsg db cr,lf,'MPM.SYS Too Short $'
|
||||
csegment db cr,lf,'Code Paragraph Address = $'
|
||||
dsegment db cr,lf,'Data Paragraph Address = $'
|
||||
lenmsg db cr,lf,'Last Paragragh = $'
|
||||
crlf db cr,lf,'$'
|
||||
|
||||
|
||||
; vector for jmpf indirect to start MP/M
|
||||
|
||||
mpm dd abs_zero ; (dummy value)
|
||||
org offset mpm ; overlay preceding with DW's
|
||||
mpmstart dw 0 ; first word of MPM code
|
||||
mpmcseg rw 1 ; second is segmet of MPM code
|
||||
|
||||
dmab rw 1 ; current DMA segment
|
||||
fcb db 0,'MPM ','SYS',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
; look on m disk first
|
||||
|
||||
org (offset $+1) and 0FFFEh ; even address for stack
|
||||
rw 32
|
||||
stack equ offset $
|
||||
db 0
|
||||
|
||||
; dummy section for BIOS init label
|
||||
|
||||
org mldbios_offset
|
||||
mldbios:
|
||||
|
||||
end
|
||||
|
||||
37
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LDMPM.H86
Normal file
37
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LDMPM.H86
Normal file
@@ -0,0 +1,37 @@
|
||||
:02000086000078
|
||||
:0400000300000000F9
|
||||
:1B000081E9FD00434F505952494748542028432920313938312C2044494749B5
|
||||
:1B001B8154414C20524553454152434820363534333231204D502F4D2D3836D2
|
||||
:16003681204C6F616465722056322E302028392F32312F383129E2
|
||||
:1B010081E9FD1033C08ED8C706800306048C0E82038CC88ED08ED88EC0BCD8A1
|
||||
:1B011B8103BA8802E84A01E82801E82D013CFF7509BAA102E83A01E944018CB4
|
||||
:1B013681CAE82A01BA8000E81F01E82E012E803E80000175242E803E8900027A
|
||||
:1B015181751C2EA183002E030681002E3B068C00750C2E03068A002E3B068348
|
||||
:1B016C81007709BAE602E8F700E90101BA1A03E8EE002EA18300E8A300BA3691
|
||||
:1B01878103E8E1002EA18C00E896002E8B1683002E89167503E8C500BA000039
|
||||
:1B01A281E8BA0052E8C8003C0174263C007409BACB02E8B500E9BF005A81C224
|
||||
:1B01BD81800083FA0075DE2E8106750300102E8B167503E9C9FF58B104D3E859
|
||||
:1B01D8812E030675032E2B0683002E8B0E81002E030E8A003BC17309BA0503AF
|
||||
:1B01F381E87600E9800051BA5203E86C00582E0306830048E81E00E85C002E23
|
||||
:1B020E81A183002EA373032E8E1E8C002EA05D003C427501CC2EFF2E7103B910
|
||||
:1B0229810404D3C05150E807005859FECD75F3C3240F3C0977050430E9020054
|
||||
:1B02448104378AD0B102E92900B10EBA0000E92100B10FBA7703B10FE917008D
|
||||
:1B025F81B11AE91200B133E90D00BA6E03B109E90500BA7703B114CDE0C3B86F
|
||||
:1B027A8100008ED8A308008C0E0A00E9FDFF0D0A0A4D502F4D2D3836205632D1
|
||||
:1B0295812E30204C6F616465720D0A240D0A5468652046696C65204D504D2EAD
|
||||
:1B02B081535953204E6F7420466F756E64204F6E2054686973204469736B24E2
|
||||
:1B02CB810D0A4572726F7220496E2052656164696E67204D504D2E535953246A
|
||||
:1B02E6810D0A42616420486561646572205265636F726420696E204D504D2E47
|
||||
:1B030181535953240D0A4D504D2E53595320546F6F2053686F727420240D0A32
|
||||
:1B031C81436F6465205061726167726170682041646472657373203D20240D80
|
||||
:1B0337810A44617461205061726167726170682041646472657373203D202469
|
||||
:1B0352810D0A4C617374205061726167726167682020202020202020203D203A
|
||||
:08036D81240D0A2400000000A8
|
||||
:02037181000009
|
||||
:1B037781004D504D202020202053595300000000000000000000000000000061
|
||||
:06039281000000000000E4
|
||||
:0103D88100A3
|
||||
:00000001FF
|
||||
5953246A
|
||||
:1B02E6810D0A42616420486561646572205265636F726420696E204D504D2E47
|
||||
:1B030181535953240D0A4D504D2E53595
|
||||
36
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/MKALL.SUB
Normal file
36
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/MKALL.SUB
Normal file
@@ -0,0 +1,36 @@
|
||||
;
|
||||
; GENERATE XIOS.MPM
|
||||
;
|
||||
a86 xios
|
||||
gencmd xios 8080
|
||||
era xios.mpm
|
||||
ren xios.mpm=xios.cmd
|
||||
vax xios.lst $$atn
|
||||
xref86 xios
|
||||
vax xios.xrf $$atn
|
||||
;
|
||||
; GENERATE LDMPM.H86
|
||||
a86 ldmpm
|
||||
xref86 ldmpm
|
||||
vax ldmpm.lst $$atn
|
||||
vax ldmpm.xrf $$atn
|
||||
;
|
||||
; GENERATE LDBDOS.H86
|
||||
a86 ldbdos
|
||||
xref86 ldbdos
|
||||
vax ldbdos.lst $$atn
|
||||
vax ldbdos.xrf $$atn
|
||||
;
|
||||
; GENERATE LDBIOS.H86
|
||||
;
|
||||
a86 ldbios
|
||||
xref86 ldbios
|
||||
vax ldbios.lst $$atn
|
||||
vax ldbios.xrf $$atn
|
||||
;
|
||||
; GENERATE MPMLDR.CMD
|
||||
;
|
||||
pip mpmldr.h86=ldmpm.h86,ldbdos.h86,ldbios.h86
|
||||
gencmd mpmldr 8080 code[a0400]
|
||||
;
|
||||
|
||||
BIN
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/MPMLDR.CMD
Normal file
BIN
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/MPMLDR.CMD
Normal file
Binary file not shown.
181
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/MPMLDR.H86
Normal file
181
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/MPMLDR.H86
Normal file
@@ -0,0 +1,181 @@
|
||||
:02000086000078
|
||||
:0400000300000000F9
|
||||
:1B000081E9FD00434F505952494748542028432920313938312C2044494749B5
|
||||
:1B001B8154414C20524553454152434820363534333231204D502F4D2D3836D2
|
||||
:16003681204C6F616465722056322E302028392F32312F383129E2
|
||||
:1B010081E9FD1033C08ED8C706800306048C0E82038CC88ED08ED88EC0BCD8A1
|
||||
:1B011B8103BA8802E84A01E82801E82D013CFF7509BAA102E83A01E944018CB4
|
||||
:1B013681CAE82A01BA8000E81F01E82E012E803E80000175242E803E8900027A
|
||||
:1B015181751C2EA183002E030681002E3B068C00750C2E03068A002E3B068348
|
||||
:1B016C81007709BAE602E8F700E90101BA1A03E8EE002EA18300E8A300BA3691
|
||||
:1B01878103E8E1002EA18C00E896002E8B1683002E89167503E8C500BA000039
|
||||
:1B01A281E8BA0052E8C8003C0174263C007409BACB02E8B500E9BF005A81C224
|
||||
:1B01BD81800083FA0075DE2E8106750300102E8B167503E9C9FF58B104D3E859
|
||||
:1B01D8812E030675032E2B0683002E8B0E81002E030E8A003BC17309BA0503AF
|
||||
:1B01F381E87600E9800051BA5203E86C00582E0306830048E81E00E85C002E23
|
||||
:1B020E81A183002EA373032E8E1E8C002EA05D003C427501CC2EFF2E7103B910
|
||||
:1B0229810404D3C05150E807005859FECD75F3C3240F3C0977050430E9020054
|
||||
:1B02448104378AD0B102E92900B10EBA0000E92100B10FBA7703B10FE917008D
|
||||
:1B025F81B11AE91200B133E90D00BA6E03B109E90500BA7703B114CDE0C3B86F
|
||||
:1B027A8100008ED8A308008C0E0A00E9FDFF0D0A0A4D502F4D2D3836205632D1
|
||||
:1B0295812E30204C6F616465720D0A240D0A5468652046696C65204D504D2EAD
|
||||
:1B02B081535953204E6F7420466F756E64204F6E2054686973204469736B24E2
|
||||
:1B02CB810D0A4572726F7220496E2052656164696E67204D504D2E535953246A
|
||||
:1B02E6810D0A42616420486561646572205265636F726420696E204D504D2E47
|
||||
:1B030181535953240D0A4D504D2E53595320546F6F2053686F727420240D0A32
|
||||
:1B031C81436F6465205061726167726170682041646472657373203D20240D80
|
||||
:1B0337810A44617461205061726167726170682041646472657373203D202469
|
||||
:1B0352810D0A4C617374205061726167726167682020202020202020203D203A
|
||||
:08036D81240D0A2400000000A8
|
||||
:02037181000009
|
||||
:1B037781004D504D202020202053595300000000000000000000000000000061
|
||||
:06039281000000000000E4
|
||||
:0103D88100A3
|
||||
:00000001FF
|
||||
:02000085000079
|
||||
:02000085000079
|
||||
:0400000300000400F5
|
||||
:1B040081000000000000E90800E804F604FC0402052EA3CD0D2E8C16CF0D2EFD
|
||||
:1B041B818926D10D8CC88ED08D2685118CD81E065557561616071FA3520F2EAF
|
||||
:1B043681A1CD0DE810005E5F5D071F2E8B26D10D2E8E16CF0DCF8916070F8800
|
||||
:1B04518116350FC706090F0000C606540F0032C0A23F0FA23D0FBB9A0D53809C
|
||||
:1B046C81F929720980E90980F9317201C38AD9B7008ACA03DB2EFFA786040358
|
||||
:1B048781121F06EE051F0612120F121F061F061F0620061F061F061F066D0DC7
|
||||
:1B04A281310D7E0D1F061F061F061F068A0D1F061F061F061F061F06930D1F52
|
||||
:1B04BD81061F061F061F061F061F061F061F061F061F061F062F062F061F069C
|
||||
:1B04D8817E057A057E057E057E057E057E057E058D1EA80FE81D003C03755AFF
|
||||
:1B04F381E90D0D8D1EB30FEB0A8D1EBF0FEB048D1EBA0FE80300E9F70C53E81A
|
||||
:1B050E81F000A0060F0441A2A40F8D0E980FE8EB0059E8E700E9E30C1E50513E
|
||||
:1B052981C606540FFF880E550F32ED8B36070F8936500F8D3EC30F893E070F80
|
||||
:1B0544818E1E520FF3A459581FC351B121EB0351B124E8CDFF59C30650518AAC
|
||||
:1B055F810E550F32ED8E06520F8D36C30F8B3E500F893E070FF3A4595807C3CE
|
||||
:1B057A8189164E0FC3C3A0040F0AC0751EE87C0C240174F1E8780C3C13750D1C
|
||||
:1B059581E8710C3C037503E9640C32C0C3A2040FB001C3A0000F0AC075165122
|
||||
:1B05B081E8CDFF5951E8540C5951803E030F007403E84B0C598AC18D1E020F79
|
||||
:1B05CB813C7F7416FE073C207310FE0F8A070AC074088AC13C087503FE0FC3B0
|
||||
:1B05E6813C0A75FBC60700C380F90975B5B120E8B0FFA0020F240775F4C3B166
|
||||
:1B0601810DE8A3FFB10AE99EFF8BF1AC3C2474EE41518AC81E161FE8D3FF1F8B
|
||||
:1B061C8159EBEBC38BCA1E8E1E520FE8E0FF1FC3A2090FC3B001EBF88D1E0B60
|
||||
:1B06378104FF2751B5008BF28BFBF3A459C38A0E060FE8CF0B83FB00744B8B0A
|
||||
:1B0652811783C302891E120F83C302891E140F83C302891E160F83C30287DA16
|
||||
:1B066D81891E2F0F8D1E180FB108E8C0FF8B161A0F8D1E200FB10FE8B3FFA03C
|
||||
:1B068881260F8D1E3C0FC607FF0AC07403C60700B0FF0AC0C3E8780B33C08BAC
|
||||
:1B06A3811E140F8907C3E87B0BEB03E8790B0AC074E78D1E0904E97CFF8B1E75
|
||||
:1B06BE81490FB102D3EB891E440F891E4B0FA1440FBA0000F736200F528BC82D
|
||||
:1B06D9818B36140F890C030E2D0FE8380B598B162F0FE8420B8BCBE92E0B8D22
|
||||
:1B06F4811E220F8A0FA0420FD2E88AE8B1072A0FA0410FD2E002C5C38B1E0798
|
||||
:1B070F810F83C31003D9803E3C0F0074058A1FB700C303D98B1FC3E8CAFF8AE4
|
||||
:1B072A81C8B500E8DCFF891E440FC38B1E440F0BDBC38A0E220F8B1E440FD3F9
|
||||
:1B074581E3891E460FA0420F2206230F0AD8891E440FC38B1E070F83C30C8AB4
|
||||
:1B07608107C3BA0F000316070FBB110003DAC3E8F0FF8A07A2420F87DA8A0782
|
||||
:1B077B81A2400FE8D7FFA0240F2207A2410FC3E8D5FFA0340F3C02750232C03C
|
||||
:1B0796810206420F880787DAA0400F8807C3B980008B1E180F32C0020743E214
|
||||
:1B07B181FBC3518A0E060FBB0100D3E3590BD9C3A10C0F8A0E060FD3E8240135
|
||||
:1B07CC81C38B0E0C0FE8DFFF891E0C0F8B16270F428B1E120F8917C3E81E0046
|
||||
:1B07E781BA090003DA8A07D0D0731E8D1E0F04E93FFEE8C5FF74128D1E0D0442
|
||||
:1B080281E933FE8B1E180FA0480FB40003D8C38B1E070F83C30E8A07C3E8F3E5
|
||||
:1B081D81FFC60700C3E8ECFF0C808807C38B16490F8B1E120F3B17C3E8F2FF4E
|
||||
:1B08388172FA428917C3522BD38BDA5AC3B1FF8B164B0F8B1E2B0FE8ECFF736D
|
||||
:1B085381E051E84CFF8B1E4B0F031E1C0F59FEC1740D3A07740BE8BEFF7306DF
|
||||
:1B086E81E85CFFC38807C3E8CDFFE81B00B101E82EFEE90600E81000E820FE2C
|
||||
:1B0889818B0E4E0FE8A3098D1E100FEB098CD9E898098D1E180F8B0FE98009BF
|
||||
:1B08A4818B16180F8B1E100FB180068E06520FE884FD07C38D1E490F8A0743F2
|
||||
:1B08BF813A077502FEC0C3BBFFFF891E490FC38B16270F8B1E490F43891E49DE
|
||||
:1B08DA810FE860FF7302EBE4A0490F240351B105D2E059A2480F0AC0754051EE
|
||||
:1B08F581E8C4FDE888FF59E948FF8AD180E207FEC28AF28AC1B103D2C8241FEA
|
||||
:1B0910818AC851B105D2E0590AC88AC5D0C8D0C8D0C8241F8AE88B1E1E0F0370
|
||||
:1B092B81D98A07518ACAD2C059C352E8C6FF24FE590AC1518ACDD2C888075904
|
||||
:1B094681C3E8BBFE83C31051B1115AFEC97501C352803E3C0F00740851538AE9
|
||||
:1B0961810FB500EB07FEC9518B0F43530BC9740B8B1E250F3BD97203E8B9FFA3
|
||||
:1B097C815B4359EBCF8B1E250FB103D3EB438BCB8B1E1E0FC6070043E2FA8BF9
|
||||
:1B09978116290F8B1E1E0F8917E8FAFC8B1E120FC7070300E818FFB1FFE81BD5
|
||||
:1B09B281FFE802FF743BE84AFE803FE574EEA0050F3A07750C438A072C2475CD
|
||||
:1B09CD8105FEC8A2090FB101E86FFFE85AFEEBD1A0330FE949FC518A2E240FB9
|
||||
:1B09E881F6D522CD22C52AC1241F59C3C606330FFF880E370F8B1E070F891E39
|
||||
:1B0A0381380FE8BEFEE892FCB100E8BEFEE8A5FE74648B16380F8BF2AC3CE50C
|
||||
:1B0A1E81740752E806FE5A7352E8DBFDA0370F8AC8B5000AC9742D8BF2AC3CDE
|
||||
:1B0A39813F741E80FD0D741980FD0C8BF2AC74082A07247F75BCEB09518A0F28
|
||||
:1B0A5481E88CFF5975B14243FEC5FEC9EBCFA0490F2403A2090F8D1E330F8AFB
|
||||
:1B0A6F8107D0D0730432C08807C3E84AFEB0FFE9ABFBE875FDB10CE86BFFE8CA
|
||||
:1B0A8A812CFE74EAE853FDE871FDC607E5B100E8ABFEE8D6FDE869FFEBE58B60
|
||||
:1B0AA581D10BC9740C495251E84FFED0D87318595A3B16250F731A4251528B07
|
||||
:1B0AC081CAE83BFED0D873045A59EBDAD0D0FEC0E86BFE5B5AC30BC975CCBB21
|
||||
:1B0ADB810000C3B100B22052B5008B16070F03D1E817FD59E848FBE8C7FBE994
|
||||
:1B0AF6817DFDE8FEFCB10CE8F4FE8B1E070F8A0783C3108807E8AAFD7501C374
|
||||
:1B0B1181E8D0FCB110B20CE8C7FFE8EDFEEBEBB10CE8CFFEE890FD74E6B100CC
|
||||
:1B0B2C81B20CE8B1FFE8D7FEEBEFB10FE8B9FEE87AFD74D0E815FC5053E8BDFD
|
||||
:1B0B4781FC87DA8B1E070FB12052E8E6FAE8CBFC5ABB0C0003DA8A0FBB0F00FB
|
||||
:1B0B628103DA8A2F5B5888073A0F8AC57406B0007202B0808B1E070FBA0F0031
|
||||
:1B0B7D8103DA8807C3833F0075FA8BF2AD8907C333C0A2090FA3490FE829FC4A
|
||||
:1B0B988175F2E874FC248075EBB10FE84EFEE80FFD74E1B91000E854FC03D9E4
|
||||
:1B0BB38187DA8B1E070F03D9B110803E3C0F00741A8A070AC08BF2AC750288CF
|
||||
:1B0BCE81070AC075058A078BFAAA3A077546EB16E8A1FF87DAE89CFF87DA8B2B
|
||||
:1B0BE981F28B043B0775324243FEC94243FEC975C3B9ECFF03D987DA03D98BEE
|
||||
:1B0C0481F2AC3A0772108807B9030003D987DA03D98A078BFAAAC606310FFFC4
|
||||
:1B0C1F81E9D0FEFE0E090FC3E8CFFBFF36070FC706070F0B0FB101E8BBFDE867
|
||||
:1B0C3A817CFC8F06070F74E487DABB0F0003DAB11132C0880743FEC975F9BB25
|
||||
:1B0C55810D0003DA8807E8D7FBE87DFEE9BEFB32C0A2310FE821FFE849FC744E
|
||||
:1B0C7081B58B1E070F83C30C8A07FEC0241F8807740F8AE8A0240F22C522062A
|
||||
:1B0C8B81310F740DEB2683C302FE078A07240F7426B10FE853FDE814FC7511DA
|
||||
:1B0CA681A0320FFEC07415E877FFE805FC740DEB03E886FEE8B2FA32C0E96A8F
|
||||
:1B0CC181F9E86BF9E95AFBC606340F01C606320FFFE89AFAA0420F3A06400FFC
|
||||
:1B0CDC8172143C807524E87FFFC706420F0000803E090F007514E831FAE83D86
|
||||
:1B0CF781FA740CE83FFAE8CCF9E8A6F9E984FAE927F98B1E0E0F8A0E060FD3DC
|
||||
:1B0D1281CB5387DAE82CF95B7503E815F9D0DB72498B0E0E0FE889FA891E0EB4
|
||||
:1B0D2D810FE950FCA0350FA2060FEBD0C6063D0FFF8B1E070F8A07241FFEC820
|
||||
:1B0D4881A2350F3C1E7312A0060FA23E0F8A07A23F0F24E08807E8D0FFA00536
|
||||
:1B0D63810F8B1E070F0A078807C333DB891E0C0F891E0E0F881E060FE98BFF01
|
||||
:1B0D7E81E8CDF7E897FAE8B2FFE9ACFDE8C1F7E8A9FFE935FF8916100FE9EFA6
|
||||
:1B0D9981FA803E3D0F0074198B1E070FC60700A03F0F0AC0740B8807A03E0FEE
|
||||
:190DB481A2350FE877FF803E540FFF7503E897F78B1E090F8AC38AEFC309
|
||||
:02000085000079
|
||||
:060DCD810000000000009F
|
||||
:02000086000078
|
||||
:1B0F00820000000000000000000000E50000000000000000000000000000006F
|
||||
:1B0F1B8200000000000000000000000000000000000000000000000000000039
|
||||
:1B0F36820000000000000000000000000000000000000000000000000000001E
|
||||
:1B0F518200000000000000000000000000000000000000000000000000000003
|
||||
:1B0F6C82000000000000000000000000000000000000000000000000000000E8
|
||||
:1B0F8782000000000000000000000000000000000042646F7320457272204F8D
|
||||
:1B0FA2826E20203A202442616420536563746F722453656C6563742446696C2C
|
||||
:060FBD826520522F4F2433
|
||||
:00000001FF
|
||||
:0400000300001200E7
|
||||
:1B120081E93C00E95B00E95B00E96100E96800E97000E96E00E96B00E9B60067
|
||||
:1B121B81E99200E9C500E9C700E9D000E9DB00E9DC00E95200E9BD00E9C6008C
|
||||
:1B123681E9C800E94A00E94A008CC88ED08ED88EC0BC8A16FC1EB800008ED80B
|
||||
:1B125181C706800306048C0E82031FB100E9A2EEE9A5EEE4DA240274020CFF5E
|
||||
:1B126C81C3E8F4FF74FBE4D8247FC3E4DA240174FA8AC1E6D8C3C3B01AC3B09A
|
||||
:1B12878100C3C32400C3E8DDFF508AC8E8E1FF583C6172063C7A77022C20C385
|
||||
:1B12A2818A0784C074288AC8E8CAFF43EBF2BB000080F9027318B08080F900B2
|
||||
:1B12BD817502B040A21315B5008BD9B104D3E381C32215C3C606161500BB18D8
|
||||
:1B12D88115E8350074F2BB1414E8BEFFEBEB880E1615C3880E1715C38BD90314
|
||||
:1B12F381DA8A1FC3890E0F15C3890E1115C3BB1D15C3B012EB02B00ABB14151E
|
||||
:1B130E81884701891E0D15C6060C150A8B1E0D15E889008B1E0D158A4701B921
|
||||
:1B13298100083C2C720BB98080240F3C0CB0007736E4A022C532C174F8E4A15B
|
||||
:1B134481241E74283C107425FE0E0C1575C8B4008BD88B9F3B14E845FFE4D868
|
||||
:1B135F81E82BFF3C4374253C5274AB3C49741A0CFFC3E81A0075A4E8150075AD
|
||||
:1B137A819FBBAC14E821FFE80A0074FBEB922400C3E9D3FEB640F6061315809C
|
||||
:1B1395817502B604BB1B15E80B00E4A0A88075FAE4A184C6C3E4A0A88075FAE5
|
||||
:1B13B0818A47013C127504B140EB063C0A7520B180B004E6A8B000E6A58AC152
|
||||
:1B13CB81E6A5A10F15E6A48AC4E6A4A11115E6AA8AC4E6AA8A0F438A070A0622
|
||||
:1513E6811315E6A0FEC9748243E4A0A82075FA8A07E6A1EBEF16
|
||||
:1B13FB820D0A0D0A4D502F4D2D3836204C6F6164657220322E300D0A000D0A1E
|
||||
:1B141682486F6D65204572726F720D0A000D0A496E74657272757074205472A5
|
||||
:1B14318261702048616C740D0A005B145B145B145B146B147B1488149914ACCE
|
||||
:1B144C8214C014D214E714F7145B145B145B140D0A4E756C6C204572726F7206
|
||||
:1B146782203F3F000D0A436C6F636B204572726F72203A000D0A4C6174652006
|
||||
:1B148282444D41203A000D0A494420435243204572726F72203A000D0A4461C5
|
||||
:1B149D82746120435243204572726F72203A000D0A4472697665204E6F7420DF
|
||||
:1B14B8825265616479203A000D0A57726974652050726F74656374203A000DBE
|
||||
:1B14D3820A54726B203030204E6F7420466F756E64203A000D0A5772697465D8
|
||||
:1B14EE82204661756C74203A000D0A536563746F72204E6F7420466F756E64F7
|
||||
:1B150982203A00000000000000004003000000022900012C01A901571E5115CA
|
||||
:1B1524820000000000006B1542150A16EB1551150000000000006B15421539BD
|
||||
:1B153F82161A161A00030700F2003F00C0001000020001070D1319050B111729
|
||||
:11155A8203090F1502080E141A060C1218040A101618
|
||||
:01164982001E
|
||||
:01168A8200DD
|
||||
:02000086000078
|
||||
:00000001FF
|
||||
|
||||
443
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/ROM.A86
Normal file
443
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/ROM.A86
Normal file
@@ -0,0 +1,443 @@
|
||||
title 'SBC86/12 w/ SBC204 Bootstrap EPROM'
|
||||
;
|
||||
; ROM bootstrap for CP/M-86 on an iSBC86/12
|
||||
; with the
|
||||
; Intel SBC 204 Floppy Disk Controller
|
||||
;
|
||||
|
||||
; Copyright (C) 1980,1981
|
||||
; Digital Research, Inc.
|
||||
; Box 579, Pacific Grove
|
||||
; California, 93950
|
||||
;
|
||||
;********************************************
|
||||
;* This is the BOOT ROM which is initiated *
|
||||
;* by a system reset. First, the ROM moves *
|
||||
;* a copy of its data area to RAM at loca- *
|
||||
;* tion 00000H, then initializes the segment*
|
||||
;* registers and the stack pointer. The *
|
||||
;* various peripheral interface chips on the*
|
||||
;* SBC 86/12 are initialized. The 8251 *
|
||||
;* serial interface is configured for a 9600*
|
||||
;* baud asynchronous terminal, and the in- *
|
||||
;* terrupt controller is setup for inter- *
|
||||
;* rupts 10H-17H (vectors at 00040H-0005FH) *
|
||||
;* and edge-triggered auto-EOI (end of in- *
|
||||
;* terrupt) mode with all interrupt levels *
|
||||
;* masked-off. Next, the SBC 204 Diskette *
|
||||
;* controller is initialized, and track 1 *
|
||||
;* sector 1 is read to determine the target *
|
||||
;* paragraph address for LOADER. Finally, *
|
||||
;* the LOADER on track 0 sectors 2-26 and *
|
||||
;* track 1 sectors 1-26 is read into the *
|
||||
;* target address. Control then transfers *
|
||||
;* to LOADER. This program resides in two *
|
||||
;* 2716 EPROM's (2K each) at location *
|
||||
;* 0FF000H on the SBC 86/12 CPU board. ROM *
|
||||
;* 0 contains the even memory locations, and*
|
||||
;* ROM 1 contains the odd addresses. BOOT *
|
||||
;* ROM uses RAM between 00000H and 000FFH *
|
||||
;* (absolute) for a scratch area, along with*
|
||||
;* the sector 1 buffer. *
|
||||
;********************************************
|
||||
true equ 0ffh
|
||||
false equ not true
|
||||
;
|
||||
debug equ true
|
||||
;debug = true indicates bootstrap is in same roms
|
||||
;with SBC 957 "Execution Vehicle" monitor
|
||||
;at FE00:0 instead of FF00:0
|
||||
;
|
||||
cr equ 13
|
||||
lf equ 10
|
||||
;
|
||||
; disk ports and commands
|
||||
;
|
||||
base204 equ 0a0h
|
||||
fdccom equ base204+0
|
||||
fdcstat equ base204+0
|
||||
fdcparm equ base204+1
|
||||
fdcrslt equ base204+1
|
||||
fdcrst equ base204+2
|
||||
dmacadr equ base204+4
|
||||
dmaccont equ base204+5
|
||||
dmacscan equ base204+6
|
||||
dmacsadr equ base204+7
|
||||
dmacmode equ base204+8
|
||||
dmacstat equ base204+8
|
||||
fdcsel equ base204+9
|
||||
fdcsegment equ base204+10
|
||||
reset204 equ base204+15
|
||||
;
|
||||
;actual console baud rate
|
||||
baud_rate equ 9600
|
||||
;value for 8253 baud counter
|
||||
baud equ 768/(baud_rate/100)
|
||||
;
|
||||
csts equ 0DAh ;i8251 status port
|
||||
cdata equ 0D8h ; " data port
|
||||
;
|
||||
tch0 equ 0D0h ;8253 PIC channel 0 port
|
||||
tch1 equ tch0+2 ;ch 1 port
|
||||
tch2 equ tch0+4 ;ch 2 port
|
||||
tcmd equ tch0+6 ;8253 command port
|
||||
;
|
||||
icp1 equ 0C0h ;8259a port 0
|
||||
icp2 equ 0C2h ;8259a port 1
|
||||
;
|
||||
;
|
||||
IF NOT DEBUG
|
||||
ROMSEG EQU 0FF00H ;normal
|
||||
ENDIF
|
||||
;
|
||||
IF DEBUG ;share prom with SBC 957
|
||||
ROMSEG EQU 0FE00H
|
||||
ENDIF
|
||||
;
|
||||
;
|
||||
; This long jump prom'd in by hand
|
||||
; cseg 0ffffh ;reset goes to here (ffff0h)
|
||||
; JMPF BOTTOM ;boot is at bottom of PROM
|
||||
; EA 00 00 00 FF ;cs = bottom of prom (ff000h)
|
||||
; ip = 0
|
||||
; EVEN PROM ODD PROM
|
||||
; 7F8 - EA 7F8 - 00
|
||||
; 7F9 - 00 7F9 - 00
|
||||
; 7FA - FF ;this is not done if special = true
|
||||
;
|
||||
cseg romseg
|
||||
;
|
||||
;First, move our data area into RAM at 0000:0200
|
||||
;
|
||||
mov ax,cs
|
||||
mov ds,ax ;point DS to CS for source
|
||||
mov SI,drombegin ;start of data
|
||||
mov DI,offset ram_start ;offset of destination
|
||||
mov ax,0
|
||||
mov es,ax ;destination segment is 0000
|
||||
mov CX,data_length ;how much to move in bytes
|
||||
rep movs al,al ;move out of eprom a byte at a time
|
||||
;
|
||||
mov ax,0
|
||||
mov ds,ax ;data segment now in RAM
|
||||
mov ss,ax
|
||||
mov sp,stack_offset ;Initialize stack segment/pointer
|
||||
cld ;clear the direction flag
|
||||
;
|
||||
IF NOT DEBUG
|
||||
;
|
||||
;Now, initialize the console USART and baud rate
|
||||
;
|
||||
mov al,0Eh
|
||||
out csts,al ;give 8251 dummy mode
|
||||
mov al,40h
|
||||
out csts,al ;reset 8251 to accept mode
|
||||
mov al,4Eh
|
||||
out csts,al ;normal 8 bit asynch mode, * 16
|
||||
mov al,37h
|
||||
out csts,al ;enable Tx & Rx
|
||||
mov al,0B6h
|
||||
out tcmd,al ;8253 ch.2 square wave mode
|
||||
mov ax,baud
|
||||
out tch2,al ;low of the baud rate
|
||||
mov al,ah
|
||||
out tch2,al ;high of the baud rate
|
||||
;
|
||||
ENDIF
|
||||
;
|
||||
;Setup the 8259 Programmable Interrupt Controller
|
||||
;
|
||||
mov al,13h
|
||||
out icp1,al ;8259a ICW 1 8086 mode
|
||||
mov al,10h
|
||||
out icp2,al ;8259a ICW 2 vector @ 40-5F
|
||||
mov al,1Fh
|
||||
out icp2,al ;8259a ICW 4 auto EOI master
|
||||
mov al,0FFh
|
||||
out icp2,al ;8259a OCW 1 mask all levels off
|
||||
;
|
||||
;Reset and initialize the iSBC 204 Diskette Interface
|
||||
;
|
||||
restart: ;also come back here on fatal errors
|
||||
out reset204,AL ;reset iSBC 204 logic and
|
||||
mov AL,1
|
||||
out fdcrst,AL ;give 8271 FDC
|
||||
mov al,0
|
||||
out fdcrst,AL ; a reset command
|
||||
mov BX,offset specs1
|
||||
CALL sendcom ;program
|
||||
mov BX,offset specs2
|
||||
CALL sendcom ; Shugart SA-800 drive
|
||||
mov BX,offset specs3
|
||||
call sendcom ; characteristics
|
||||
homer: mov BX,offset home
|
||||
CALL execute ;home drive 0
|
||||
;
|
||||
mov bx,sector1 ;offset for first sector DMA
|
||||
mov ax,0
|
||||
mov es,ax ;segment " " " "
|
||||
call setup_dma
|
||||
;
|
||||
mov bx,offset read0
|
||||
call execute ;get T0 S1
|
||||
;
|
||||
mov es,ABS
|
||||
mov bx,0 ;get loader load address
|
||||
call setup_dma ;setup DMA to read loader
|
||||
;
|
||||
mov bx,offset read1
|
||||
call execute ;read track 0
|
||||
mov bx,offset read2
|
||||
call execute ;read track 1
|
||||
;
|
||||
mov leap_segment,ES
|
||||
; setup far jump vector
|
||||
mov leap_offset,0
|
||||
;
|
||||
; enter LOADER
|
||||
jmpf dword ptr leap_offset
|
||||
;
|
||||
pmsg:
|
||||
mov cl,[BX]
|
||||
test cl,cl
|
||||
jz return
|
||||
call conout
|
||||
inc BX
|
||||
jmp pmsg
|
||||
;
|
||||
conout:
|
||||
in al,csts
|
||||
test al,1
|
||||
jz conout
|
||||
mov al,cl
|
||||
out cdata,al
|
||||
ret
|
||||
;
|
||||
conin:
|
||||
in al,csts
|
||||
test al,2
|
||||
jz conin
|
||||
in al,cdata
|
||||
and al,7Fh
|
||||
ret
|
||||
;
|
||||
;
|
||||
;
|
||||
execute: ;execute command string @ [BX]
|
||||
;<BX> points to length,
|
||||
;followed by Command byte
|
||||
;followed by length-1 parameter bytes
|
||||
;
|
||||
mov lastcom,BX ;remember what it was
|
||||
retry: ;retry if not ready drive
|
||||
call sendcom ;execute the command
|
||||
;now, let's see what type
|
||||
;of status poll was necessary
|
||||
;for that command type . . .
|
||||
mov BX,lastcom ;point to command string
|
||||
mov AL,1[BX] ;get command op code
|
||||
and AL,3fh ;drop drive code bits
|
||||
mov CX,0800h ;mask if it will be "int req"
|
||||
cmp AL,2ch ;see if interrupt type
|
||||
jb execpoll
|
||||
mov CX,8080h ;else we use "not command busy"
|
||||
and AL,0fh ;unless . . .
|
||||
cmp AL,0ch ;there isn't
|
||||
mov AL,0
|
||||
ja return ;any result at all
|
||||
;
|
||||
execpoll: ;poll for bit in b, toggled with c
|
||||
in AL,FDCSTAT
|
||||
and AL,CH
|
||||
xor AL,CL ! JZ execpoll
|
||||
;
|
||||
in AL,fdcrslt ;get result register
|
||||
and AL,1eh ;look only at result type & code
|
||||
jz return ;zero means it was a good operation
|
||||
;
|
||||
cmp al,10h
|
||||
jne fatal ;if other than "Not Ready", stop
|
||||
;
|
||||
mov bx,offset rdstat
|
||||
call sendcom ;perform read status command
|
||||
rd_poll:
|
||||
in al,fdc_stat
|
||||
test al,80h ;wait for command not busy
|
||||
jnz rd_poll
|
||||
mov bx,last_com ;recover last attempted command
|
||||
jmp retry ;and try it over again
|
||||
;
|
||||
fatal: ; fatal error
|
||||
mov ah,0
|
||||
mov bx,ax ;make 16 bits
|
||||
mov bx,errtbl[BX]
|
||||
; print appropriate error message
|
||||
call pmsg
|
||||
call conin ;wait for key strike
|
||||
pop ax ;discard unused item
|
||||
jmp restart ;then start all over
|
||||
;
|
||||
return:
|
||||
RET ;return from EXECUTE
|
||||
;
|
||||
setupdma:
|
||||
mov AL,04h
|
||||
out dmacmode,AL ;enable dmac
|
||||
mov al,0
|
||||
out dmaccont,AL ;set first (dummy) byte to
|
||||
mov AL,40h
|
||||
out dmaccont,AL ;force read data mode
|
||||
mov AX,ES
|
||||
out fdcsegment,AL
|
||||
mov AL,AH
|
||||
out fdcsegment,AL
|
||||
mov AX,BX
|
||||
out dmacadr,AL
|
||||
mov AL,AH
|
||||
out dmacadr,AL
|
||||
RET
|
||||
;
|
||||
;
|
||||
;
|
||||
sendcom: ;routine to send a command string to SBC204
|
||||
in AL,fdcstat
|
||||
and AL,80h
|
||||
jnz sendcom ;insure command not busy
|
||||
mov CL,[BX] ;get count
|
||||
inc BX
|
||||
mov al,[BX] ;point to and fetch command byte
|
||||
out fdccom,AL ;send command
|
||||
parmloop:
|
||||
dec CL
|
||||
jz return ;see if any (more) parameters
|
||||
inc BX ;point to next parameter
|
||||
parmpoll:
|
||||
in AL,fdcstat
|
||||
and AL,20h
|
||||
jnz parmpoll ;loop until parm not full
|
||||
mov AL,[BX]
|
||||
out fdcparm,AL ;output next parameter
|
||||
jmp parmloop ;go see about another
|
||||
;
|
||||
;
|
||||
; Image of data to be moved to RAM
|
||||
;
|
||||
drombegin equ offset $
|
||||
;
|
||||
clastcom dw 0000h ;last command
|
||||
;
|
||||
creadstring db 3 ;length
|
||||
db 52h ;read function code for drive 0
|
||||
db 0 ;track #
|
||||
db 1 ;sector #
|
||||
;
|
||||
creadtrk0 db 4
|
||||
db 53h ;read multiple
|
||||
db 0 ;track 0
|
||||
db 2 ;sectors 2
|
||||
db 25 ;through 26
|
||||
;
|
||||
creadtrk1 db 4
|
||||
db 53h
|
||||
db 1 ;track 1
|
||||
db 1 ;sectors 1
|
||||
db 26 ;through 26
|
||||
;
|
||||
chome0 db 2,69h,0
|
||||
crdstat0 db 1,6ch
|
||||
cspecs1 db 5,35h,0dh
|
||||
db 08h,08h,0e9h
|
||||
cspecs2 db 5,35h,10h
|
||||
db 255,255,255
|
||||
cspecs3 db 5,35h,18h
|
||||
db 255,255,255
|
||||
;
|
||||
cerrtbl dw offset er0
|
||||
dw offset er1
|
||||
dw offset er2
|
||||
dw offset er3
|
||||
dw offset er4
|
||||
dw offset er5
|
||||
dw offset er6
|
||||
dw offset er7
|
||||
dw offset er8
|
||||
dw offset er9
|
||||
dw offset erA
|
||||
dw offset erB
|
||||
dw offset erC
|
||||
dw offset erD
|
||||
dw offset erE
|
||||
dw offset erF
|
||||
;
|
||||
Cer0 db cr,lf,'Null Error ??',0
|
||||
Cer1 equ cer0
|
||||
Cer2 equ cer0
|
||||
Cer3 equ cer0
|
||||
Cer4 db cr,lf,'Clock Error',0
|
||||
Cer5 db cr,lf,'Late DMA',0
|
||||
Cer6 db cr,lf,'ID CRC Error',0
|
||||
Cer7 db cr,lf,'Data CRC Error',0
|
||||
Cer8 db cr,lf,'Drive Not Ready',0
|
||||
Cer9 db cr,lf,'Write Protect',0
|
||||
CerA db cr,lf,'Trk 00 Not Found',0
|
||||
CerB db cr,lf,'Write Fault',0
|
||||
CerC db cr,lf,'Sector Not Found',0
|
||||
CerD equ cer0
|
||||
CerE equ cer0
|
||||
CerF equ cer0
|
||||
;
|
||||
dromend equ offset $
|
||||
;
|
||||
data_length equ dromend-drombegin
|
||||
;
|
||||
; reserve space in RAM for data area
|
||||
; (no hex records generated here)
|
||||
;
|
||||
dseg 0
|
||||
org 0200h
|
||||
;
|
||||
ram_start equ $
|
||||
lastcom rw 1 ;last command
|
||||
read0 rb 4 ;read track 0 sector 1
|
||||
read1 rb 5 ;read T0 S2-26
|
||||
read2 rb 5 ;read T1 S1-26
|
||||
home rb 3 ;home drive 0
|
||||
rdstat rb 2 ;read status
|
||||
specs1 rb 6
|
||||
specs2 rb 6
|
||||
specs3 rb 6
|
||||
errtbl rw 16
|
||||
er0 rb length cer0 ;16
|
||||
er1 equ er0
|
||||
er2 equ er0
|
||||
er3 equ er0
|
||||
er4 rb length cer4 ;14
|
||||
er5 rb length cer5 ;11
|
||||
er6 rb length cer6 ;15
|
||||
er7 rb length cer7 ;17
|
||||
er8 rb length cer8 ;18
|
||||
er9 rb length cer9 ;16
|
||||
erA rb length cerA ;19
|
||||
erB rb length cerB ;14
|
||||
erC rb length cerC ;19
|
||||
erD equ er0
|
||||
erE equ er0
|
||||
erF equ er0
|
||||
;
|
||||
leap_offset rw 1
|
||||
leap_segment rw 1
|
||||
;
|
||||
;
|
||||
rw 32 ;local stack
|
||||
stack_offset equ offset $;stack from here down
|
||||
;
|
||||
; T0 S1 read in here
|
||||
sector1 equ offset $
|
||||
;
|
||||
Ty rb 1
|
||||
Len rw 1
|
||||
Abs rw 1 ;ABS is all we care about
|
||||
Min rw 1
|
||||
Max rw 1
|
||||
end
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
disks 3
|
||||
diskdef 0,1,26,6,1024,243,64,64,2
|
||||
diskdef 1,0
|
||||
diskdef 2,1,26,,1024,127,64,0,0
|
||||
endef
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
; DISKS 3
|
||||
dpbase equ $ ;Base of Disk Parameter Blocks
|
||||
dpe0 dw xlt0,0000h ;Translate Table
|
||||
dw 0000h,0000h ;Scratch Area
|
||||
dw dirbuf,dpb0 ;Dir Buff, Parm Block
|
||||
dw csv0,alv0 ;Check, Alloc Vectors
|
||||
dpe1 dw xlt1,0000h ;Translate Table
|
||||
dw 0000h,0000h ;Scratch Area
|
||||
dw dirbuf,dpb1 ;Dir Buff, Parm Block
|
||||
dw csv1,alv1 ;Check, Alloc Vectors
|
||||
dpe2 dw xlt2,0000h ;Translate Table
|
||||
dw 0000h,0000h ;Scratch Area
|
||||
dw dirbuf,dpb2 ;Dir Buff, Parm Block
|
||||
dw csv2,alv2 ;Check, Alloc Vectors
|
||||
; DISKDEF 0,1,26,6,1024,243,64,64,2
|
||||
;
|
||||
; 1944: 128 Byte Record Capacity
|
||||
; 243: Kilobyte Drive Capacity
|
||||
; 64: 32 Byte Directory Entries
|
||||
; 64: Checked Directory Entries
|
||||
; 128: Records / Extent
|
||||
; 8: Records / Block
|
||||
; 26: Sectors / Track
|
||||
; 2: Reserved Tracks
|
||||
; 6: Sector Skew Factor
|
||||
;
|
||||
dpb0 equ offset $ ;Disk Parameter Block
|
||||
dw 26 ;Sectors Per Track
|
||||
db 3 ;Block Shift
|
||||
db 7 ;Block Mask
|
||||
db 0 ;Extnt Mask
|
||||
dw 242 ;Disk Size - 1
|
||||
dw 63 ;Directory Max
|
||||
db 192 ;Alloc0
|
||||
db 0 ;Alloc1
|
||||
dw 16 ;Check Size
|
||||
dw 2 ;Offset
|
||||
xlt0 equ offset $ ;Translate Table
|
||||
db 1,7,13,19
|
||||
db 25,5,11,17
|
||||
db 23,3,9,15
|
||||
db 21,2,8,14
|
||||
db 20,26,6,12
|
||||
db 18,24,4,10
|
||||
db 16,22
|
||||
als0 equ 31 ;Allocation Vector Size
|
||||
css0 equ 16 ;Check Vector Size
|
||||
; DISKDEF 1,0
|
||||
;
|
||||
; Disk 1 is the same as Disk 0
|
||||
;
|
||||
dpb1 equ dpb0 ;Equivalent Parameters
|
||||
als1 equ als0 ;Same Allocation Vector Size
|
||||
css1 equ css0 ;Same Checksum Vector Size
|
||||
xlt1 equ xlt0 ;Same Translate Table
|
||||
; DISKDEF 2,1,26,,1024,127,64,0,0
|
||||
;
|
||||
; 1016: 128 Byte Record Capacity
|
||||
; 127: Kilobyte Drive Capacity
|
||||
; 64: 32 Byte Directory Entries
|
||||
; 0: Checked Directory Entries
|
||||
; 128: Records / Extent
|
||||
; 8: Records / Block
|
||||
; 26: Sectors / Track
|
||||
; 0: Reserved Tracks
|
||||
;
|
||||
dpb2 equ offset $ ;Disk Parameter Block
|
||||
dw 26 ;Sectors Per Track
|
||||
db 3 ;Block Shift
|
||||
db 7 ;Block Mask
|
||||
db 0 ;Extnt Mask
|
||||
dw 126 ;Disk Size - 1
|
||||
dw 63 ;Directory Max
|
||||
db 192 ;Alloc0
|
||||
db 0 ;Alloc1
|
||||
dw 0 ;Check Size
|
||||
dw 0 ;Offset
|
||||
xlt2 equ 0 ;No Translate Table
|
||||
als2 equ 16 ;Allocation Vector Size
|
||||
css2 equ 0 ;Check Vector Size
|
||||
; ENDEF
|
||||
;
|
||||
; Uninitialized Scratch Memory Follows:
|
||||
;
|
||||
begdat equ offset $ ;Start of Scratch Area
|
||||
dirbuf rs 128 ;Directory Buffer
|
||||
alv0 rs als0 ;Alloc Vector
|
||||
csv0 rs css0 ;Check Vector
|
||||
alv1 rs als1 ;Alloc Vector
|
||||
csv1 rs css1 ;Check Vector
|
||||
alv2 rs als2 ;Alloc Vector
|
||||
csv2 rs css2 ;Check Vector
|
||||
enddat equ offset $ ;End of Scratch Area
|
||||
datsiz equ offset $-begdat ;Size of Scratch Area
|
||||
db 0 ;Marks End of Module
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
;*****************************************************
|
||||
;*
|
||||
;* System Data Area
|
||||
;*
|
||||
;*****************************************************
|
||||
|
||||
org 00h
|
||||
supmod rw 2
|
||||
|
||||
org 038h
|
||||
dispatcher equ (offset $)
|
||||
|
||||
org 040h
|
||||
mpmseg rw 1
|
||||
|
||||
org 044h
|
||||
endseg rw 1
|
||||
|
||||
org 068h
|
||||
rlr rw 1 ;Ready List Root
|
||||
|
||||
org 072h
|
||||
thrdrt rw 1 ;Process Thread Root
|
||||
qlr rw 1 ;Queue List Root
|
||||
|
||||
org 078h
|
||||
version rw 1 ;addr. version in SUP
|
||||
vernum rw 1 ;MPM-86 w/BDOS v3.0
|
||||
mpmvernum rw 1 ;MPM-86 Version 2.0
|
||||
tod rb 5 ;Time of Day Structure
|
||||
|
||||
org 01000h
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
;*****************************************************
|
||||
;*
|
||||
;* SYSTEM DEFINITIONS
|
||||
;*
|
||||
;*****************************************************
|
||||
|
||||
true equ 0ffffh ; value of TRUE
|
||||
false equ 0 ; value of FALSE
|
||||
unknown equ 0 ; value to be filled in
|
||||
dskrecl equ 128 ; log. disk record len
|
||||
fcblen equ 32 ; size of file control block
|
||||
pnamsiz equ 8 ; size of process name
|
||||
qnamsiz equ pnamsiz ; size of queue name
|
||||
fnamsiz equ pnamsiz ; size of file name
|
||||
ftypsiz equ 3 ; size of file type
|
||||
mpmint equ 224 ; int vec for mpm ent.
|
||||
debugint equ mpmint+1 ; int vec for debuggers
|
||||
ulen equ 0100h ; size of uda
|
||||
pdlen equ 030h ; size of Process Descriptor
|
||||
todlen equ 5 ; size of Time of Day struct
|
||||
flag_tick equ 1 ; flag 0 = tick flag
|
||||
flag_sec equ 2 ; flag 1 = second flag
|
||||
flag_min equ 3 ; flag 2 = minute flag
|
||||
ldtabsiz equ 0aah ; ldtablen=11, 10 entries
|
||||
|
||||
1579
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/XIOS.A86
Normal file
1579
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/XIOS.A86
Normal file
File diff suppressed because it is too large
Load Diff
BIN
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/XIOS.MPM
Normal file
BIN
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/XIOS.MPM
Normal file
Binary file not shown.
Reference in New Issue
Block a user