ser_a2232fw.ax 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  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. CODE equ $3800 ; start address for program code
  76. CTL_CHAR equ $00 ; byte in ibuf is a character
  77. CTL_EVENT equ $01 ; byte in ibuf is an event
  78. EVENT_BREAK equ $01
  79. EVENT_CDON equ $02
  80. EVENT_CDOFF equ $03
  81. EVENT_SYNC equ $04
  82. XON equ $11
  83. XOFF equ $13
  84. VARBASE macro *starting_address ; was VARINIT
  85. _varbase set \1
  86. endm
  87. VARDEF macro *name space_needs
  88. \1 equ _varbase
  89. _varbase set _varbase+\2
  90. endm
  91. stz macro * address
  92. db $64,\1
  93. endm
  94. stzax macro * address
  95. db $9e,<\1,>\1
  96. endm
  97. biti macro * immediate value
  98. db $89,\1
  99. endm
  100. smb0 macro * address
  101. db $87,\1
  102. endm
  103. smb1 macro * address
  104. db $97,\1
  105. endm
  106. smb2 macro * address
  107. db $a7,\1
  108. endm
  109. smb3 macro * address
  110. db $b7,\1
  111. endm
  112. smb4 macro * address
  113. db $c7,\1
  114. endm
  115. smb5 macro * address
  116. db $d7,\1
  117. endm
  118. smb6 macro * address
  119. db $e7,\1
  120. endm
  121. smb7 macro * address
  122. db $f7,\1
  123. endm
  124. ;-----------------------------------------------------------------------;
  125. ; ;
  126. ; stuff common for all ports, non-critical (run once / loop) ;
  127. ; ;
  128. DO_SLOW macro * port_number ;
  129. .local ; ;
  130. lda CIA+C_PA ; check all CD inputs ;
  131. cmp CommonCDo ; changed from previous accptd? ;
  132. beq =over ; nope, do nothing else here ;
  133. ; ;
  134. cmp CommonCDb ; bouncing? ;
  135. beq =nobounce ; nope -> ;
  136. ; ;
  137. sta CommonCDb ; save current state ;
  138. lda #64 ; reinitialize counter ;
  139. sta CommonCDc ; ;
  140. jmp =over ; skip CD save ;
  141. ; ;
  142. =nobounce dec CommonCDc ; no, decrement bounce counter ;
  143. bpl =over ; not done yet, so skip CD save ;
  144. ; ;
  145. =saveCD ldx CDHead ; get write index ;
  146. sta cdbuf,x ; save status in buffer ;
  147. inx ; ;
  148. cpx CDTail ; buffer full? ;
  149. .if ne ; no: preserve status: ;
  150. stx CDHead ; update index in RAM ;
  151. sta CommonCDo ; save state for the next check ;
  152. .end ; ;
  153. =over .end local ;
  154. endm ;
  155. ;
  156. ;-----------------------------------------------------------------------;
  157. ; port specific stuff (no data transfer)
  158. DO_PORT macro * port_number
  159. .local ; ;
  160. lda SetUp\1 ; reconfiguration request? ;
  161. .if ne ; yes: ;
  162. lda SoftFlow\1 ; get XON/XOFF flag ;
  163. sta XonOff\1 ; save it ;
  164. lda Param\1 ; get parameter ;
  165. ora #%00010000 ; use baud generator for Rx ;
  166. sta ACIA\1+A_CTRL ; store in control register ;
  167. stz OutDisable\1 ; enable transmit output ;
  168. stz SetUp\1 ; no reconfiguration no more ;
  169. .end ; ;
  170. ; ;
  171. lda InHead\1 ; get write index ;
  172. sbc InTail\1 ; buffer full soon? ;
  173. cmp #200 ; 200 chars or more in buffer? ;
  174. lda Command\1 ; get Command reg value ;
  175. and #%11110011 ; turn RTS OFF by default ;
  176. .if cc ; still room in buffer: ;
  177. ora #%00001000 ; turn RTS ON ;
  178. .end ; ;
  179. sta ACIA\1+A_CMD ; set/clear RTS ;
  180. ; ;
  181. lda OutFlush\1 ; request to flush output buffer;
  182. .if ne ; yessh! ;
  183. lda OutHead\1 ; get head ;
  184. sta OutTail\1 ; save as tail ;
  185. stz OutDisable\1 ; enable transmit output ;
  186. stz OutFlush\1 ; clear request ;
  187. .end
  188. .end local
  189. endm
  190. DO_DATA macro * port number
  191. .local
  192. lda ACIA\1+A_SR ; read ACIA status register ;
  193. biti [1<<3] ; something received? ;
  194. .if ne ; yes: ;
  195. biti [1<<1] ; framing error? ;
  196. .if ne ; yes: ;
  197. lda ACIA\1+A_DATA ; read received character ;
  198. bne =SEND ; not break -> ignore it ;
  199. ldx InHead\1 ; get write pointer ;
  200. lda #CTL_EVENT ; get type of byte ;
  201. sta ictl\1,x ; save it in InCtl buffer ;
  202. lda #EVENT_BREAK ; event code ;
  203. sta ibuf\1,x ; save it as well ;
  204. inx ; ;
  205. cpx InTail\1 ; still room in buffer? ;
  206. .if ne ; absolutely: ;
  207. stx InHead\1 ; update index in memory ;
  208. .end ; ;
  209. jmp =SEND ; go check if anything to send ;
  210. .end ; ;
  211. ; normal char received: ;
  212. ldx InHead\1 ; get write index ;
  213. lda ACIA\1+A_DATA ; read received character ;
  214. sta ibuf\1,x ; save char in buffer ;
  215. stzax ictl\1 ; set type to CTL_CHAR ;
  216. inx ; ;
  217. cpx InTail\1 ; buffer full? ;
  218. .if ne ; no: preserve character: ;
  219. stx InHead\1 ; update index in RAM ;
  220. .end ; ;
  221. and #$7f ; mask off parity if any ;
  222. cmp #XOFF ; XOFF from remote host? ;
  223. .if eq ; yes: ;
  224. lda XonOff\1 ; if XON/XOFF handshaking.. ;
  225. sta OutDisable\1 ; ..disable transmitter ;
  226. .end ; ;
  227. .end ; ;
  228. ; ;
  229. ; BUFFER FULL CHECK WAS HERE ;
  230. ; ;
  231. =SEND lda ACIA\1+A_SR ; transmit register empty? ;
  232. and #[1<<4] ; ;
  233. .if ne ; yes: ;
  234. ldx OutCtrl\1 ; sending out XON/XOFF? ;
  235. .if ne ; yes: ;
  236. lda CIA+C_PB ; check CTS signal ;
  237. and #[1<<\1] ; (for this port only) ;
  238. bne =DONE ; not allowed to send -> done ;
  239. stx ACIA\1+A_DATA ; transmit control char ;
  240. stz OutCtrl\1 ; clear flag ;
  241. jmp =DONE ; and we're done ;
  242. .end ; ;
  243. ; ;
  244. ldx OutTail\1 ; anything to transmit? ;
  245. cpx OutHead\1 ; ;
  246. .if ne ; yes: ;
  247. lda OutDisable\1 ; allowed to transmit? ;
  248. .if eq ; yes: ;
  249. lda CIA+C_PB ; check CTS signal ;
  250. and #[1<<\1] ; (for this port only) ;
  251. bne =DONE ; not allowed to send -> done ;
  252. lda obuf\1,x ; get a char from buffer ;
  253. sta ACIA\1+A_DATA ; send it away ;
  254. inc OutTail\1 ; update read index ;
  255. .end ; ;
  256. .end ; ;
  257. .end ; ;
  258. =DONE .end local
  259. endm
  260. PORTVAR macro * port number
  261. VARDEF InHead\1 1
  262. VARDEF InTail\1 1
  263. VARDEF OutDisable\1 1
  264. VARDEF OutHead\1 1
  265. VARDEF OutTail\1 1
  266. VARDEF OutCtrl\1 1
  267. VARDEF OutFlush\1 1
  268. VARDEF SetUp\1 1
  269. VARDEF Param\1 1
  270. VARDEF Command\1 1
  271. VARDEF SoftFlow\1 1
  272. ; private:
  273. VARDEF XonOff\1 1
  274. endm
  275. VARBASE 0 ; start variables at address $0000
  276. PORTVAR 0 ; define variables for port 0
  277. PORTVAR 1 ; define variables for port 1
  278. PORTVAR 2 ; define variables for port 2
  279. PORTVAR 3 ; define variables for port 3
  280. PORTVAR 4 ; define variables for port 4
  281. PORTVAR 5 ; define variables for port 5
  282. PORTVAR 6 ; define variables for port 6
  283. VARDEF Crystal 1 ; 0 = unknown, 1 = normal, 2 = turbo
  284. VARDEF Pad_a 1
  285. VARDEF TimerH 1
  286. VARDEF TimerL 1
  287. VARDEF CDHead 1
  288. VARDEF CDTail 1
  289. VARDEF CDStatus 1
  290. VARDEF Pad_b 1
  291. VARDEF CommonCDo 1 ; for carrier detect optimization
  292. VARDEF CommonCDc 1 ; for carrier detect debouncing
  293. VARDEF CommonCDb 1 ; for carrier detect debouncing
  294. VARBASE $0200
  295. VARDEF obuf0 256 ; output data (characters only)
  296. VARDEF obuf1 256
  297. VARDEF obuf2 256
  298. VARDEF obuf3 256
  299. VARDEF obuf4 256
  300. VARDEF obuf5 256
  301. VARDEF obuf6 256
  302. VARDEF ibuf0 256 ; input data (characters, events etc - see ictl)
  303. VARDEF ibuf1 256
  304. VARDEF ibuf2 256
  305. VARDEF ibuf3 256
  306. VARDEF ibuf4 256
  307. VARDEF ibuf5 256
  308. VARDEF ibuf6 256
  309. VARDEF ictl0 256 ; input control information (type of data in ibuf)
  310. VARDEF ictl1 256
  311. VARDEF ictl2 256
  312. VARDEF ictl3 256
  313. VARDEF ictl4 256
  314. VARDEF ictl5 256
  315. VARDEF ictl6 256
  316. VARDEF cdbuf 256 ; CD event queue
  317. ACIA0 equ $4400
  318. ACIA1 equ $4c00
  319. ACIA2 equ $5400
  320. ACIA3 equ $5c00
  321. ACIA4 equ $6400
  322. ACIA5 equ $6c00
  323. ACIA6 equ $7400
  324. A_DATA equ $00
  325. A_SR equ $02
  326. A_CMD equ $04
  327. A_CTRL equ $06
  328. ; 00 write transmit data read received data
  329. ; 02 reset ACIA read status register
  330. ; 04 write command register read command register
  331. ; 06 write control register read control register
  332. CIA equ $7c00 ; 8520 CIA
  333. C_PA equ $00 ; port A data register
  334. C_PB equ $02 ; port B data register
  335. C_DDRA equ $04 ; data direction register for port A
  336. C_DDRB equ $06 ; data direction register for port B
  337. C_TAL equ $08 ; timer A
  338. C_TAH equ $0a
  339. C_TBL equ $0c ; timer B
  340. C_TBH equ $0e
  341. C_TODL equ $10 ; TOD LSB
  342. C_TODM equ $12 ; TOD middle byte
  343. C_TODH equ $14 ; TOD MSB
  344. C_DATA equ $18 ; serial data register
  345. C_INTCTRL equ $1a ; interrupt control register
  346. C_CTRLA equ $1c ; control register A
  347. C_CTRLB equ $1e ; control register B
  348. section main,code,CODE-2
  349. db >CODE,<CODE
  350. ;-----------------------------------------------------------------------;
  351. ; here's the initialization code: ;
  352. ; ;
  353. R_RESET ldx #$ff ;
  354. txs ; initialize stack pointer ;
  355. cld ; in case a 6502 is used... ;
  356. ldx #0 ; ;
  357. lda #0 ; ;
  358. ldy #Crystal ; this many bytes to clear ;
  359. clr_loop sta 0,x ; clear zero page variables ;
  360. inx ; ;
  361. dey ; ;
  362. bne clr_loop ; ;
  363. ; ;
  364. stz CommonCDo ; force CD test at boot ;
  365. stz CommonCDb ; ;
  366. stz CDHead ; clear queue ;
  367. stz CDTail ; ;
  368. ; ;
  369. lda #0 ; ;
  370. sta Pad_a ; ;
  371. lda #170 ; test cmp ;
  372. cmp #100 ; ;
  373. .if cs ; ;
  374. inc Pad_a ; C was set ;
  375. .end ; ;
  376. ;
  377. ;-----------------------------------------------------------------------;
  378. ; Speed check ;
  379. ;-----------------------------------------------------------------------;
  380. ;
  381. lda Crystal ; speed already set? ;
  382. beq DoSpeedy ; ;
  383. jmp LOOP ; yes, skip speed test ;
  384. ; ;
  385. DoSpeedy lda #%10011000 ; 8N1, 1200/2400 bps ;
  386. sta ACIA0+A_CTRL ; ;
  387. lda #%00001011 ; enable DTR ;
  388. sta ACIA0+A_CMD ; ;
  389. lda ACIA0+A_SR ; read status register ;
  390. ; ;
  391. lda #%10000000 ; disable all ints (unnecessary);
  392. sta CIA+C_INTCTRL ; ;
  393. lda #255 ; program the timer ;
  394. sta CIA+C_TAL ; ;
  395. sta CIA+C_TAH ; ;
  396. ; ;
  397. ldx #0 ; ;
  398. stx ACIA0+A_DATA ; transmit a zero ;
  399. nop ; ;
  400. nop ; ;
  401. lda ACIA0+A_SR ; read status ;
  402. nop ; ;
  403. nop ; ;
  404. stx ACIA0+A_DATA ; transmit a zero ;
  405. Speedy1 lda ACIA0+A_SR ; read status ;
  406. and #[1<<4] ; transmit data reg empty? ;
  407. beq Speedy1 ; not yet, wait more ;
  408. ; ;
  409. lda #%00010001 ; load & start the timer ;
  410. stx ACIA0+A_DATA ; transmit one more zero ;
  411. sta CIA+C_CTRLA ; ;
  412. Speedy2 lda ACIA0+A_SR ; read status ;
  413. and #[1<<4] ; transmit data reg empty? ;
  414. beq Speedy2 ; not yet, wait more ;
  415. stx CIA+C_CTRLA ; stop the timer ;
  416. ; ;
  417. lda CIA+C_TAL ; copy timer value for 68k ;
  418. sta TimerL ; ;
  419. lda CIA+C_TAH ; ;
  420. sta TimerH ; ;
  421. cmp #$d0 ; turbo or normal? ;
  422. .if cs ; ;
  423. lda #2 ; turbo! :-) ;
  424. .else ; ;
  425. lda #1 ; normal :-( ;
  426. .end ; ;
  427. sta Crystal ; ;
  428. lda #0 ; ;
  429. sta ACIA0+A_SR ; ;
  430. sta ACIA0+A_CTRL ; reset UART ;
  431. sta ACIA0+A_CMD ; ;
  432. ;
  433. jmp LOOP ;
  434. ;
  435. ; ;
  436. ;-----------------------------------------------------------------------;
  437. ; ;
  438. ; The Real Thing: ;
  439. ; ;
  440. LOOP DO_SLOW ; do non-critical things ;
  441. jsr do_input ; check for received data
  442. DO_PORT 0
  443. jsr do_input
  444. DO_PORT 1
  445. jsr do_input
  446. DO_PORT 2
  447. jsr do_input
  448. DO_PORT 3
  449. jsr do_input
  450. DO_PORT 4
  451. jsr do_input
  452. DO_PORT 5
  453. jsr do_input
  454. DO_PORT 6
  455. jsr do_input
  456. jmp LOOP
  457. do_input DO_DATA 0
  458. DO_DATA 1
  459. DO_DATA 2
  460. DO_DATA 3
  461. DO_DATA 4
  462. DO_DATA 5
  463. DO_DATA 6
  464. rts
  465. ;-----------------------------------------------------------------------;
  466. section vectors,data,$3ffa
  467. dw $d0d0
  468. dw R_RESET
  469. dw $c0ce
  470. ;-----------------------------------------------------------------------;
  471. end