*****************************************************************************
* Program:  newser.i - ©1990 by The Puzzle Factory
* Function: The One & Only master include file for the I/O Expansion board.
*
* Author:   Jeff Lavin
* History:  08/23/90 JL V0.50 Created
*           11/25/90 JL V0.51 Started to add parallel stuff
*           12/10/90 JL V0.51 Added some more parallel stuff
*           01/13/91 JL V0.52 Changed PUTDEBUG macro slightly
*
* [To all: Please don't forget to bump the revision numbers if you do *any*
*          modifications at all.  -Jeff]
*
*****************************************************************************
*
* Some of the following is:
*
*****************************************************************************
*
* Copyright (C) 1985, Commodore Amiga Inc.  All rights reserved.
* Permission granted for non-commercial use
*
* asmsupp.i -- random low level assembly support routines
*              used by the Commodore sample Library & Device
*
*****************************************************************************

;Set Tabs           |       |                 |       |


PUTDEBUG 	macro		;[level,msg]
	ifgt	INFO_LEVEL-\1
	pea	subSysName
	movem.l a0/a1/d0/d1,-(sp)
	lea	.msg\@,a0	;Point to static format string
	lea	4*4(sp),a1	;Point to args
	bsr	KPutFmt
	movem.l (sp)+,d0/d1/a0/a1
	addq.w	#4,sp
	bra.b	.end\@

.msg\@	dc.b	'%s/',\2,10
	even
.end\@
	endc
	endm

ISDEBUG	macro
	ifne	INFO_LEVEL	;If any debugging enabled at all
KPutFmt
	move.l	a2,-(sp)
	lea	KPutChar,a2
	bsr.b	KDoFmt
	movea.l	(sp)+,a2
	rts

KDoFmt	
        move.l	a6,-(sp)
	movea.l	(SysBase).w,a6
	mySYS	RawDoFmt
	movea.l	(sp)+,a6
	rts
	
KPutChar
	move.l	a6,-(sp)
	movea.l	(SysBase).w,a6
	mySYS	RawPutChar
	movea.l	(sp)+,a6
	rts

subSysName	dc.b	\1	;This name for debugging use
	even
	endc
	endm


*****************************************************************************
*
* Here are the includes for the serial portion of the I/O Expansion Board.
* Everything from here to the end of the file is:
*
*      Copyright (C) 1990 by Jeff Lavin  --  All rights reserved.
*      Permission granted for non-commercial use.
*
*****************************************************************************

*** MACROS ***

	ifnd	SYS
mySYS	macro
	jsr	_LVO\1(a6)
	endm
	endc

myEXEC	macro
	move.l	a1,-(sp)
	move.l	a6,-(sp)
	movea.l	(SysBase).w,a6
	jsr	_LVO\1(a6)
	movea.l	(sp)+,a6
	movea.l	(sp)+,a1
	endm

myDisable	macro
	ifc	'\1',''
	move.w	#INTF_INTEN,(_intena).l
	move.l	a6,-(sp)
	movea.l	(SysBase).w,a6
	addq.b	#1,IDNestCnt(a6)
	movea.l	(sp)+,a6
	endc
	ifnc	'\1',''
	movea.l	(SysBase).w,\1
	move.w	#INTF_INTEN,(_intena).l
	addq.b	#1,IDNestCnt(\1)
	endc
	endm


myEnable	macro
	ifc	'\1',''
	move.l	a6,-(sp)
	movea.l	(SysBase).w,a6
	subq.b	#1,IDNestCnt(a6)
	movea.l	(sp)+,a6
	bge.s	.Enable\@
	move.w	#INTF_SETCLR!INTF_INTEN,(_intena).l
.Enable\@
	endc
	ifnc	'\1',''
	movea.l	(SysBase).w,\1
	subq.b	#1,IDNestCnt(\1)
	bge.s	.Enable\@
	move.w	#INTF_SETCLR!INTF_INTEN,(_intena).l
.Enable\@
	endc
	endm

myForbid	macro
	move.l	a6,-(sp)
	movea.l	(SysBase).w,a6
	addq.b	#1,TDNestCnt(a6)
	movea.l	(sp)+,a6
	endm

myPermit	macro
	movem.l	d0/d1/a0/a1/a6,-(sp)
	movea.l	(SysBase).w,a6
	mySYS	Permit
	movem.l	(sp)+,d0/d1/a0/a1/a6
	endm

PREFFILE macro
	dc.b	'S:Serial-Preferences',0
	even
	endm


MYUNITNAME1 macro
	dc.b	'SER1:',0
	even
	endm

MYUNITNAME2 macro
	dc.b	'SER2:',0
	even
	endm

MYUNITNAME3 macro
	dc.b	'SER3:',0
	even
	endm

