1;----------------------------------------------------------------------
2; Serial Bus
3;----------------------------------------------------------------------
4; (C)1983 Commodore Business Machines (CBM)
5; additions: (C)2020 Michael Steil, License: 2-clause BSD
6
7.feature labels_without_colons
8
9.include "io.inc"
10.include "mac.inc"
11
12.import status
13.import udst
14
15.export serial_secnd
16.export serial_tksa
17.export serial_acptr
18.export serial_ciout
19.export serial_untlk
20.export serial_unlsn
21.export serial_listn
22.export serial_talk
23
24.export tkatn; [channel]
25.export scatn; [channel]
26.export clklo; [machine init]
27
28sdata	=HACK  ; XXX fill for X16 - now points to #$80, so serial doesn't hang
29d1crb	=$ffff ; XXX fill for X16
30d1icr	=$ffff ; XXX fill for X16
31timrb	=$19            ;6526 crb enable one-shot tb
32
33.segment "KVAR"
34
35c3p0	.res 1           ;$94 ieee buffered char flag
36bsour	.res 1           ;$95 char buffer for ieee
37r2d2	.res 1           ;$A3 serial bus usage
38bsour1	.res 1           ;$A4 temp used by serial routine
39count	.res 1           ;$A5 temp used by serial routine
40
41	.segment "SERIAL"
42
43HACK	.byte $80
44
45;command serial bus device to talk
46;
47serial_talk
48	ora #$40        ;make a talk adr
49	bra list1
50
51;command serial bus device to listen
52;
53serial_listn
54	ora #$20        ;make a listen adr
55list1	pha
56;
57;
58	bit c3p0        ;character left in buf?
59	bpl list2       ;no...
60;
61;send buffered character
62;
63	sec             ;set eoi flag
64	ror r2d2
65;
66	jsr isour       ;send last character
67;
68	lsr c3p0        ;buffer clear flag
69	lsr r2d2        ;clear eoi flag
70;
71;
72list2	pla             ;talk/listen address
73	sta bsour
74	sei
75	jsr datahi
76	cmp #$3f        ;clkhi only on unlisten
77	bne list5
78	jsr clkhi
79;
80list5	lda sdata       ;assert attention
81	ora #$08
82	sta sdata
83;
84
85isoura	sei
86	jsr clklo       ;set clock line low
87	jsr datahi
88	jsr w1ms        ;delay 1 ms
89
90isour	sei             ;no irq's allowed
91	jsr datahi      ;make sure data is released
92	jsr debpia      ;data should be low
93	bcs nodev
94	jsr clkhi       ;clock line high
95	bit r2d2        ;eoi flag test
96	bpl noeoi
97; do the eoi
98isr02	jsr debpia      ;wait for data to go high
99	bcc isr02
100;
101isr03	jsr debpia      ;wait for data to go low
102	bcs isr03
103;
104noeoi	jsr debpia      ;wait for data high
105	bcc noeoi
106	jsr clklo       ;set clock low
107;
108; set to send data
109;
110	lda #$08        ;count 8 bits
111	sta count
112;
113isr01
114	lda sdata       ;debounce the bus
115	cmp sdata
116	bne isr01
117	asl a           ;set the flags
118	bcc frmerr      ;data must be hi
119;
120	ror bsour       ;next bit into carry
121	bcs isrhi
122	jsr datalo
123	bne isrclk
124isrhi	jsr datahi
125isrclk	jsr clkhi       ;clock hi
126	nop
127	nop
128	nop
129	nop
130	lda sdata
131	and #$ff-$20    ;data high
132	ora #$10        ;clock low
133	sta sdata
134	dec count
135	bne isr01
136	lda #$04        ;set timer for 1ms
137	sta d1t2h
138	lda #timrb      ;trigger timer
139	sta d1crb
140	lda d1icr       ;clear the timer flags<<<<<<<<<<<<<
141isr04	lda d1icr
142	and #$02
143	bne frmerr
144	jsr debpia
145	bcs isr04
146	cli             ;let irq's continue
147	rts
148;
149nodev	;device not present error
150	lda #$80
151	bra csberr
152frmerr	;framing error
153	lda #$03
154csberr	jsr udst        ;commodore serial buss error entry
155	cli             ;irq's were off...turn on
156	clc             ;make sure no kernal error returned
157	bcc dlabye      ;turn atn off ,release all lines
158;
159
160;send secondary address after listen
161;
162serial_secnd
163	sta bsour       ;buffer character
164	jsr isoura      ;send it
165
166;release attention after listen
167;
168scatn	lda sdata
169	and #$ff-$08
170	sta sdata       ;release attention
171	rts
172
173;talk second address
174;
175serial_tksa
176	sta bsour       ;buffer character
177	jsr isoura      ;send second addr
178
179tkatn	;shift over to listener
180	sei             ;no irq's here
181	jsr datalo      ;data line low
182	jsr scatn
183	jsr clkhi       ;clock line high jsr/rts
184tkatn1	jsr debpia      ;wait for clock to go low
185	bmi tkatn1
186	cli             ;irq's okay now
187	rts
188
189;buffered output to serial bus
190;
191serial_ciout
192	bit c3p0        ;buffered char?
193	bmi ci2         ;yes...send last
194;
195	sec             ;no...
196	ror c3p0        ;set buffered char flag
197	bne ci4         ;branch always
198;
199ci2	pha             ;save current char
200	jsr isour       ;send last char
201	pla             ;restore current char
202ci4	sta bsour       ;buffer current char
203	clc             ;carry-good exit
204	rts
205
206;send untalk command on serial bus
207;
208serial_untlk
209	sei
210	jsr clklo
211	lda sdata       ;pull atn
212	ora #$08
213	sta sdata
214	lda #$5f        ;untalk command
215	bra :+
216
217;send unlisten command on serial bus
218;
219serial_unlsn
220	lda #$3f        ;unlisten command
221:	jsr list1       ;send it
222;
223; release all lines
224dlabye	jsr scatn       ;always release atn
225; delay then release clock and data
226;
227dladlh	txa             ;delay approx 60 us
228	ldx #10
229dlad00	dex
230	bne dlad00
231	tax
232	jsr clkhi
233	jmp datahi
234
235;input a byte from serial bus
236;
237serial_acptr
238	sei             ;no irq allowed
239	lda #$00        ;set eoi/error flag
240	sta count
241	jsr clkhi       ;make sure clock line is released
242acp00a	jsr debpia      ;wait for clock high
243	bpl acp00a
244;
245eoiacp
246	lda #$01        ;set timer 2 for 256us
247	sta d1t2h
248	lda #timrb
249	sta d1crb
250	jsr datahi      ;data line high (makes timming more like vic-20
251	lda d1icr       ;clear the timer flags<<<<<<<<<<<<
252acp00	lda d1icr
253	and #$02        ;check the timer
254	bne acp00b      ;ran out.....
255	jsr debpia      ;check the clock line
256	bmi acp00       ;no not yet
257	bpl acp01       ;yes.....
258;
259acp00b	lda count       ;check for error (twice thru timeouts)
260	beq acp00c
261	lda #2
262	jmp csberr      ; st = 2 read timeout
263;
264; timer ran out do an eoi thing
265;
266acp00c	jsr datalo      ;data line low
267	jsr clkhi       ; delay and then set datahi (fix for 40us c64)
268	lda #$40
269	jsr udst        ;or an eoi bit into status
270	inc count       ;go around again for error check on eoi
271	bne eoiacp
272;
273; do the byte transfer
274;
275acp01	lda #08         ;set up counter
276	sta count
277;
278acp03	lda sdata       ;wait for clock high
279	cmp sdata       ;debounce
280	bne acp03
281	asl a           ;shift data into carry
282	bpl acp03       ;clock still low...
283	ror bsour1      ;rotate data in
284;
285acp03a	lda sdata       ;wait for clock low
286	cmp sdata       ;debounce
287	bne acp03a
288	asl a
289	bmi acp03a
290	dec count
291	bne acp03       ;more bits.....
292;...exit...
293	jsr datalo      ;data low
294	bit status      ;check for eoi
295	bvc acp04       ;none...
296;
297	jsr dladlh      ;delay then set data high
298;
299acp04	lda bsour1
300	cli             ;irq is ok
301	clc             ;good exit
302	rts
303;
304clkhi	;set clock line high (inverted)
305	lda sdata
306	and #$ff-$10
307	sta sdata
308	rts
309;
310clklo	;set clock line low  (inverted)
311	lda sdata
312	ora #$10
313	sta sdata
314	rts
315;
316;
317datahi	;set data line high (inverted)
318	lda sdata
319	and #$ff-$20
320	sta sdata
321	rts
322;
323datalo	;set data line low  (inverted)
324	lda sdata
325	ora #$20
326	sta sdata
327	rts
328;
329debpia	lda sdata       ;debounce the pia
330	cmp sdata
331	bne debpia
332	asl a           ;shift the data bit into the carry...
333	rts             ;...and the clock into neg flag
334;
335w1ms	;delay 1ms using loop
336	txa             ;save .x
337	ldx #200-16     ;1000us-(1000/500*8=#40us holds)
338w1ms1	dex             ;5us loop
339	bne w1ms1
340	tax             ;restore .x
341	rts
342
343;*******************************
344;written 8/11/80 bob fairbairn
345;test serial0.6 8/12/80  rjf
346;change i/o structure 8/21/80 rjf
347;more i/o changes 8/24/80 rjf
348;final release into kernal 8/26/80 rjf
349;some clean up 9/8/80 rsr
350;add irq protect on isour and tkatn 9/22/80 rsr
351;fix untalk 10/7/80 rsr
352;modify for vic-40 i/o system 12/08/81 rsr
353;add sei to (untlk,isoura,list2) 12/14/81 rsr
354;modify for 6526 flags fix errs 12/31/81 rsr
355;modify for commodore 64 i/o  3/11/82 rsr
356;change acptr eoi for better response 3/28/82 rsr
357;change wait 1 ms routine for less code 4/8/82 rsr
358;******************************
359
360