From: u895174@bruny.cc.utas.edu.au (Tim Morris)
Subject: 8530 Serial Controller Sample Code
Organization: University of Tasmania, Australia.
Date: Tue, 7 Apr 1992 01:04:07 GMT

I've had a few requests for the sample code I received to initialise the
8530 Serial Controller Chip. Here's one of the posts I received, posted
with his permission. (Thanks Dave!)

First is a discussion of the time delay calculations. Second is some
sample code, in 68000.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

From ficenec@fermi.wustl.edu Sun Apr  5 09:16:34 1992
Subject: time constant
Date: Sat, 04 Apr 92 17:14:32 CST

Hi,

(1) You must set bits 7-6 in WR4 to indicate a conversion constant
    (used later in the time constant) between clock rate and data
    rate. In the example code, the 16x factor is used. 

	Bits 7-6    00    1x
	Bits 7-6    01    16x
	Bits 7-6    10    32x
        Bits 7-6    11    64x

	
(2) You must calculate a 16 bit time constant where you put the low
    8 bits in WR12 and the high 8 bits in WR13. In general:

	Time_Constant = clock_rate / (2 * baud_rate * conversion ) - 2

    So, if the clock rate is 2.4576 MHz, baud rate is 9600, and the
    conversion constant is 16 (WR4[7:6] = 01), then

	Time_Constant = 2,457,600 / ( 2 * 9600 * 16 ) - 2 = 6
 
    Therefore put 6 in WR12 and 0 in WR13.


Hope this helps. If you have any other specific questions, I can try and
answer them. As I mentioned before, I have used the initialization code 
given to me as a black box. I do have some documentation from Zilog,
which is where the example above came from. I assume the AMD chip is 
programmed the same???? 

Dave


From ficenec@fermi.wustl.edu Sun Apr  5 06:00:20 1992
Subject: example Z83C50 code
Date: Sat, 04 Apr 92 13:58:10 CST

Below is example code for initializing the Z83C50 in a Dynatem DCPU30
VME computer. I got the Z83C50 part of the code from Dynatem and have 
used it as a "black box". Note that the port to the chip is memory 
mapped (CTRL4/DATA4 and CTRL3/DATA3) where there is pair of addresses 
for each of the two channels in hte chip - one with the D/C pin
asserted, and one without. Below the boot code, I have also placed 
the subroutines I wrote to interface to the chip as more examples.

Regards,
Dave


;******************************************************************************
;	Set assembler to generate 68020 code.
;******************************************************************************

		machine MC68020

CTRL4		equ	$3050000	; r/w register 0 (control) P4
DATA4		equ	$3050001	; r/w register 8 (data) P4
CTRL3		equ	$3050002	; r/w register 0 (control) P3
DATA3		equ	$3050003	; r/w register 8 (data) P3


; Skip non-Zilog code

;******************************************************************************
;	Initialize serial ports.
;******************************************************************************

		move.l	#CTRL4,a0	; load P4 control register address
		move.b	#$9,(a0) 	; load write register 9
		jsr	sccwait		; wait for SCC to settle
		move.b 	#$C0,(a0)  	; reset SCC chip
		longwait		; wait for reset to settle
		jsr	sccprog		; program P4
		move.l	#CTRL3,a0	; load P3 control register address
		jsr	sccprog		; program P3
	
;******************************************************************************
; 		sccprog		programs SSC to 9600b, 8bit, 1stop, no parity 
; 		sscwait		delay for programming SCC chip
;******************************************************************************

