-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCONIO.asm
More file actions
352 lines (323 loc) · 11.3 KB
/
Copy pathCONIO.asm
File metadata and controls
352 lines (323 loc) · 11.3 KB
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
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
;***************************************************************************
; PROGRAM: CONIO
; PURPOSE: Subroutines for console I/O
; ASSEMBLER: original: TASM 3.2 , converted to z80pack/z80asm
; LICENCE: The MIT Licence
; AUTHOR : MCook
; CREATE DATE : 19 May 15
;***************************************************************************
;***************************************************************************
;PRINT_STRING
;Function: Prints string to terminal program. Start in HL
;***************************************************************************
PRINT_STRING:
CALL UART_PRNT_STR
RET
;***************************************************************************
;GET_CHAR
;Function: Get upper case ASCII character from user into Accumulator
;***************************************************************************
GET_CHAR:
CALL UART_RX ;Get char into Acc
CALL TO_UPPER ;Character has to be upper case
RET
;***************************************************************************
;PRINT_CHAR
;Function: Get upper case ASCII character from Accumulator to UART
;***************************************************************************
PRINT_CHAR:
CALL UART_TX ; Echo character to terminal
RET
; Optional print char
OPRINTCHAR:
LD C, A
LD A, (MUTE)
CP MUTEON ; compare with 1=true
JR Z, PRTSKIP
LD A, C
CALL PRINT_CHAR
PRTSKIP:
LD A, C
RET
;***************************************************************************
;TO_UPPER
;Function: Convert character in Accumulator to upper case
;***************************************************************************
TO_UPPER:
CP 'a' ; Nothing to do if not lower case
RET C
CP 'z' + 1 ; > 'z'?
RET NC ; Nothing to do, either
AND 5Fh ; Convert to upper case
RET
;***************************************************************************
;MKPRINT
;Function: Make all characters printable by replacing control-chars with '.'
;***************************************************************************
LOWPRTV: EQU ' '
HIGPRTV: EQU '~'
MKPRINT:
CP LOWPRTV
JR C, ADDOT
CP HIGPRTV
JR NC, ADDOT
RET
ADDOT:
LD A, '.'
RET
;***************************************************************************
;PRINT_NEW_LINE
;Function: Prints carriage return and line feed
;***************************************************************************
NEW_LINE_STRING:
DEFB 0Dh, 0Ah ,EOS
PRINT_NEW_LINE:
PUSH HL
LD HL,NEW_LINE_STRING
CALL PRINT_STRING
POP HL
RET
;***************************************************************************
;CHAR_ISHEX
;Function: Checks if value in A is a hexadecimal digit, C flag set if true
;***************************************************************************
CHAR_ISHEX:
; Checks if Acc between '0' and 'F'
CP 'F' + 1 ; (Acc) > 'F'?
RET NC ; Yes - Return / No - Continue
CP '0' ; (Acc) < '0'?
JP NC,CIH1 ; Yes - Jump / No - Continue
CCF ; Complement carry (clear it)
RET
CIH1:
; Checks if Acc below '9' and above 'A'
CP '9' + 1 ; (Acc) < '9' + 1?
RET C ; Yes - Return / No - Continue (meaning Acc between '0' and '9')
CP 'A' ; (Acc) > 'A'?
JP NC,CIH2 ; Yes - Jump / No - Continue
CCF ; Complement carry (clear it)
RET
CIH2:
; Only gets here if Acc between 'A' and 'F'
SCF ; Set carry flag to indicate the char is a hex digit
RET
;***************************************************************************
;GET_HEX_NIBBLE
;Function: Translates char to HEX nibble in bottom 4 bits of A
;***************************************************************************
GETHEXNIB:
CALL GET_CHAR
CALL CHAR_ISHEX ; Is it a hex digit?
JP NC,NONHEXNIB ; Yes - Continue / No - Exit
CALL OPRINTCHAR
CP '9' + 1 ; Is it a digit less or equal '9' + 1?
JP C,IS_NUM ; Yes - Jump / No - Continue
SUB 07h ; Adjust for A-F digits
IS_NUM:
SUB '0' ; Subtract to get nib between 0->15
AND 0Fh ; Only return lower 4 bits
RET
NONHEXNIB: ; Allow exit on wrong char
LD A, E_NOHEX
LD (ERRFLAG), A ; Error flag
RET
;***************************************************************************
;GET_HEX_BTYE
;Function: Gets HEX byte into A
;Uses: AF, D
;***************************************************************************
GETHEXBYTE:
CALL GETHEXNIB ; Get high nibble
PUSH DE
PUSH AF
LD A, (ERRFLAG)
CP E_NONE
JR NZ, GHB_ERR
POP AF
RLC A ; Rotate nibble into high nibble
RLC A
RLC A
RLC A
LD D,A ; Save upper four bits
CALL GETHEXNIB ; Get lower nibble
PUSH AF
LD A, (ERRFLAG)
CP E_NONE
JR NZ, GHB_ERR
POP AF
OR D ; Combine both nibbles
POP DE
RET
GHB_ERR:
POP AF
POP DE
RET
;***************************************************************************
;GET_HEX_WORD
;Function: Gets two HEX bytes into HL
;Uses: AF
;***************************************************************************
GETHEXWORD:
CALL GETHEXBYTE ; Get high byte
PUSH AF
LD A, (ERRFLAG)
CP E_NONE
JR NZ, GHW_ERR
POP AF
LD H,A
CALL GETHEXBYTE ; Get low byte
PUSH AF
LD A, (ERRFLAG)
CP E_NONE
JR NZ, GHW_ERR
POP AF
LD L,A
RET
GHW_ERR:
POP AF
RET
;***************************************************************************
;NIB2CHAR
;Function: Converts the lower nibble in A into a HEX character
;***************************************************************************
NIB2CHAR:
AND 0Fh ; Only low nibble in byte
ADD A,'0' ; Adjust for char offset
CP '9' + 1 ; Is the hex digit > 9?
JR C,N2C1 ; Yes - Jump / No - Continue
ADD A,'A' - '0' - 0Ah ; Adjust for A-F
N2C1:
RET
;***************************************************************************
;SHFTNIB
;Function: Shift the upper nibble to the lower position
;***************************************************************************
SHFTNIB:
AND 0F0h
RRCA
RRCA
RRCA
RRCA
RET
;***************************************************************************
;PRINT_HEX_NIB
;Function: Prints a low nibble in hex notation from Acc to the serial line.
;***************************************************************************
PRINTHNIB:
PUSH AF
CALL NIB2CHAR
CALL PRINT_CHAR ; Print the nibble
POP AF
RET
;***************************************************************************
;PRINT_HEX_BYTE
;Function: Prints a byte in hex notation from Acc to the serial line.
;***************************************************************************
PRINTHBYTE:
PUSH AF ; Save registers
PUSH DE
LD D,A ; Save for low nibble
RRCA ; Rotate high nibble into low nibble
RRCA
RRCA
RRCA
CALL PRINTHNIB ; Print high nibble
LD A,D ; Restore for low nibble
CALL PRINTHNIB ; Print low nibble
POP DE
POP AF
RET
;***************************************************************************
;PRINT_HEX_WORD
;Function: Prints the four hex digits of a word to the serial line from HL
;***************************************************************************
PRINTHWORD:
; PUSH HL
PUSH AF
LD A,H
CALL PRINTHBYTE ; Print high byte
LD A,L
CALL PRINTHBYTE ; Print low byte
POP AF
; POP HL
RET
;***************************************************************************
;CHAR TO NIBBLE
;Transforms the HEX-character in A to a value fitting in the lower nibble
;***************************************************************************
CHAR2NIB:
SUB '0'
CP 015h
JR NC, C2N_DONE
SUB 005h
c2N_DONE:
AND 0Fh
RET
PRTBIT:
JR C, PB0
LD A, '1'
JR PBPRT
PB0:
LD A, '0'
JR PBPRT
PBPRT:
CALL PRINT_CHAR
RET
;***************************************************************************
;PRT8BIT
;Function: Special case: print the MPF's user flag bits
;***************************************************************************
PRT8BIT:
LD C, A
LD B, 8
P8B1:
RLC A
LD C, A
CALL PRTBIT
DEC B
JR Z, P8B_RET
LD A, C
JR P8B1
P8B_RET:
RET
;TWO CHARS TO BYTE
; convert the (hex) char at (HL) and the next to a byte in A. On exit
; HL points to the next, ininterpreted character.
CHARS2BYTE:
PUSH BC
LD A, (HL)
CALL CHAR2NIB ; Get upper nibble from char
RLC A
RLC A
RLC A
RLC A
LD B, A
INC HL
LD A, (HL)
CALL CHAR2NIB ; Get lower nibble from char
OR B
LD A, B
POP BC
INC HL
RET
;***************************************************************************
; GETSIZE
; Calculate the size, being End address - Start address
; Start address in MVADDR + MVADDR+1, End address in MVADDR+2 + MVADDR+3
; Size will be in MVADDR+4 + MVADDR+5
;***************************************************************************
;GETSIZE:
; LD A, (MVADDR+2) ; End LSB
; LD HL, MVADDR+0 ; (Start LSB)
; SUB (HL)
; PUSH AF ; keep Carry flag
; LD (MVADDR+4), A ; range LSB
; LD A, (MVADDR+3) ; End MSB
; LD HL, MVADDR+1 ; (Start MSB)
; SUB (HL)
; LD (MVADDR+5), A ; range MSB
; POP AF
; JR NC, _MTNC
; DEC (HL) ; Correct MSB
;_MTNC
; RET