-
Notifications
You must be signed in to change notification settings - Fork 0
/
ATL_SERIAL.Z80
242 lines (215 loc) · 5.33 KB
/
ATL_SERIAL.Z80
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
NAME SERIAL
GLOBAL RS_INI
GLOBAL RS_TX
GLOBAL RS_RX
GLOBAL RS_RXNW
GLOBAL RS_TXT
GLOBAL RS_MESG
GLOBAL RS_KEYRD
GLOBAL SERERR ;SET ON MAIN
GLOBAL RS_NEWLINE
;DEVSER EQU $20 ; SET ON MAIN
RBR EQU DEVSER + 0 ;RECEIVER BUFFER REGISTER (READ ONLY) (DLAB = 0)
THR EQU DEVSER + 0 ;TRANSMITER HOLDING REGISTER (WRITE ONLY) (DLAB = 0)
IER EQU DEVSER + 1 ;INTERRUPT ENABLE REGISTER (DLAB = 0)
;BIT 0= ENABLE RECEIVED DATA AVAILABLE INTERRUPT
;BIT 1= ENABLE TRANSMITTER HOLDING REGISTER EMPTY INTERRUPT
;BIT 2= ENABLE RECEIVER LINE STATUS INTERRUPT
;BIT 3= ENABLE MODEM STATUS INTERRUPT
IIR EQU DEVSER + 2 ;INTERRUPT IDENT. REGISTER (READ ONLY)
;BIT 0=0 IF INTERRUPT PENDING
;BIT 1-3 INTERRUPT ID
;BIT 4,5 =0
;BIT 6,7 FIFOS ENABLED
FCR EQU DEVSER + 2 ;FIFO CONTROL REGISTER (WRITE ONLY)
;BIT 0 FIFO ENABLE
;BIT 1 RCVR FIFO RESET
;BIT 2 XMIT FIFO RESET
;BIT 3 DMA MODE SELECT
;BIT 4,5 RESERVED
;BIT 6 RCVR TRIGGER LSBIT
;BIT 7 RCVR TRIGGER MSBIT
LCR EQU DEVSER + 3 ;LINE CONTROL REGISTER
;BIT 0,1 WORD LENGTH SELECT
;BIT 2 NUMBER OF STOP BITS
;BIT 3 PARITY ENABLE
;BIT 4 EVEN PARITY SELECT
;BIT 5 STICK PARITY
;BIT 6 SET BREAK
;BIT 7 DIVISOR LATCH ACCESS BIT *** DLAB ****
MCR EQU DEVSER + 4 ;MODEM CONTROL REGISTER
LSR EQU DEVSER + 5 ;LINE STATUS REGISTER
;BIT 0 DATA READY
;BIT 1 OVERRUN ERROR
;BIT 2 PARITY ERROR
;BIT 3 FRAMING ERROR
;BIT 4 BREAK INTERRUPT
;BIT 5 TRANSMITTER HOLDING REGISTER
;BIT 6 TRANSMITTER EMPTY
;BIT 7 ERROR IN RCVR FIFO
MSR EQU DEVSER + 6 ;MODEM STATUS REGISTER
SCR EQU DEVSER + 7 ;SCRATCH REGISTER
DLL EQU DEVSER + 0 ;DIVISOR LATCH (LEAST SIGNIFICANT BYTE) (DLAB = 1)
DLM EQU DEVSER + 1 ;DIVISOR LATCH (MOST SIGNIFICANT BYTE) (DLAB = 1)
; SERERR EQU RAMAD+2 ;SERIAL ERROR
;A=5 RECEIVE INTERRUPTS ON
;A IS THE BAUD RATE PARAM
RS_INI: PUSH AF
LD A, $80 ; Mask to set DLAB on
OUT (LCR), A ; Send to LINe Control Register
;LD A,12 ; Divisor of 12 = 9600 bps with 1.8432 MHz clock
;LD A,96 ; Divisor of 96 = 1200 bps with 1.8432 MHz clock
;LD A,72 ; Divisor of 96 = 7200?? bps with 14.7456 MHz clock
; 72=1600BPS WITH 1.8432
;LD A,6 ;19200BPS
;LD A,3 ;38400BPS
;LD A,2 ;56000BPS
;LD A,1 ;115200BPS
POP AF
OUT (DLL), A ; Set LSB of divisor
LD A, 00 ; This will be the MSB of the divisior
OUT (DLM), A ; Send to the MSB register
LD A, $03 ; 8 bits, 1 stop, no parity (and clear DLAB)
OUT (LCR), A ; Write new value to LCR
;LD A, 1+2+4+8 ; set fifo mode and reset fifio counters //was 0 and commented
LD A, 0
OUT (FCR), A ;//was commented
LD A, $00 ; 5 A=0 Disable all INterrupts
OUT (IER), A ; Send to INterrupt Enable Register
RET
; Sends byte IN A to the UART
RS_TX: CALL RSTXRD
OUT (THR), A
;CALL CHKERR2 ;CHECK ERROR ON TRANSMITION
RET
; RETurns when UART is ready to receive
RSTXRD: PUSH AF
RSTXLP: IN A, (LSR) ; fetch the control register
BIT 5, A ; bit will be set if UART is ready
JR Z, RSTXLP
POP AF
RET
;HL THE STRING TO PRINT
;DESTROYS A
RS_TXT: LD A, (HL)
INC HL
CP 0
RET Z
CALL RS_TX
JR RS_TXT
;PRINTS A ZT MESSAGE FOLLOWING THIS CALL
;PRESERVES ALL REGS
RS_MESG: PUSH HL
PUSH BC
PUSH DE
PUSH AF
LD HL,9 ;POINTS TO RET ADDRESS +10 FROM SP = OUR STRING
ADD HL,SP
LD B,(HL)
DEC HL
LD C,(HL)
LD H,B
LD L,C
CALL RS_TXT
POP AF
POP DE
LD B,H ;NEW RET ADDRESS
LD C,L
LD HL,5 ;POINTS TO RET ADDRESS +6 FROM SP
ADD HL,SP
LD (HL),B
DEC HL
LD (HL),C
POP BC
POP HL
RET
; Wait for a byte from the UART, and save it IN A
;DESTROYS DE,A
RS_RX: LD A,I ;SETS PV IF INTS ARE ENABLED
PUSH AF
POP DE
DI
LD A, 1 ;ready to receive SIGNAL DSR 1
OUT (MCR), A
CALL RSRXRD
RS_GTCH: XOR A ;NOT ready to receive SIGNAL DSR 0
OUT (MCR), A
;CALL CHKERR ;CHECK ERROR ON RECEIVED CHAR
IN A, (RBR)
PUSH DE
LD D,A
POP AF
LD A,D
RET PO
EI
RET
RS_RXNW: LD A, 1 ;ready to receive SIGNAL DSR 1
OUT (MCR), A
IN A, (LSR) ; fetch the conrtol register
BIT 0, A
JR Z, RS_NOCHAR
DI
JR RS_GTCH
RS_NOCHAR: XOR A ;RETURN ZERO
RET
; RETurns when UART has received data
RSRXRD: ;DI
PUSH AF
;PUSH BC
;LD BC,2000 ;TIMEOUT
RSRXLP: ;LD A,B
;OR C
;JR Z,RSRXEX
IN A, (LSR) ; fetch the control register
BIT 0, A ; bit will be set if UART has data
JR Z, RSRXLP
RSRXEX: ;POP BC
POP AF
;EI
RET
; ZF=1 IF NO CHAR SENT
; ZF=0 IF CHAR WAITING T BE RECEIVED
RS_KEYRD: IN A, (LSR) ; fetch the conrtol register
BIT 0, A ; bit will be set if UART has data
RET
SHLCD: PUSH AF
;CALL LCDLN2
POP AF
;CALL LCDCHR
RET
RS_NEWLINE: PUSH AF
LD A,13
CALL RS_TX
LD A,10
CALL RS_TX
POP AF
RET
CHKERR: PUSH AF
PUSH HL
PUSH BC
IN A, (LSR) ;FETCH LINE STATUS REGISTER
BIT 4, A
JR Z, LBLPE
LD A, 'B' ;$20 ;BREAK
JR EXIT
LBLPE: BIT 2, A
JR Z, LBLFE
LD A, 'P' ;$40 ;PARITY
JR EXIT
LBLFE: BIT 3, A
JR Z, LBLOE
LD A, 'F' ;$60 ;FRAME
JR EXIT
LBLOE: BIT 1, A
JR Z, LBLNE
LD A, 'O' ;$80 ;OVERRUN
JR EXIT
LBLNE: LD A, 'N' ;NO ERROR
EXIT: LD HL, SERERR
LD (HL), A
; CALL SHLCD
POP BC
POP HL
POP AF
RET
END