	title	'Root module of relocatable BIOS for CP/M 3.0 -- BIOSKERN 1.700'

	; version 1.0 15 Sept 82

	;********************************************************
	;*	jk82 version 1.700			d.j.	*
	;*	modifikations are marked with '*'		*
	;*	last modifikation:	23.05.84	d.j.	*
	;*	last modifikation:	16.05.85	d.j.	*+
	;*	last modifikation:	31.03.87	d.j.	*@
	;********************************************************

	maclib z80			;				*

true	equ -1
false	equ not true

banked	equ true
	

;		  Copyright (C), 1982
;		 Digital Research, Inc
;		     P.O. Box 579
;		Pacific Grove, CA  93950

;		Copyright (C), 1984/85/87				*
;	     Janich & Klass Computersystems				*
;		  Zum Alten Zollhaus 20					*
;		   D 5600 Wuppertal 1					*
;		      West Germany					*

;   This is the invariant portion of the modular BIOS and is
;	distributed as source for informational purposes only.
;	All desired modifications should be performed by
;	adding or changing externally defined modules.
;	This allows producing "standard" I/O modules that
;	can be combined to support a particular system 
;	configuration.

cr	equ 13
lf	equ 10
bell	equ 7
ctlQ	equ 'Q'-'@'
ctlS	equ 'S'-'@'
ctlc	equ 'C'-'@'	;						*
esc	equ '['-'@'	;						*

ccp	equ 0100h	; Console Command Processor gets loaded into the TPA

;									*
;---------------------------------------------------------------------- *
	cseg		; GENCPM puts CSEG stuff in common memory
;									*

    ; variables in system data page

	extrn @covec,@civec,@aovec,@aivec,@lovec ; I/O redirection vectors
	extrn @mxtpa				; addr of system entry point
	extrn @bnkbf				; 128 byte scratch buffer

    ; initialization

	extrn intsem			; interrupt semaphor in BOOT	  *
	extrn ?init			; general initialization and signon
	extrn ?ldccp,?rlccp		; load & reload CCP for BOOT & WBOOT
	extrn bnkini			; initialize banking hardware	  *
	extrn cioini			; initialize character i/o modul  *
	extrn ?trap			; handle illegal opcode trap (64180) *@

    ; user defined character I/O routines

	extrn ?chrin,?chrout,?chris,?chros ; each take device in <B>	  *
	extrn ?dvini			   ; (re)initialize device in <B> *
	extrn @ctbl,@xctbl		   ; physical character device table *
	public xxlst			   ; xon/xoff-list		  ;*+

    ; disk communication data items

	extrn @dtbl			; table of pointers to XDPHs
	public @adrv,@rdrv,@trk,@sect	; parameters for disk I/O
	public @dma,@dbnk,@cnt		;    ''       ''   ''  ''

    ; memory control

	public @cbnk			; current bank
	public cpubnk			; current cpu-bank		*+
	extrn ?xmove,?move		; select move bank, and block move
	extrn ?bank			; select CPU bank
	extrn call0			; call routine in bank 0	*
	public lowbnk			; start of BIOS in bank 0	*

    ; clock support

	extrn ?time			; signal time operation

    ; spezial functions							*

	extrn sysext			; system extension		*
;	extrn dskch			; disk change			*

    ; general utility routines

	public ?pmsg,?pdec	; print message, print number from 0 to 65535
	public ?pderr		; print BIOS disk error message header
	public ipchl		; vectored CALL point			*

	maclib modebaud		; define mode bits


    ; External names for BIOS entry points

	public ?boot,?wboot,WBOOT,const,conin,conout,list,auxout,auxin	;*+@
	public ?home,?sldsk,?sttrk,?stsec,?stdma,?read,?write
	public listst,?sctrn						;*+
	public conost,auxist,auxost,?dvtbl,?devin,?drtbl		;*+
	public ?mltio,?flush,?mov,?tim,?bnksl,?stbnk,?xmov


    ; BIOS Jump vector.

		; All BIOS routines are invoked by calling these
		;	entry points.

?boot:	jmp boot	; initial entry on cold start
?wboot:	jmp wboot	; reentry on program exit, warm start

?const:	jmp const	; return console input status
?conin:	jmp conin	; return console input character
?cono:	jmp conout	; send console output character
?list:	jmp list	; send list output character
?auxo:	jmp auxout	; send auxilliary output character
?auxi:	jmp auxin	; return auxilliary input character

