Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | - | 1 | ;---------------------------------------------------------- |
2 | ; MACRO.INC |
||
3 | ; PROGETTO: B1601 |
||
4 | ; |
||
5 | ; Bit registro di stato / macro |
||
6 | ;---------------------------------------------------------- |
||
7 | |||
8 | ; il file puo' essere incluso solo all'interno di GLOBAL.INC |
||
9 | .IFNDEF _GLOBAL_INC_ |
||
10 | .EXIT "ERROR: This file cannot be included." |
||
11 | .ENDIF |
||
12 | |||
13 | ; flag registro di stato CPU |
||
14 | PNFLAG .EQU 10000000B ; Negative flag |
||
15 | PVFLAG .EQU 01000000B ; Overflow flag |
||
16 | PMFLAG .EQU 00100000B ; Acc/Mem 8 bit flag |
||
17 | PXFLAG .EQU 00010000B ; Index 8 bit flag |
||
18 | PDFLAG .EQU 00001000B ; Decimal flag |
||
19 | PIFLAG .EQU 00000100B ; IRQ disable flag |
||
20 | PZFLAG .EQU 00000010B ; Zero flag |
||
21 | PCFLAG .EQU 00000001B ; Carry flag |
||
22 | |||
23 | PFALL .EQU PNFLAG+PVFLAG+PZFLAG+PCFLAG |
||
24 | |||
25 | .MNLIST |
||
26 | |||
27 | ; attiva MEM/ACC 16 bit |
||
28 | ACC16: .MACRO |
||
29 | .MLIST |
||
30 | rep #PMFLAG |
||
31 | .LONGA on |
||
32 | .MNLIST |
||
33 | .ENDM |
||
34 | |||
35 | ; attiva MEM/ACC 16 bit + CLC |
||
36 | ACC16CLC: .MACRO |
||
37 | .MLIST |
||
38 | rep #(PMFLAG.OR.PCFLAG) |
||
39 | .LONGA on |
||
40 | .MNLIST |
||
41 | .ENDM |
||
42 | |||
43 | ; attiva MEM/ACC 16 bit + CLC + CLV |
||
44 | ACC16CV: .MACRO |
||
45 | .MLIST |
||
46 | rep #(PMFLAG.OR.PCFLAG.OR.PVFLAG) |
||
47 | .LONGA on |
||
48 | .MNLIST |
||
49 | .ENDM |
||
50 | |||
51 | ; attiva MEM/ACC 8 bit |
||
52 | ACC08: .MACRO |
||
53 | .MLIST |
||
54 | sep #PMFLAG |
||
55 | .LONGA off |
||
56 | .MNLIST |
||
57 | .ENDM |
||
58 | |||
59 | ACC08SEC: .MACRO |
||
60 | .MLIST |
||
61 | sep #(PMFLAG.OR.PCFLAG) |
||
62 | .LONGA off |
||
63 | .MNLIST |
||
64 | .ENDM |
||
65 | |||
66 | ; attiva INDEX 16 bit |
||
67 | INDEX16: .MACRO |
||
68 | .MLIST |
||
69 | rep #PXFLAG |
||
70 | .LONGI on |
||
71 | .MNLIST |
||
72 | .ENDM |
||
73 | |||
74 | ; attiva INDEX 16 bit+CLC |
||
75 | INDEX16CLC: .MACRO |
||
76 | .MLIST |
||
77 | rep #(PXFLAG.OR.PCFLAG) |
||
78 | .LONGI on |
||
79 | .MNLIST |
||
80 | .ENDM |
||
81 | |||
82 | ; attiva INDEX 16 bit+CLC+CLV |
||
83 | INDEX16CV: .MACRO |
||
84 | .MLIST |
||
85 | rep #(PXFLAG.OR.PCFLAG.OR.PVFLAG) |
||
86 | .LONGI on |
||
87 | .MNLIST |
||
88 | .ENDM |
||
89 | |||
90 | ; attiva INDEX 8 bit |
||
91 | INDEX08: .MACRO |
||
92 | .MLIST |
||
93 | sep #PXFLAG |
||
94 | .LONGI off |
||
95 | .MNLIST |
||
96 | .ENDM |
||
97 | |||
98 | ; attiva INDEX 8 bit |
||
99 | INDEX08VF: .MACRO |
||
100 | .MLIST |
||
101 | sep #(PXFLAG.OR.PVFLAG) |
||
102 | .LONGI off |
||
103 | .MNLIST |
||
104 | .ENDM |
||
105 | |||
106 | ; attiva MEM/ACC/INDEX 16 bit |
||
107 | CPU16: .MACRO |
||
108 | .MLIST |
||
109 | rep #(PMFLAG.OR.PXFLAG) |
||
110 | .LONGA on |
||
111 | .LONGI on |
||
112 | .MNLIST |
||
113 | .ENDM |
||
114 | |||
115 | ; attiva MEM/ACC/INDEX 16 bit + CLC |
||
116 | CPU16CLC: .MACRO |
||
117 | .MLIST |
||
118 | rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG) |
||
119 | .LONGA on |
||
120 | .LONGI on |
||
121 | .MNLIST |
||
122 | .ENDM |
||
123 | |||
124 | ; attiva MEM/ACC/INDEX 8 bit |
||
125 | CPU08: .MACRO |
||
126 | .MLIST |
||
127 | sep #(PMFLAG.OR.PXFLAG) |
||
128 | .LONGA off |
||
129 | .LONGI off |
||
130 | .MNLIST |
||
131 | .ENDM |
||
132 | |||
133 | ; attiva MEM/ACC/INDEX 8 bit + SEC |
||
134 | CPU08SEC: .MACRO |
||
135 | .MLIST |
||
136 | sep #(PMFLAG.OR.PXFLAG.OR.PCFLAG) |
||
137 | .LONGA off |
||
138 | .LONGI off |
||
139 | .MNLIST |
||
140 | .ENDM |
||
141 | |||
142 | ; attiva MEM/ACC/INDEX 8 bit + VF |
||
143 | CPU08VF: .MACRO |
||
144 | .MLIST |
||
145 | sep #(PMFLAG.OR.PXFLAG.OR.PVFLAG) |
||
146 | .LONGA off |
||
147 | .LONGI off |
||
148 | .MNLIST |
||
149 | .ENDM |
||
150 | |||
151 | LONG_OFF .MACRO |
||
152 | .MLIST |
||
153 | .LONGA off |
||
154 | .LONGI off |
||
155 | .MNLIST |
||
156 | .ENDM |
||
157 | |||
158 | LONG_ON .MACRO |
||
159 | .MLIST |
||
160 | .LONGA on |
||
161 | .LONGI on |
||
162 | .MNLIST |
||
163 | .ENDM |
||
164 | |||
165 | ;---------------------------------------------------------- |
||
166 | ; MACRO DEFINIZIONE VARIABILI |
||
167 | ;---------------------------------------------------------- |
||
168 | |||
169 | ; definisce un long-pointer (24 bit) |
||
170 | LP .MACRO |
||
171 | .DS 3 |
||
172 | .ENDM |
||
173 | |||
174 | ; definisce un intero a 32 bit |
||
175 | DD .MACRO |
||
176 | .LWORD |
||
177 | .ENDM |
||
178 | |||
179 | ; definisce un intero a 64 bit |
||
180 | DQ .MACRO |
||
181 | .BLKL 2 |
||
182 | .ENDM |
||
183 | |||
184 | ;---------------------------------------------------------- |
||
185 | ; MACRO DEFINIZIONE JMP-TABLE |
||
186 | ;---------------------------------------------------------- |
||
187 | |||
188 | SYSFUNC .MACRO SFunc, LocFunc |
||
189 | .MNLIST |
||
190 | .IFNDEF SFunc |
||
191 | .EXIT "ERROR: <SFunc> not defined." |
||
192 | .ENDIF |
||
193 | .MLIST |
||
194 | .ABSOLUTE |
||
195 | .ORG (.LOW16.SFunc - JMPTOFS) |
||
196 | jsr LocFunc |
||
197 | rtl |
||
198 | .RELATIVE |
||
199 | .MNLIST |
||
200 | .ENDM |
||
201 | |||
202 | SYSJMP .MACRO SFunc, LocFunc |
||
203 | .MNLIST |
||
204 | .IFNDEF SFunc |
||
205 | .EXIT "ERROR: <SFunc> not defined." |
||
206 | .ENDIF |
||
207 | .MLIST |
||
208 | .ABSOLUTE |
||
209 | .ORG (.LOW16.SFunc - JMPTOFS) |
||
210 | jmp LocFunc |
||
211 | .RELATIVE |
||
212 | .MNLIST |
||
213 | .ENDM |
||
214 | |||
215 | ;---------------------------------------------------------- |
||
216 | ; MACRO DEFINIZIONE RECORD/STRUCT |
||
217 | ;---------------------------------------------------------- |
||
218 | |||
219 | STRUCT .MACRO SName |
||
220 | .MLIST |
||
221 | _|SName| .SECTION page0,common,ref_only,offset 0 ;SName Struct |
||
222 | ;.ABSOLUTE |
||
223 | ;.ORG 0 |
||
224 | .MNLIST |
||
225 | .ENDM |
||
226 | |||
227 | LSTRUCT .MACRO SName |
||
228 | .MLIST |
||
229 | _|SName| .SECTION common,ref_only,offset 0 ;SName Struct |
||
230 | .MNLIST |
||
231 | .ENDM |
||
232 | |||
233 | ESTRUCT .MACRO SName |
||
234 | .MLIST |
||
235 | |SName|SIZE .DS 0 |
||
236 | ;.RELATIVE |
||
237 | .ENDS |
||
238 | .MNLIST |
||
239 | .ENDM |
||
240 | |||
241 | |||
242 | .IFDEF _ACIA_INC_ |
||
243 | |||
244 | SPISR .MACRO num |
||
245 | |||
246 | .MLIST |
||
247 | .IFZ num |
||
248 | k .SET 0 |
||
249 | SOBUFADDR .SET SPOUTBUFF |
||
250 | SIBUFADDR .SET SPINBUFF |
||
251 | .ELSE |
||
252 | k .SET 4 |
||
253 | SOBUFADDR .SET SPOUTBUFF2 |
||
254 | SIBUFADDR .SET SPINBUFF2 |
||
255 | .ENDIF |
||
256 | |||
257 | ldy .ABS.ACIAISR+k ; interrupt status reg. (clear bit 3,4,5) |
||
258 | lda .ABS.ACIACSR+k ; control status register |
||
259 | ;sty spisr+k ; save interrupt status reg. |
||
260 | sta spcsr+k ; save control status reg. |
||
261 | tya ; Y=status reg. |
||
262 | lsr a ; test RDRF bit |
||
263 | bcc ?lin ; go to test control lines |
||
264 | ldx .ABS.ACIARDR+k ; fetch rx data (clear int. status bits 0,1,2) |
||
265 | bit spstat+k ; rx error pending? |
||
266 | bmi ?lin ; yes, discard received data & test ctr. lines |
||
267 | and #00000011B ; 1: overrun/frame error, 2: parity error |
||
268 | bit spcsr+k ; test control status reg. bit 7: FE |
||
269 | bpl ?nof ; no framing error |
||
270 | ora #00000100B ; set framing error bit... |
||
271 | and #$FE ; ...and clear overrun error |
||
272 | ?nof: cmp #0 |
||
273 | beq ?rxok ; no rx error |
||
274 | ora #10000000B ; set rx error bit |
||
275 | bra ?sst ; set stus reg. & discard received data |
||
276 | ?rxok: txa ; A=received data |
||
277 | INDEX16 |
||
278 | .MLIST |
||
279 | ldx ibufcnt+k ; count of bytes stored in input buffer |
||
280 | bit spmode+k ; test if handshake is active |
||
281 | bpl ?chk ; bit 7=0 -> no handshake so check input buff. |
||
282 | bvs ?tst ; bit 6=1 -> hardware handshake |
||
283 | cmp #SPXON ; received an XON control byte? |
||
284 | bne ?xoff ; no, check if received an XOFF |
||
285 | lda #$40 ; received an XON: clear local pause flag |
||
286 | trb sppause+k ; bit 6=0 -> local pause off (resume tx) |
||
287 | bra ?cnt ; discard received data |
||
288 | ?xoff: cmp #SPXOFF ; received an XOFF control byte? |
||
289 | bne ?tst ; no, check condition for remote pause |
||
290 | lda #$40 ; set local pause flag |
||
291 | tsb sppause+k ; bit 6=1 -> local pause on (stop tx operation) |
||
292 | bra ?cnt ; discard received data |
||
293 | ?tst: cpx icntmax+k ; check input buff. for remote pause condition |
||
294 | bcc ?str ; below guard limit: store data |
||
295 | bit sppause+k ; remote pause is already on ? |
||
296 | bmi ?chk ; yes, so check input buffer |
||
297 | xba ; B = received data |
||
298 | bit spmode+k ; test handshake type |
||
299 | bvs ?rtsh ; bit 6=1 -> hardware handshake so set RTS=1 |
||
300 | lda #SPXOFF ; send an XOFF to remote terminal |
||
301 | sta spout+k ; XOFF sending deffered until TDRE is set |
||
302 | bra ?xba ; check input buffer |
||
303 | ?rtsh: lda spfr+k ; hardware handshake... |
||
304 | ora #10000001B ; ...set RTS=1 |
||
305 | sta .ABS.ACIAFR+k ; update format register |
||
306 | lda #$80 ; set remote pause |
||
307 | tsb sppause+k ; bit 7=1 -> remote pause on |
||
308 | ?xba: xba ; A = received data |
||
309 | ?chk: cpx #SIBUFSIZ ; left room in input buffer? |
||
310 | bcc ?str ; yes, store received byte |
||
311 | lda #$C0 ; set bit 7: rx error, bit 6: rx overflow |
||
312 | ?sst: sta spstat+k ; set status register |
||
313 | bra ?cnt ; discard received data |
||
314 | ?str: inx ; now store received data |
||
315 | stx ibufcnt+k ; update bytes count |
||
316 | ldx ibuftail+k ; pointer to rx tail queue |
||
317 | sta >SIBUFADDR,x |
||
318 | inx ; update tail pointer |
||
319 | CPU16 |
||
320 | .MLIST |
||
321 | txa |
||
322 | and #(SIBUFSIZ-1) ; circular queue |
||
323 | sta ibuftail+k |
||
324 | ?cnt: CPU08 ; continue... |
||
325 | .MLIST |
||
326 | ?lin: lda spcsr+k ; get control lines status |
||
327 | and #00111011B ; mask lines level |
||
328 | bit #00001000B ; check DSR line level |
||
329 | beq ?lin2 ; DSR is low |
||
330 | ora #01000000B ; DSR is high |
||
331 | ?lin2: asl a ; 7:DSR, 6:CTS, 5:DCD, 2:DTR, 1:RTS |
||
332 | sta splin+k ; save lines level |
||
333 | ;tya |
||
334 | bit spmode+k ; test for active handshake |
||
335 | bpl ?cnt2 ; no handshake, so ignore CTS/DCD trans. |
||
336 | bvc ?cnt2 ; softw. handshake, so ignore CTS/DCD trans. |
||
337 | ;bit #00001000B ; change state on DSR line? |
||
338 | ;beq ?cts ; no, go to check CTS line |
||
339 | ;ldx #00100000B ; remote disconnession flag |
||
340 | ;lda #00001000B ; check DSR line level |
||
341 | ;bit spcsr+k |
||
342 | ;beq ?dsrl ; DSR line at low level |
||
343 | ;txa ; remote disconnession |
||
344 | ;tsb spstat+k ; set status register |
||
345 | ;bra ?cts |
||
346 | ;?dsrl: ;txa ; remote terminal ready |
||
347 | ;trb spstat+k ; set status register |
||
348 | ;?cts: |
||
349 | lda spmode+k |
||
350 | lsr a ; check if uplink handshake (RTS/DCD control) |
||
351 | tya ; A=interrupt status reg. |
||
352 | bcs ?dcd ; yes, so check DCD line (uplink cable) |
||
353 | bit #00100000B ; change state on CTS line? |
||
354 | beq ?chkt ; no, so check TDRE flag |
||
355 | lda #00100000B ; check CTS line level |
||
356 | bra ?lvl |
||
357 | ?dcd: bit #00010000B ; change state on DCD line? |
||
358 | beq ?chkt ; no, so check TDRE flag |
||
359 | lda #00010000B ; check DCD line level |
||
360 | ?lvl: ldx #$40 ; local pause flag |
||
361 | bit spcsr+k |
||
362 | beq ?clp ; CTS (or DCD) = low so clear local pause |
||
363 | txa ; CTS (or DCD) = high so set local pause |
||
364 | tsb sppause+k |
||
365 | bra ?cnt2 |
||
366 | ?clp: txa |
||
367 | trb sppause+k |
||
368 | ?cnt2: tya |
||
369 | ?chkt: asl a ; check TDRE bit |
||
370 | bpl ?end ; TDRE=0: can't transmit at this time |
||
371 | lda spout+k ; pending an XON/XOFF sending? |
||
372 | beq ?cklp ; no... check local pause flag |
||
373 | sta .ABS.ACIATDR+k ; send XON/XOFF |
||
374 | stz spout+k ; clear XON/XOFF flag |
||
375 | cmp #SPXOFF |
||
376 | beq ?srp ; sent an XOFF |
||
377 | lda #$80 ; sent an XON: clear remote pause flag |
||
378 | trb sppause+k ; bit 7 = 0 -> remote pause off |
||
379 | ?end: rts ; done |
||
380 | ?srp: lda #$80 ; set remote pause flag |
||
381 | tsb sppause+k |
||
382 | rts |
||
383 | ?cklp: bit sppause+k ; local pause is set ? |
||
384 | bvs ?end ; yes, no tx possible at this time |
||
385 | ;bit spcsr+k ; check if remote terminal is ready |
||
386 | ;bmi ?end ; not ready, skip tx |
||
387 | INDEX16 |
||
388 | .MLIST |
||
389 | ldx obufcnt+k ; count of bytes in output buffer |
||
390 | beq ?done ; output buffer is empty: nothing to send |
||
391 | dex ; update count |
||
392 | stx obufcnt+k |
||
393 | ldx obufhead+k ; pointer to head of out buffer |
||
394 | lda >SOBUFADDR,x ; get data from output buffer |
||
395 | sta .ABS.ACIATDR+k ; send data |
||
396 | inx ; update head pointer |
||
397 | CPU16 |
||
398 | .MLIST |
||
399 | txa |
||
400 | and #(SOBUFSIZ-1) ; circular queue |
||
401 | sta obufhead+k |
||
402 | ?done: CPU08 |
||
403 | .MLIST |
||
404 | rts |
||
405 | .ENDM |
||
406 | |||
407 | SPGETB .MACRO num |
||
408 | |||
409 | .MLIST |
||
410 | .IFZ num |
||
411 | k .SET 0 |
||
412 | SIBUFADDR .SET SPINBUFF |
||
413 | .ELSE |
||
414 | k .SET 4 |
||
415 | SIBUFADDR .SET SPINBUFF2 |
||
416 | .ENDIF |
||
417 | |||
418 | sei ; disable interrupt |
||
419 | sec ; assume error |
||
420 | stx sptmp ; save X reg. |
||
421 | lda spstat+k ; rx pending error? |
||
422 | bmi ?done ; yes, exit |
||
423 | lda #0 ; assume no data available |
||
424 | tay ; Y = 0 |
||
425 | INDEX16 |
||
426 | .MLIST |
||
427 | ldx ibufcnt+k ; available new data? |
||
428 | beq ?done ; input queue is empty (exit with CF=1, A=0) |
||
429 | dex ; update count |
||
430 | stx ibufcnt+k |
||
431 | ldx ibufhead+k ; head input buffer pointer |
||
432 | lda >SIBUFADDR,x ; get byte from queue |
||
433 | inx ; update head pointer |
||
434 | cpx #SIBUFSIZ |
||
435 | bcc ?upd |
||
436 | tyx ; circular queue |
||
437 | ?upd: stx ibufhead+k |
||
438 | bit sppause+k ; remote pause is on? |
||
439 | bpl ?ok ; no |
||
440 | ldx ibufcnt+k |
||
441 | cpx icntmin+k ; can clear remote pause? |
||
442 | bcs ?ok ; no |
||
443 | bit spmode+k ; handshake is on? |
||
444 | bpl ?ok ; no |
||
445 | xba ; save data |
||
446 | bvs ?hw ; hardware handshake |
||
447 | lda #SPXON ; software handshake: send an XON |
||
448 | bit .ABS.ACIACSR+k ; check TUR bit |
||
449 | bvc ?def ; can't send an XON at this time |
||
450 | sta .ABS.ACIATDR+k ; send now an XON |
||
451 | bra ?crp ; clear remote pause flag |
||
452 | ?def: sta spout+k ; XON is deffered |
||
453 | bra ?xba |
||
454 | ?hw: lda spfr+k ; hardware handshake: set RTS=0 |
||
455 | sta .ABS.ACIAFR+k |
||
456 | ?crp: lda #$80 |
||
457 | trb sppause+k ; clear remote pause flag |
||
458 | ?xba: xba ; recover data |
||
459 | ?ok: clc |
||
460 | ?done: INDEX08 |
||
461 | .MLIST |
||
462 | ldx sptmp ; restore X reg. |
||
463 | cli |
||
464 | rts ; CF=1 & A=0 mean: no data available |
||
465 | .ENDM |
||
466 | |||
467 | SPPUTB .MACRO num |
||
468 | |||
469 | .MLIST |
||
470 | .IFZ num |
||
471 | k .SET 0 |
||
472 | SOBUFADDR .SET SPOUTBUFF |
||
473 | .ELSE |
||
474 | k .SET 4 |
||
475 | SOBUFADDR .SET SPOUTBUFF2 |
||
476 | .ENDIF |
||
477 | |||
478 | sei ; disable interrupt |
||
479 | stx sptmp ; save X reg. |
||
480 | ldy #0 ; Y = 0 |
||
481 | INDEX16 |
||
482 | .MLIST |
||
483 | ldx obufcnt+k |
||
484 | cpx #SOBUFSIZ ; output buffer is full? |
||
485 | bcc ?str ; no, store byte |
||
486 | bit splin+k |
||
487 | bpl ?done ; exit with CF=1, Y=0: output buffer is full |
||
488 | dey |
||
489 | bra ?done ; exit with CF=1, Y=$FF: remote terminal off |
||
490 | ?str: inx ; update count |
||
491 | stx obufcnt+k |
||
492 | ldx obuftail+k ; output buffer tail pointer |
||
493 | sta >SOBUFADDR,x ; store byte in output buffer |
||
494 | inx ; update tail pointer |
||
495 | cpx #SOBUFSIZ |
||
496 | bcc ?upd |
||
497 | tyx ; circular queue |
||
498 | ?upd: stx obuftail+k |
||
499 | bit .ABS.ACIACSR+k ; check TUR bit: try to free output buffer |
||
500 | bvc ?ok ; can't send now: send by ISR |
||
501 | xba ; save data |
||
502 | lda spout+k ; XON/XOFF send pending? |
||
503 | beq ?snd ; no |
||
504 | sta .ABS.ACIATDR+k ; send an XON/XOFF |
||
505 | cmp #SPXON |
||
506 | bne ?xon |
||
507 | lda #$80 |
||
508 | tsb sppause+k ; set remote pause |
||
509 | stz spout+k ; clear XOFF flag |
||
510 | bra ?xba ; done |
||
511 | ?xon: lda #$80 |
||
512 | trb sppause+k ; clear remote pause |
||
513 | stz spout+k ; clear XON flag |
||
514 | bra ?xba ; done |
||
515 | ?snd: bit sppause+k |
||
516 | bvs ?xba ; local pause is on, can't send at this time |
||
517 | ldx obufcnt+k |
||
518 | beq ?xba ; output buffer is empty |
||
519 | dex ; update count |
||
520 | stx obufcnt+k |
||
521 | ldx obufhead+k |
||
522 | lda >SOBUFADDR,x ; get data from output buffer |
||
523 | sta .ABS.ACIATDR+k ; send data |
||
524 | inx ; update head pointer |
||
525 | cpx #SOBUFSIZ |
||
526 | bcc ?upd2 |
||
527 | tyx ; circular queue |
||
528 | ?upd2: stx obufhead+k |
||
529 | ?xba: xba ; return A = sent data |
||
530 | ?ok: clc ; no error |
||
531 | ?done: INDEX08 |
||
532 | .MLIST |
||
533 | ldx sptmp ; restore X reg. |
||
534 | cli |
||
535 | rts |
||
536 | .ENDM |
||
537 | |||
538 | .ENDIF |