NEW
  AUTO 3,1
				.OP	65C02
				.OR $2000
*--------------------------------------
				.DO SSCIRQ=1
				.TF DRV/SSC.I.DRV
				.ELSE
				.TF DRV/SSC.DRV
				.FIN
*--------------------------------------
				.DO SSCIRQ=1
BUF.SIZE		.EQ $40
BUF.MASK		.EQ $3F
				.FIN
*--------------------------------------
ZPArgPtr		.EQ ZPBIN
ZPParityPtr		.EQ ZPBIN+2
ZPControlPtr	.EQ ZPBIN+4
ZPhParity		.EQ ZPBIN+6
ZPhControl		.EQ ZPBIN+7
*--------------------------------------
*			File Header (16 Bytes)
*--------------------------------------
CS.START		cld
				jmp Dev.Detect			cld,jmp abs=DRV
				.DA #$61				6502,Level 1 (65c02)
				.DA #1					DRV Layout Version 1
				.DA 0
				.DA CS.END-CS.START			Code Length
				.DA 0
				.DA #32					SS
				.DA #8					ZP
				.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
L.MSG.DETECT	.DA MSG.DETECT
L.MSG.DETECT.OK	.DA MSG.DETECT.OK
L.MSG.DETECT.KO	.DA MSG.DETECT.KO
L.DRV.CS.START	.DA DRV.CS.START
L.FD.DEV		.DA FD.DEV
L.FD.DEV.NAME	.DA FD.DEV.NAME
L.SSCANF.ARGS	.DA SSCANF.ARGS
L.DCB.BAUD		.DA DCB+S.DCB.COM.BAUD
L.DCB.DATA		.DA DCB+S.DCB.COM.DATA
L.DCB.STOP		.DA DCB+S.DCB.COM.STOP
				.DA 0					End Of Reloc Table
*--------------------------------------
Dev.Detect		>STYA ARGS

				>LDYA L.MSG.DETECT
				>SYSCALL puts
				
				stz ZPArgPtr
				lda #$C1
				sta ZPArgPtr+1
				
.1				and #$0f
				tay
				lda A2osX.S,y
				bne .3

				ldx #DEVSIG.Length-1

.2				ldy DEVSIG.Offset,x
				lda (ZPArgPtr),y
				cmp DEVSIG.Value,x
				bne .3
				dex
				bpl .2
				bra .4
				
.3				inc FD.DEV.NAME+3
				inc ZPArgPtr+1			no match, try next slot....
				lda ZPArgPtr+1
				cmp #$C8
				bne .1	
				
				>LDYA L.MSG.DETECT.KO
				>SYSCALL puts

				lda #MLI.E.NODEV		Not Found in any slot, exiting
				sec
				rts	

.4				lda ZPArgPtr+1
				and #$0F
				pha
				tay
				lda #A2osX.S.COM
				sta A2osX.S,y
				pla
				asl
				asl
				asl
				asl
				clc
				adc #$8F
				sta DEVSLOTn08F
				
				jsr Dev.ParseArgs
				bcs .9
				
.8				>PUSHW L.FD.DEV.NAME
				>PUSHBI 2
				>LDYA L.MSG.DETECT.OK
				>SYSCALL printf
				
				>PUSHWI DRV.END
				>PUSHWI DRV.CS.END
				>PUSHWI DRV.CS.START
				>LDYA L.DRV.CS.START
				>SYSCALL InsDrv
				bcs .9
				>STYA FD.DEV+S.FD.DEV.DRVPTR
				
				>PUSHW L.FD.DEV.NAME
				>LDYA L.FD.DEV
				>SYSCALL MKDEV

.9				rts
*--------------------------------------
Dev.ParseArgs	>LDYA ARGS
				>STYA ZPArgPTR
				lda (ZPArgPTR)
				bne .1
				clc
				rts
				
.1				stz ZPhParity
				stz ZPhControl
				
				>LDYAI 256
				>SYSCALL getmem
				bcs .2
				>STYA ZPParityPtr
				stx ZPhParity
				
				>LDYAI 256
				>SYSCALL getmem