?home:	jmp home	; set disks to logical home
?sldsk:	jmp seldsk	; select disk drive, return disk parameter info
?sttrk:	jmp settrk	; set disk track
?stsec:	jmp setsec	; set disk sector
?stdma:	jmp setdma	; set disk I/O memory address
?read:	jmp read	; read physical block(s)
?write:	jmp write	; write physical block(s)

?lists:	jmp listst	; return list device status
?sctrn:	jmp sectrn	; translate logical to physical sector

?conos:	jmp conost	; return console output status
?auxis:	jmp auxist	; return aux input status
?auxos:	jmp auxost	; return aux output status
?dvtbl:	jmp devtbl	; return address of device def table
?devin:	jmp cinit	; change baud rate of device

?drtbl:	jmp getdrv	; return address of disk drive table
?mltio:	jmp multio	; set multiple record count for disk I/O
?flush:	jmp flush	; flush BIOS maintained disk caching

?mov:	jmp ?move	; block move memory to memory
?tim:	jmp ?time	; Signal Time and Date operation
?bnksl:	jmp bnksel	; select bank for code execution and default DMA
?stbnk:	jmp setbnk	; select different bank for disk I/O DMA operations.
?xmov:	jmp ?xmove	; set source and destination banks for one operation

	jmp sysext	; system function implementet for special control *
	jmp 0		; reserved for future expansion
	jmp 0		; reserved for future expansion

	; BOOT
	;	Initial entry point for system startup.

;									*
;---------------------------------------------------------------------- *
	dseg	; this part can be banked
;									*
lowbnk:			; start of BIOS in bank 0			*
boot:
	di		; no interrupts allowed at this time		*
	lxi sp,boot$stack
	call bnkini	; initialize banking hardware			*
	call cioini	; initialize character i/o modul		*
	lxi b,16*256+0 	; initialize all 16 character devices		*@
c$init$loop:
	push b ! call cinit ! pop b		;			*@
	inr c  ! djnz c$init$loop		;			*@

	call ?init	; perform any additional system initialization
			; and print signon message

	lxi b,16*256+0 ! lxi h,@dtbl	; init all 16 logical disk drives
d$init$loop:
	push b		; save remaining count and abs drive
	mov e,m ! inx h ! mov d,m ! inx h	; grab @drv entry
	mov a,e ! ora d ! jrz d$init$next	; if null, no drive	*
	push h					; save @drv pointer 
	xchg					; XDPH address in <HL>
	dcx h ! dcx h ! mov a,m ! sta @RDRV	; get relative drive code
	mov a,c ! sta @ADRV			; get absolute drive code
	dcx h					; point to init pointer
	mov d,m ! dcx h ! mov e,m		; get init pointer
	inx h ! inx h ! inx h ! inx h		; XDPH address in <HL>	*
	xchg ! call ipchl			; call init routine
	pop h					; recover @drv pointer
d$init$next:
	pop b					; recover counter and drive #
	inr c ! djnz d$init$loop		; and loop for each drive *@
	xra a ! sta intsem ! ei			; enable interrupt	  *
	jmp boot$1

;=======================================================================*
;									*
; BIOSKERN-Identifikation						*
;									*
	public kernid			; BIOSKERN-ID			*
;									*
	dseg				;				*
;									*
kernid:					;				*
	db	'ID',cr,lf,'BIOSKERN 1.700',0	;			*
;									*
;=======================================================================*

;									*
;---------------------------------------------------------------------- *
	cseg	; following in resident memory
;									*

boot$1:
	call set$jumps
	call ?ldccp				; fetch CCP for first time
	jr ccp$jmp				;			*


	; WBOOT
	;	Entry for system restarts.

wboot:
	pop d			; trap address from user stack		*@
	lxi sp,boot$stack
	call ?trap		; check for trap and handle it		*@
	call set$jumps		; initialize page zero
	lxi h,?rlccp ! call call0	; reload CCP			 *
ccp$jmp:			;					 *
	jmp ccp			; then reset jmp vectors and exit to ccp


set$jumps:

  if banked
	mvi a,1 ! call ?bnksl
  endif

	mvi a,JMP
	sta 0 ! sta 5		; set up jumps in page zero
	lxi h,?wboot ! shld 1	; BIOS warm start entry
	lhld @MXTPA ! shld 6	; BDOS system call entry
	ret