sccprog		move.b	#$4,(a0)	; load write register 4 
		jsr	sccwait 
		move.b	#$44,(a0)	; x16 clk, 1 stop bit, no parity 
		jsr	sccwait 
		move.b	#$3,(a0)	; load write register 3
		jsr	sccwait 
		move.b	#$c0,(a0)	; rx 8 bit, rx disable
		jsr	sccwait 
		move.b	#$05,(a0)	; load write regsiter 5
		jsr	sccwait 
		move.b	#$60,(a0)	; tx 8bits, dtr, rts, tx off
		jsr	sccwait 
		move.b	#$09,(a0)	; load write regsiter 9
		jsr	sccwait 
		move.b	#$0,(a0)	; interrupt disable
		jsr	sccwait 
		move.b	#$0a,(a0)	; load write regsiter 10
		jsr	sccwait 
		move.b	#$0,(a0)	; nrz
		jsr	sccwait 
		move.b	#$0b,(a0)	; load write regsiter 11
		jsr	sccwait 
		move.b	#$54,(a0)	; tx&rx=brgout, trxc=brgout
		jsr	sccwait 
		move.b	#$0c,(a0)	; load write regsiter 12
		jsr	sccwait 
		move.b	#$e,(a0)	; low time constant
		jsr	sccwait 
		move.b	#$d,(a0)	; load write regsiter 13
		jsr	sccwait 
		move.b	#$0,(a0)	; high time constant
		jsr	sccwait 
		move.b	#$0e,(a0)	; load write regsiter 14
		jsr	sccwait 
		move.b	#$02,(a0)	; brgin=pclk, brg=off, no loopback
		jsr	sccwait 
		move.b	#$0e,(a0)	; load write regsiter 14
		jsr	sccwait 
		move.b	#$03,(a0)	; brg=enable
		jsr	sccwait  
		move.b	#$03,(a0)	; load write regsiter 3
		jsr	sccwait 
		move.b	#$c1,(a0)	; rx enable 
		jsr	sccwait 
		move.b	#$05,(a0)	; load write regsiter 5
		jsr	sccwait 
		move.b	#$68,(a0)	; tx enable
		jsr   	sccwait 
		rts

sccwait		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		rts

		end

;******************************************************************************
;	End of initialization code. Start of subroutine library.
;******************************************************************************

********************************************************************
*       Assembly language interface routines to the DCPU30 serial 
*	ports. P4 as labelled on the front panel corresponds to 
*       channel B on SSC2, and P3 corresponds to channel A. P4 is 
*       also the standard I/O port used by the debugger program: 
*	DYNABUG. Therefore, the Aztec libraries will be modified 
*	to use P4 as the stdin, stdout, stderr. P3 will be set
*       to correspond to the descriptors auxin, auxout.
*
*       D. Ficenec, Feb 92.
*
*	Added two routines clr3 and clr4 which send the VT100
*       escape sequence to clear the output. D. Ficenec.
*
*
********************************************************************

		XDEF	_put4
		XDEF	_put3
		XDEF	_get4
		XDEF    _get3
		XDEF    _pol4
		XDEF    _pol3
		XDEF    _clr4
		XDEF    _clr3
		
*********************************************************************
*	Constant definitions.
*********************************************************************

CTRL4		EQU	$3050000	; R/W register 0 (control) P4.
DATA4		EQU	$3050001	; R/W register 8 (data) P4.
CTRL3		EQU	$3050002	; R/W register 0 (control) P3.
DATA3		EQU	$3050003	; R/W register 8 (data) P3.		

*********************************************************************
*	Macro to execute 4 NOP's to allow SCC chip to settle.
*********************************************************************

SCCWAIT		MACRO				
		NOP
		NOP
		NOP
		NOP
		ENDM

*********************************************************************
*	Macro to output a character to port 3 or 4.
*       Usage:  outch n m    where n = port number, m = char
*********************************************************************

outch		macro
		clr.l   d0          
\@		move.b	(CTRL\1),d0
		sccwait		
		btst	#2,d0	
		beq	\@	
		move.b	#\2,DATA\1
		sccwait		
		endm		

*********************************************************************
*	Function:   _PUT4
*
*	Purpose:    Writes low byte of the argument to P4.
*
*	Input:      5(sp) = Value of 8 bit ASCII character.
*
*       Returns:    SCC status rgister RR0 in D0.
*
*	C Usage:    put4(char)
*
*       Notes:      Waits for SSC chip output buffer to clear.
*********************************************************************

_put4		CLR.L   D0                      ; clear D0 
PUT4_WAIT	MOVE.B	(CTRL4),D0		; get SCC RR0 (P4)
		SCCWAIT				; wait for SCC
		BTST	#2,D0			; test for empty buffer
		BEQ	PUT4_WAIT		; if not empty, test again
		MOVE.B	5(SP),DATA4		; put char to SCC WR8 (P4)
		SCCWAIT				; wait for SCC
		RTS				; return from subroutine

