PageRenderTime 31ms CodeModel.GetById 12ms app.highlight 8ms RepoModel.GetById 2ms app.codeStats 0ms

/drivers/char/ser_a2232fw.ax

https://bitbucket.org/evzijst/gittest
Unknown | 529 lines | 471 code | 58 blank | 0 comment | 0 complexity | f71126dac3d774e972095bd159bb1e30 MD5 | raw file
  1;.lib "axm"
  2;
  3;begin
  4;title "A2232 serial board driver"
  5;
  6;set modules "2232"
  7;set executable "2232.bin"
  8;
  9;;;;set nolink
 10;
 11;set temporary directory "t:"
 12;
 13;set assembly options "-m6502 -l60:t:list"
 14;set link options "bin"; loadadr"
 15;;;bin2c 2232.bin msc6502.h msc6502code
 16;end
 17;
 18;
 19; ### Commodore A2232 serial board driver for NetBSD by JM v1.3 ###
 20;
 21; - Created 950501 by JM -
 22;
 23;
 24; Serial board driver software.
 25;
 26;
 27% Copyright (c) 1995 Jukka Marin <jmarin@jmp.fi>.
 28% All rights reserved.
 29%
 30% Redistribution and use in source and binary forms, with or without
 31% modification, are permitted provided that the following conditions
 32% are met:
 33% 1. Redistributions of source code must retain the above copyright
 34%    notice, and the entire permission notice in its entirety,
 35%    including the disclaimer of warranties.
 36% 2. Redistributions in binary form must reproduce the above copyright
 37%    notice, this list of conditions and the following disclaimer in the
 38%    documentation and/or other materials provided with the distribution.
 39% 3. The name of the author may not be used to endorse or promote
 40%    products derived from this software without specific prior
 41%    written permission.
 42%
 43% ALTERNATIVELY, this product may be distributed under the terms of
 44% the GNU General Public License, in which case the provisions of the
 45% GPL are required INSTEAD OF the above restrictions.  (This clause is
 46% necessary due to a potential bad interaction between the GPL and
 47% the restrictions contained in a BSD-style copyright.)
 48%
 49% THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
 50% WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 51% OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 52% DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 53% INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 54% (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 55% SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 56% HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 57% STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 58% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 59% OF THE POSSIBILITY OF SUCH DAMAGE.
 60;
 61;
 62; Bugs:
 63;
 64; - Can't send a break yet
 65;
 66;
 67;
 68; Edited:
 69;
 70; - 950501 by JM -> v0.1	- Created this file.
 71; - 951029 by JM -> v1.3	- Carrier Detect events now queued in a separate
 72;				  queue.
 73;
 74;
 75
 76
 77CODE		equ	$3800		; start address for program code
 78
 79
 80CTL_CHAR	equ	$00		; byte in ibuf is a character
 81CTL_EVENT	equ	$01		; byte in ibuf is an event
 82
 83EVENT_BREAK	equ	$01
 84EVENT_CDON	equ	$02
 85EVENT_CDOFF	equ	$03
 86EVENT_SYNC	equ	$04
 87
 88XON		equ	$11
 89XOFF		equ	$13
 90
 91
 92VARBASE		macro	*starting_address	; was VARINIT
 93_varbase	set	\1
 94		endm
 95
 96VARDEF		macro	*name space_needs
 97\1		equ	_varbase
 98_varbase	set	_varbase+\2
 99		endm
100
101
102stz		macro	* address
103		 db	$64,\1
104		endm
105
106stzax		macro	* address
107		 db	$9e,<\1,>\1
108		endm
109
110
111biti		macro	* immediate value
112		db	$89,\1
113		endm
114
115smb0		macro	* address
116		db	$87,\1
117		endm
118smb1		macro	* address
119		db	$97,\1
120		endm
121smb2		macro	* address
122		db	$a7,\1
123		endm
124smb3		macro	* address
125		db	$b7,\1
126		endm
127smb4		macro	* address
128		db	$c7,\1
129		endm
130smb5		macro	* address
131		db	$d7,\1
132		endm
133smb6		macro	* address
134		db	$e7,\1
135		endm
136smb7		macro	* address
137		db	$f7,\1
138		endm
139
140
141
142;-----------------------------------------------------------------------;
143;									;
144; stuff common for all ports, non-critical (run once / loop)		;
145;									;
146DO_SLOW		macro	* port_number					;
147		.local			;				;
148		lda	CIA+C_PA	; check all CD inputs		;
149		cmp	CommonCDo	; changed from previous accptd?	;
150		beq	=over		; nope, do nothing else here	;
151					;				;
152		cmp	CommonCDb	; bouncing?			;
153		beq	=nobounce	; nope ->			;
154					;				;
155		sta	CommonCDb	; save current state		;
156		lda	#64		; reinitialize counter		;
157		sta	CommonCDc	;				;
158		jmp	=over		; skip CD save			;
159					;				;
160=nobounce	dec	CommonCDc	; no, decrement bounce counter	;
161		bpl	=over		; not done yet, so skip CD save	;
162					;				;
163=saveCD		ldx	CDHead		; get write index		;
164		sta	cdbuf,x		; save status in buffer		;
165		inx			;				;
166		cpx	CDTail		; buffer full?			;
167		.if	ne		; no: preserve status:		;
168		 stx	CDHead		; update index in RAM		;
169		 sta	CommonCDo	; save state for the next check	;
170		.end			;				;
171=over		.end	local						;
172		endm							;
173									;
174;-----------------------------------------------------------------------;
175
176
177; port specific stuff (no data transfer)
178
179DO_PORT		macro	* port_number
180		.local			;				;
181		lda	SetUp\1		; reconfiguration request?	;
182		.if	ne		; yes:				;
183		 lda	SoftFlow\1	; get XON/XOFF flag		;
184		 sta	XonOff\1	; save it			;
185		 lda	Param\1		; get parameter			;
186		 ora	#%00010000	; use baud generator for Rx	;
187		 sta	ACIA\1+A_CTRL	; store in control register	;
188		 stz	OutDisable\1	; enable transmit output	;
189		 stz	SetUp\1		; no reconfiguration no more	;
190		.end			;				;
191					;				;
192		lda	InHead\1	; get write index		;
193		sbc	InTail\1	; buffer full soon?		;
194		cmp	#200		; 200 chars or more in buffer?	;
195		lda	Command\1	; get Command reg value		;
196		and	#%11110011	; turn RTS OFF by default	;
197		.if	cc		; still room in buffer:		;
198		 ora	#%00001000	; turn RTS ON			;
199		.end			;				;
200		sta	ACIA\1+A_CMD	; set/clear RTS			;
201					;				;
202		lda	OutFlush\1	; request to flush output buffer;
203		.if	ne		; yessh!			;
204		 lda	OutHead\1	; get head			;
205		 sta	OutTail\1	; save as tail			;
206		 stz	OutDisable\1	; enable transmit output	;
207		 stz	OutFlush\1	; clear request			;
208		.end
209		.end	local
210		endm
211
212
213DO_DATA		macro	* port number
214		.local
215		lda	ACIA\1+A_SR	; read ACIA status register	;
216		biti	[1<<3]		; something received?		;
217		.if	ne		; yes:				;
218		 biti	[1<<1]		; framing error?		;
219		 .if	ne		; yes:				;
220		  lda	ACIA\1+A_DATA	; read received character	;
221		  bne	=SEND		; not break -> ignore it	;
222		  ldx	InHead\1	; get write pointer		;
223		  lda	#CTL_EVENT	; get type of byte		;
224		  sta	ictl\1,x	; save it in InCtl buffer	;
225		  lda	#EVENT_BREAK	; event code			;
226		  sta	ibuf\1,x	; save it as well		;
227		  inx			;				;
228		  cpx	InTail\1	; still room in buffer?		;
229		  .if	ne		; absolutely:			;
230		   stx	InHead\1	; update index in memory	;
231		  .end			;				;
232		  jmp	=SEND		; go check if anything to send	;
233		 .end			;				;
234		 			; normal char received:		;
235		 ldx	InHead\1	; get write index		;
236		 lda	ACIA\1+A_DATA	; read received character	;
237		 sta	ibuf\1,x	; save char in buffer		;
238		 stzax	ictl\1		; set type to CTL_CHAR		;
239		 inx			;				;
240		 cpx	InTail\1	; buffer full?			;
241		 .if	ne		; no: preserve character:	;
242		  stx	InHead\1	; update index in RAM		;
243		 .end			;				;
244		 and	#$7f		; mask off parity if any	;
245		 cmp	#XOFF		; XOFF from remote host?	;
246		 .if	eq		; yes:				;
247		  lda	XonOff\1	; if XON/XOFF handshaking..	;
248		  sta	OutDisable\1	; ..disable transmitter		;
249		 .end			;				;
250		.end			;				;
251					;				;
252					; BUFFER FULL CHECK WAS HERE	;
253					;				;
254=SEND		lda	ACIA\1+A_SR	; transmit register empty?	;
255		and	#[1<<4]		;				;
256		.if	ne		; yes:				;
257		 ldx	OutCtrl\1	; sending out XON/XOFF?		;
258		 .if	ne		; yes:				;
259		  lda	CIA+C_PB	; check CTS signal		;
260		  and	#[1<<\1]	; (for this port only)		;
261		  bne	=DONE		; not allowed to send -> done	;
262		  stx	ACIA\1+A_DATA	; transmit control char		;
263		  stz	OutCtrl\1	; clear flag			;
264		  jmp	=DONE		; and we're done		;
265		 .end			;				;
266					;				;
267		 ldx	OutTail\1	; anything to transmit?		;
268		 cpx	OutHead\1	;				;
269		 .if	ne		; yes:				;
270		  lda	OutDisable\1	; allowed to transmit?		;
271		  .if	eq		; yes:				;
272		   lda	CIA+C_PB	; check CTS signal		;
273		   and	#[1<<\1]	; (for this port only)		;
274		   bne	=DONE		; not allowed to send -> done	;
275		   lda	obuf\1,x	; get a char from buffer	;
276		   sta	ACIA\1+A_DATA	; send it away			;
277		   inc	OutTail\1	; update read index		;
278		  .end			;				;
279		 .end			;				;
280		.end			;				;
281=DONE		.end	local
282		endm
283
284
285
286PORTVAR		macro	* port number
287		VARDEF	InHead\1 1
288		VARDEF	InTail\1 1
289		VARDEF	OutDisable\1 1
290		VARDEF	OutHead\1 1
291		VARDEF	OutTail\1 1
292		VARDEF	OutCtrl\1 1
293		VARDEF	OutFlush\1 1
294		VARDEF	SetUp\1 1
295		VARDEF	Param\1 1
296		VARDEF	Command\1 1
297		VARDEF	SoftFlow\1 1
298		; private:
299		VARDEF	XonOff\1 1
300		endm
301
302
303 VARBASE 0	; start variables at address $0000
304 PORTVAR 0	; define variables for port 0
305 PORTVAR 1	; define variables for port 1
306 PORTVAR 2	; define variables for port 2
307 PORTVAR 3	; define variables for port 3
308 PORTVAR 4	; define variables for port 4
309 PORTVAR 5	; define variables for port 5
310 PORTVAR 6	; define variables for port 6
311
312
313
314 VARDEF	Crystal	1	; 0 = unknown, 1 = normal, 2 = turbo
315 VARDEF	Pad_a	1
316 VARDEF	TimerH	1
317 VARDEF	TimerL	1
318 VARDEF	CDHead	1
319 VARDEF	CDTail	1
320 VARDEF	CDStatus 1
321 VARDEF	Pad_b	1
322
323 VARDEF	CommonCDo 1	; for carrier detect optimization
324 VARDEF	CommonCDc 1	; for carrier detect debouncing
325 VARDEF	CommonCDb 1	; for carrier detect debouncing
326
327
328 VARBASE $0200
329 VARDEF	obuf0 256	; output data (characters only)
330 VARDEF	obuf1 256
331 VARDEF	obuf2 256
332 VARDEF	obuf3 256
333 VARDEF	obuf4 256
334 VARDEF	obuf5 256
335 VARDEF	obuf6 256
336
337 VARDEF	ibuf0 256	; input data (characters, events etc - see ictl)
338 VARDEF	ibuf1 256
339 VARDEF	ibuf2 256
340 VARDEF	ibuf3 256
341 VARDEF	ibuf4 256
342 VARDEF	ibuf5 256
343 VARDEF	ibuf6 256
344
345 VARDEF	ictl0 256	; input control information (type of data in ibuf)
346 VARDEF	ictl1 256
347 VARDEF	ictl2 256
348 VARDEF	ictl3 256
349 VARDEF	ictl4 256
350 VARDEF	ictl5 256
351 VARDEF	ictl6 256
352
353 VARDEF	cdbuf 256	; CD event queue
354
355
356ACIA0		equ	$4400
357ACIA1		equ	$4c00
358ACIA2		equ	$5400
359ACIA3		equ	$5c00
360ACIA4		equ	$6400
361ACIA5		equ	$6c00
362ACIA6		equ	$7400
363
364A_DATA		equ	$00
365A_SR		equ	$02
366A_CMD		equ	$04
367A_CTRL		equ	$06
368;  00	write transmit data	read received data
369;  02	reset ACIA		read status register
370;  04	write command register	read command register
371;  06	write control register	read control register
372
373CIA		equ	$7c00		; 8520 CIA
374C_PA		equ	$00		; port A data register
375C_PB		equ	$02		; port B data register
376C_DDRA		equ	$04		; data direction register for port A
377C_DDRB		equ	$06		; data direction register for port B
378C_TAL		equ	$08		; timer A
379C_TAH		equ	$0a
380C_TBL		equ	$0c		; timer B
381C_TBH		equ	$0e
382C_TODL		equ	$10		; TOD LSB
383C_TODM		equ	$12		; TOD middle byte
384C_TODH		equ	$14		; TOD MSB
385C_DATA		equ	$18		; serial data register
386C_INTCTRL	equ	$1a		; interrupt control register
387C_CTRLA		equ	$1c		; control register A
388C_CTRLB		equ	$1e		; control register B
389
390
391
392
393
394		section	main,code,CODE-2
395
396		db	>CODE,<CODE
397
398;-----------------------------------------------------------------------;
399; here's the initialization code:					;
400;									;
401R_RESET		ldx	#$ff						;
402		txs			; initialize stack pointer	;
403		cld			; in case a 6502 is used...	;
404		ldx	#0		;				;
405		lda	#0		;				;
406		ldy	#Crystal	; this many bytes to clear	;
407clr_loop	sta	0,x		; clear zero page variables	;
408		inx			;				;
409		dey			;				;
410		bne	clr_loop	;				;
411					;				;
412		stz	CommonCDo	; force CD test at boot		;
413		stz	CommonCDb	;				;
414		stz	CDHead		; clear queue			;
415		stz	CDTail		;				;
416					;				;
417		lda	#0		;				;
418		sta	Pad_a		;				;
419		lda	#170		; test cmp			;
420		cmp	#100		;				;
421		.if	cs		;				;
422		 inc	Pad_a		; C was set			;
423		.end			;				;
424									;
425;-----------------------------------------------------------------------;
426; Speed check								;
427;-----------------------------------------------------------------------;
428									;
429		lda	Crystal		; speed already set?		;
430		beq	DoSpeedy	;				;
431		jmp	LOOP		; yes, skip speed test		;
432					;				;
433DoSpeedy	lda	#%10011000	; 8N1, 1200/2400 bps		;
434		sta	ACIA0+A_CTRL	;				;
435		lda	#%00001011	; enable DTR			;
436		sta	ACIA0+A_CMD	;				;
437		lda	ACIA0+A_SR	; read status register		;
438					;				;
439		lda	#%10000000	; disable all ints (unnecessary);
440		sta	CIA+C_INTCTRL	;				;
441		lda	#255		; program the timer		;
442		sta	CIA+C_TAL	;				;
443		sta	CIA+C_TAH	;				;
444					;				;
445		ldx	#0		;				;
446		stx	ACIA0+A_DATA	; transmit a zero		;
447		nop			;				;
448		nop			;				;
449		lda	ACIA0+A_SR	; read status			;
450		nop			;				;
451		nop			;				;
452		stx	ACIA0+A_DATA	; transmit a zero		;
453Speedy1		lda	ACIA0+A_SR	; read status			;
454		and	#[1<<4]		; transmit data reg empty?	;
455		beq	Speedy1		; not yet, wait more		;
456					;				;
457		lda	#%00010001	; load & start the timer	;
458		stx	ACIA0+A_DATA	; transmit one more zero	;
459		sta	CIA+C_CTRLA	;				;
460Speedy2		lda	ACIA0+A_SR	; read status			;
461		and	#[1<<4]		; transmit data reg empty?	;
462		beq	Speedy2		; not yet, wait more		;
463		stx	CIA+C_CTRLA	; stop the timer		;
464					;				;
465		lda	CIA+C_TAL	; copy timer value for 68k	;
466		sta	TimerL		;				;
467		lda	CIA+C_TAH	;				;
468		sta	TimerH		;				;
469		cmp	#$d0		; turbo or normal?		;
470		.if	cs		;				;
471		 lda	#2		; turbo! :-)			;
472		.else			;				;
473		 lda	#1		; normal :-(			;
474		.end			;				;
475		sta	Crystal		;				;
476		lda	#0		;				;
477		sta	ACIA0+A_SR	;				;
478		sta	ACIA0+A_CTRL	; reset UART			;
479		sta	ACIA0+A_CMD	;				;
480									;
481		jmp	LOOP						;
482									;
483;									;
484;-----------------------------------------------------------------------;
485;									;
486; The Real Thing:							;
487;									;
488LOOP		DO_SLOW			; do non-critical things	;
489		jsr	do_input	; check for received data
490		DO_PORT	0
491		jsr	do_input
492		DO_PORT	1
493		jsr	do_input
494		DO_PORT	2
495		jsr	do_input
496		DO_PORT	3
497		jsr	do_input
498		DO_PORT	4
499		jsr	do_input
500		DO_PORT	5
501		jsr	do_input
502		DO_PORT	6
503		jsr	do_input
504		jmp	LOOP
505
506
507do_input	DO_DATA	0
508		DO_DATA	1
509		DO_DATA	2
510		DO_DATA	3
511		DO_DATA	4
512		DO_DATA	5
513		DO_DATA	6
514		rts
515
516
517;-----------------------------------------------------------------------;
518		section	vectors,data,$3ffa
519		dw	$d0d0
520		dw	R_RESET
521		dw	$c0ce
522;-----------------------------------------------------------------------;
523
524
525
526		end
527
528
529