mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
289 lines
6.1 KiB
ArmAsm
289 lines
6.1 KiB
ArmAsm
*****************************************************************
|
|
* *
|
|
* CP/M-68K Loader BIOS *
|
|
* Basic Input/Output Subsystem *
|
|
* For ERG 68000 with Tarbell floppy disk controller *
|
|
* *
|
|
*****************************************************************
|
|
|
|
|
|
.globl _bios * declare external entry point
|
|
|
|
|
|
_bios:
|
|
cmpi #nfuncs,d0
|
|
bge nogood
|
|
lsl #2,d0 * multiply bios function by 4
|
|
movea.l 6(pc,d0),a0 * get handler address
|
|
jsr (a0) * call handler
|
|
nogood:
|
|
rts
|
|
|
|
biosbase:
|
|
.dc.l nogood
|
|
.dc.l nogood
|
|
.dc.l constat
|
|
.dc.l conin
|
|
.dc.l conout
|
|
.dc.l nogood
|
|
.dc.l nogood
|
|
.dc.l nogood
|
|
.dc.l home
|
|
.dc.l seldsk
|
|
.dc.l settrk
|
|
.dc.l setsec
|
|
.dc.l setdma
|
|
.dc.l read
|
|
.dc.l nogood
|
|
.dc.l nogood
|
|
.dc.l sectran
|
|
.dc.l setdma
|
|
.dc.l getseg
|
|
.dc.l nogood
|
|
.dc.l nogood
|
|
.dc.l nogood
|
|
.dc.l setexc
|
|
|
|
nfuncs=(*-biosbase)/4
|
|
|
|
|
|
constat: move.b $ffff01,d0 * get status byte
|
|
andi.w #2,d0 * data available bit on?
|
|
beq noton * branch if not
|
|
moveq.l #$1,d0 * set result to true
|
|
rts
|
|
|
|
noton: clr.l d0 * set result to false
|
|
rts
|
|
|
|
conin: bsr constat * see if key pressed
|
|
tst d0
|
|
beq conin * wait until key pressed
|
|
move.b $ffff00,d0 * get key
|
|
and.l #$7f,d0 * clear all but low 7 bits
|
|
rts
|
|
|
|
conout: move.b $ffff01,d0 * get status
|
|
and.b #$1,d0 * check for transmitter buffer empty
|
|
beq conout * wait until our port has aged...
|
|
move.b d1,$ffff00 * and output it
|
|
rts * and exit
|
|
|
|
|
|
*
|
|
* Disk Handlers for Tarbell 1793 floppy disk controller
|
|
*
|
|
maxdsk = 2 * this BIOS supports 2 floppy drives
|
|
dphlen = 26 * length of disk parameter header
|
|
|
|
iobase = $00fffff8 * Tarbell floppy disk port base address
|
|
dcmd = iobase * output port for command
|
|
dstat = iobase * input status port
|
|
dtrk = iobase+1 * disk track port
|
|
dsect = iobase+2 * disk sector port
|
|
ddata = iobase+3 * disk data port
|
|
dwait = iobase+4 * input port to wait for op finished
|
|
dcntrl = iobase+4 * output control port for drive selection
|
|
|
|
|
|
home: clr.b track
|
|
rts
|
|
|
|
seldsk:
|
|
* select disk A
|
|
clr.b seldrv * select drive A
|
|
clr.b selcode * select code is 00 for drv 0, $10 for drv 1
|
|
move.l #dph0,d0
|
|
selrtn: rts
|
|
|
|
settrk: move.b d1,track
|
|
rts
|
|
|
|
setsec: move.b d1,sector
|
|
rts
|
|
|
|
sectran:
|
|
* translate sector in d1 with translate table pointed to by d2
|
|
* result in d0
|
|
movea.l d2,a0
|
|
ext.l d1
|
|
move.b #0(a0,d1),d0
|
|
ext.l d0
|
|
rts
|
|
|
|
setdma:
|
|
move.l d1,dma
|
|
rts
|
|
|
|
read:
|
|
* Read one sector from requested disk, track, sector to dma address
|
|
* Retry if necessary, return in d0 00 if ok, else non-zero
|
|
move.b #10,errcnt * set up retry counter
|
|
rretry:
|
|
bsr setup
|
|
ori #$88,d3 * OR read command with head load bit
|
|
move.b d3,dcmd * output it to FDC
|
|
rloop: btst #7,dwait
|
|
beq rdone * if end of read, exit
|
|
move.b ddata,(a0)+ * else, move next byte of data
|
|
bra rloop
|
|
rdone:
|
|
bsr rstatus * get FDC status
|
|
bne rerror
|
|
clr.l d0
|
|
rts
|
|
rerror: bsr errchk * go to error handler
|
|
subq.b #1,errcnt
|
|
bne rretry
|
|
move.l #$ffffffff,d0
|
|
rts
|
|
|
|
|
|
setup:
|
|
* common read and write setup code
|
|
* select disk, set track, set sector were all deferred until now
|
|
move.b #$d0,dcmd * clear controller, get status
|
|
move.b curdrv,d3
|
|
cmp.b seldrv,d3
|
|
bne newdrive * if drive not selected, do it
|
|
move.b track,d3
|
|
cmp.b oldtrk,d3
|
|
bne newtrk * if not on right track, do it
|
|
clr.l d3 * if head already loaded, no head load delay
|
|
btst #5,dstat * if head unloaded, treat as new disk
|
|
bne sexit
|
|
newdrive:
|
|
move.b selcode,dcntrl * select the drive
|
|
move.b seldrv,curdrv
|
|
newtrk:
|
|
bsr chkseek * seek to correct track if required
|
|
moveq #4,d3 * force head load delay
|
|
sexit:
|
|
move.b sector,dsect * set up sector number
|
|
move.b track,dtrk * set up track number
|
|
move.l dma,a0 * dma address to a0
|
|
rts
|
|
|
|
errchk:
|
|
btst.b #4,d7
|
|
bne chkseek * if record not found error, reseek
|
|
rts
|
|
|
|
chkseek:
|
|
* check for correct track, seek if necessary
|
|
bsr readid * find out what track we're on
|
|
beq chks1 * if read id ok, skip restore code
|
|
restore:
|
|
* home the drive and reseek to correct track
|
|
move.b #$0B,dcmd * restore command to command port
|
|
rstwait:
|
|
btst #7,dwait
|
|
bne rstwait * loop until restore completed
|
|
btst #2,dstat
|
|
beq restore * if not at track 0, try again
|
|
clr.l d3 * track number returned in d3 from readid
|
|
chks1:
|
|
move.b d3,dtrk * update track register in FDC
|
|
move.b track,oldtrk * update oldtrk
|
|
cmp.b track,d3 * are we at right track?
|
|
beq chkdone * if yes, exit
|
|
move.b track,ddata * else, put desired track in data reg of FDC
|
|
move.b #$18,dcmd * and issue a seek command
|
|
chks2: btst #7,dwait
|
|
bne chks2 * loop until seek complete
|
|
move.b dstat,d3 * read status to clear FDC
|
|
chkdone:
|
|
rts
|
|
|
|
readid:
|
|
* read track id, return track number in d3
|
|
move.b #$c4,dcmd * issue read id command
|
|
move.b dwait,d7 * wait for intrq
|
|
move.b ddata,d3 * track byte to d3
|
|
rid2:
|
|
btst #7,dwait
|
|
beq rstatus * wait for intrq
|
|
move.b ddata,d7 * read another byte
|
|
bra rid2 * and loop
|
|
rstatus:
|
|
move.b dstat,d7
|
|
andi.b #$9d,d7 * set condition codes
|
|
rts
|
|
|
|
|
|
getseg:
|
|
move.l #memrgn,d0 * return address of mem region table
|
|
rts
|
|
|
|
|
|
setexc:
|
|
andi.l #$ff,d1 * do only for exceptions 0 - 255
|
|
lsl #2,d1 * multiply exception number by 4
|
|
movea.l d1,a0
|
|
move.l (a0),d0 * return old vector value
|
|
move.l d2,(a0) * insert new vector
|
|
rts
|
|
|
|
|
|
.data
|
|
|
|
seldrv: .dc.b $ff * drive requested by seldsk
|
|
curdrv: .dc.b $ff * currently selected drive
|
|
|
|
track: .dc.b 0 * track requested by settrk
|
|
oldtrk: .dc.b 0 * track we were on
|
|
|
|
sector: .dc.w 0
|
|
dma: .dc.l 0
|
|
selcode: .dc.b 0 * drive select code
|
|
|
|
errcnt: .dc.b 10 * retry counter
|
|
|
|
memrgn: .dc.w 1 * 1 memory region
|
|
.dc.l $18000 * load the system at 18000 hex
|
|
.dc.l $8000
|
|
|
|
|
|
* disk parameter headers
|
|
|
|
dph0: .dc.l xlt
|
|
.dc.w 0 * dummy
|
|
.dc.w 0
|
|
.dc.w 0
|
|
.dc.l dirbuf * ptr to directory buffer
|
|
.dc.l dpb * ptr to disk parameter block
|
|
.dc.l 0 * ptr to check vector
|
|
.dc.l 0 * ptr to allocation vector
|
|
|
|
|
|
* disk parameter block
|
|
|
|
dpb: .dc.w 26 * sectors per track
|
|
.dc.b 3 * block shift
|
|
.dc.b 7 * block mask
|
|
.dc.b 0 * extent mask
|
|
.dc.b 0 * dummy fill
|
|
.dc.w 242 * disk size
|
|
.dc.w 63 * 64 directory entries
|
|
.dc.w $c000 * directory mask
|
|
.dc.w 16 * directory check size
|
|
.dc.w 2 * track offset
|
|
|
|
* sector translate table
|
|
|
|
xlt: .dc.b 1, 7,13,19
|
|
.dc.b 25, 5,11,17
|
|
.dc.b 23, 3, 9,15
|
|
.dc.b 21, 2, 8,14
|
|
.dc.b 20,26, 6,12
|
|
.dc.b 18,24, 4,10
|
|
.dc.b 16,22
|
|
|
|
|
|
.bss
|
|
|
|
dirbuf: .ds.b 128 * directory buffer
|
|
|
|
|
|
.end
|