
***************************************************************
*		CP/M-68K BIOS
*	Basic Input/Output Subsystem
*	For VMEs10 Emulator with CPM Disk Controller 
***************************************************************
* >as68 -L -T booter.s (occupies $800) 2K
* >as68 -L -T ldrbios.s (occupies $2000) 8k
* >LO68 -s -tb00 -uldr -o cpmldr.sys booter.o ldrlib ldrbios.o 
*     $b00 + $800 = $1300 (which is load address of CPMLDR.sys)
* >putboot cpmldr.sys a:
* >as68 -L -T bios.s 
* >lo68 -r -o cpm.rel -ucpm -um68010 cpmlib bios.o (for mc68010)
* >lo68 -r -o cpm.rel -ucpm cpmlib bios.o (for mc68000)
*
* >size68 CPM.REL
* >reloc -Bf1e000 CPM.REL CPM.SYS

	.globl	_init		* bios initialization entry point
	.globl	_ccp		* ccp entry point

vMajor	equ	1
vMinor	equ	3
vRev		equ	0


* SCM's Control registers and status register
scmCR0	equ		$f19f05
scmCR1	equ		$f19f07
scmCR2	equ		$f19f09
scmCR3	equ		$f19f0b
scmCR4	equ		$f19f0d
scmCR5	equ		$f19f0f
scmCR6	equ		$f19f11
scmSR		equ		$f19f85

	.text

_init:
	bsr.w		SetTPA
	bsr.w		signon
	bsr.b		initHW
	move.l	#trap3h,$8c	* set up trap #3 handler
* assume last drive used (by CPMLDR) is boot drive
*	clr.l		d0
	move.w 	cdcDRV,d0	
	and.l		#$000000FF,d0	*user zero 
	rts

initHW:
	ori.b		#$80,scmCR6	*allow interrupts so abort will work
	rts

trap3h:
	cmpi.w	#nfuncs,d0
	bcc		trapng
	lsl.w		#2,d0		* multiply bios function by 4
	lea		biosbase,a0
	add.w		d0,a0		* get handler address
	move.l	(a0),a0
	jsr		(a0)		* call handler
trapng:
	rte

biosbase:
	dc.l  _init
	dc.l  wboot
	dc.l  ConInSt
	dc.l  ConIn
	dc.l  ConOut
	dc.l  LstOut
	dc.l  AuxOut
	dc.l  AuxIn
	dc.l  home
	dc.l  seldsk
	dc.l  settrk
	dc.l  setsec
	dc.l  setdma
	dc.l  read
	dc.l  write
	dc.l  LstOutSt
	dc.l  sectran
	dc.l  setdma
	dc.l  getseg
	dc.l  getiob
	dc.l  setiob
	dc.l  flush
	dc.l  setexc

tvalue	equ		*-biosbase
nfuncs	equ		tvalue/4

wboot:
		jmp		_ccp

* 	LST   AUXOUT	AUXIN   	CON
* 0	TTY	 TTY		 TTY		TTY
* 1	CRT	 PTP		 PTR		CRT
* 2	LPT	 UP1		 UR1		BAT
* 3	UL1	 UP2		 UR2		UC1

TblCIS
	dc.l		TTYInSt	* TTY
	dc.l		CRTInSt	* CRT
	dc.l		AuxInSt	* BAT
	dc.l		TTYInSt	* UC1
TblCI
	dc.l		TTYIn		* TTY
	dc.l		CRTIn		* CRT
	dc.l		AuxIn		* BAT
	dc.l		TTYIn		* UC1
TblCOS
	dc.l		TTYOutSt	* TTY
	dc.l		CRTOutSt	* CRT
	dc.l		LstOutSt	* BAT
	dc.l		TTYOutSt	* UC1
TblCO
	dc.l		TTYOut	* TTY
	dc.l		CRTOut	* CRT
	dc.l		LstOut	* BAT
	dc.l		TTYOut	* UC1

TblAIS
	dc.l		TTYInSt	* TTY
	dc.l		TTYInSt	* RDR
	dc.l		TTYInSt	* UR1
	dc.l		TTYInSt	* UR2
TblAI
	dc.l		TTYIn		* TTY
	dc.l		TTYIn		* RDR
	dc.l		TTYIn		* UR1
	dc.l		TTYIn		* UR2
