OpenCores
URL https://opencores.org/ocsvn/rf6809/rf6809/trunk

Subversion Repositories rf6809

[/] [rf6809/] [trunk/] [software/] [boot/] [serial.asm] - Blame information for rev 21

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 robfinch
; ============================================================================
2
;        __
3
;   \\__/ o\    (C) 2022  Robert Finch, Waterloo
4
;    \  __ /    All rights reserved.
5
;     \/_//     robfinch@opencores.org
6
;       ||
7
;
8
;
9
; Serial port routines for a WDC6551 compatible circuit.
10
;
11
; This source file is free software: you can redistribute it and/or modify
12
; it under the terms of the GNU Lesser General Public License as published
13
; by the Free Software Foundation, either version 3 of the License, or
14
; (at your option) any later version.
15
;
16
; This source file is distributed in the hope that it will be useful,
17
; but WITHOUT ANY WARRANTY; without even the implied warranty of
18
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
; GNU General Public License for more details.
20
;
21
; You should have received a copy of the GNU General Public License
22
; along with this program.  If not, see .
23
;
24
; ============================================================================
25
;
26
;------------------------------------------------------------------------------
27
; Initialize serial port.
28
;
29
; Clear buffer indexes. Two bytes are used for the buffer index even though
30
; only a single byte is needed. This is for convenience in calculating the
31
; number of characters in the buffer, done later. The upper byte remains at
32
; zero.
33
; The port is initialized for 9600 baud, 1 stop bit and 8 bits data sent.
34
; The internal baud rate generator is used.
35
;
36
; Parameters:
37
;               none
38
; Modifies:
39
;               d
40
; Returns:
41
;               none
42
;------------------------------------------------------------------------------
43
 
44 21 robfinch
        setdp   $FFC
45
 
46 8 robfinch
InitSerial:
47
SerialInit:
48 21 robfinch
        pshs    dpr
49
        lda             #$FFC
50
        tfr             a,dpr
51 8 robfinch
        clra
52
        clrb
53 21 robfinch
        clr             SerHeadRcv
54
        clr             SerTailRcv
55
        clr             SerHeadXmit
56
        clr             SerTailXmit
57 8 robfinch
        clr             SerRcvXon
58
        clr             SerRcvXoff
59
        lda             COREID
60
sini1:
61
        cmpa    IOFocusID
62
        bne             sini1
63 21 robfinch
        ldb             #$0B                                            ; dtr,rts active, rxint enabled (bit 1=0), no parity
64 8 robfinch
        stb             ACIA+ACIA_CMD
65 21 robfinch
        ldb             #$1E                                            ; baud 9600, 1 stop bit, 8 bit, internal baud gen
66 8 robfinch
        stb             ACIA+ACIA_CTRL
67 21 robfinch
        ldb             #$0AC                                           ; disable fifos (bit zero, one), reset fifos
68 8 robfinch
        stb             ACIA+ACIA_CTRL2
69 21 robfinch
        puls    dpr,pc
70 8 robfinch
 
71
;------------------------------------------------------------------------------
72
; SerialGetChar
73
;
74
; Check the serial port buffer to see if there's a char available. If there's
75
; a char available then return it. If the buffer is almost empty then send an
76
; XON.
77
;
78
; Stack Space:
79 21 robfinch
;               3 words
80 8 robfinch
; Parameters:
81
;               none
82
; Modifies:
83
;               none
84
; Returns:
85
;               d = character or -1
86
;------------------------------------------------------------------------------
87
 
88
SerialGetChar:
89 21 robfinch
        pshs    ccr,x,y,dpr
90
        lda             #$FFC
91
        tfr             a,dpr
92
        sei                                                                             ; disable interrupts
93
        bsr             SerialRcvCount                  ; check number of chars in receive buffer
94
        cmpb    #8                                                      ; less than 8?
95
        bhi             sgc2
96
        ldb             SerRcvXon                               ; skip sending XON if already sent
97
        bne       sgc2            ; XON already sent?
98
        ldb             #XON                                            ; if <8 send an XON
99
        clr             SerRcvXoff                      ; clear XOFF status
100
        stb             SerRcvXon                               ; flag so we don't send it multiple times
101
        bsr             SerialPutChar
102 8 robfinch
sgc2:
103 21 robfinch
        ldb             SerHeadRcv                      ; check if anything is in buffer
104
        cmpb    SerTailRcv
105
        beq             sgcNoChars                      ; no?
106
        leax    SerRcvBuf                               ; x = buffer address
107
        clra