boot$stack	equ 0ff80h+32	; boot stack in interrupt page		*


	; DEVTBL
	;	Return address of character device table

devtbl:
	lxi h,@ctbl ! ret


	; GETDRV
	;	Return address of drive table

getdrv:
	lxi h,@dtbl ! ret

	; CINIT								*
	;	Charater I/O device initialisation			*
	;	initialize device in <C>				*

cinit:					;				*
	mov b,c				; device in <B>			*
cinit$b:				;				*
	lxi d,?dvini ! jr chario	; initialize			*

	; CONOUT
	;	Console Output.  Send character in <C>
	;			to all selected devices

conout:	

	lhld @covec			; fetch console output bit vector
	lxi d,out$scan ! jr chario	; output 			*

	; AUXOUT
	;	Auxiliary Output. Send character in <C>
	;			to all selected devices

auxout:
	lhld @aovec			; fetch aux output bit vector
	lxi d,out$scan ! jr chario	; output 			*

	; LIST
	;	List Output.  Send character in <C>
	;			to all selected devices.

list:
	lhld @lovec			; fetch list output bit vector
	lxi d,out$scan ! jr chario	; output 			*


	; CONOST
	;	Console Output Status.  Return true if
	;		all selected console output devices
	;		are ready.

conost:
	lhld @covec			; get console output bit vector
	lxi d,ost$scan ! jr chario	; output status			*


	; AUXOST
	;	Auxiliary Output Status.  Return true if
	;		all selected auxiliary output devices
	;		are ready.

auxost:
	lhld @aovec			; get aux output bit vector
	lxi d,ost$scan ! jr chario	; output status			*


	; LISTST
	;	List Output Status.  Return true if
	;		all selected list output devices
	;		are ready.

listst:
	lhld @lovec			; get list output bit vector
	lxi d,ost$scan ! jr chario	; output status			*



	; CONST
	;	Console Input Status.  Return true if
	;		any selected console input device
	;		has an available character.

const:
	lhld @civec			; get console input bit vector
	lxi d,ist$scan ! jr chario	; input status			*


	; AUXIST
	;	Auxiliary Input Status.  Return true if
	;		any selected auxiliary input device
	;		has an available character.

auxist:
	lhld @aivec			; get aux input bit vector
	lxi d,ist$scan ! jr chario	; input status			*



	; CONIN
	;	Console Input.  Return character from first
	;		ready console input device.

conin:
	lhld @civec
	lxi d,in$scan ! jr chario	; input 			*


	; AUXIN
	;	Auxiliary Input.  Return character from first
	;		ready auxiliary input device.

auxin:
	lhld @aivec
	lxi d,in$scan 			; input 			*

chario:	xchg ! jmp call0		; call routine in bank 0	*
;									*
;---------------------------------------------------------------------- *
	dseg				;				*
;									*
; character i/o in bank 0						*
;									*
;---------								*
out$scan:
;---------								*
	xchg		;						*
	mvi b,0		; start with device 0
co$next:
	dad h		; shift out next bit
	jrnc not$out$device				;		*
	push h		; save the vector
	call fetch$time$out$byte			;		*
	lxi  h,time$out$const				;		*
not$out$ready:
	push b		; save the count and character
	dcx  h						;		*
	mov  a,h					;		*
	ora  l						;		*
	push h						;		*
	jrnz no$time$out				;		*
	lxi  h,time$out$const				;		*
	xthl			; ex (sp),hl				*
	lda  time$out$byte				;		*
	ana  a			; restore flags				*
	jrz  no$time$out				;		*
	dcr  a						;		*
	push psw	; save time out byte in stack for reentrant	*
	cz time$out	; send 'TIME OUT" to console			*
	pop  psw	; restore time out byte				*
	jrz  no$time$out				;		*
	sta  time$out$byte				;		*
no$time$out:						;		*
	call coster ! ora a ! pop h ! pop b ! jrz not$out$ready	;	*
	push b		; resave the character and device		*
	call ?chrout	; if device selected, print it			*
next$device:		; entry from time$out				*
	pop b		; recover count and character
	pop h		; recover the rest of the vector
not$out$device:
	inr b		; next device number
	mov a,h ! ora l	; see if any devices left
	jrnz co$next	; and go find them...				*
	ret