TblAOS
	dc.l		TTYOutSt	* TTY
	dc.l		TTYOutSt	* PTP
	dc.l		TTYOutSt	* UP1
	dc.l		TTYOutSt	* UP2
TblAO
	dc.l		TTYOut	* TTY
	dc.l		TTYOut	* PTP
	dc.l		TTYOut	* UP1
	dc.l		TTYOut	* UP2

TblLOS
	dc.l		TTYOutSt	* TTY
	dc.l		CRTOutSt	* CRT
	dc.l		LPTOutSt	* LPT
	dc.l		UL1OutSt	* UL1
TblLO
	dc.l		TTYOut	* TTY
	dc.l		CRTOut	* CRT
	dc.l		LPTOut	* LPT
	dc.l		UL1Out	* UL1

ConInSt:
	lea		TblCIS,a2
CIS	move.b	ioByte,d0
	and.w		#$3,d0
	lsl.w		#2,d0
	move.l	0(a2,d0),a2
	jmp		(a2)
ConIn:
	lea		TblCI,a2
	bra		CIS
ConOutSt:
	lea		TblCOS,a2
	bra		CIS
ConOut:
	lea		TblCO,a2
	bra		CIS

AuxInSt:
	lea		TblAIS,a2
AIS	move.b	ioByte,d0
	and.w		#$c,d0
	move.l	0(a2,d0),a2
	jmp		(a2)
AuxIn:
	lea		TblAI,a2
	bra		AIS

AuxOutSt:
	lea		TblAOS,a2
AOS	move.b	ioByte,d0
	and.w		#$30,d0
	lsr.w		#2,d0
	move.l	0(a2,d0),a2
	jmp		(a2)
AuxOut:
	lea		TblAO,a2
	bra		AOS

LstOutSt:
	lea		TblLOS,a2
LOS	move.b	ioByte,d0
	and.w		#$C0,d0
	lsr.w		#4,d0
	move.l	0(a2,d0),a2
	jmp		(a2)
LstOut:
	lea		TblLO,a2
	bra		LOS

TTYDR 		equ		$f1c1c9
TTYSR			equ		$f1c1cd
TTYRxRDY		equ		$1
TTYTxRDY		equ		$4

TTYInSt:
	move.b	TTYSR,d0		* get status byte
	andi.b	#TTYRxRDY,d0	* data available bit on?
	beq		TTYInNR		* branch if not
	move.w	#$00FF,d0		* set result to ready
	rts
TTYInNR:
	clr.w		d0			* set result to not ready
	rts

TTYIn:
	bsr		TTYInSt		* see if key pressed
	tst.w		d0
	beq		TTYIn			* wait until key pressed
	move.b	TTYDR,d0		* get key
	and.w		#$7f,d0		* clear all but low 7 bits
	cmpi.b	#1,d0
	beq		break
	rts
break:
	trap		#15
	dc.w		0			* return to TenBUG
	rts

TTYOutSt:
	move.b	TTYSR,d0		* get status
	and.b		#TTYTxRDY,d0	* check for transmitter buffer empty
	beq		TTYOutNR		* wait until data can go...
	move.w	#$00FF,d0		* set result to ready
	rts
TTYOutNR:
	clr.w		d0			* set result to not ready
	rts

TTYOut:
	bsr		TTYOutSt		* see if key pressed
	tst.w		d0
	beq		TTYOut		* wait until data can go...
	move.b	d1,TTYDR 		* and output it
	rts					* and exit

CRTDR 		equ		$f1c1cb
CRTSR			equ		$f1c1cf
CRTRxRDY		equ		$1
CRTTxRDY		equ		$4

CRTInSt:
	move.b	CRTSR,d0		* get status byte
	andi.b	#CRTRxRDY,d0	* data available bit on?
	beq		CRTInNR		* branch if not
	move.w	#$00FF,d0		* set result to ready
	rts
CRTInNR:
	clr.w		d0			* set result to not ready
	rts

CRTIn:
	bsr		CRTInSt		* see if key pressed
	tst.w		d0
	beq		CRTIn			* wait until key pressed
	move.b	CRTDR,d0		* get key
	and.w		#$7f,d0		* clear all but low 7 bits
	cmpi.b	#1,d0
	beq		CRTbrk
	rts
CRTbrk:
	trap		#15
	dc.w		0			* return to TenBUG
	rts

CRTOutSt:
	move.b	CRTSR,d0		* get status
	and.b		#CRTTxRDY,d0	* check for transmitter buffer empty
	beq		CRTOutNR		* wait until data can go...
	move.w	#$00FF,d0		* set result to ready
	rts