108
        ldb             b,x                                                     ; get byte from buffer
109
        inc             SerHeadRcv                      ; 4k wrap around
110
        bra             sgcXit
111 8 robfinch
sgcNoChars:
112 21 robfinch
        ldd             #-1
113 8 robfinch
sgcXit:
114 21 robfinch
        puls    ccr,x,y,dpr,pc
115 8 robfinch
 
116
;------------------------------------------------------------------------------
117
; SerialPeekChar
118
;
119
; Check the serial port buffer to see if there's a char available. If there's
120
; a char available then return it. But don't update the buffer indexes. No need
121
; to send an XON here.
122
;
123
; Stack Space:
124 21 robfinch
;               2 words
125 8 robfinch
; Parameters:
126
;               none
127
; Modifies:
128
;               none
129
; Returns:
130
;               d = character or -1
131
;------------------------------------------------------------------------------
132
 
133
SerialPeekChar:
134 21 robfinch
        pshs    x,ccr,dpr
135
        lda             #$FFC
136
        tfr             a,dpr
137 8 robfinch
        sei
138
        ldb             SerHeadRcv                              ; check if anything is in buffer
139
        cmpb    SerTailRcv
140
        beq             spcNoChars                              ; no?
141 21 robfinch
        leax    SerRcvBuf
142 8 robfinch
        clra
143
        ldb             b,x                                                             ; get byte from buffer
144
        bra             spcXit
145
spcNoChars:
146
        ldd             #-1
147
spcXit:
148 21 robfinch
        puls    x,ccr,dpr,pc
149 8 robfinch
 
150
;------------------------------------------------------------------------------
151
; SerialPeekChar
152
;               Get a character directly from the I/O port. This bypasses the input
153
; buffer.
154
;
155
; Stack Space:
156
;               0 words
157
; Parameters:
158
;               none
159
; Modifies:
160
;               d
161
; Returns:
162
;               d = character or -1
163
;------------------------------------------------------------------------------
164
 
165
SerialPeekCharDirect:
166 21 robfinch
        pshs    ccr,dpr
167
        lda             #$FFC
168
        tfr             a,dpr
169 8 robfinch
        lda             COREID                                                  ; Ensure we have the IO Focus
170
        cmpa    IOFocusID
171
        bne             spcd0001
172
        ; Disallow interrupts between status read and rx read.
173
        sei
174
        ldb             ACIA+ACIA_STAT
175
        bitb    #8                                                                      ; look for Rx not empty
176
        beq             spcd0001
177
        clra
178
        ldb             ACIA+ACIA_RX
179 21 robfinch
        puls    ccr,dpr,pc
180 8 robfinch
spcd0001:
181
        ldd             #-1
182 21 robfinch
        puls    ccr,dpr,pc
183 8 robfinch
 
184
;------------------------------------------------------------------------------
185
; SerialPutChar
186
;    Put a character to the serial transmitter. This routine blocks until the
187
; transmitter is empty.
188
;
189
; Stack Space
190
;               0 words
191
; Parameters:
192
;               b = character to put
193
; Modifies:
194
;               none
195
;------------------------------------------------------------------------------
196
 
197
SerialPutChar:
198 21 robfinch
        pshs    a,ccr,dpr
199
        lda             #$FFC
200
        tfr             a,dpr
201 8 robfinch
spc0001:
202
        lda             COREID                                  ; Ensure we have the IO Focus
203
        cmpa    IOFocusID
204
        bne             spc0001
205
        cli                                                                             ; provide a window for an interrupt to occur
206
        sei
207
        ; Between the status read and the transmit do not allow an
208
        ; intervening interrupt.
209
        lda             ACIA+ACIA_STAT  ; wait until the uart indicates tx empty
210
        bita    #16                                                     ; bit #4 of the status reg
211
        beq             spc0001                     ; branch if transmitter is not empty
212
        stb             ACIA+ACIA_TX            ; send the byte
213 21 robfinch
        puls    a,ccr,dpr,pc
214 8 robfinch
 
215
;------------------------------------------------------------------------------
216 21 robfinch
; Calculate number of character in input buffer. Direct page must be set
217
; already.
218 8 robfinch
;
219
; Parameters:
220 21 robfinch
;               none
221 8 robfinch
; Returns:
222
;               d = number of bytes in buffer.
223
;------------------------------------------------------------------------------
224
 
225
SerialRcvCount:
226
        clra
227 21 robfinch
        ldb             SerTailRcv
228
        subb    SerHeadRcv
