patch-2.4.7 linux/drivers/char/ser_a2232fw.ax

Next file: linux/drivers/char/ser_a2232fw.h
Previous file: linux/drivers/char/ser_a2232.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.6/linux/drivers/char/ser_a2232fw.ax linux/drivers/char/ser_a2232fw.ax
@@ -0,0 +1,529 @@
+;.lib "axm"
+;
+;begin
+;title "A2232 serial board driver"
+;
+;set modules "2232"
+;set executable "2232.bin"
+;
+;;;;set nolink
+;
+;set temporary directory "t:"
+;
+;set assembly options "-m6502 -l60:t:list"
+;set link options "bin"; loadadr"
+;;;bin2c 2232.bin msc6502.h msc6502code
+;end
+;
+;
+; ### Commodore A2232 serial board driver for NetBSD by JM v1.3 ###
+;
+; - Created 950501 by JM -
+;
+;
+; Serial board driver software.
+;
+;
+% Copyright (c) 1995 Jukka Marin <jmarin@jmp.fi>.
+% All rights reserved.
+%
+% Redistribution and use in source and binary forms, with or without
+% modification, are permitted provided that the following conditions
+% are met:
+% 1. Redistributions of source code must retain the above copyright
+%    notice, and the entire permission notice in its entirety,
+%    including the disclaimer of warranties.
+% 2. Redistributions in binary form must reproduce the above copyright
+%    notice, this list of conditions and the following disclaimer in the
+%    documentation and/or other materials provided with the distribution.
+% 3. The name of the author may not be used to endorse or promote
+%    products derived from this software without specific prior
+%    written permission.
+%
+% ALTERNATIVELY, this product may be distributed under the terms of
+% the GNU General Public License, in which case the provisions of the
+% GPL are required INSTEAD OF the above restrictions.  (This clause is
+% necessary due to a potential bad interaction between the GPL and
+% the restrictions contained in a BSD-style copyright.)
+%
+% THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+% WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+% OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+% DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+% INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+% (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+% SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+% HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+% STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+% OF THE POSSIBILITY OF SUCH DAMAGE.
+;
+;
+; Bugs:
+;
+; - Can't send a break yet
+;
+;
+;
+; Edited:
+;
+; - 950501 by JM -> v0.1	- Created this file.
+; - 951029 by JM -> v1.3	- Carrier Detect events now queued in a separate
+;				  queue.
+;
+;
+
+
+CODE		equ	$3800		; start address for program code
+
+
+CTL_CHAR	equ	$00		; byte in ibuf is a character
+CTL_EVENT	equ	$01		; byte in ibuf is an event
+
+EVENT_BREAK	equ	$01
+EVENT_CDON	equ	$02
+EVENT_CDOFF	equ	$03
+EVENT_SYNC	equ	$04
+
+XON		equ	$11
+XOFF		equ	$13
+
+
+VARBASE		macro	*starting_address	; was VARINIT
+_varbase	set	\1
+		endm
+
+VARDEF		macro	*name space_needs
+\1		equ	_varbase
+_varbase	set	_varbase+\2
+		endm
+
+
+stz		macro	* address
+		 db	$64,\1
+		endm
+
+stzax		macro	* address
+		 db	$9e,<\1,>\1
+		endm
+
+
+biti		macro	* immediate value
+		db	$89,\1
+		endm
+
+smb0		macro	* address
+		db	$87,\1
+		endm
+smb1		macro	* address
+		db	$97,\1
+		endm
+smb2		macro	* address
+		db	$a7,\1
+		endm
+smb3		macro	* address
+		db	$b7,\1
+		endm
+smb4		macro	* address
+		db	$c7,\1
+		endm
+smb5		macro	* address
+		db	$d7,\1
+		endm
+smb6		macro	* address
+		db	$e7,\1
+		endm
+smb7		macro	* address
+		db	$f7,\1
+		endm
+
+
+
+;-----------------------------------------------------------------------;
+;									;
+; stuff common for all ports, non-critical (run once / loop)		;
+;									;
+DO_SLOW		macro	* port_number					;
+		.local			;				;
+		lda	CIA+C_PA	; check all CD inputs		;
+		cmp	CommonCDo	; changed from previous accptd?	;
+		beq	=over		; nope, do nothing else here	;
+					;				;
+		cmp	CommonCDb	; bouncing?			;
+		beq	=nobounce	; nope ->			;
+					;				;
+		sta	CommonCDb	; save current state		;
+		lda	#64		; reinitialize counter		;
+		sta	CommonCDc	;				;
+		jmp	=over		; skip CD save			;
+					;				;
+=nobounce	dec	CommonCDc	; no, decrement bounce counter	;
+		bpl	=over		; not done yet, so skip CD save	;
+					;				;
+=saveCD		ldx	CDHead		; get write index		;
+		sta	cdbuf,x		; save status in buffer		;
+		inx			;				;
+		cpx	CDTail		; buffer full?			;
+		.if	ne		; no: preserve status:		;
+		 stx	CDHead		; update index in RAM		;
+		 sta	CommonCDo	; save state for the next check	;
+		.end			;				;
+=over		.end	local						;
+		endm							;
+									;
+;-----------------------------------------------------------------------;
+
+
+; port specific stuff (no data transfer)
+
+DO_PORT		macro	* port_number
+		.local			;				;
+		lda	SetUp\1		; reconfiguration request?	;
+		.if	ne		; yes:				;
+		 lda	SoftFlow\1	; get XON/XOFF flag		;
+		 sta	XonOff\1	; save it			;
+		 lda	Param\1		; get parameter			;
+		 ora	#%00010000	; use baud generator for Rx	;
+		 sta	ACIA\1+A_CTRL	; store in control register	;
+		 stz	OutDisable\1	; enable transmit output	;
+		 stz	SetUp\1		; no reconfiguration no more	;
+		.end			;				;
+					;				;
+		lda	InHead\1	; get write index		;
+		sbc	InTail\1	; buffer full soon?		;
+		cmp	#200		; 200 chars or more in buffer?	;
+		lda	Command\1	; get Command reg value		;
+		and	#%11110011	; turn RTS OFF by default	;
+		.if	cc		; still room in buffer:		;
+		 ora	#%00001000	; turn RTS ON			;
+		.end			;				;
+		sta	ACIA\1+A_CMD	; set/clear RTS			;
+					;				;
+		lda	OutFlush\1	; request to flush output buffer;
+		.if	ne		; yessh!			;
+		 lda	OutHead\1	; get head			;
+		 sta	OutTail\1	; save as tail			;
+		 stz	OutDisable\1	; enable transmit output	;
+		 stz	OutFlush\1	; clear request			;
+		.end
+		.end	local
+		endm
+
+
+DO_DATA		macro	* port number
+		.local
+		lda	ACIA\1+A_SR	; read ACIA status register	;
+		biti	[1<<3]		; something received?		;
+		.if	ne		; yes:				;
+		 biti	[1<<1]		; framing error?		;
+		 .if	ne		; yes:				;
+		  lda	ACIA\1+A_DATA	; read received character	;
+		  bne	=SEND		; not break -> ignore it	;
+		  ldx	InHead\1	; get write pointer		;
+		  lda	#CTL_EVENT	; get type of byte		;
+		  sta	ictl\1,x	; save it in InCtl buffer	;
+		  lda	#EVENT_BREAK	; event code			;
+		  sta	ibuf\1,x	; save it as well		;
+		  inx			;				;
+		  cpx	InTail\1	; still room in buffer?		;
+		  .if	ne		; absolutely:			;
+		   stx	InHead\1	; update index in memory	;
+		  .end			;				;
+		  jmp	=SEND		; go check if anything to send	;
+		 .end			;				;
+		 			; normal char received:		;
+		 ldx	InHead\1	; get write index		;
+		 lda	ACIA\1+A_DATA	; read received character	;
+		 sta	ibuf\1,x	; save char in buffer		;
+		 stzax	ictl\1		; set type to CTL_CHAR		;
+		 inx			;				;
+		 cpx	InTail\1	; buffer full?			;
+		 .if	ne		; no: preserve character:	;
+		  stx	InHead\1	; update index in RAM		;
+		 .end			;				;
+		 and	#$7f		; mask off parity if any	;
+		 cmp	#XOFF		; XOFF from remote host?	;
+		 .if	eq		; yes:				;
+		  lda	XonOff\1	; if XON/XOFF handshaking..	;
+		  sta	OutDisable\1	; ..disable transmitter		;
+		 .end			;				;
+		.end			;				;
+					;				;
+					; BUFFER FULL CHECK WAS HERE	;
+					;				;
+=SEND		lda	ACIA\1+A_SR	; transmit register empty?	;
+		and	#[1<<4]		;				;
+		.if	ne		; yes:				;
+		 ldx	OutCtrl\1	; sending out XON/XOFF?		;
+		 .if	ne		; yes:				;
+		  lda	CIA+C_PB	; check CTS signal		;
+		  and	#[1<<\1]	; (for this port only)		;
+		  bne	=DONE		; not allowed to send -> done	;
+		  stx	ACIA\1+A_DATA	; transmit control char		;
+		  stz	OutCtrl\1	; clear flag			;
+		  jmp	=DONE		; and we're done		;
+		 .end			;				;
+					;				;
+		 ldx	OutTail\1	; anything to transmit?		;
+		 cpx	OutHead\1	;				;
+		 .if	ne		; yes:				;
+		  lda	OutDisable\1	; allowed to transmit?		;
+		  .if	eq		; yes:				;
+		   lda	CIA+C_PB	; check CTS signal		;
+		   and	#[1<<\1]	; (for this port only)		;
+		   bne	=DONE		; not allowed to send -> done	;
+		   lda	obuf\1,x	; get a char from buffer	;
+		   sta	ACIA\1+A_DATA	; send it away			;
+		   inc	OutTail\1	; update read index		;
+		  .end			;				;
+		 .end			;				;
+		.end			;				;
+=DONE		.end	local
+		endm
+
+
+
+PORTVAR		macro	* port number
+		VARDEF	InHead\1 1
+		VARDEF	InTail\1 1
+		VARDEF	OutDisable\1 1
+		VARDEF	OutHead\1 1
+		VARDEF	OutTail\1 1
+		VARDEF	OutCtrl\1 1
+		VARDEF	OutFlush\1 1
+		VARDEF	SetUp\1 1
+		VARDEF	Param\1 1
+		VARDEF	Command\1 1
+		VARDEF	SoftFlow\1 1
+		; private:
+		VARDEF	XonOff\1 1
+		endm
+
+
+ VARBASE 0	; start variables at address $0000
+ PORTVAR 0	; define variables for port 0
+ PORTVAR 1	; define variables for port 1
+ PORTVAR 2	; define variables for port 2
+ PORTVAR 3	; define variables for port 3
+ PORTVAR 4	; define variables for port 4
+ PORTVAR 5	; define variables for port 5
+ PORTVAR 6	; define variables for port 6
+
+
+
+ VARDEF	Crystal	1	; 0 = unknown, 1 = normal, 2 = turbo
+ VARDEF	Pad_a	1
+ VARDEF	TimerH	1
+ VARDEF	TimerL	1
+ VARDEF	CDHead	1
+ VARDEF	CDTail	1
+ VARDEF	CDStatus 1
+ VARDEF	Pad_b	1
+
+ VARDEF	CommonCDo 1	; for carrier detect optimization
+ VARDEF	CommonCDc 1	; for carrier detect debouncing
+ VARDEF	CommonCDb 1	; for carrier detect debouncing
+
+
+ VARBASE $0200
+ VARDEF	obuf0 256	; output data (characters only)
+ VARDEF	obuf1 256
+ VARDEF	obuf2 256
+ VARDEF	obuf3 256
+ VARDEF	obuf4 256
+ VARDEF	obuf5 256
+ VARDEF	obuf6 256
+
+ VARDEF	ibuf0 256	; input data (characters, events etc - see ictl)
+ VARDEF	ibuf1 256
+ VARDEF	ibuf2 256
+ VARDEF	ibuf3 256
+ VARDEF	ibuf4 256
+ VARDEF	ibuf5 256
+ VARDEF	ibuf6 256
+
+ VARDEF	ictl0 256	; input control information (type of data in ibuf)
+ VARDEF	ictl1 256
+ VARDEF	ictl2 256
+ VARDEF	ictl3 256
+ VARDEF	ictl4 256
+ VARDEF	ictl5 256
+ VARDEF	ictl6 256
+
+ VARDEF	cdbuf 256	; CD event queue
+
+
+ACIA0		equ	$4400
+ACIA1		equ	$4c00
+ACIA2		equ	$5400
+ACIA3		equ	$5c00
+ACIA4		equ	$6400
+ACIA5		equ	$6c00
+ACIA6		equ	$7400
+
+A_DATA		equ	$00
+A_SR		equ	$02
+A_CMD		equ	$04
+A_CTRL		equ	$06
+;  00	write transmit data	read received data
+;  02	reset ACIA		read status register
+;  04	write command register	read command register
+;  06	write control register	read control register
+
+CIA		equ	$7c00		; 8520 CIA
+C_PA		equ	$00		; port A data register
+C_PB		equ	$02		; port B data register
+C_DDRA		equ	$04		; data direction register for port A
+C_DDRB		equ	$06		; data direction register for port B
+C_TAL		equ	$08		; timer A
+C_TAH		equ	$0a
+C_TBL		equ	$0c		; timer B
+C_TBH		equ	$0e
+C_TODL		equ	$10		; TOD LSB
+C_TODM		equ	$12		; TOD middle byte
+C_TODH		equ	$14		; TOD MSB
+C_DATA		equ	$18		; serial data register
+C_INTCTRL	equ	$1a		; interrupt control register
+C_CTRLA		equ	$1c		; control register A
+C_CTRLB		equ	$1e		; control register B
+
+
+
+
+
+		section	main,code,CODE-2
+
+		db	>CODE,<CODE
+
+;-----------------------------------------------------------------------;
+; here's the initialization code:					;
+;									;
+R_RESET		ldx	#$ff						;
+		txs			; initialize stack pointer	;
+		cld			; in case a 6502 is used...	;
+		ldx	#0		;				;
+		lda	#0		;				;
+		ldy	#Crystal	; this many bytes to clear	;
+clr_loop	sta	0,x		; clear zero page variables	;
+		inx			;				;
+		dey			;				;
+		bne	clr_loop	;				;
+					;				;
+		stz	CommonCDo	; force CD test at boot		;
+		stz	CommonCDb	;				;
+		stz	CDHead		; clear queue			;
+		stz	CDTail		;				;
+					;				;
+		lda	#0		;				;
+		sta	Pad_a		;				;
+		lda	#170		; test cmp			;
+		cmp	#100		;				;
+		.if	cs		;				;
+		 inc	Pad_a		; C was set			;
+		.end			;				;
+									;
+;-----------------------------------------------------------------------;
+; Speed check								;
+;-----------------------------------------------------------------------;
+									;
+		lda	Crystal		; speed already set?		;
+		beq	DoSpeedy	;				;
+		jmp	LOOP		; yes, skip speed test		;
+					;				;
+DoSpeedy	lda	#%10011000	; 8N1, 1200/2400 bps		;
+		sta	ACIA0+A_CTRL	;				;
+		lda	#%00001011	; enable DTR			;
+		sta	ACIA0+A_CMD	;				;
+		lda	ACIA0+A_SR	; read status register		;
+					;				;
+		lda	#%10000000	; disable all ints (unnecessary);
+		sta	CIA+C_INTCTRL	;				;
+		lda	#255		; program the timer		;
+		sta	CIA+C_TAL	;				;
+		sta	CIA+C_TAH	;				;
+					;				;
+		ldx	#0		;				;
+		stx	ACIA0+A_DATA	; transmit a zero		;
+		nop			;				;
+		nop			;				;
+		lda	ACIA0+A_SR	; read status			;
+		nop			;				;
+		nop			;				;
+		stx	ACIA0+A_DATA	; transmit a zero		;
+Speedy1		lda	ACIA0+A_SR	; read status			;
+		and	#[1<<4]		; transmit data reg empty?	;
+		beq	Speedy1		; not yet, wait more		;
+					;				;
+		lda	#%00010001	; load & start the timer	;
+		stx	ACIA0+A_DATA	; transmit one more zero	;
+		sta	CIA+C_CTRLA	;				;
+Speedy2		lda	ACIA0+A_SR	; read status			;
+		and	#[1<<4]		; transmit data reg empty?	;
+		beq	Speedy2		; not yet, wait more		;
+		stx	CIA+C_CTRLA	; stop the timer		;
+					;				;
+		lda	CIA+C_TAL	; copy timer value for 68k	;
+		sta	TimerL		;				;
+		lda	CIA+C_TAH	;				;
+		sta	TimerH		;				;
+		cmp	#$d0		; turbo or normal?		;
+		.if	cs		;				;
+		 lda	#2		; turbo! :-)			;
+		.else			;				;
+		 lda	#1		; normal :-(			;
+		.end			;				;
+		sta	Crystal		;				;
+		lda	#0		;				;
+		sta	ACIA0+A_SR	;				;
+		sta	ACIA0+A_CTRL	; reset UART			;
+		sta	ACIA0+A_CMD	;				;
+									;
+		jmp	LOOP						;
+									;
+;									;
+;-----------------------------------------------------------------------;
+;									;
+; The Real Thing:							;
+;									;
+LOOP		DO_SLOW			; do non-critical things	;
+		jsr	do_input	; check for received data
+		DO_PORT	0
+		jsr	do_input
+		DO_PORT	1
+		jsr	do_input
+		DO_PORT	2
+		jsr	do_input
+		DO_PORT	3
+		jsr	do_input
+		DO_PORT	4
+		jsr	do_input
+		DO_PORT	5
+		jsr	do_input
+		DO_PORT	6
+		jsr	do_input
+		jmp	LOOP
+
+
+do_input	DO_DATA	0
+		DO_DATA	1
+		DO_DATA	2
+		DO_DATA	3
+		DO_DATA	4
+		DO_DATA	5
+		DO_DATA	6
+		rts
+
+
+;-----------------------------------------------------------------------;
+		section	vectors,data,$3ffa
+		dw	$d0d0
+		dw	R_RESET
+		dw	$c0ce
+;-----------------------------------------------------------------------;
+
+
+
+		end
+
+
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)