CRTOutNR:
	clr.w		d0			* set result to not ready
	rts

CRTOut:
	bsr		CRTOutSt		* see if key pressed
	tst.w		d0
	beq		CRTOut		* wait until data can go...
	move.b	d1,CRTDR 		* and output it
	rts					* and exit

PBASE1	equ		$f1c1e1
PBASE2	equ		$f1c1e9
PDATA  	equ		$0
PDATB		equ		$4
PCNTRLA	equ		$2
PCNTRLB	equ		$6
PSTATA	equ		PCNTRLA
PSTATB	equ		PCNTRLB
PDDRA		equ		PDATA
PDDRB		equ		PDATB

PACKN		equ		PSTATA
PSTRB		equ		PCNTRLA
PRDY		equ		PDATB

LPTOutSt:
	lea		PBASE1,a2

	move.b	PRDY(a2),d0
	and.b		#3,d0
	sub.b		#1,d0
	bne.b		LPTNR			* error if not zero
	move.w	#$00ff,d0		* set result to Ready
	rts
LPTNR
	clr.w		d0			* set result to Not Ready
	rts

LPTOut:
	bsr		LPTOutSt		* see if printer online
	tst.w		d0
	beq		LPTOut		* wait until data can go...

	lea		PBASE1,a2

	move.b	d1,PDATA(a2)	* send character
	move.b	PDATA(a2),d1	* clear ack

	move.b	#$34,PSTRB(a2)	* strobe LOW
	move.b	#$3c,PSTRB(a2)	* destrobe

LPTNACK
	btst.b	#7,PACKN(a2)	*check for Ack
	beq.b		LPTNACK

	rts

* User List 1
UL1OutSt:
	lea		PBASE2,a2

	move.b	PRDY(a2),d0
	and.b		#3,d0
	sub.b		#1,d0
	bne.b		UL1NR			* error if not zero
	move.w	#$00ff,d0		* set result to Ready
	rts
UL1NR
	clr.w		d0			* set result to Not Ready
	rts

UL1Out:
	bsr		UL1OutSt		* see if printer online
	tst.w		d0
	beq		UL1Out		* wait until data can go...

	lea		PBASE2,a2

	move.b	d1,PDATA(a2)	* send character
	move.b	PDATA(a2),d1	* clear ack

	move.b	#$34,PSTRB(a2)	* strobe LOW
	move.b	#$3c,PSTRB(a2)	* destrobe

UL1NACK
	btst.b	#7,PACKN(a2)	*check for Ack
	beq.b		UL1NACK

	rts

* Aux - PTP RDR
PTPOutSt:
	move.w	#$00ff,d0		* set result to Ready
	rts
PTPOut:
	bsr		PTPOutSt		* see if punch ready
	tst.w		d0
	beq		PTPOut		* wait until data can go...
	rts

PTRInSt:
	move.w	#$00ff,d0		* set result to Ready
	rts
PTRIn:
	bsr		PTRInSt		* see if Reader ready
	tst.w		d0
	beq		PTRIn		* wait until data availible...
	move.w	#$001a,d0
	rts

*
* routine to print sign on message
*
signon:
		pea		memrgn+2	* convert Tpa start to hex ascii
		move.w	#4,-(a7)
		pea		TpaStart
		bsr.w		cHexB
		lea		10(a7),a7 	* remove 4 + 4 + 2

		pea		memrgn+6	* convert Tpa length to hex ascii
		move.w	#4,-(a7)
		pea		TpaLength
		bsr.w		cHexB
		lea		10(a7),a7 	* remove 4 + 4 + 2

		lea		message,a0
prints:
		move.b	(a0)+,d1
		beq.b		prsDone
		jsr		ConOut
		bra.b		prints
prsDone:
		rts
*
* routines to convert number to hex string
*
tbHex:
	dc.b		'0123456789ABCDEF'
	.even
cHexN:
	move.b	tbHex(pc,d1.w),d0
	rts

* entry - stack has been pushed - InBuff.L, Count.W, OutBuff.L
*  d0 = count, d1 = byte, d2 = shifter/index 
cHexB:
	link		a6,#-2
	movem.l	d0/d1/d2/a0/a1,-(a7)

	move.l	8(a6),a1	*outbuff
	move.w	12(a6),d0	*count
	move.l	14(a6),a0	*in buff