MYUNITNAME4 macro
	dc.b	'SER4:',0
	even
	endm

PARDEVNAME macro
        dc.b    'eightbit.device',0
        even
	endm


PARIDENT macro
	dc.b	'eightbit alpha test version 1.0 (10 Dec 1990)',13,10,0
	even
	endm

PARUNITNAME1 macro
	dc.b	'PAR1:',0
	even
	endm

PARUNITNAME2 macro
	dc.b	'PAR2:',0
	even
	endm

PARUNITNAME3 macro
	dc.b	'PAR3:',0
	even
	endm

PARUNITNAME4 macro
	dc.b	'PAR4:',0
	even
	endm

*** EQUATES ***

	ifnd	SysBase
SysBase	equ	4
	endc

MYPROCSTACKSIZE	equ	$900    	;Stack size for the task we will create

MYDEV_END	equ	CMD_NONSTD+7	;Number of device comands

MD_NUMUNITS	equ	4       	;Maximum number of units in this device

*** New SerialPrefs Structure ***

;UnitPrefs
 STRUCTURE	up,0
    UWORD       up_BufSize	;0 to 7
    UWORD       up_BaudRate	;0 to 15
    UBYTE       up_WordLen	;0=5, 1=6, 2=7, 3=8
    UBYTE       up_StopBits	;0=1, 1=2
    UBYTE       up_Parity	;0=Odd, 1=Even, 2=Mark, 3=Space, 4=None
    UBYTE       up_Shake	;0=RTS/CTS, 1=xON/xOFF
    LABEL       up_SIZE

;SerialPrefs
 STRUCTURE	sp,0
   STRUCT       sp_Unit01,up_SIZE	;For ACIA 0, Unit 1
   STRUCT       sp_Unit02,up_SIZE	;For ACIA 0, Unit 2
   STRUCT       sp_Unit11,up_SIZE	;For ACIA 1, Unit 1
   STRUCT       sp_Unit12,up_SIZE	;For ACIA 1, Unit 2
    LABEL       sp_SIZE

;serprefs
 STRUCTURE	prefs,0
    ULONG       prefs_CTLCHAR	;Control char's (order = xON,xOFF,rsvd,rsvd)
    ULONG       prefs_RBUFLEN	;Length in bytes of serial port's read buffer
    ULONG       prefs_EXTFLAGS	;Additional serial flags
    ULONG       prefs_BAUD	;Baud rate requested (true baud)
    ULONG       prefs_BRKTIME	;Duration of break signal in MICROseconds
   STRUCT       prefs_TERMARRAY,TERMARRAY_SIZE	;Termination character array
    UBYTE       prefs_READLEN	;Bits per read char (bit count)
    UBYTE       prefs_WRITELEN	;Bits per write char (bit count)
    UBYTE       prefs_STOPBITS	;Stopbits for read (count)
    UBYTE       prefs_SERFLAGS	;See SERFLAGS bit definitions
    LABEL       prefs_SIZE

;MyDev	
 STRUCTURE	md,LIB_SIZE
    UBYTE       md_Flags
    UBYTE       md_Pad1
    ULONG       md_SysLib
    ULONG       md_SegList
   STRUCT       md_Units,MD_NUMUNITS*4
   STRUCT       prefs_unit0,prefs_SIZE	;The reason why prefs are in this
   STRUCT       prefs_unit1,prefs_SIZE	;structure instead of the unit structure
   STRUCT       prefs_unit2,prefs_SIZE	;is that the pref settings should be saved
   STRUCT       prefs_unit3,prefs_SIZE	;across CloseDevice calls (which usually
    LABEL       md_SIZE		        ;causes the unit to be dumped).