;									*
;---------								*
time$out:		; send 'TIME OUT' to console			*
;---------								*
			; input: b = time out device			*
	mov  a,b ! add a ! add a ! add a 	; a = 8 * b		*
	lxi  h,@ctbl 				;			*
	mov  e,a ! mvi d,0 ! dad d 		; hl = .device name	*
	lxi  d,device$message			;			*
	push b					;			*
	lxi  b,6 ! ldir				; device name in message*
	pop  b	 ! push b			;			*
	mvi  d,1000$0000b 			;			*
	mvi  e,0				;			*
time$out$dev$loop:				;			*
	xra  a		; a = 0						*
	cmp  b		; first device ?				*
	jrz  blank$device			;			*
	srlr d					;			*
	rarr e		; shift device bit right			*
	dcr  b		; search for device				*
	jr   time$out$dev$loop			;			*
blank$device:					;			*
	lhld @covec	; fetch console output bit vektor		*
	push h		; save it					*
	call blank$out				;			*
	shld @covec	; no console output to time out device		*
	lhld @aovec	; fetch aux output bit vector			*
	push h		; save it					*
	call blank$out				;			*
	shld @aovec	; no oux output to time out device		*
	lhld @lovec	; fetch list output bit vector			*
	push h		; save it					*
	call blank$out				;			*
	shld @lovec	; no list output to time out device		*
	lhld device$message   ! push h		; save device name	*
	lhld device$message+2 ! push h		; save device name	*
	lhld device$message+4 ! push h		; save device name	*
	lxi  h,time$out$message			;			*
	call ?pmsg				;			*
	pop h ! shld device$message+4		; restore device name	*
	pop h ! shld device$message+2		; restore device name	*
	pop h ! shld device$message		; restore device name	*
	lxi h,device$message			;			*
	call ?pmsg				; output device name	*
	call conin	; get response					*
	cpi  esc	; escape ?					*
	jrz  device$blank			;			*
	pop  h ! shld @lovec ; restore list output bit vector		*
	pop  h ! shld @aovec ; restore oux output bit vector		*
	pop  h ! shld @covec ; restore console output bit vector	*
	cpi  ctlc	; control c ?					*
	jz   ?wboot	; warm start on ctl c				*
	jr   time$out$end			;			*

device$blank:					;			*
	pop h ! pop h ! pop h	; adjust stack				*
	pop b		; restore count and character			*
	pop h ! pop h ! pop h	; adjust stack				*
	jmp next$device				;			*

time$out$end:					;			*
	pop b		; restore count and character			*

fetch$time$out$byte:				;			*
	lxi  d,@xctbl+1	; extended device table				*
	mov  l,b	;						*
	mvi  h,0	;						*
	dad  h ! dad h ! dad h	; hl = hl * 8				*
	dad  d		;						*
	mov  a,m	; time out byte					*
	sta  time$out$byte			;			*
	ret					;			*

blank$out:					;			*
	mov  a,d ! cma ! ana h ! mov h,a	;			*
	mov  a,e ! cma ! ana l ! mov l,a ; blank out time out device	*
	ret					;			*

time$out$message:				;			*
	db	bell,cr,lf,'TIME OUT ',0	;			*
device$message:					;			*
	db	0,0,0,0,0,0			;			*
	db	'? ',0				;			*
time$out$byte:					;			*
	db	0				;			*
;									*
;---------								*
ost$scan:
;---------								*
	xchg		;						*
	mvi b,0		; start with device 0
cos$next:
	dad h		; check next bit
	push h		; save the vector
	push b		; save the count
	mvi a,0FFh	; assume device ready
	cc coster	; check status for this device
	pop b		; recover count
	pop h		; recover bit vector
	ora a		; see if device ready
	rz		; if any not ready, return false
	inr b		; drop device number
	mov a,h ! ora l	; see if any more selected devices
	jrnz cos$next	;						*
	ori 0FFh	; all selected were ready, return true
	ret

coster:		; check for output device ready, including optional
		;	xon/xoff support
	mov l,b ! mvi h,0	; make device code 16 bits
	push h			; save it in stack
	dad h ! dad h ! dad h	; create offset into device characteristics tbl
	lxi d,@ctbl+6 ! dad d	; make address of mode byte
	mov a,m ! ani mb$xonxoff
	pop h			; recover console number in <HL>
	jz ?chros		; not a xon device, go get output status direct *
	lxi d,xofflist ! dad d	; make pointer to proper xon/xoff flag
	call cist1		; see if this keyboard has character
	mov a,m ! cnz ci1	; get flag or read key if any
	cpi ctlq ! jrnz not$q	; if its a ctl-Q,			*
	mvi a,0FFh 		;	set the flag ready