cHexTop:
	tst.w		d0
	beq		cHexEx		
	move.b	(a0)+,d1	*get byte

	move.b	d1,d2
	lsr.w		#4,d2
	andi.w	#$f,d2
	move.b	tbHex(pc,d2.w),d2
	move.b	d2,(a1)+
	move.w	d1,d2
	andi.w	#$f,d2
	move.b	tbHex(pc,d2.w),d2
	move.b	d2,(a1)+

	subq.w	#1,d0
	bra		cHexTop

cHexEx:
	movem.l	(a7)+,d0/d1/d2/a0/a1
	unlk		a6
	rts

SetTPA:
	lea		msgTPA,a0
	jsr		prints
	jsr		ConIn
	move.w	d0,d1		*echo 
	jsr		ConOut
	move.w	d1,d0
	
	lea		TPASPECS,a0
	move.w	#11,d1
N2:
	cmp.b		0(a0,d1.w),d0
	dbeq		d1,N2

	tst.w		d1
	bmi		SetTPA

	lsr.w		#1,d1
	
	lea		rgndata,a0
	lsl.w		#3,d1		*multiply by 8
	move.l	0(a0,d1.w),memrgn+2
	move.l	4(a0,d1.w),memrgn+6

	lea		msgCRL2,a0
	bsr		prints

	rts
*
* Disk Handlers for CPM disk controller
*

cdcCMDr	equ	1		* read command
cdcCMDw	equ	2		* write command

cdcIOB	equ 	$00f1a200	* CPM disk port base address
cdcCMD	equ	cdcIOB		* output port for command
cdcSTS	equ 	cdcIOB		* input status port
cdcDRV	equ	cdcIOB+2	* drive select port
cdcCYL	equ 	cdcIOB+4	* disk cylinder port
cdcHD	 	equ	cdcIOB+6	* disk head port
cdcSCT	equ 	cdcIOB+8	* disk sector port
cdcDMA	equ	cdcIOB+$a	* disk dma port
cdcTRK	equ	cdcIOB+$e	* CPM track port

cdcCYLS equ	cdcIOB+$14
cdcHDS  equ	cdcIOB+$16
cdcSPT equ	cdcIOB+$18
cdcSSZ equ	cdcIOB+$1a

*   CmdSts-H     CmdSts-L     +00
*   Drive-H      Drive-L      +02
*   Cylinder-H   Cylinder-L   +04
*   Head-H       Head-L       +06
*   Sector-H     Sector-L     +08
*   DMA-hh       DMA-hl       +0a
*   DMA-lh       DMA-ll       +0c
*   Track-h	     Track-l      +0e
* Must access as words (except DMA can be long)

* 15 14 13 12 11 10 9  8  7   6   5   4   3   2   1   0
*                        R/W  WP DMA  C   H   S  DRV CMD

home:
	clr.w		track
	rts

seldsk:	
*	select disk given by register d1.b
	move.b	d1,d0
	and.w		#$f,d0	* make sure 0-15
	lsl.w		#2,d0		* mult by 4 to make longword pointer
	lea		dphtbl,a0	* address of 16 pointers to DPHs
	move.l	0(a0,d0.w),d0
	tst.l		d0		* check for invalid drive
	beq.b		selrtn	* drive is invalid
	btst.l	#0,d2		* check for disk already logged in
	bne.b		loggedin
	bsr.b		dologin
loggedin:
	move.b	d1,seldrv	* save drive number
selrtn:
	rts

dologin:
* spectbl format $hds16 spt16,  ssz16  cyls16 , DPB32 ,XLT32
* d4 = hds16 spt16 
* d5 = ssz16 cyls16

	move.w	cdcSTS,d4	* clear errors
	move.b	d1,d4		* get drive number 0-f
	and.w		#$f,d4	* make sure 0-15
	move.w	d4,cdcDRV	* Select Disk to get specs
	move.w	#2,cdcTRK	* Select data track
	move.w	cdcSTS,d4	* see if good drive
	beq.b		OK
	clr.l		d0		*set bad select
	rts
OK:
	move.w	cdcHDS,d4
	swap		d4
	move.w	cdcSPT,d4
	move.w	cdcSSZ,d5
	swap		d5
	move.w	cdcCYLS,d5
* search SpecTble for Match of D4 and D5 to SpecTlb +0 and +4
	move.w	#MaxSTE,d6
	bra.b		NEXT
