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

417 lines
7.6 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; MP/M 2.0 Loader BIOS
; (modified CP/M 2.2 BIOS)
; MDS I/O drivers for CP/M 2.2
; (single drive, single density)
; -or-
; (single drive, double density)
; Version 2.0 -- Sept 81
vers equ 20 ;version 2.0
; Copyright (C) 1980, 1981
; Digital Research
; Box 579, Pacific Grove
; California, 93950
false equ 0
true equ not false
asm equ true
mac equ not asm
sgl equ true
dbl equ not sgl
if mac
maclib diskdef
numdsks equ 1 ;number of drives available
endif
ram$top equ 1d00h ; top address+1
bios equ ram$top-0600h ; basic input/output system
bdos equ bios-0e00h ; base of the bdos
org bios
buff equ 0080h ;default buffer address
retry equ 10 ;max retries on disk i/o before error
; jump vector for indiviual routines
jmp boot
wboote: jmp wboot
jmp const
jmp conin
jmp conout
jmp list
jmp punch
jmp reader
jmp home
jmp seldsk
jmp settrk
jmp setsec
jmp setdma
jmp read
jmp write
jmp list$st ; list status poll
jmp sect$tran ; sector translation
; we also assume the MDS system has four disk drives
numdisks equ 1 ;number of drives available
revrt equ 0fdh ;interrupt revert port
intc equ 0fch ;interrupt mask port
icon equ 0f3h ;interrupt control port
inte equ 0111$1110b ;enable rst 0(warm boot), rst 7 (monitor)
; MDS monitor equates
rmon80 equ 0ff0fh ;restart mon80 (boot error)
; disk ports and commands
base equ 78h ;base of disk command io ports
dstat equ base ;disk status (input)
rtype equ base+1 ;result type (input)
rbyte equ base+3 ;result byte (input)
ilow equ base+1 ;iopb low address (output)
ihigh equ base+2 ;iopb high address (output)
readf equ 4h ;read function
writf equ 6h ;write function
recal equ 3h ;recalibrate drive
iordy equ 4h ;i/o finished mask
cr equ 0dh ;carriage return
lf equ 0ah ;line feed
boot:
wboot:
gocpm:
ret
crtin: ; crt: input
in 0f7h ! ani 2 ! jz crtin
in 0f6h ! ani 7fh
ret
crtout: ; crt: output
in 0f7h ! ani 1 ! jz crtout
mov a,c ! out 0f6h
ret
crtst: ; crt: status
in 0f7h ! ani 2 ! rz
ori 0ffh
ret
ttyin: ; tty: input
in 0f5h ! ani 2 ! jz ttyin
in 0f4h ! ani 7fh
ret
ttyout: ; tty: output
in 0f5h ! ani 1 ! jz ttyout
mov a,c ! out 0f4h
ret
;ttyst:
; in 0f5h ! ani 2 ! rz
; ori -1
; ret
lptout: ; lpt: output
in 0fbh ! ani 1 ! jz lptout
mov a,c ! cma ! out 0fah
ret
lpt$st:
in 0fbh ! ani 1 ! rz
ori 0ffh
ret
conin equ crtin
const equ crtst
conout equ crtout
reader equ ttyin
punch equ ttyout
list equ lptout
listst equ lptst
seldsk: ;select disk given by register c
lxi h, 0 ! mov a,c ! cpi num$disks ! rnc ; first, insure good select
ani 2 ! sta dbank ; then save it
lxi h,sel$table ! mvi b,0 ! dad b ! mov a,m ! sta iof
mov h,b ! mov l,c
dad h ! dad h ! dad h ! dad h ; times 16
lxi d,dpbase ! dad d
ret
home: ;move to home position
; treat as track 00 seek
mvi c,0
;
settrk: ;set track address given by c
lxi h,iot
mov m,c
ret
;
setsec: ;set sector number given by c
mov a,c ;sector number to accum
sta ios ;store sector number to iopb
ret
;
setdma: ;set dma address given by regs b,c
mov l,c
mov h,b
shld iod
ret
sect$tran: ; translate the sector # in <c> if needed
mov h,b ! mov l,c ! inx h ; in case of no translation
mov a, d ! ora e ! rz
xchg ! dad b ; point to physical sector
mov l,m ! mvi h,0
ret
read: ;read next disk record (assuming disk/trk/sec/dma set)
mvi c,readf ;set to read function
jmp setfunc
;
write: ;disk write function
mvi c,writf
;
setfunc:
; set function for next i/o (command in reg-c)
lxi h,iof ;io function address
mov a,m ;get it to accumulator for masking
ani 1111$1000b ;remove previous command
ora c ;set to new command
mov m,a ;replaced in iopb
; single density drive 1 requires bit 5 on in sector #
; mask the bit from the current i/o function
ani 0010$0000b ;mask the disk select bit
lxi h,ios ;address the sector select byte
ora m ;select proper disk bank
mov m,a ;set disk select bit on/off
;
waitio:
mvi c,retry ;max retries before perm error
rewait:
; start the i/o function and wait for completion
call intype ;in rtype
call inbyte ;clears the controller
lda dbank ;set bank flags
ora a ;zero if drive 0,1 and nz if 2,3
mvi a,iopb and 0ffh ;low address for iopb
mvi b,iopb shr 8 ;high address for iopb
jnz iodr1 ;drive bank 1?
out ilow ;low address to controller
mov a,b
out ihigh ;high address
jmp wait0 ;to wait for complete
iodr1: ;drive bank 1
out ilow+10h ;88 for drive bank 10
mov a,b
out ihigh+10h
wait0: call instat ;wait for completion
ani iordy ;ready?
jz wait0
; check io completion ok
call intype ;must be io complete (00) unlinked
; 00 unlinked i/o complete, 01 linked i/o complete (not used)
; 10 disk status changed 11 (not used)
cpi 10b ;ready status change?
jz wready
; must be 00 in the accumulator
ora a
jnz werror ;some other condition, retry
; check i/o error bits
call inbyte
ral
jc wready ;unit not ready
rar
ani 11111110b ;any other errors? (deleted data ok)
jnz werror
; read or write is ok, accumulator contains zero
ret
wready: ;not ready, treat as error for now
call inbyte ;clear result byte
jmp trycount
werror: ;return hardware malfunction (crc, track, seek, etc.)
; the MDS controller has returned a bit in each position
; of the accumulator, corresponding to the conditions:
; 0 - deleted data (accepted as ok above)
; 1 - crc error
; 2 - seek error
; 3 - address error (hardware malfunction)
; 4 - data over/under flow (hardware malfunction)
; 5 - write protect (treated as not ready)
; 6 - write error (hardware malfunction)
; 7 - not ready
; (accumulator bits are numbered 7 6 5 4 3 2 1 0)
trycount:
; register c contains retry count, decrement 'til zero
dcr c
jnz rewait ;for another try
; cannot recover from error
mvi a,1 ;error code
ret
; intype, inbyte, instat read drive bank 00 or 10
intype: lda dbank
ora a
jnz intyp1 ;skip to bank 10
in rtype
ret
intyp1: in rtype+10h ;78 for 0,1 88 for 2,3
ret
inbyte: lda dbank
ora a
jnz inbyt1
in rbyte
ret
inbyt1: in rbyte+10h
ret
instat: lda dbank
ora a
jnz insta1
in dstat
ret
insta1: in dstat+10h
ret
; utility subroutines
prmsg: ;print message at h,l to 0
mov a,m ! ora a ! rz
push h ! mov c,a ! call conout ! pop h
inx h ! jmp prmsg
; data areas (must be in ram)
dbank: db 0 ;disk bank 00 if drive 0,1
; 10 if drive 2,3
iopb: ;io parameter block
db 80h ;normal i/o operation
iof: db readf ;io function, initial read
ion: db 1 ;number of sectors to read
iot: db 2 ;track number
ios: db 1 ;sector number
iod: dw buff ;io address
;
;
sel$table:
if sgl
db 00h, 30h, 00h, 30h ; drive select bits
endif
if dbl
db 00h, 10h, 00h, 30h ; drive select bits
endif
if mac and sgl
disks numdisks ; generate drive tables
diskdef 0,1,26,6,1024,243,64,64,2
endef
endif
if mac and dbl
disks numdisks ; generate drive tables
diskdef 0,1,52,,2048,243,128,128,2,0
endef
endif
if asm
dpbase equ $ ;base of disk param blks
dpe0: dw xlt0,0000h ;translate table
dw 0000h,0000h ;scratch area
dw dirbuf,dpb0 ;dir buff, parm block
dw csv0,alv0 ;check, alloc vectors
dpb0 equ $ ;disk param block
endif
if asm and sgl
dw 26 ;sec 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 $ ;translate table
db 1
db 7
db 13
db 19
db 25
db 5
db 11
db 17
db 23
db 3
db 9
db 15
db 21
db 2
db 8
db 14
db 20
db 26
db 6
db 12
db 18
db 24
db 4
db 10
db 16
db 22
endif
if asm and dbl
xlt0 equ 0
endif
if asm
begdat equ $
dirbuf: ds 128 ;directory access buffer
alv0: ds 31
csv0: ds 16
endif
if asm and dbl
ds 16
endif
if asm
enddat equ $
datsiz equ $-begdat
endif
end