Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.15-rc2 529 lines 13 kB view raw
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