AGAIN:
	lea		SpecTbl,a1
	move.w	d6,d7
	lsl.w		#4,d7		* mult by 16
	cmp.l		0(a1,d7.w),d4
	bne.b		NEXT
	cmp.l		4(a1,d7.w),d5
	bne.b		NEXT

	move.l	d0,a0			* move pointer to dph in d0 to a0
	move.l	8(a1,d7.w),14(a0) * to DPB in DPH
	move.l	12(a1,d7.w),0(a0) * to XLT in DPH
	rts
NEXT:
	dbf		d6,AGAIN
	clr.l		d0 	* make select invalid
	rts

* end of doLogin


settrk:
	move.w	d1,track
	rts

setsec:
	move.w	d1,sector
	rts

sectran:
*	translate sector in d1 with translate table pointed to by d2
*	result in d0
	tst.l		d2
	beq.b		zerobased
	cmpi.l	#1,d2
	bne.b		trans
onebased:
	move.w	d1,d0
	addq.w	#1,d0
	rts
zerobased:
	move.w	d1,d0
	rts
trans:
	movea.l	d2,a0
*	ext.l	d1
	move.b	0(a0,d1.w),d0
	ext.w		d0
*	ext.l		d0
	rts

setdma:
	move.l	d1,dma
	rts

read:
* Read one sector from requested disk, track, sector to dma address
*  return in d0 00 if ok, else non-zero
	
	move.w	cdcSTS,d7	*read to clear previous errors
	move.l 	dma,cdcDMA
	move.b	seldrv,d7
	ext.w		d7
	move.w	d7,cdcDRV
	move.w	track,cdcTRK
	move.w	sector,cdcSCT
	move.w	#cdcCMDr,cdcCMD

	
rdone:
	move.w	cdcSTS,d7
	andi.w	#$ff,d7		* set condition codes
	bne		rerror
	clr.w		d0
	rts
rerror:
	move.w	#1,d0
	rts

write:
* Write one sector to requested disk, track, sector from dma address
*  return in d0 00 if ok, else non-zero
	move.w	cdcSTS,d7	*read to clear previous errors
	move.l 	dma,cdcDMA
	move.b	seldrv,d7
	ext.w		d7
	move.w	d7,cdcDRV
	move.w	track,cdcTRK
	move.w	sector,cdcSCT
	move.w	#cdcCMDw,cdcCMD

wdone:
	move.w	cdcSTS,d7
	andi.w	#$ff,d7		* set condition codes
	bne		werror
	clr.w		d0
	rts
werror:
	move.w	#1,d0
	rts


flush:
	clr.w		d0		* return successful
	rts

getseg:
	move.l	#memrgn,d0	* return address of mem region table
	rts

getiob:
	clr.w		d0
	move.b	ioByte,d0
	rts

setiob:
	move.b	d1,ioByte
	rts

setexc:
	andi.l	#$ff,d1	* do only for exceptions 0 - 255
	cmpi.w	#47,d1
	beq		noset		* this BIOS doesn't set Trap 15
	cmpi.w	#9,d1		* or Trace
	beq		noset
	lsl.l		#2,d1		* multiply exception nmbr by 4
	movec.l	vbr,a0	* this is a 68010
	adda.l	d1,a0
	move.l	(a0),d0	* return old vector value
	move.l	d2,(a0)	* insert new vector
noset:
	rts

	.data

message:
*	dc.b		13,10
*	dc.b		'CPM68K v',vMajor+$30,'.',vMinor+$30,13,10
	dc.b		'-BIOS v',vMajor+$30,'.',vMinor+$30,'.',vRev+$30
	dc.b		' for VME10 Emulator using CPM DC I/O',13,10
	dc.b		' TPA=0x'
TpaStart:
	dc.b		'xxxxxxxx',' Length=0x'
TpaLength:
	dc.b		'xxxxxxxx'
	dc.b		13,10,0
msgTPA:
	dc.b		13,10
	dc.b		' Select TPA ( H L V 2 C S )- ',0
msgCRL2:
	dc.b		13,10
msgCRLF:
	dc.b		13,10,0

	.even

*   LST   AUXO   AUXI   CON
*---------------------------
*   TTY   TTY    TTY    TTY   0 00
*   CRT   PTP    PTR    CRT   1 01
*   LPT   UP1    UR1    BAT   2 10
*   UL1   UP2    UR2    UC1   3 11