.2				bcs .90
				>STYA ZPControlPtr
				stx ZPhControl
				
				>PUSHW ZPControlPtr
				>PUSHW ZPParityPtr
				>PUSHW L.DCB.STOP
				>PUSHW L.DCB.DATA
				>PUSHW L.DCB.BAUD
				>PUSHBI 10				5 x byte PTRs
				>PUSHW L.SSCANF.ARGS
				>LDYA ZPArgPtr
				>SYSCALL sscanf

				bcs .90
				
.90				lda ZPhControl
				beq .91
				>SYSCALL freemem

.91				lda ZPhParity
				beq .92
				>SYSCALL freemem

.92				lda #E.SYN
				sec
				rts
*--------------------------------------
CS.END
DEVSIG.Offset	.HS 05070B0C
DEVSIG.Value	.HS 38180131
DEVSIG.Length	.EQ DEVSIG.Value-DEVSIG.Offset
MSG.DETECT		.AS "Apple SSC (Super Serial Card,//c Serial Port) Driver"
				.DO SSCIRQ=1
				.AS " (IRQ Enabled)"
				.FIN
				.AZ "."				
MSG.DETECT.OK	.AZ "SSC Installed As Device : %s\r\n"
MSG.DETECT.KO	.AZ "No SSC Found."
SSCANF.ARGS		.AZ "%u,%d,%d,%s,%s"
ARGS			.BS 2
*--------------------------------------
FD.DEV			.DA #S.FD.T.CDEV
				.DA #0					HANDLER
				.DA #0					BUSID
				.DA #0					DEVID
				.DA 0					BUSPTR
				.BS 2					DRVPTR
				.DA 0					DCBPTR
				.DA 0					BUFPTR
FD.DEV.NAME		.AZ "COM1"
*--------------------------------------
*			Driver Code
*--------------------------------------
ZPIOCTL			.EQ ZPDRV
ZPBufPtr		.EQ ZPDRV+2
ZPCount			.EQ ZPDRV+4
ZPCount2		.EQ ZPDRV+6
*--------------------------------------
DRV.CS.START	cld
				jmp (.1,x)
.1				.DA STATUS
				.DA A2osX.BADCALL
				.DA A2osX.BADCALL
				.DA A2osX.BADCALL
				.DA CONTROL
				.DA A2osX.BADCALL
				.DA OPEN
				.DA CLOSE
				.DA READ
				.DA WRITE
				.DO SSCIRQ=1
				.DA IRQ
				.FIN
				.DA 0					end or relocation
*--------------------------------------
STATUS			jsr STATUS.CONTROL.Init
				
				ldy #S.IOCTL.STATCODE
				lda (ZPIOCTL),y
				beq .1
				
				cmp #S.IOCTL.STATCODE.GETDIB
				bne STATUS.DCB
				
				ldy #S.DIB-1
				.HS 2C					bit abs
.1				ldy #3

.2				lda DIB,y
				sta (ZPBufPtr),y
				dey
				bpl .2
				
				clc
				rts

STATUS.DCB		cmp #S.IOCTL.STATCODE.GETDCB
				bne .3

				ldy #S.DCB.COM-1
				
.2				lda DCB,y
				sta (ZPBufPtr),y
				dey
				bpl .2

				clc
				rts
				
.3				cmp #S.IOCTL.STATCODE.EOF
				bne STATUS.9

				lda DIB+S.DIB.S
				and #S.DIB.S.OPENED
				beq OPEN.E
				
				.DO SSCIRQ=1
				lda INBUF.TAIL
				eor INBUF.HEAD
				beq .4					NO DATA? eof = TRUE
				
				lda #1
				
.4				dec
				clc
				rts
				.ELSE
				
				
				
				.FIN
				
.8				clc
				rts
				
STATUS.9		lda #MLI.E.BADCTL
				sec
				rts				
*--------------------------------------
CONTROL			jsr STATUS.CONTROL.Init

				ldy #S.IOCTL.CTRLCODE
				lda (ZPIOCTL),y
				cmp #S.IOCTL.CTRLCODE.SETDCB
				bne STATUS.9
				
				ldy #S.DCB.COM-1
				
.2				lda (ZPBufPtr),y
				sta DCB,y
				dey
				bpl .2
*--------------------------------------
OPEN			lda DIB+S.DIB.S
				bit #S.DIB.S.OPENED
				beq OPEN.1
				