not$q:
	cpi ctls ! jrnz not$s	; if its a ctl-S,			*
	mvi a,00h		;	clear the flag
not$s:
	mov m,a			; save the flag
	call cost1		; get the actual output status,
	ana m			; and mask with ctl-Q/ctl-S flag
	ret			; return this as the status

cist1:			; get input status with <BC> and <HL> saved
	push b ! push h 
	call ?chris		;					*
	pop h ! pop b
	ora a
	ret

cost1:			; get output status, saving <BC> & <HL>
	push b ! push h
	call ?chros		;					*
	pop h ! pop b
	ora a
	ret

ci1:			; get input, saving <BC> & <HL>
	push b ! push h
	call ?chrin		;					*
	pop h ! pop b
	ret
;									*
;---------								*
ist$scan:
;---------								*
;
	xchg		;						*
	mvi b,0		; start with device 0
cis$next:
	dad h		; check next bit
	mvi a,0		; assume device not ready
	cc cist1	; check status for this device
	ora a ! rnz	; if any ready, return true
	inr b		; drop device number
	mov a,h ! ora l	; see if any more selected devices
	jrnz cis$next					;		*
	xra a		; all selected were not ready, return false
	ret
;									*
;--------								*
in$scan:
;--------								*
;									*
	mvi b,0
	push d		; save bit vector				*
	call ist$scan	; input status scan				*
			; if ready ==> return with b = number of device	*
	pop d		; recover bit vektor				*
	jnz ?chrin	; character input				*
	jr in$scan	; loop til we find a character			*

xxlst:									;*+
xofflist:	db	-1,-1,-1,-1,-1,-1,-1,-1		; ctl-s clears to zero
		db	-1,-1,-1,-1,-1,-1,-1,-1
;									*
;---------------------------------------------------------------------- *
	cseg
;									*
;	Utility Subroutines


ipchl:		; vectored CALL point
	pchl


;									*
;---------------------------------------------------------------------- *
	dseg					;			*
;									*
?pmsg:		; print message @<HL> up to a null
		; saves <BC> & <DE>
	push b
	push d
pmsg$loop:
	mov a,m ! ora a ! jrz pmsg$exit					;*+
	mov c,a ! push h
	call conout ! pop h						;*+
	inx h ! jr pmsg$loop						;*+
pmsg$exit:
	pop d
	pop b
	ret

?pdec:		; print binary number 0-65535 from <HL>
	lxi b,table10! lxi d,-10000
next:
	mvi a,'0'-1
pdecl:
	push h! inr a! dad d! jrnc stoploop				;*+
	inx sp! inx sp! jr pdecl					;*+
stoploop:
	push d! push b
	mov c,a! call conout						;*+
	pop b! pop d
nextdigit:
	pop h
	ldax b! mov e,a! inx b
	ldax b! mov d,a! inx b
	mov a,e! ora d! jrnz next					;*+
	ret

table10:
	dw	-1000,-100,-10,-1,0

?pderr:
	lxi h,drive$msg ! call ?pmsg			; error header
	lda @adrv ! adi 'A' ! mov c,a ! call conout	; drive code	;*+
	lxi h,track$msg ! call ?pmsg			; track header
	lhld @trk ! call ?pdec				; track number
	lxi h,sector$msg ! call ?pmsg			; sector header
	lhld @sect ! call ?pdec				; sector number
	ret

;									*
;---------------------------------------------------------------------- *
	cseg					;			*
;									*
	; BNKSEL
	;	Bank Select.  Select CPU bank for further execution.

bnksel:
	sta @cbnk 			; remember current bank
	jmp ?bank			; and go exit through users
					; physical bank select routine


;									*
;----------------------------------------------------------------------	*
	dseg	; following resides in banked memory
;									*


;	Disk I/O interface routines


	; SELDSK
	;	Select Disk Drive.  Drive code in <C>.
	;		Invoke login procedure for drive
	;		if this is first select.  Return
	;		address of disk parameter header
	;		in <HL>