ioByte:	dc.b	$80	*IOBYTE Initially CON,AUXi,AUXo to TTY; and LST to LPT
seldrv:	dc.b	$ff	* drive requested by seldsk

track:	dc.w	0	* track requested by settrk

sector:	dc.w	0

dma:		dc.l	0

* Set up Memory to run from $180000 to $d00000-1

memrgn:	dc.w	1		* 1 memory region
		dc.l	$180000		* start
		dc.l	$b80000		* length - Size = start + (length-1)

* Data for multiple memory regions (only one at a time)
* TENbug uses $400-$AFF
rgndata:
*  this runs from the start of the VMEbus to 1MB below the Pixel Ram
*H Set up Memory to run from $180000 to $e00000-1 (EMULATOR)
		dc.l	$180000		* start
		dc.l	$c80000		* length - Size = start + (length-1)
*L Set up Memory to run from $b00 to $e00000-1 (EMULATOR 2)
		dc.l	$b00
		dc.l	$DFF500
*V Set up Memory to run from $400 to $60000-1 (VME10 - Trashes TENBUG)
		dc.l	$400
		dc.l	$5Fc00
*2 Set up Memory to run from $b00 to $60000-1 (VME10 - Protects TENBUG)
		dc.l	$b00
		dc.l	$5F500
*C Set up Memory to run from $400 to $e00000-1 (CPMSIM)
		dc.l	$400
		dc.l	$dffc00
*S Set up Memory to run from $b00 to $15000-1 (SREC CPM15000.SR - Protects TENBUG)
		dc.l	$b00
		dc.l	$14500
TPASPECS:
		dc.b	'HhLlVv22CcSs'

		.even

* disk specs
*	size	hds	cyls	spt	ssz
*	.25	1	77	26	128	dpb3740	XLT=xlt3740
*	5	2	306	32	256	dpb5mb
*	10	4	306	32	256	dpb10mb
*	15	6	306	32	256	dpb15mb
*	40	6	830	32	256
*	70	8	1024	32	256
*	48tpi	2	40	8	512	dpb48tpi	data tracks
*     CPM86	2	40	8	512	dpb48tpi	data tracks
*	96tpi	2	80	8	512	dpb96tpi	data tracks
*    pc1440 2	80	9	512	dpbPC1440
*  CPMSIM16	1	512	256	128	dpbCS16

* spectbl format $hds16 spt16,  ssz16  cyls16 , DPB32 ,XLT32
* d4 = hds16 spt16 
* d5 = ssz16 cyls16
	
SpecTbl:
	dc.l	$00020020,$01000132,dpb5mb,0		* 5mb
	dc.l	$00040020,$01000132,dpb10mb,0		*10mb
	dc.l	$00060020,$01000132,dpb15mb,0		*15mb
*	dc.l	$00060020,$0100033e,dpb40mb,0		*40mb
*	dc.l	$00080020,$01000400,dpb70mb,0		*70mb
	dc.l	$00020008,$02000028,dpb48TPI,1	*48tpi
*	dc.l	$00020008,$02000028,dpbCPM86,1	*48tpi
	dc.l	$00020008,$02000050,dpb96TPI,1	*96tpi
	dc.l	$0001001a,$0080004d,dpb3470,xlt3470	*.25
	dc.l	$00020012,$02000050,dpbPC1440,1	*PC1440
	dc.l	$00010100,$00800200,dpbCS16,0		*CPMSIM16MB
*MaxSTE equ (*-SpecTbl)\$10	* BUG divide wont work
MaxSTE equ 8

* DPH table
dphtbl:
	dc.l	dph0
	dc.l	dph1
	dc.l	dph2
	dc.l	dph3
	dc.l	0,0,0,0
	dc.l	0,0,0,0
	dc.l	0,0,0,0

* DPHs - disk parameter headers

dph0:	dc.l	xlt3470	* standard IBM 34 translation skew=6
	dc.w	0		* dummy
	dc.w	0
	dc.w	0
	dc.l	dirbuf	* ptr to directory buffer
	dc.l	dpb3470	* ptr to disk parameter block
	dc.l	ckv0	* ptr to check vector
	dc.l	alv0	* ptr to allocation vector

dph1:	dc.l	0	*zero based
	dc.w	0	* dummy
	dc.w	0
	dc.w	0
	dc.l	dirbuf	* ptr to directory buffer
	dc.l	dpb5mb	* ptr to disk parameter block
	dc.l	ckv1	* ptr to check vector
	dc.l	alv1	* ptr to allocation vector