OPEN.E			lda #MLI.E.OPEN
				sec
				rts
				
OPEN.1			php
				sei
				
				ldx DEVSLOTn08F
				
				stz SSC.RESET-$8F,x 

				lda #SSC.CTL.CLKINT+SSC.CTL.B9600+SSC.CTL.8D+SSC.CTL.1S+SSC.CMD.NOP
				sta SSC.CTL-$8F,x
				
				.DO SSCIRQ=1
				
				lda #SSC.CMD.TEIRQ+SSC.CMD.TE+SSC.CMD.DTR
				sta SSC.CMD-$8F,x

				stz INBUF.HEAD
				stz INBUF.TAIL
				stz OUTBUF.HEAD
				stz OUTBUF.TAIL
			
				.ELSE
				
				lda #SSC.CMD.RIRQDIS+SSC.CMD.TE+SSC.CMD.DTR
				sta SSC.CMD-$8F,x
				
				.FIN

				lda SSC.DATA-$8F,x			discard any garbage byte
				lda SSC.STATUS-$8F,x		clear any IRQ pending

				lda #S.DIB.S.OPENED
				tsb DIB+S.DIB.S

				plp
				clc
				rts
*--------------------------------------
CLOSE			php
				sei
				
				ldx DEVSLOTn08F
				stz SSC.RESET-$8F,x 

				lda #S.DIB.S.OPENED
				trb DIB+S.DIB.S

				plp
				clc
				rts
*--------------------------------------
READ			php
				sei
				
				jsr READ.WRITE.Init

				stz ZPCount2
				stz ZPCount2+1
				
.10				inc ZPCount
				bne .11
				inc ZPCount+1
				beq .8							
				
.11				.DO SSCIRQ=1
				ldy INBUF.TAIL
				cpy INBUF.HEAD
				beq .2
				
				lda INBUF,y
				iny
				cpy #BUF.SIZE
				bne .1
				
				ldy #0
				
.1				sty INBUF.TAIL

				sta (ZPBufPtr)
				inc ZPBufPtr
				bne .12
				inc ZPBufPtr+1
				
.12				inc ZPCount2
				bne .10
				inc ZPCount2+1
				bra .10				

				.FIN
				
.2				lda SSC.STATUS-$8F,x
				bit #SSC.STATUS.nDSR	true when 0
				bne .9

				bit #SSC.STATUS.RDRF	incoming char?
				beq	.8
				
				lda SSC.DATA-$8F,x
				sta (ZPBufPtr)
				inc ZPBufPtr
				bne .13
				inc ZPBufPtr+1
				
.13				inc ZPCount2
				bne .2
				inc ZPCount2+1
				bra .2
				
.8				lda ZPCount2
				bne .81
				ora ZPCount2+1
				beq .99
				lda ZPCount2
				
.81				ldy #S.IOCTL.BYTECNT
				sta (ZPIOCTL),y
				iny
				lda ZPCount2+1
				sta (ZPIOCTL),y

				plp
				clc
				rts				
				
.9				lda #MLI.E.IO
				.HS 2C					BIT ABS

.99				lda	#E.NODATA
				plp
				sec
				rts				
*--------------------------------------
WRITE			php
				sei
				
				jsr READ.WRITE.Init
				
.2				inc ZPCount
				bne .3
				inc ZPCount+1
				beq .8
				
.3				.DO SSCIRQ=1
				lda SSC.STATUS-$8F,x
				bit #SSC.STATUS.nDSR	true when 0
				bne .9
				
				lda OUTBUF.HEAD
				cmp OUTBUF.TAIL			Buffer Empty?
				bne .6					not empty, queue char

				lda SSC.STATUS-$8F,x
				
				and #SSC.STATUS.TDRE 	Register Empty ?
				beq .5					not empty, queue char
				
				lda (ZPBufPtr)			yes, write directly to ACIA
				inc ZPBufPtr
				bne .4
				inc ZPBufPtr+1

.4				sta SSC.DATA-$8F,x
				
				bra .2
	
.5				lda OUTBUF.HEAD
				
.6				tay
				inc
				and #BUF.MASK
				cmp OUTBUF.TAIL	
				beq .99					Buffer Full!!

				sta OUTBUF.HEAD
				
				lda (ZPBufPtr)
				inc ZPBufPtr
				bne .7
				inc ZPBufPtr+1
				