*********************************************************************
*	Function:   _PUT3
*
*	Purpose:    Writes low byte of the argument to P3.
*
*	Input:      5(sp) = Value of 8 bit ASCII character.
*
*       Returns:    SCC status register RR0 in D0.
*
*	C Usage:    put3(char)
*
*       Notes:      Waits for SSC chip output buffer to clear.
*********************************************************************

_put3		CLR.L   D0                      ; clear D0 
PUT3_WAIT	MOVE.B	(CTRL3),D0		; get SCC RR0 (P3)
		SCCWAIT				; wait for SCC
		BTST	#2,D0			; test for empty buffer
		BEQ	PUT3_WAIT		; if not empty, test again
		MOVE.B	5(SP),DATA4		; put char to SCC WR8 (P3)
		SCCWAIT				; wait for SCC
		RTS				; return from subroutine

**********************************************************************
*	Function:   _GET4
*
*	Purpose:    Reads a character from port 4. 
*
*	Input:      None
*
*	Returns:    Character input from P4 in D0.
*
*	C Usage:    c = get4()
*
*	Notes:	    Does not check for char in SCC buffer; use POL4.
***********************************************************************

_get4		CLR.L	D0			; clear D0
		MOVE.B	(DATA4),D0		; get SSC RR8 (P4)
		SCCWAIT				; wait for SCC
		RTS				; return from subroutine

**********************************************************************
*	Function:   _GET3
*
*	Purpose:    Reads a character from port 3. 
*
*	Input:      None
*
*	Returns:    Character input from P3 in D0.
*
*	C Usage:    c = get3()
*
*	Notes:	    Does not check for char in SCC buffer; use POL3.
***********************************************************************

_get3		CLR.L	D0			; clear D0
		MOVE.B	(DATA3),D0		; get SSC RR8 (P3)
		SCCWAIT				; wait for SCC
		RTS				; return from subroutine

**********************************************************************
*	Function:   _POL4
*
*	Purpose:    Checks for char in the input buffer of P4. 
*
*	Input:      None
*
*	Returns:    1 if char available, 0 otherwise.
*
*	C Usage:    istat = pol4()
***********************************************************************

_pol4		CLR.L	D0			; clear D0
		MOVE.B	(CTRL4),D0		; get SSC RR0 (P4)
		ANDI.B  #1,D0                   ; zero other stat bits
		SCCWAIT				; wait for SCC
		RTS				; return from subroutine

**********************************************************************
*	Function:   _POL3
*
*	Purpose:    Checks for char in the input buffer of P3. 
*
*	Input:      None
*
*	Returns:    1 if char available, 0 otherwise.
*
*	C Usage:    istat = pol3()
***********************************************************************

_pol3		CLR.L	D0			; clear D0
		MOVE.B	(CTRL3),D0		; get SSC RR0 (P3)
		ANDI.B  #1,D0                   ; zero other stat bits
		SCCWAIT				; wait for SCC
		RTS				; return from subroutine

*********************************************************************
*	Function:   _CLR4
*
*	Purpose:    Writes VT100 clear screen sequence to P4.
*
*	Input:      void.
*
*       Returns:    void.
*
*	C Usage:    clr4()
*
*       Notes:      Waits for SSC chip output buffer to clear.
*********************************************************************

_clr4		outch 4,$1b
		outch 4,$5b
		outch 4,$32
		outch 4,$4a
		outch 4,$1b
		outch 4,$5b
		outch 4,$3b
		outch 4,$48
		rts

*********************************************************************
*	Function:   _CLR3
*
*	Purpose:    Writes VT100 clear screen sequence to P3.
*
*	Input:      void.
*
*       Returns:    void.
*
*	C Usage:    clr3()
*
*       Notes:      Waits for SSC chip output buffer to clear.
*********************************************************************

_clr3		outch 3,$1b
		outch 3,$5b
		outch 3,$32
		outch 3,$4a
		outch 3,$1b
		outch 3,$5b
		outch 3,$3b
		outch 3,$48
		rts