dph2:	dc.l	1	* one based
	dc.w	0	* dummy
	dc.w	0
	dc.w	0
	dc.l	dirbuf	* ptr to directory buffer
	dc.l	dpb96TPI * ptr to disk parameter block
	dc.l	ckv2	* ptr to check vector
	dc.l	alv2	* ptr to allocation vector

dph3:	dc.l	1	* one based
	dc.w	0	* dummy
	dc.w	0
	dc.w	0
	dc.l	dirbuf	* ptr to directory buffer
	dc.l	dpb96TPI * ptr to disk parameter block
	dc.l	ckv3	* ptr to check vector
	dc.l	alv3	* ptr to allocation vector

* DPBs - disk parameter blocks

dpb3470:
	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
dpb96TPI:
	dc.w	32	* sectors per track
	dc.b	4	* block shift
	dc.b	15	* block mask
	dc.b	0	* extent mask
	dc.b	0	* dummy fill
	dc.w	313	* disk size
	dc.w	127	* 128 directory entries
	dc.w	$c000	* directory mask
	dc.w	32	* directory check size
	dc.w	2	* track offset
dpb48TPI:
	dc.w	32	* sectors per track
	dc.b	4	* block shift
	dc.b	15	* block mask
	dc.b	1	* extent mask
	dc.b	0	* dummy fill
	dc.w	153	* disk size
	dc.w	127	* 128 directory entries
	dc.w	$c000	* directory mask
	dc.w	32	* directory check size
	dc.w	2	* track offset
*dpbCPM86:
*	dc.w	32	* sectors per track
*	dc.b	4	* block shift
*	dc.b	15	* block mask
*	dc.b	1	* extent mask
*	dc.b	0	* dummy fill
*	dc.w	157	* disk size
*	dc.w	63	* 128 directory entries
*	dc.w	$8000	* directory mask
*	dc.w	16	* directory check size
*	dc.w	1	* track offset
dpb5mb:
	dc.w	64	* sectors per track
	dc.b	5	* block shift
	dc.b	31	* block mask
	dc.b	1	* extent mask
	dc.b	0	* dummy fill
	dc.w	1215	* disk size
	dc.w	1023	* 1k directory entries
	dc.w	$ff00	* directory mask
	dc.w	$100	* directory check size
	dc.w	2	* track offset
dpb10mb:
	dc.w	64	* sectors per track
	dc.b	5	* block shift
	dc.b	31	* block mask
	dc.b	1	* extent mask
	dc.b	0	* dummy fill
	dc.w	2435	* disk size
	dc.w	2047	* 2k directory entries
	dc.w	$ffff	* directory mask
	dc.w	$200	* directory check size
	dc.w	2	* track offset
dpb15mb:
	dc.w	64	* sectors per track
	dc.b	5	* block shift
	dc.b	31	* block mask
	dc.b	1	* extent mask
	dc.b	0	* dummy fill
	dc.w	3655	* disk size
	dc.w	2047	* 2k directory entries
	dc.w	$ffff	* directory mask
	dc.w	$200	* directory check size
	dc.w	2	* track offset
dpbPC1440:
	dc.w	72	* sectors per track
	dc.b	4	* block shift
	dc.b	15	* block mask
	dc.b	0	* extent mask
	dc.b	0	* dummy fill
	dc.w	710	* disk size
	dc.w	255	* 256 directory entries
	dc.w	$f000	* directory mask
	dc.w	64	* directory check size
	dc.w	2	* track offset
dpbCS16:
	dc.w	256	* sectors per track
	dc.b	4	* block shift
	dc.b	15	* block mask
	dc.b	0	* extent mask
	dc.b	0	* dummy fill
	dc.w	8176	* disk size
	dc.w	4095	* 2k directory entries
	dc.w	0	* directory mask
	dc.w	$400	* directory check size
	dc.w	1	* track offset

* XLTs - sector translate table

xlt3470:
	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

ckv0:	ds.b	$400	* check vector
ckv1:	ds.b	$400
ckv2:	ds.b	$100	* check vector
ckv3:	ds.b	$100

alv0:	ds.b	$400	* allocation vector
alv1:	ds.b	$400
alv2:	ds.b	$200	* allocation vector
alv3:	ds.b	$200

	.end