229 8 robfinch
        bge             srcXit
230
        ldd             #$1000
231 21 robfinch
        subd    SerHeadRcv
232
        addd    SerTailRcv
233 8 robfinch
srcXit:
234
        rts
235
 
236
;------------------------------------------------------------------------------
237
; Serial IRQ routine
238
;
239
; Keeps looping as long as it finds characters in the ACIA recieve buffer/fifo.
240
; Received characters are buffered. If the buffer becomes full, new characters
241
; will be lost.
242
;
243
; Parameters:
244
;               none
245
; Modifies:
246
;               d,x
247
; Returns:
248
;               none
249
;------------------------------------------------------------------------------
250
 
251
SerialIRQ:
252 21 robfinch
        pshs    dpr                                                     ; set direct page register to boot variables
253
        lda             #$FFC
254
        tfr             a,dpr
255
        lda             PIC+$D3                                 ; Serial active interrupt flag
256
        beq             notSerInt
257 8 robfinch
sirqNxtByte:
258 21 robfinch
        ldb             ACIA+ACIA_IRQS  ; look for IRQs
259
        bpl             notSerInt                               ; quick test for any irqs
260 8 robfinch
        ldb             ACIA+ACIA_STAT  ; check the status
261 21 robfinch
        bitb    #$08                                            ; bit 3 = rx full (not empty)
262
        beq             notRxInt1
263 8 robfinch
        ldb             ACIA+ACIA_RX            ; get data from Rx buffer to clear interrupt
264 21 robfinch
        lda             SerTailRcv                      ; check if recieve buffer full
265 8 robfinch
        inca
266 21 robfinch
        cmpa    SerHeadRcv
267 8 robfinch
        beq             sirqRxFull
268 21 robfinch
        sta             SerTailRcv                      ; update tail pointer
269 8 robfinch
        deca                                                                    ; backup
270
        exg             a,b
271 21 robfinch
        leax    SerRcvBuf                               ; x = buffer address
272 8 robfinch
        sta             b,x                                                     ; store recieved byte in buffer
273 21 robfinch
        tst             SerRcvXoff                      ; check if xoff already sent
274 8 robfinch
        bne             sirqNxtByte
275 21 robfinch
        bsr             SerialRcvCount  ; if more than 4070 chars in buffer
276
        cmpb    #4070
277 8 robfinch
        blo             sirqNxtByte
278
        ldb             #XOFF                                           ; send an XOFF
279 21 robfinch
        clr             SerRcvXon                               ; clear XON status
280
        stb             SerRcvXoff                      ; set XOFF status
281 8 robfinch
        stb             ACIA+ACIA_TX
282
        bra             sirqNxtByte     ; check the status for another byte
283 21 robfinch
        ; Process other serial IRQs
284
notRxInt1:
285
        puls    dpr,pc
286 8 robfinch
sirqRxFull:
287
notRxInt:
288 21 robfinch
notSerInt:
289
        puls    dpr,pc
290 8 robfinch
 
291
nmeSerial:
292
        fcb             "Serial",0
293
 
294
;------------------------------------------------------------------------------
295
; Put a string to the serial port.
296
;
297
; Parameters:
298
;               d = pointer to string
299
; Modifies:
300
;               none
301
; Returns:
302
;               none
303
;------------------------------------------------------------------------------
304
 
305
SerialPutString:
306
        pshs    d,x
307
        tfr             d,x
308
sps2:
309
        ldb             ,x
310
        beq             spsXit
311
        inx
312
        bsr             SerialPutChar
313
        bra             sps2
314
spsXit:
315
        puls    d,x,pc
316
 
317
;------------------------------------------------------------------------------
318
; A little routine to test serial output.
319
;
320
; Parameters:
321
;               none
322
; Modifies:
323
;               none
324
; Returns:
325
;               none
326
;------------------------------------------------------------------------------
327
 
328
SerialOutputTest:
329
        pshs    d
330
        ldd             #msgSerialTest
331
        lbsr    DisplayString
332
        bsr             SerialInit
333
sotst1:
334
        ldb             #XON
335
        bsr             SerialPutChar
336
        bsr             SerialPutChar
337
        bsr             SerialPutChar
338
        ldd             #msgSerialTest
339
        bsr             SerialPutString
340
        lbsr    INCH
341
        cmpb    #CTRLC
342
        bne             sotst1
343
        puls    d,pc
344
 
345
msgSerialTest:
346
        fcb     "Serial port test",CR,LF,0
347
 
348 21 robfinch
        setdp   $000

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.