; NUAN-1.INS - Apple // with PCPI Applicard and MTN CPS Serial Card
;
;		2651 with internal baudrate generator
;
; This insert version is for the Apple ][+ with the Mountain Computer
; CPS Serial Interface Card and PCPI Applicard.
;
; Thanks to Norman Beeler for previous versions of this insert.
;
; --------
;
; 04/21/86  Modified for NUBYE
; 12/23/85  Written for BYE5		- H. Middlebrook
;
; --------
;
; CPS Serial Interface Routines
;
SLOT	EQU	2			; CPS card slot number
;
; CPS Serial Port and Register Equates
;
DATREG	EQU	0C0FAH + SLOT *	100H	;Serial Data Register
STAREG	EQU	0C0FBH + SLOT *	100H	;Serial Status Register
SCRCTL	EQU	0C0FEH + SLOT *	100H	;CPS Serial Ctl Register
CLKREG	EQU	0C0F9H + SLOT *	100H	;CPS Clock Data Register
;
RDBYTEAPPL	EQU	0FFE0H		;Read byte from Apple
WRBYTEAPPL	EQU	0FFE3H		;Write byte to Apple
RDWORD		EQU	0FFE6H		;Read 2 bytes  (DE = Bytes)
WRWORD		EQU	0FFE9H		;Write 2 bytes (DE = Bytes)
;
PEEK1BYTE	EQU	6		;Command to Peek 1 byte to Apple
POKE1BYTE	EQU	7		;Command to Poke 1 byte to Apple
;
; The following routines communicate with hardware in Apple Slots
; directly from Applicard.
;
; Read the UART Status Register
;
RD$STAREG:
	PUSH	D
	LXI	D,STAREG
	CALL	PEEK
	POP	D
	RET
;
; Write to the UART Status Register
;
WR$STAREG:
	PUSH	D
	LXI	D,STAREG
	CALL	POKE
	POP	D
	RET
;
; Write to the UART Command Port
;
WR$SCRCTL:
	PUSH	D
	LXI	D,SCRCTL
	CALL	POKE
	POP	D
	RET
;
; Read the UART Data Register
;
RD$DATREG:
	PUSH	D
	LXI	D,DATREG
	CALL	PEEK
	POP	D
	RET
;
; Write to the UART Data Register
;
WR$DATREG: PUSH	D
	LXI	D,DATREG
	CALL	POKE
	POP	D
	RET
;
; Read a byte from CPS clock register
;
RD$CLKDATA:
	PUSH	D
	LXI	D,CLKREG	; Select clock data
	CALL	PEEK
	POP	D
	RET
;
; PEEK at 1 byte in Apple address space
;    ENTRY  DE = Address in 6502 RAM/ROM
;    EXIT   A  = Data from 6502
;
PEEK:	PUSH	B
	MVI	C,PEEK1BYTE
	CALL	WRBYTEAPPL
	CALL	WRWORD
	CALL	RDBYTEAPPL
	POP	B
	RET
;
; POKE 1 byte to Apple address space
;    ENTRY  DE = Address in 6502 RAM/ROM
;    EXIT   A  = data to 6502
;
POKE:	PUSH	B
	MOV	B,A
	MVI	C,POKE1BYTE
	CALL	WRBYTEAPPL
	CALL	WRWORD
	MOV	C,B
	CALL	WRBYTEAPPL
	POP	B
	RET
;
; This routine intializes Serial Port of CPS card and (optionally)
; initializes ASCII commanded modem.  NOTE: PSW and BAUD must be set
; by two sequential writes to DATREG with SCRCTL access open.
;
MDINIT:	MVI	A,80H
	CALL	WR$SCRCTL
	MVI	A,15H		; Drop DTR and reset serial I/O
	CALL	WR$STAREG
	MVI	B,20
;
MDDLOP:	CALL	DELAY		; 2 second delay
	DCR	B
	JNZ	MDDLOP
	MVI	A,27H		; Now re-enable serial port
	CALL	WR$STAREG
	MVI	A,4EH		; Set PSW = 8N1  (1st DATREG write)
	CALL	WR$DATREG
	MVI	A,3AH		; Default to 2400 baud
;
	 IF	HS1200
	MVI	A,37H
	 ENDIF			; HS1200
;
	 IF	HS300
	MVI	A,35H
	 ENDIF			; HS300
;
	CALL	WR$DATREG	; Set baud (2nd DATREG write)
	XRA	A		; Close BAUD/PSW access
	CALL	WR$SCRCTL
;
	 IF	IMODEM
	CALL	IMINIT		; Initialize smartmodem
	 ENDIF			; IMODEM
;
	RET
;
; This routine is called when NUBYE is to go off the air
;
MDQUIT:	 IF	IMODEM
	CALL	IMQUIT
	 ENDIF			; IMODEM
;
; This routine will shut everything down permanently.
;
MDSTOP:	MVI	A,80H		; Enable UART command register
	CALL	WR$SCRCTL
	MVI	A,5		; Disable DTR and RTS (UART Cmd Reg)
	CALL	WR$STAREG
	XRA	A		; Enable CPS status register
	CALL	WR$SCRCTL
	CALL	DELAY		; 100 msec delay
	RET
;
; The following is a routine to determine if there is a character wait-
; ing to be received.  If none are there, the Zero flag will be set,
; otherwise, 255 will be returned in register A.
;
MDINST:	CALL	RD$STAREG	; Read UART command register
	ANI	2		; Mask everything but RxRDY, char ready?
	RZ			; No, then return
	ORI	0FFH		; Yes, be sure to set flag and A reg
	RET
;
; The following is a routine to determine if the transmit buffer is
; empty.  If it is empty, it will return with the Zero flag clear.  If
; the transmitter is busy, then it will return with the Zero flag set.
;
;
MDOUTST:CALL	RD$STAREG	; Read status register
	ANI	1		; Mask everything but TxRDY and...
	RET			; Return with flags set
;
; The following is a routine that will check to make sure we still have
; carrier.  If there is no carrier, it will return with the Zero flag
; set.	There are two entry points to this section: the 1st MDCRDL delays
; for 2 seconds or until carrier is detected.  The second is the normal
; entry for carrier check.
;
MDCRDL:	PUSH	B
	MVI	B,20		; Set for 2 sec delay max
;
MDCK2:	CALL	DELAY		; Wait 100 msecs
	CALL	MDCARCK
	JNZ	MDCK1		; If carrier, then return
	DCR	B
	JNZ	MDCK2		; If not 2 secs, then continue timing
;
MDCK1:	POP	B		; When done fall thru to carrier check
;
;
; This is normal carrier check routine.
;
MDCARCK:CALL	RD$STAREG	; Read status register
	ANI	080H		; Use DSR bit instead of DTR bit
	RET
;
; The following is a routine that will input one character from the
; CPS UART register.
;
MDINP:	CALL	RD$DATREG	; Get character
	RET
;
; The following is a routine that will output one character in register
; A to the CPS UART data register.
;
MDOUTP:	CALL	WR$DATREG	; Send character to CPS UART
	RET
;
; The following routines set the CPS card to a specified baud rate. A
; common setup routine is jumped to after baud setup byte in local
; storage.
;
SET300:	MVI	A,35H		; 300 baud setup byte
	STA	MBSET
	JMP	BPSET		; Jump to psw/baud set routine
;
SET1200:MVI	A,37H		; 1200 bps byte
	STA	MBSET
	JMP	BPSET
;
SET2400:MVI	A,3AH		; 2400 bps byte
	STA	MBSET
;
BPSET:	MVI	A,80H		; Open command register
	CALL	WR$SCRCTL	; By storing 80H in SCRCTL
	MVI	A,27H		; Initialize the serial chip
	CALL	WR$STAREG	; By storing 27H in STAREG
	MVI	A,4EH		; Set default format 8N1
	CALL	WR$DATREG
	LDA	MBSET		; Get baud rate byte from local storage
	CALL	WR$DATREG
	XRA	A
	CALL	WR$SCRCTL	; Close command port by storing 0
	RET
;
MBSET:	DB	0		; Storage for baud setup byte
;
; end of insert
; -------------