seldsk:
	mov a,c ! sta @adrv			; save drive select code
	mov l,c ! mvi h,0 ! dad h		; create index from drive code
	lxi b,@dtbl ! dad b			; get pointer to dispatch table
	mov a,m ! inx h ! mov h,m ! mov l,a	; point at disk descriptor
	ora h ! rz 				; if no entry in table, no disk
	mov a,e ! ani 1 ! jrnz not$first$select	; examine login bit		;*+
	push h ! xchg				; put pointer in stack & <DE>
	lxi h,-2 ! dad d ! mov a,m ! sta @RDRV	; get relative drive
	lxi h,-6 ! dad d			; find LOGIN addr
	mov a,m ! inx h ! mov h,m ! mov l,a	; get address of LOGIN routine
	call ipchl				; call LOGIN
	pop h					; recover DPH pointer
not$first$select:
	ret


	; HOME
	;	Home selected drive.  Treated as SETTRK(0).

home:
	lxi b,0		; same as set track zero


	; SETTRK
	;	Set Track. Saves track address from <BC> 
	;		in @TRK for further operations.

settrk:
	mov l,c ! mov h,b
	shld @trk
	ret


	; SETSEC
	;	Set Sector.  Saves sector number from <BC>
	;		in @sect for further operations.

setsec:
	mov l,c ! mov h,b
	shld @sect
	ret


	; SETDMA
	;	Set Disk Memory Address.  Saves DMA address
	;		from <BC> in @DMA and sets @DBNK to @CBNK
	;		so that further disk operations take place
	;		in current bank.

setdma:
	mov l,c ! mov h,b
	shld @dma

	lda @cbnk	; default DMA bank is current bank
			; fall through to set DMA bank

	; SETBNK
	;	Set Disk Memory Bank.  Saves bank number
	;		in @DBNK for future disk data
	;		transfers.

setbnk:
	sta @dbnk
	ret


	; SECTRN
	;	Sector Translate.  Indexes skew table in <DE>
	;		with sector in <BC>.  Returns physical sector
	;		in <HL>.  If no skew table (<DE>=0) then
	;		returns physical=logical.

sectrn:
	mov l,c ! mov h,b
	mov a,d ! ora e ! rz
	xchg ! dad b ! mov l,m ! mvi h,0
	ret


	; READ
	;	Read physical record from currently selected drive.
	;		Finds address of proper read routine from
	;		extended disk parameter header (XDPH).

read:
	lhld @adrv ! mvi h,0 ! dad h	; get drive code and double it
	lxi d,@dtbl ! dad d		; make address of table entry
	mov a,m ! inx h ! mov h,m ! mov l,a	; fetch table entry
	push h				; save address of table
	lxi d,-8 ! dad d		; point to read routine address
	jr rw$common			; use common code		;*+


	; WRITE
	;	Write physical sector from currently selected drive.
	;		Finds address of proper write routine from
	;		extended disk parameter header (XDPH).

write:
	lhld @adrv ! mvi h,0 ! dad h	; get drive code and double it
	lxi d,@dtbl ! dad d		; make address of table entry
	mov a,m ! inx h ! mov h,m ! mov l,a	; fetch table entry
	push h				; save address of table
	lxi d,-10 ! dad d		; point to write routine address

rw$common:
	mov a,m ! inx h ! mov h,m ! mov l,a	; get address of routine
	pop d				; recover address of table
	dcx d ! dcx d			; point to relative drive
	ldax d ! sta @rdrv		; get relative drive code and post it
	inx d ! inx d			; point to DPH again
	pchl				; leap to driver


	; MULTIO
	;	Set multiple sector count. Saves passed count in
	;		@CNT

multio:
	sta @cnt ! ret


	; FLUSH
	;	BIOS deblocking buffer flush.  Not implemented.

flush:
	xra a ! ret		; return with no error



	; error message components
drive$msg:	db	cr,lf,bell,'BIOS Error on ',0
track$msg:	db	': T-',0
sector$msg:	db	', S-',0


    ; disk communication data items

@adrv:	ds	1		; currently selected disk drive
@rdrv:	ds	1		; controller relative disk drive
@trk:	ds	2		; current track number
@sect:	ds	2		; current sector number
@dma:	ds	2		; current DMA address
@cnt:	db	0		; record count for multisector transfer
@dbnk:	db	0		; bank for DMA operations


;									*
;---------------------------------------------------------------------- *
	cseg	; common memory
;									*

@cbnk:	db	0		; bank for processor operations
cpubnk:	db	0		; active cpu bank			*+

	end