.7				sta OUTBUF,y
				
				bra .2
				.ELSE				
.4				lda SSC.STATUS-$8F,x
				bit #SSC.STATUS.nDSR	true when 0
				bne .9
				
				bit #SSC.STATUS.TDRE	Outgoing char?
				beq .4
				
				lda (ZPBufPtr)
				inc ZPBufPtr
				bne .5
				inc ZPBufPtr+1
				
.5				sta SSC.DATA-$8F,x
				
				bra .2
				.FIN
				
.8				plp
				clc
				rts				
				
.9				lda	#MLI.E.IO
				.HS 2C					BIT ABS
.99				lda #E.NODATA
				plp
				sec
				rts
*--------------------------------------
READ.WRITE.Init	ldx DEVSLOTn08F

STATUS.CONTROL.Init
				>STYA ZPIOCTL

				ldy #S.IOCTL.BUFPTR
				lda (ZPIOCTL),y
				sta ZPBufPtr

				iny 

				lda (ZPIOCTL),y
				sta ZPBufPtr+1
				
				iny 					#S.IOCTL.BYTECNT

				lda (ZPIOCTL),y
				eor #$ff
				sta ZPCount

				iny

				lda (ZPIOCTL),y
				eor #$ff
				sta ZPCount+1
				
				rts
*--------------------------------------
* IRQ Handler
* on exit, CC if handled
*--------------------------------------
				.DO SSCIRQ=1
IRQ				ldx DEVSLOTn08F
				lda SSC.STATUS-$8F,x
				
*				and #SSC.STATUS.IRQ		Useless
				bpl .9					IRQ from this device ? no, exit !!!!Applewin bug #308!!!!

				bit #SSC.STATUS.RDRF	incoming char?
				beq .2					

*------------ IRQ In

				pha
				
				lda INBUF.HEAD
				tay						save actual head for later
				
				inc
				and #BUF.MASK
				cmp INBUF.TAIL				
				beq .1					buffer full, discard and exit
				
				sta INBUF.HEAD

				lda SSC.DATA-$8F,x			read data to clear IRQ
				sta INBUF,y

.1				pla
				
*------------ IRQ Out
				
.2				bit #SSC.STATUS.TDRE
				beq .8					no transmition possible....

				ldy OUTBUF.TAIL			something to transmit ?
				cpy OUTBUF.HEAD
				beq .8					in that case, HOW TO CLEAR IRQ ????
				
				lda OUTBUF,y
				sta SSC.DATA-$8F,x			write data to clear IRQ
				
				tya
				inc
				and #BUF.MASK
				
				sta OUTBUF.TAIL	
				
.8				clc
				rts
				
.9				sec
				rts
				.FIN
*--------------------------------------
DRV.CS.END
DEVSLOTn08F		.BS 1
				.DO SSCIRQ=1
INBUF.TAIL		.BS 1
INBUF.HEAD		.BS 1
OUTBUF.TAIL		.BS 1
OUTBUF.HEAD		.BS 1
INBUF			.BS BUF.SIZE
OUTBUF			.BS BUF.SIZE
				.FIN
*--------------------------------------
DIB				.DO SSCIRQ=1
				.DA #S.DIB.S.WRITE+S.DIB.S.READ+S.DIB.S.IRQ
				.ELSE
				.DA #S.DIB.S.WRITE+S.DIB.S.READ
				.FIN
				.DA #0,#0,#0
				>PSTR "Serial Card/Port"
				.DA #S.DIB.T.CHAR
				.DA #0
				.DA K.VER
*--------------------------------------
DCB				.DA #S.DCB.T.COM
				.DA #0					FLAGS
				.DO SSCIRQ=1
				.DA >9600				BAUD (DWORD)
				.ELSE
				.DA >115200
				.FIN
				.DA #8					DATA
				.DA #1					STOP
				.DA #S.DCB.COM.P.NONE	PARITY
				.DA #S.DCB.COM.C.XONXOFF
*--------------------------------------
DRV.END
MAN
SAVE USR/SRC/DRV/X.SSC.DRV.S
LOAD USR/SRC/DRV/SSC.I.DRV.S
ASM
