;**************************************************************************
;*               CP/M 3 BIOS for Z80em86 Z80 CPU emulator                 *
;*                                                                        *
;*                         Character I/O driver                           *
;*                                                                        *
;*                  Copyright (C) 1992-2009 Stewart Kay                   *
;**************************************************************************
;
; ChangeLog (most recent entries are at top)
; ------------------------------------------
; v1.0.0 - 16 February 2009, S.J.Kay
; - Prepare for public release.
;
; v1.00 - 17 April 1995, S.J.Kay
; - Undocumented changes.
;
; v0.00 - 1992, S.J.Kay
; - Initial creation date.

	.z80
;
	maclib	MODEBAUD.LIB
	maclib	TPORTS.LIB
;
	public	?cinit, ?cist, ?cost, ?co, ?ci
	public	@ctbl
;
crt1	equ	0		;CRT #1   O
crt2	equ	1		;CRT #2   O
kbd1	equ	2		;KBD #1   I
kbd2	equ	3		;KBD #2   I
com1	equ	4		;COM #1  IO
com2	equ	5		;COM #2  IO
com3	equ	6		;COM #3  IO
com4	equ	7		;COM #4  IO
lpt1	equ	8		;LPT #1   O
lpt2	equ	9		;LPT #2   O
lpt3	equ	10		;LPT #3   O
;
	cseg			;common memory
;
; Initialize character devices
?cinit:	ld	a,c
	cp	crt1
	jp	z,cr1int	;CRT #1 initialize
	cp	crt2
	jp	z,cr2int	;CRT #2 initialize
	cp	kbd1
	jp	z,kb1int	;KBD #1 initialize
	cp	kbd2
	jp	z,kb2int	;KBD #2 initialize
	cp	com1
	jp	z,comint	;COM #1 initialize
	cp	com2
	jp	z,comint	;COM #2 initialize
	cp	com3
	jp	z,comint	;COM #3 initialize
	cp	com4
	jp	z,comint	;COM #4 initialize
	cp	lpt1
	jp	z,lptint	;LPT #1 initialize
	cp	lpt2
	jp	z,lptint	;LPT #2 initialize
	cp	lpt3
	jp	z,lptint	;LPT #3 initialize
	ret			;return if no device
;
; Console input status
?cist:	ld	a,b
	cp	kbd1
	jp	z,kb1ist	;KBD #1 input status
	cp	kbd2
	jp	z,kb2ist	;KBD #2 input status
	cp	com1
	jp	z,comips	;COM #1 input status
	cp	com2
 	jp	z,comips	;COM #2 input status
	cp	com3
	jp	z,comips	;COM #3 input status
	cp	com4
 	jp	z,comips	;COM #4 input status
	xor	a
	ret			;return if no device
;
; Console input
?ci:	ld	a,b
	cp	kbd1
	jp	z,kb1ip		;KBD #1 input
	cp	kbd2
	jp	z,kb2ip		;KBD #2 input
	cp	com1
	jp	z,comip		;COM #1 input
	cp	com2
 	jp	z,comip		;COM #2 input
	cp	com3
	jp	z,comip		;COM #3 input
	cp	com4
 	jp	z,comip		;COM #4 input
	xor	a
	ret			;return if no device
;
; Console output status
?cost:	ld	a,b
	cp	crt1
	jp	z,cr1ost	;CRT #1 output status
	cp	crt2
	jp	z,cr2ost	;CRT #2 output status
	cp	com1
	jp	z,comops	;COM #1 output status
	cp	com2
 	jp	z,comops	;COM #2 output status
	cp	com3
	jp	z,comops	;COM #3 output status
	cp	com4
 	jp	z,comops	;COM #4 output status
	cp	lpt1
	jp	z,lptost	;LPT #1 output status
	cp	lpt2
	jp	z,lptost	;LPT #2 output status
	cp	lpt3
	jp	z,lptost	;LPT #3 output status
	ld	a,0ffh
	ret			;return if no device
;
; Console output
?co:	ld	a,b
	cp	crt1
	jp	z,cr1out	;CRT #1 output
	cp	crt2
	jp	z,cr2out	;CRT #2 output
	cp	com1
	jp	z,comop		;COM #1 output
	cp	com2
	jp	z,comop		;COM #2 output
	cp	com3
	jp	z,comop		;COM #3 output
	cp	com4
	jp	z,comop		;COM #4 output
	cp	lpt1
	jp	z,lptop		;LPT #1 output
	cp	lpt2
	jp	z,lptop		;LPT #2 output
	cp	lpt3
	jp	z,lptop		;LPT #3 output
	ret			;return if no device
;
kb1int:	out	(kbd1in),a	;keyboard #1 initialize
	ret
kb1ist:	out	(kbd1st),a	;keyboard #1 status
	ret
kb1ip:	out	(kbd1ip),a	;keyboard #1 input
	ret
;
kb2int:	out	(kbd2in),a	;keyboard #2 initialize
	ret
kb2ist:	out	(kbd2st),a	;keyboard #2 status
	ret