;MyDevUnit
 STRUCTURE	mdu,UNIT_SIZE	                ;Odd # longwords
   STRUCT       mdu_wport,MP_SIZE       	;MsgPort for write task
    UBYTE       MDU_FLAGS
    UBYTE       IERstate	                ;Current state of IER used as a mask
    UBYTE       mdu_UnitNum
    UBYTE       frstate                  	;This var mirrors a write-only register
    ULONG       mdu_SysLib               	;Copy of location 4
    ULONG       mdu_Device              	;Ptr to main device struct
   STRUCT       mdu_rstack,MYPROCSTACKSIZE	;For read task
   STRUCT       mdu_wstack,MYPROCSTACKSIZE	;For write task
   STRUCT       mdu_rtcb,TC_SIZE        	;Task Control Block (TCB) for read task
   STRUCT       mdu_wtcb,TC_SIZE        	;Task Control Block (TCB) for write task
   STRUCT       mdu_is,IS_SIZE	                ;Interrupt structure
   STRUCT       timerport,MP_SIZE
   STRUCT       timeriorequest,IOTV_SIZE
   STRUCT       AltBuf,64               	;64-byte alternate buffer
    ULONG       readsig                 	;Read task signals
    ULONG       readabortsig
    ULONG       tdresig                 	;Transmit buffer empty - put another byte
    ULONG       dsrsig                  	;Transition on DSR - used for handshaking (if enabled)
    ULONG       writeabortsig
    ULONG       xonsig                  	;Comes from read task, and indicates xon received
    ULONG       breaksig                	;This is an Exec exception signal
    ULONG       head                    	;Ptr to start of circular buffer (logical)
    ULONG       tail                     	;Ptr to end of circular buffer (logical)
    ULONG       startbuf                 	;Ptr to physical start of input buffer
    ULONG       endbuf                   	;Ptr to physical end of input buffer
    ULONG       ReadRequestPtr
    ULONG       WriteRequestPtr
    ULONG       breakiorequest
    UBYTE       xstate                  	;Zero if 'x-off' received, else $FF
    UBYTE       ISRcopy                 	;Used for read error diagnosis
    UBYTE       CSRcopy                 	;Used for read error diagnosis
    UBYTE       Exclusive               	;True if someone has exclusive access to this unit
    ULONG       daciabase
    ULONG       mdu_prefs               	;Ptr to prefs for this unit (in MyDev)
    LABEL       mdu_SIZE

;Note that we have a single unit structure used by both the read and write
;tasks (and the interrupt routine).

* UNIT_FLAG definitions:

	BITDEF	UNIT,INREADTASK,0    
	BITDEF	UNIT,INWRITETASK,1
	BITDEF	UNIT,READACTIVE,2
	BITDEF	UNIT,WRITEACTIVE,3
	BITDEF	UNIT,BREAKACTIVE,4
	BITDEF	UNIT,INBREAK,5

;INBREAK is used by the queued break routine to protect against immediate breaks
;(a rather unlikely scenereo, but it might happen; who knows?)

* Bit definitions for MDU_FLAGS

	BITDEF	MDU,STOPPED,2	;State bit for unit stopped
	BITDEF	MDU,V,3 	;Buffer overflow flag - set in int routine if an overflow occurs

* Bit definitions for ioflags

	BITDEF	ioflags,Active,4	;IO request in progress
	BITDEF	ioflags,Ignore,5	;Ignore this IO request

* Equates & bit defs for IERstate

READINT 	equ	$87
READINTMASK	equ	$7

HANDINT 	equ	$88
HANDINTMASK	equ	$8

WRITEINT	equ	$C0
WRITEINTMASK	equ	$40

WRITEOFF	equ	$40
WRITEOFFMASK	equ	$BF

*** The Hardware ***

_custom	equ	$DFF000
_intena	equ	_custom+intena

;The ACIAs are located at $400 byte boundaries beginning at ACIA_Base:
;
; Unit1	equ	$BF9000	;65C52 DACIA chip 1, unit 1
; Unit2	equ	$BF9400	;65C52 DACIA chip 1, unit 2
; Unit3	equ	$BF9800	;65C52 DACIA chip 2, unit 1
; Unit4	equ	$BF9C00	;65C52 DACIA chip 2, unit 2

ACIA_Base	equ	$BF9000	;Base address of all units
ACIA0	equ	$0000	;Offset of 1st chip
ACIA1	equ	$0800	;Offset of 2nd chip
UNIT2	equ	$0400	;Offset of 2nd unit

IER	equ	$0000	;Interrupt Enable Register
ISR	equ	$0000	;Interrupt Status Register
CTR	equ	$0100	;Control Register
FMR	equ	$0100	;Format Register
CSR	equ	$0100	;Control Status Register
CDR	equ	$0200	;Compare Data Register
ACR	equ	$0200	;Auxilliary Control Register
TDR	equ	$0300	;Transmit Data Register
RDR	equ	$0300	;Receive Data Register

* Interrupt Status Registers (ISR1=0, ISR2=4) Read only

	BITDEF	ISR,SETCLR,7	;Any bit set
	BITDEF	ISR,TDRE,6	;Transmit Data Register Empty
	BITDEF	ISR,CTST,5	;Transition on *CTS Line
	BITDEF	ISR,DCDT,4	;Transition on *DCD Line
	BITDEF	ISR,DSRT,3	;Transition on *DSR Line
	BITDEF	ISR,PAR,2	;Parity status
	BITDEF	ISR,FEOB,1	;Frame error, Overrun, Break
	BITDEF	ISR,RDRF,0	;Receive Data Register Full

