forked from jmatzen/leventhal-6809
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path6809_RDLINE.s
318 lines (310 loc) · 8.37 KB
/
6809_RDLINE.s
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
.macro INX
LEAX 1,X
.endm
; Title: Read Line
;
; Name: RDLINE
;
; Purpose: Read characters from an input device until
; a carriage return is found.
; Defines the control characters
; Control H Delete latest character.
; Control X Delete all characters.
; Any other control character is placed in the buffer
; and displayed as the equivalent printable
; ASCII character preceded by an up-arrow or caret.
;
;
; Entry: Register X = Base address of buffer
; Register A = Length of buffer in bytes
;
; Base address of buffer
;
; Length of buffer in bytes
;
; Exit: Register A = Number of characters in buffer
;
; Registers Used: ALL
;
; Time: Not applicable.
;
; Size: Program 139 bytes
;
;
; EQUATES
;
BELL EQU $07 ; BELL CHARACTER
BSKEY EQU $08 ; BACKSPACE KEYBOARD CHARACTER
CR EQU $00 ; CARRIAGE RETURN FOR CONSOLE
CRKEY EQU $00 ; CARRIAGE RETURN KEYBOARD CHARACTER
CSRLFT EQU $08 ; MOVE CURSOR LEFT FOR CONSGLE
CTLOFF EQU $40 ; OFFSET FROM CONTROL CHARACTER TO PRINTED FORM
; (E.G., CONTROL-X TO X)
DLNKEY EQU $18 ; DELETE LINE KEYBOARD CHARACTER
DNARRW EQU $0A ; DOWNARROW KEY (USED AS CONTROL INDICATOR ON KEYBOARD
LF EQU $0A ; LINE FEED FOR CONSOLE
SPACE EQU $20 ; SPACE CHARACTER (ALSO MARKS END OF CONTROL CHARACTERS
; IN ASCII SEQUENCE)
STERM EQU $24 ; STRING TERMINATOR (DOLLAR SIGN)
UPARRW EQU $5E ; OR CARET USED AS CONTROL INDICATOR
RDLINE:
;
; INITIALIZE CHARACTER COUNT TO ZERO, SAVE BUFFER LENGTH
;
INIT:
CLRB ; CHARACTER COUNT = 0
PSHS A ; SAVE BUFFER LENGTH IN STACK
;
; READ LOOP
; READ CHARACTERS UNTIL A CARRIAGE RETURN IS TYPED
;
RDLOOP:
JSR RDCHAR ; READ CHARACTER FROM KEYBOARD
; DOES NOT ECHO CHARACTER
;
; CHECK FOR CARRIAGE RETURN, EXIT IF FOUND
;
CMPA #CR ; CHECK FOR CARRIAGE RETURN
BEQ EXITRD ; END OF LINE IF CARRIAGE RETURN
;
; CHECK FOR BACKSPACE AND DELETE CHARACTER IF FOUND
;
CMPA #BSKEY ; CHECK FOR BACKSPACE KEY
BNE RDLP1 ; BRANCH IF NOT BACKSPACE
JSR BACKSP ; IF BACKSPACE, DELETE ONE CHARACTER
BRA RDLOOP ; THEN START READ LOOP AGAIN
;
; CHECK FOR DELETE LINE CHARACTER AND EMPTY BUFFER IF FOUND
;
RDLP1:
CMPA #DLNKEY ; CHECK FOR DELETE LINE KEY
BNE RDLP2 ; BRANCH IF NOT DELETE LINE
DEL1:
JSR BACKSP ; DELETE A CHARACTER
TSTB ; CHECK IF BUFFER EMPTY
BNE DEL1 ; CONTINUE UNTIL BUFFER EMPTY
; THIS ACTUALLY BACKS UP OVER EACH
; CHARACTER RATHER THAN JUST MOVING
; UP A LINE
BRA RDLOOP
;
; KEYBOARD ENTRY IS NOT A SPECIAL CHARACTER
; CHECK IF BUFFER IS FULL
; IF FULL, RING BELL AND CONTINUE
; IF NOT FULL, STORE CHARACTER AND ECHO
;
RDLP2:
CMPA ,S ; COMPARE COUNT AND BUFFER LENGTH
BCS STRCH ; JUMP IF BUFFER NOT FULL
LDA #BELL ; BUFFER FULL, RING THE TERMINAL'S BELL
JSR WRCHAR
BRA RDLOOP ; THEN CONTINUE THE READ LOOP
;
; BUFFER NOT FULL, STORE CHARACTER
;
STRCH:
STA ,X+ ; STORE CHARACTER IN BUFFER
INCB ; INCREMENT CHARACTER COUNT
;
; IF CHARACTER IS CONTROL, THEN OUTPUT
; UPARROW FOLLOWED BY PRINTABLE EQUIVALENT
;
CMPA #SPACE ; CONTROL CHARACTER IF CODE IS BELOW
; SPACE (2O HEX)
; IN ASCII SEQUENCE
BCC PRCH ; JUMP IF A PRINTABLE CHARACTER
PSHS A ; SAVE NONPRINTABLE CHARACTER
LDA #UPARRW ; WRITE UP-ARROW OR CARET
PRCH:
JSR WRCHAR ;
PULS A ; RECOVER NONPRINTABLE CHARACTER
ADDA #CTLOFF ; CHANGE TO PRINTABLE FORM
JSR WRCHAR ; ECHO CHARACTER TO TERMINAL
BRA RDLOOP ; THEN CONTINUE READ LOOP
;
; EXIT
; SEND NEW LINE SEQUENCE (USUALLY CR,LF) TO TERMINAL
; LINE LENGTH = CHARACTER COUNT
;
EXITRD:
JSR WRNEWL ; ECHO NEW LINE SEQUENCE
TFR B,A ; RETURN LINE LENGTH IN A
LEAS 1,S ; REMOVE BUFFER LENGTH FROM STACK
RTS
;
; *********************************************************
;
; THE FOLLOWING SUBROUTINES ARE TYPICAL EXAMPLES USING THE
; BASIC CALLS FOR THE RADIO SHACK COLOR COMPUTER
;
;
; *********************************************************
;
; COLOR COMPUTER EOUATES
KBDPTR EQU $A000 ; POINTER TO KEYBOARD INPUT ROUTINE
; CHARACTER ENDS UP IN REGISTER A
; ZERO FLAG = 1 IF NO CHARACTER,
; 0 IF CHARACTER
OUTPTR EQU $A002 ; POINTER TO OUTPUT ROUTINE
; UNIT NUMBER GOES IN LOCATION
; $006F (0 = SCREEN)
; CHARACTER GOES IN REGISTER A
;
; **********************************************************
; ROUTINE: RDCHAR
; PURPOSE: READ A CHARACTER BUT DO NOT ECHO TO OUTPUT DEVICE
; ENTRY: NONE
; EXIT: REGISTER A = CHARACTER
; REGISTERS USED: ALL
; ***********************************************************
RDCHAR:
;
; WAIT FOR CHARACTER FROM CONSOLE
; EXIT UNLESS IT IS CONTROL INDICATOR
;
JSR [KBDPTR] ; POLL KEYBOARD
BEQ RDCHAR ; LOOP UNTIL KEY PRESSED
CMPA #DNARRW ; CHECK IF CONTROL CHARACTER
BNE RDCHXT ; EXIT IF NOT CONTROL
;
; IF CONTROL CHARACTER, WAIT UNTIL NEXT KEY IS READ
; THEN CONVERT NEXT KEY TO ASCII CONTROL CHARACTER
;
CNTCHR:
JSR [KBDPTR] ; POLL KEYBOARD
BEQ CNTCHR ; LOOP UNTIL KEY PRESSED
CMPA #'A' ; COMPARE WITH ASCII A
BLO RDCHXT ; EXIT IF LESS THAN A
SUBA #CTLOFF ; ELSE CONVERT TO CONTROL
; CHARACTER EQUIVALENT
;
; EXIT WITH CHARACTER IN REGISTER A
RDCHXT:
RTS ; RETURN ASCII CHARACTER IN REGISTER A
;
; ****************************************
; ROUTINE: WRCHAR
; PURPOSE: WRITE CHARACTER TO OUTPUT DEVICE
; ENTRY: REGISTER A = CHARACTER
; EXIT: NONE
; REGISTERS USED: ALL
; *****************************************
WRCHAR:
;
; WRITE A CHARACTER TO OUTPUT DEVICE
; LOCATION $006F MUST CONTAIN UNIT NUMBER (0 = SCREEN)
;
JSR [OUTPTR] ; SEND CHARACTER
RTS
;
; ********************************************************
; ROUTINE: HRNEWL
; PURPOSE: ISSUE NEW LINE SEQUENCE TO TERMINAL
; NORMALLY, THIS SEQUENCE IS A CARRIAGE RETURN AND
; LINE FEED, BUT SOME COMPUTERS REQUIRE ONLY
; A CARRIAGE RETURN.
; ENTRY: NONE
; EXIT: NONE
; REGISTERS USED: ALL
; *********************************************************
WRNEWL:
; SEND NEW LINE STRING TO TERMINAL
LDY #NLSTRG ; POINT TO NEW LINE STRING
JSR WRSTRG ; SEND STRING TO TERMINAL RTS
NLSTRG:
FCB CR,LF,STERM ; NEW LINE STRING
;
; ***************************************
; ROUTINE: BACKSP
; PURPOSE: PERFORM A DESTRUCTIVE BACKSPACE
; ENTRY: A = NUMBER OF CHARACTERS IN BUFFER
; X = NEXT AVAILABLE BUFFER ADDRESS
; EXIT: IF NO CHARACTERS IN BUFFER
; Z = 1
; ELSE
; Z = 0
; CHARACTER REMOVED FROM BUFFER
; REGISTERS USED: ALL
; ***************************************
BACKSP:
;
; CHECK FOR EMPTY BUFFER
;
TSTB ; TEST NUMBER OF CHARACTERS
BEQ EXITBS ; BRANCH (EXIT) BUFFER EMPTY
;
; OUTPUT BACKSPACE STRING
; TO REMOVE CHARACTER FROM DISPLAY
;
LEAX -1,X ; DECREMENT BUFFER POINTER
LDA ,X ; GET CHARACTER
CMPA #SPACE ; IS IT A CONTROL CHARACTER?
BNE BS1 ; NO, BRANCH, DELETE ONLY ONE CHARACTER
LDX #BSSTRG ; YES, DELETE 2 CHARACTERS
; (UP-ARROW AND PRINTABLE EQUIVALENT)
JSR WRSTRG ; WRITE BACKSPACE STRING
; DECREMENT CHARACTER COUNT BY 1
BS1: LDX #BSSTRG
JSR WRSTRG ; WRITE BACKSPACE STRING
DECB ; ONE LESS CHARACTER IN BUFFER
EXITBS:
RTS
;
; DESTRUCTIVE BACKSPACE STRING FOR TERMINAL
; THE COLOR COMPUTER DOES NOT PROVIDE A FLASHING CURSOR WHEN
; RUNNING THIS ROUTINE, SO ONLY A BACKSPACE CHARACTER IS
; NECESSARY
; IF THE CURSOR HERE ENABLED, THE SEQUENCE BACKSPACE, SPACE,
; BACKSPACE WOULD BE NECESSARY TO MOVE THE CURSOR LEFT,
; PRINT A SPACE OVER THE CHARACTER, AND MOVE THE CURSOR LEFT
;
BSSTRG: FCB CSRLFT,STERM
;
; ********************************
; ROUTINE: WRSTRG
; PURPOSE: OUTPUT STRING TO CONSOLE
; ENTRY: X = BASE ADDRESS OF STRING
; EXIT: NONE
; REGISTERS USED: ALL
; *********************************
WRSTRG:
LDA ,Y+ ; GET CHARACTER FROM STRING
CMPA #STERM ; CHECK IF AT END
BEQ WREXIT ; EXIT IF AT END
JSR [OUTPTR] ; WRITE CHARACTER
BRA WRSTRG ; CHECK NEXT CHARACTER
WREXIT:
RTS
;
; SAMPLE EXECUTION:
; EQUATES
;
PROMPT EQU '?' ; OPERATOR PROMPT = QUESTION MARK
SC8A:
;
; READ LINE FROM TERMINAL
LDA #PROMPT ; WRITE PROMPT (?)
JSR WRCHAR
LDX #INBUFF ; GET INPUT BUFFER ADDRESS
LDA #LINBUF ; GET LENGTH OF BUFFER
JSR RDLINE ; READ LINE
TSTA ; CHECK LINE LENGTH
BEQ SC8A ; READ NEXT LINE IF LENGTH IS 0
;
; ECHO LINE TO CONSOLE
;
LDX #INBUFF ; POINT TO START OF BUFFER
WRBUFF:
LDA ,X ; WRITE NEXT CHARACTER
JSR WRCHAR
INX ; INCREMENT BUFFER POINTER
DECB ; DECREMENT CHARACTER COUNT
BNE WRBUFF ; CONTINUE UNTIL ALL CHARACTERS SENT
JSR WRNEWL ; THEN END WITH CR,LF
BRA SC8A ; READ NEXT LINE
;
; DATA SECTION
;
LINBUF EQU 16 ; LENGTH OF INPUT BUFFER
INBUFF RMB LINBUF ; INPUT BUFFER
END