kb2ip:	out	(kbd2ip),a	;keyboard #2 input
	ret

cr1int:	out	(crt1in),a	;CRT #1 initialize
	ret
cr1ost:	out	(crt1st),a	;CRT #1 status
	ret
cr1out:	out	(crt1op),a	;CRT #1 output
	ret
;
cr2int:	out	(crt2in),a	;CRT #2 initialize
	ret
cr2ost:	out	(crt2st),a	;CRT #2 status
	ret
cr2out:	out	(crt2op),a	;CRT #2 output
	ret
;
comint:	ld	bc,com1bd
	cp	com2
	jp	c,fndbdr
	ld	bc,com2bd
	jp	z,fndbdr
	ld	bc,com3bd
	cp	com4
	jp	c,fndbdr
	ld	bc,com4bd
fndbdr:	sub	com1
	ld	d,0		;COM port # to DE (DX in Z80 emulator)
	ld	e,a
	ld	hl,bdrtbl
	ld	a,(bc)		;get CP/M baud rate code from control table
	push	de
	ld	d,0
	ld	e,a
	add	hl,de
	pop	de
	ld	a,(hl)		;get IBM baud rate code from IBM table
	sla	a
	jr	c,badbdr	;baud rate not allowed if C flag set
	or	00000011b	;parity none, 1 stop bit, 8 data bits
	out	(comini),a	;COM initialize
	ret
badbdr:	xor	a
	ld	(bc),a		;kill baud rate in table
	ret

comops:	sub	com1
	ld	d,0		;COM port # to DE (DX in Z80 emulator)
	ld	e,a
	out	(comost),a	;COM output status
	ret
comop:	sub	com1
	ld	d,0		;COM port # to DE (DX in Z80 emulator)
	ld	e,a
	out	(comout),a	;COM output
	ret

comips:	sub	com1
	ld	d,0		;COM port # to DE (DX in Z80 emulator)
	ld	e,a
	out	(comist),a	;COM input status
	ret
comip:	sub	com1
	ld	d,0		;COM port # to DE (DX in Z80 emulator)
	ld	e,a
	out	(cominp),a	;COM input
	ret
;
lptint:	sub	lpt1
	ld	d,0		;LPT port # to DE (DX in Z80 emulator)
	ld	e,a
	out	(lptini),a	;LPT initialize
	ret
lptost:	sub	lpt1
	ld	d,0		;LPT port # to DE (DX in Z80 emulator)
	ld	e,a
	out	(lptsta),a	;LPT status
	ret
lptop:	sub	lpt1
	ld	d,0		;LPT port # to DE (DX in Z80 emulator)
	ld	e,a
	out	(lptout),a	;LPT output
	ret
;
bdrtbl:	db	10000000b	;-- no baud rate
	db	10000000b	;50    baud n/a
	db	10000000b	;75    baud n/a
	db	00000000b	;110   baud - IBM
	db	10000000b	;134   baud n/a
	db	00010000b	;150   baud - IBM
	db	00100000b	;300   baud - IBM
	db	00110000b	;600   baud - IBM
	db	01000000b	;1200  baud - IBM
	db	10000000b	;1800  baud n/a
	db	01010000b	;2400  baud - IBM
	db	10000000b	;3600  baud n/a
	db	01100000b	;4800  baud - IBM
	db	10000000b	;7200  baud n/a
	db	01110000b	;9600  baud - IBM
	db	10000000b	;19200 baud n/a
;
@ctbl:	db	'CRT1  '	;Dev 0, CRT #1 driver
	db	mb$output
	db	baud$none
;
	db	'CRT2  '	;Dev 1, CRT #2 driver
	db	mb$output
	db	baud$none
;
	db	'KBD1  '	;Dev 2, KBD #1 Keyboard
	db	mb$input
	db	baud$none
;
	db	'KBD2  '	;Dev 3, KBD #2 Keyboard
	db	mb$input
	db	baud$none
;
	db	'COM1  '	;Dev 4, serial via COM #1
	db	mb$input+mb$output+mb$serial+mb$soft$baud
com1bd:	db	baud$9600
;
	db	'COM2  '	;Dev 5, serial via COM #2
	db	mb$input+mb$output+mb$serial+mb$soft$baud
com2bd:	db	baud$9600
;
	db	'COM3  '	;Dev 6, serial via COM #3
	db	mb$input+mb$output+mb$serial+mb$soft$baud
com3bd:	db	baud$9600
;
	db	'COM4  '	;Dev 7, serial via COM #4
	db	mb$input+mb$output+mb$serial+mb$soft$baud
com4bd:	db	baud$9600
;
	db	'LPT1  '	;Dev 8,  Centronics via LPT#1
	db	mb$output
	db	baud$none
;
	db	'LPT2  '	;Dev 9,  Centronics via LPT#2
	db	mb$output
	db	baud$none
;
	db	'LPT3  '	;Dev 10, Centronics via LPT#3
	db	mb$output
	db	baud$none
;
	db	0		;marks end of table
;
	end