* Interrupt Enable Registers (IER1=0, IER2=4) Write only

	BITDEF	IER,SETCLR,7	;Same as above
	BITDEF	IER,TDRE,6
	BITDEF	IER,CTST,5
	BITDEF	IER,DCDT,4
	BITDEF	IER,DSRT,3
	BITDEF	IER,PAR,2
	BITDEF	IER,FEOB,1
	BITDEF	IER,RDRF,0

* Control Status Registers (CSR1=1, CSR2=5) Read only

	BITDEF	CSR,FE,7	;Framing Error
	BITDEF	CSR,TUR,6	;Transmitter Underrun
	BITDEF	CSR,CTSL,5	;*CTS Level
	BITDEF	CSR,DCDL,4	;*DCD Level
	BITDEF	CSR,DSRL,3	;*DSR Level
	BITDEF	CSR,RBRK,2	;Receive Break
	BITDEF	CSR,DTRL,1	;*DTR Level
	BITDEF	CSR,RTSL,0	;*RTS Level

* Control Registers (CR1=1, CR2=5) Write only

	BITDEF	CR,CTRL,7	;1=Access FMR,  0=Access CTR
	BITDEF	CR,AUX,6	;1=Access ACR,  0=Access CDR
	BITDEF	CR,STOP2,5	;1=2 stop bits, 0=1 stop bit
	BITDEF	CR,ECHO,4	;1=Echo mode,   0=Echo mode disabled

Baud_50 	equ	%00000000	;Bits 3-0
Baud_110	equ	%00000001
Baud_134	equ	%00000010
Baud_150	equ	%00000011
Baud_300	equ	%00000100
Baud_600	equ	%00000101
Baud_1200	equ	%00000110
Baud_1800	equ	%00000111
Baud_2400	equ	%00001000
Baud_3600	equ	%00001001
Baud_4800	equ	%00001010
Baud_7200	equ	%00001011
Baud_9600	equ	%00001100
Baud_19200	equ	%00001101
Baud_38400	equ	%00001110
Baud_EXT	equ	%00001111

* Format Registers (FR1=1, FR2=5) Write only

	BITDEF	FR,FRMT,7	;1=Access FR, 0=Access CR

WORDLEN_5	equ	%00000000	;Bits 5-6
WORDLEN_6	equ	%00100000
WORDLEN_7	equ	%01000000
WORDLEN_8	equ	%01100000

PAR_ODD 	equ	%00000000	;Bits 3-4
PAR_EVEN	equ	%00001000
PAR_MARK	equ	%00010000
PAR_SPACE	equ	%00011000

	BITDEF	FR,PAR,2	;1=Parity as specified in bits 3-4
	BITDEF	FR,DTR,1	;1=Set DTR hi, 0=Set DTR lo
	BITDEF	FR,RTS,0	;1=Set RTS hi, 0=Set RTS lo

* Compare Data Register  (CDR1=2, CDR2=6) Write only

;Bit 6 of Control Register must be 0.  By writing a value into this
;register, the DACIA is put into the compare mode.  In this mode the Receive
;Data Register Full bit is inhibited until a character is received that
;matches the value in this register.  The next character is then received
;normally.

* Auxiliary Control Registers (ACR1=2, ACR2=6) Write only

;Bit 6 of Control Register must be 1.

	BITDEF	ACR,BRK,1	;Transmit break
	BITDEF	ACR,ARM,0	;Address recognition mode

*****************************************************************************
*
* Here are the includes for the parallel portion of the I/O Expansion Board.
*
*****************************************************************************

VIA_Base	equ	$BF1000	;Base address of all units
VIA0	equ	$0000	;VIA #0 Base offset
VIA1	equ	$4000	;VIA #1 Base offset

ORB	equ	$0000	;I/O Register B
ORA	equ	$0100	;I/O Register A
DDRB	equ	$0200	;Data Direction Register B
DDRA	equ	$0300	;Data Direction Register A
T1CL	equ	$0400	;Timer #1 Counter (lower 8 bits)
T1CH	equ	$0500	;Timer #1 Counter (upper 8 bits)
T1LL	equ	$0600	;Timer #1 Latch (lower 8 bits)
T1LH	equ	$0700	;Timer #1 Latch (upper 8 bits)
T2CL	equ	$0800	;Timer #2 Counter (lower 8 bits)
T2CH	equ	$0900	;Timer #2 Counter (upper 8 bits)
SHFTR	equ	$0A00	;Shift Register
AUXCR	equ	$0B00	;Auxiliary Control Register
PERCR	equ	$0C00	;Peripheral Control Register
INTFR	equ	$0D00	;Interrupt Flag Register
INTER	equ	$0E00	;Interrupt Enable Register
ORAF	equ	$0F00	;I/O Register A (no handshake)

;End of File
