	title	'CP/M plus loader BIOS kernel for PROF-180X'

;letzte Aenderung am 26.02.1987 (Joachim)

dirbuf	equ	4000h		; deblocking buffer liegen
dtabuf	equ	dirbuf+1024	; unterhalb von CPMLDR

; Achtung, dieser Teil des LDRBIOS fuer PROF-180X kann im allgemeinen
; unveraendert bleiben. Bei Aenderungen des Disk-Treiber-Modules (neue
; Formate) braucht lediglich der Disktreiber (P7.ASM, PD..asm) neu
; assembliert zu werden.
; 
; Linken:
;
;	LINK CPMLDR[L4900]=CPMLDR,PL,P7,PD
;
;


    ; disk communication data items

	extrn	fdsd0			;	

	public @ermde			;
	public @adrv,@rdrv,@trk,@sect	; parameters for disk I/O
	public @dma,@dbnk,@cnt		;    ''       ''   ''  ''

    ; memory control

	public @cbnk			; current bank


	public ?pmsg		; print message
	public ibtab,ciecho	;

	maclib	pvec		; monitorvector

	maclib	hd64180		;

    ; External names for BIOS entry points

	public ?const,?conin,?cono,?bank


	cseg

	jmp 	boot	; initial entry on cold start
?wboot:	call 	restart	; reentry to monitor

?const:	jmp 	mcs	; return console input status
?conin:	jmp 	mci	; return console input character
?cono:	jmp 	mco	; send console output character
	call	restart	; send list output character
	call	restart	; send auxilliary output character
	call	restart	; return auxilliary input character

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

	call	restart	; return list device status
	jmp	sectrn	; translate logical to physical sector

	call	restart	; return console output status
	call	restart	; return aux input status
	call	restart	; return aux output status
	call	restart	; return address of device def table
	call	restart	; change baud rate of device

	call	restart	; return address of disk drive table
	jmp	multio	; set multiple record count for disk I/O
	call	restart	; flush BIOS maintained disk caching

	jmp	move	; block move memory to memory
	call	restart	; Signal Time and Date operation
?bank	ret ! nop ! nop	; select bank for code execution and default DMA
	jmp	setbnk	; select different bank for disk I/O DMA operations.
	call	restart	; set source and destination banks for one operation

	call	restart	; user funktion

	call	restart	; reserved for future expansion
	call	restart	; reserved for future expansion

restart	jmp	38h	; Ruecksprung in Monitor bei ungueltiger
			; BIOS-funktion


boot:						; Initial entry point for
						; loader startup
						;
	lxi	h,fdsd0				; zeige auf dph von drive A
	dcx	h				;
	dcx	h				;
	dcx	h				; point to init pointer
	mov	a,m				;
	dcx	h				;
	mov	l,m				; get init pointer
	mov	h,a				;
	call	ipchl				; call init routine
						;
	lxi	h,fdsd0				; trage deblocking
	lxi	d,18				; buffer in dph ein
	dad	d				;
	lxi	d,buftab			;
	xchg					;
	lxi	b,6				;
	ldir					;

	ret

buftab:	dw	dirbcb
	dw	dtabcb
	dw	0FFFFh

move:
	xchg		;
	ldir		;
	xchg		;
	ret		;


;	Utility Subroutines


ipchl:		; vectored CALL point
	pchl



?pmsg:		; print message @<HL> up to a null
		; saves <BC> & <DE>
	push b
	push d
	push psw
pmsg$loop:
	mov a,m ! ora a ! jz pmsg$exit
	mov c,a ! push h
	call ?cono ! pop h
	inx h ! jmp pmsg$loop
pmsg$exit:
	pop psw
	pop d
	pop b
	ret

ciecho:				;
	call	?conin		;
	push	psw		;
	mov	c,a		;
	call	?cono		;
	mvi	c,0dh		;
	call	?cono		;
	mvi	c,0ah		;
	call	?cono		;
	pop	psw		;
	cpi	'a'		;
	rc			;
	sui	'a'-'A'		;
	ret			;


;	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:
	xra	a				;
	sta	@adrv				; save drive select code
	lxi	h,fdsd0				;
	mov a,e ! ani 1 ! jnz 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

ibtab:				; ibtab gibt die Basisadressen der
				; internen Banks an.
				; Da im Loader-BIOS nur Bank 0
				; benutzt wird, reicht hier ein
				; Eintrag aus.
				;
	db	00h		;


	; 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:
	xra	a			; set @cbnk and
	sta	@cbnk			; and @dbnk
	sta	@dbnk			; to zero
	lxi	h,fdsd0			;
	push h				; save address of table
	lxi d,-8 ! dad d		; point to read routine address
	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	13,10,7,'loader 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
@ermde	db	0		; error message, normaly in scb



@cbnk	db	0		; bank for processor operations
				
				; buffer controll
DIRBCB	DB	0FFH,0,0,0
	DB	0FFH
	DB	0,0,0,0,0
	DW	DIRBUF

DTABCB	DB	0FFH,0,0,0
	DB	0FFH
	DB	0,0,0,0,0
	DW	DTABUF

	end
