1978
|
1 ********************************************************************
|
|
2 * KrnP3 - NoICE Serial Debugger for 6809/6309
|
|
3 *
|
|
4 * $Id$
|
|
5 *
|
|
6 * This module is called by the kernel at boot time and initializes itself
|
|
7 * by creating a new system call: os9 F$Debug
|
|
8 *
|
|
9 * The process that called the F$Debug system call is the one that will
|
|
10 * be debugged.
|
|
11 *
|
|
12 * Using the NoICE serial protocol, the debugger can talk to a host, and can be
|
|
13 * driven by simple commands to read/write registers and memory, and continue
|
|
14 * execution.
|
|
15 *
|
|
16 * Notes:
|
|
17 * o The NoICE protocol specifies a 'page' byte in addition to the
|
|
18 * 16-bit memory address when reading/writing memory. We currently
|
|
19 * ignore this page, and I cannot think of a need for this.
|
|
20 *
|
|
21 * o The 6309 is now a supported processor under the Windows version
|
|
22 * of NoICE. Its processor ID is 17.
|
|
23 *
|
|
24 * Edt/Rev YYYY/MM/DD Modified by
|
|
25 * Comment
|
|
26 * ------------------------------------------------------------------
|
|
27 * 1 2005/04/03 Boisy G. Pitre
|
|
28 * Started
|
1990
|
29 *
|
|
30 * 2 2006/02/02 Boisy G. Pitre
|
|
31 * Added USERSTATE flag to allow module to debug current process or
|
|
32 * system.
|
1978
|
33
|
|
34 NAM KrnP3
|
|
35 TTL NoICE Serial Debugger for 6809/6309
|
|
36
|
|
37 IFP1
|
|
38 USE defsfile
|
|
39 ENDC
|
|
40
|
|
41 IFNE KRNMOD
|
|
42 tylg SET Systm+Objct
|
|
43 ELSE
|
|
44 tylg SET Prgrm+Objct
|
|
45 ENDC
|
|
46 atrv SET ReEnt+rev
|
|
47 rev SET $00
|
|
48 edition SET 1
|
|
49
|
1992
|
50 * If an MPI is being used, set RS232SLOT to slot value - 1 and set MPI to 1
|
1995
|
51 MPICTRL EQU $FF7F
|
|
52 RS232SLOT EQU 1 slot 2
|
|
53
|
1992
|
54 *MPI EQU 1
|
|
55
|
1978
|
56 FN_ERROR EQU $F0
|
|
57 FN_SET_BYTES EQU $F9
|
|
58 FN_RUN_TARGET EQU $FA
|
|
59 FN_WRITE_REGS EQU $FB
|
|
60 FN_READ_REGS EQU $FC
|
|
61 FN_WRITE_MEM EQU $FD
|
|
62 FN_READ_MEM EQU $FE
|
|
63 FN_GET_STATUS EQU $FF
|
|
64
|
|
65
|
|
66 cbsize EQU 200
|
|
67
|
|
68 * this location is in lo-System RAM. We clear the low bit upon
|
|
69 * initialization from the kernel, then on subsequent breakpoints,
|
|
70 * we set the low bit
|
|
71
|
|
72 * offsets into our on stack storage
|
|
73 ORG 0
|
|
74 callregs RMB 2
|
|
75 firsttime RMB 1
|
1992
|
76 IFNE MPI
|
|
77 slot RMB 1
|
|
78 ENDC
|
1978
|
79 combuff RMB cbsize
|
|
80 size EQU .
|
|
81
|
|
82
|
|
83 L0000 MOD eom,name,tylg,atrv,start,size
|
|
84
|
|
85 name EQU *
|
|
86 IFNE KRNMOD
|
|
87 FCS /KrnP3/
|
|
88 ELSE
|
|
89 FCS /noice/
|
|
90 ENDC
|
|
91 FCB edition
|
|
92
|
|
93 nextname FCC /krnp4/ next module name to link to
|
|
94 FCB C$CR
|
|
95
|
|
96 svctabl FCB F$Debug
|
|
97 FDB dbgent-*-2
|
|
98 FCB $80
|
|
99
|
|
100 start
|
|
101 IFNE KRNMOD
|
|
102 leay <svctabl,pcr
|
|
103 os9 F$SSvc
|
|
104 bcs ex@
|
|
105 ldd #$0100
|
|
106 os9 F$SRqMem allocate memory
|
|
107 bcs ex@
|
|
108 stu <D.DbgMem save our allocated memory
|
1991
|
109 * clear the firsttime flag so that the first time we get
|
1978
|
110 * called at dbgent, we DON'T subtract the SWI from the PC.
|
|
111 sta firsttime,u A = $01
|
|
112 * get next KrnP module going
|
|
113 lda #tylg get next module type (same as this one!)
|
|
114 leax <nextname,pcr get address of next module name
|
|
115 os9 F$Link attempt to link to it
|
|
116 bcs ex@ no good...skip this
|
|
117 jsr ,y else go execute it
|
|
118 ex@ rts return
|
|
119 ENDC
|
|
120
|
|
121
|
|
122 * Debugger Entry Point
|
|
123 *
|
|
124 * We enter here when a process or the system makes an os9 F$Debug call.
|
|
125 dbgent
|
|
126 ldx <D.DbgMem get pointer to our statics in X
|
|
127 stu callregs,x save pointer to caller's regs
|
|
128 exg x,u exchange X and U
|
|
129 * If this is a breakpoint (state = 1) then back up PC to point at SWI2
|
|
130 tst firsttime,u
|
|
131 bne notbp
|
|
132 ldd R$PC,x
|
|
133 subd #$03
|
|
134 std R$PC,x
|
|
135 * set bit so next time we do the sub on the $PC
|
|
136 notbp clr firsttime,u
|
|
137 lbsr llinit initialize I/O
|
|
138 lda #FN_RUN_TARGET
|
|
139 sta combuff,u
|
|
140 lbra _readregs
|
|
141
|
|
142 * mainloop - processes requests from the server
|
|
143 mainloop
|
1990
|
144
|
|
145 * ADDITION: We insist on having a "Pre-Opcode" OP_XBUG if we are using
|
|
146 * this client in conjunction with DriveWire on the same serial line.
|
|
147 * This is because DriveWire's Opcodes conflict with NoICE's.
|
|
148 * lbsr llread get command byte
|
|
149 * cmpa #OP_XBUG X-Bug Op-Code?
|
|
150 * bne mainloop if not, continue waiting
|
|
151
|
1978
|
152 clrb clear B (for checksum)
|
|
153 leax combuff,u point to comm buffer
|
|
154 lbsr llread get command byte
|
|
155 sta ,x+ save in comm buffer and inc X
|
|
156 addb -1,x compute checksum
|
|
157 lbsr llread get byte count of incoming message
|
|
158 sta ,x+ save in comm buffer and inc X
|
|
159 addb -1,x compute checksum
|
|
160 pshs a save count on stack
|
|
161 tsta count zero?
|
|
162 beq csum@ branch if so
|
|
163 n@ lbsr llread read data byte (count on stack)
|
|
164 sta ,x+ save in our local buffer
|
|
165 addb -1,x compute checksum
|
|
166 dec ,s decrement count
|
|
167 bne n@ if not zero, get next byte
|
|
168 csum@ lbsr llread read checksum byte from host
|
|
169 sta ,s save on stack (where count was)
|
|
170 negb make 2's complement
|
|
171 cmpa ,s+ same as host's?
|
|
172 bne mainloop if not, ignore message
|
|
173
|
|
174 * Here we have a message with a valid checksum.
|
|
175 * Now we evaluate the command byte.
|
|
176 processmsg
|
|
177 lda combuff,u get command byte
|
|
178 bpl _sendstatus command byte hi bit not set
|
|
179 cmpa #FN_READ_MEM Read Memory?
|
|
180 lbeq _readmem branch if so
|
|
181 cmpa #FN_READ_REGS Read Registers?
|
|
182 lbeq _readregs branch if so
|
|
183 cmpa #FN_WRITE_MEM Write Memory?
|
|
184 lbeq _writemem branch if so
|
|
185 cmpa #FN_WRITE_REGS Write Registers?
|
|
186 lbeq _writeregs branch if so
|
|
187 cmpa #FN_GET_STATUS Get Status?
|
|
188 lbeq _getstatus branch if so
|
|
189 cmpa #FN_SET_BYTES Set Bytes?
|
|
190 beq _setbytes branch if so
|
|
191 cmpa #FN_RUN_TARGET Run Target?
|
|
192 lbeq _runtarget
|
|
193
|
|
194 * Here we send an error status
|
|
195 _senderror
|
|
196 lda #FN_ERROR
|
|
197 sta combuff,u
|
|
198 lda #1
|
|
199 _sendstatus
|
|
200 sta combuff+2,u
|
|
201 lda #1
|
|
202 sta combuff+1,u
|
|
203 lbsr _sendtohost
|
|
204 bra mainloop
|
|
205
|
|
206 _runtarget
|
|
207 IFNE KRNMOD
|
|
208 clrb
|
|
209 rts
|
|
210 ELSE
|
|
211 clrb
|
|
212 os9 F$Exit
|
|
213 ENDC
|
|
214
|
|
215 * This routine is given a list of bytes to change. It must read the current
|
|
216 * byte at that location and return it in a packet to the host so that
|
|
217 * the host can restore the contents at a later time.
|
|
218 _setbytes
|
|
219 ldb combuff+1,u get count byte
|
|
220 clr combuff+1,u set return count as zero
|
|
221 lsrb divide number of bytes by 4
|
|
222 lsrb
|
|
223 beq sb9@
|
|
224 pshs u save our statics pointer
|
|
225 leau combuff+2,u point U to write outgoing data
|
|
226 tfr u,y point Y to first 4 bytes
|
|
227 sb1@ pshs b save loop counter
|
|
228 ldd 1,y get address to write to
|
|
229 exg a,b swap!
|
|
230 tfr d,x memory address is now in X
|
|
231 * Here, X = memory address to read
|
|
232 * Y = 4 byte component in input packet
|
|
233 * U = next place in com buffer to write "previous" byte
|
|
234 * Read current data at byte location in process' space
|
|
235 pshs u,a save byte spot for later and "next" ptr
|
1990
|
236 IFNE USERSTATE
|
1978
|
237 ldu <D.Proc
|
|
238 ldb P$Task,u
|
|
239 os9 F$LDABX
|
1990
|
240 ELSE
|
|
241 lda ,x
|
|
242 ENDC
|
1978
|
243 sta ,s save original ,X value on stack for now
|
|
244 * A now holds the data byte -- insert new data at byte location
|
|
245 lda 3,y get byte to store
|
1990
|
246 IFNE USERSTATE
|
1978
|
247 os9 F$STABX
|
|
248 * Re-read current data at byte location in process' space
|
|
249 os9 F$LDABX
|
1990
|
250 ELSE
|
|
251 sta ,x
|
|
252 lda ,x
|
|
253 ENDC
|
1978
|
254 cmpa 3,y compare what we read from what we wrote
|
|
255 puls a,u get "original" value and next ptr
|
|
256 puls b restore loop count
|
|
257 bne sb8@ carry affected by last cmpa
|
|
258 * Save target byte in return buffer
|
|
259 sta ,u+
|
|
260 ldx ,s get original statics ptr in X for now
|
|
261 inc combuff+1,x count one return byte
|
|
262 * Loop for next byte
|
|
263 leay 4,y step to next byte in specifier
|
|
264 cmpb combuff+1,x done?
|
|
265 bne sb1@
|
|
266 * Return buffer with data from byte locations
|
|
267 sb8@ puls u restore our original statics ptr
|
|
268 sb9@ lbsr _sendtohost
|
|
269 lbra mainloop
|
|
270 sbe@ puls u restore what's on the stack
|
|
271 bra _senderror
|
|
272
|
|
273 * This routine reads memory from the calling process' address space
|
|
274 * using F$Move.
|
|
275 _readmem
|
|
276 ldd combuff+3,u get source pointer
|
|
277 exg a,b byte swap!
|
|
278 tfr d,x and put in X
|
|
279 clra clear A
|
|
280 ldb combuff+5,u get count
|
|
281 stb combuff+1,u and store count back in our header
|
|
282 tfr d,y put count in Y
|
|
283 pshs u,x save source pointer
|
|
284 leau combuff+2,u point U to destination
|
1990
|
285 IFNE USERSTATE
|
|
286 * User state
|
1978
|
287 ldx <D.Proc get current process pointer
|
1990
|
288 * cmpx <D.SysPrc same as system process?
|
|
289 * beq copysys
|
1978
|
290 lda P$Task,x get source task #
|
|
291 ldb <D.SysTsk get destination task #
|
|
292 puls x restore source pointer
|
|
293 os9 F$Move move 'em out!
|
1990
|
294 ELSE
|
|
295 * System state
|
|
296 puls x
|
|
297 l@ lda ,x+ get byte at source and inc
|
|
298 sta ,u+ save byte at dest and inc
|
|
299 leay -1,y done?
|
|
300 bne l@ branch if not
|
|
301 ENDC
|
1978
|
302 puls u restore statics pointer
|
|
303 bsr _sendtohost
|
|
304 lbra mainloop
|
|
305
|
|
306 * This routine writes memory from the host to the calling process'
|
|
307 * address space using F$Move.
|
|
308 _writemem
|
|
309 leax combuff+5,u point X to source
|
|
310 clra
|
|
311 ldb combuff+1,u get count of packet
|
|
312 subb #3 subtract 3 -- now we have our write count
|
|
313 tfr d,y put count in Y
|
|
314 ldd combuff+3,u get destination pointer
|
|
315 exg a,b byte swap!
|
|
316 pshs u,x save on stack
|
|
317 tfr d,u and put source in U
|
1990
|
318 IFNE USERSTATE
|
|
319 * User state
|
1978
|
320 ldx <D.Proc get current process pointer
|
|
321 lda <D.SysTsk get source task #
|
|
322 ldb P$Task,x get destination task #
|
|
323 puls x restore source pointer
|
|
324 os9 F$Move move 'em out!
|
1990
|
325 ELSE
|
|
326 * System state
|
|
327 puls x
|
|
328 l@ lda ,x+ get byte at source and inc
|
|
329 sta ,u+ save byte at dest and inc
|
|
330 leay -1,y done?
|
|
331 bne l@ branch if not
|
|
332 ENDC
|
1978
|
333 puls u restore our static pointer
|
|
334 ldd #$0100 assume successful write
|
|
335 std combuff+1,u
|
|
336 bsr _sendtohost
|
|
337 lbra mainloop
|
|
338
|
|
339
|
1991
|
340 * This data is provided to the NoICE server upon receipt of FN_GET_STATUS.
|
1978
|
341 statdata
|
1991
|
342 FCB 33 number of bytes to send
|
|
343 IFNE H6309
|
|
344 FCB 17 processor type: 6309
|
|
345 ELSE
|
|
346 FCB 5 processor type: 6809
|
|
347 ENDC
|
|
348 FCB cbsize size of communications buffer
|
|
349 FCB %00000000 options flags
|
|
350 FDB $0000 target mapped memory low bound
|
|
351 FDB $FFFF target mapped memory high bound
|
|
352 FCB 3 length of breakpoint instruction
|
|
353 FCB $10,$3F,F$Debug breakpoint instruction
|
|
354 * target description
|
|
355 FCC "NitrOS-9/6"
|
|
356 IFNE H6309
|
|
357 FCC "3"
|
|
358 ELSE
|
|
359 FCC "8"
|
|
360 ENDC
|
|
361 FCC "09 Level "
|
|
362 IFEQ Level-1
|
|
363 FCC "1"
|
|
364 ELSE
|
|
365 FCC "2"
|
|
366 ENDC
|
1978
|
367 FCB 0
|
|
368
|
|
369 _getstatus
|
|
370 * copy status to our buffer
|
|
371 leax statdata,pcr
|
|
372 leay combuff+1,u
|
|
373 ldb statdata,pcr
|
|
374 l@ lda ,x+
|
|
375 sta ,y+
|
|
376 decb
|
1991
|
377 bpl l@
|
1978
|
378 bsr _sendtohost
|
|
379 lbra mainloop
|
|
380
|
|
381
|
|
382 * This routine sends the contents of combuff,u to the communications
|
|
383 * hardware. Note that the count that is stored at combuff+1,u is
|
|
384 * set by the caller, and reflects the number of data bytes to be sent.
|
|
385 *
|
|
386 * Also, we compute the checksum as we send the bytes out so that
|
|
387 * we don't have to call a separate routine.
|
|
388 _sendtohost
|
|
389 leax combuff,u point X to communications buffer
|
|
390 ldb 1,x get count from header into B
|
|
391 addb #2 add header bytes to count var B
|
|
392 pshs b save on stack (this is our counter)
|
|
393 clrb B is now used for checksum
|
|
394 n@ addb ,x compute checksum
|
|
395 lda ,x+ get byte from buffer and inc X
|
|
396 lbsr llwrite write it out
|
|
397 dec ,s decrement count on stack
|
|
398 bne n@ if not zero, branch
|
|
399 negb make 2's complement
|
|
400 * comb make 2's complement
|
|
401 * incb
|
|
402 tfr b,a put in A
|
|
403 lbsr llwrite write it
|
|
404 puls b,pc return
|
|
405
|
|
406
|
|
407 _readregs
|
|
408 ldy callregs,u get pointer to caller's regs
|
1995
|
409 leax combuff+1,u
|
|
410 IFNE H6309
|
|
411 ldb #21 get number of bytes to send
|
|
412 ELSE
|
1978
|
413 ldb #16 get number of bytes to send
|
1995
|
414 ENDC
|
|
415 stb ,x+ save number of bytes
|
1978
|
416 lda firsttime,u get first time called flag
|
1995
|
417 sta ,x+ write it
|
|
418 clr ,x+ clear page reg
|
1978
|
419 ldd R$U,y
|
|
420 exg a,b
|
1995
|
421 std ,x++
|
1978
|
422 ldd R$Y,y
|
|
423 exg a,b
|
1995
|
424 std ,x++
|
1978
|
425 ldd R$X,y
|
|
426 exg a,b
|
1995
|
427 std ,x++
|
|
428 IFNE H6309
|
|
429 ldd R$E,y
|
|
430 exg a,b
|
|
431 std ,x++
|
|
432 ENDC
|
1978
|
433 ldd R$A,y
|
|
434 exg a,b
|
1995
|
435 std ,x++
|
1978
|
436 ldb R$DP,y
|
1995
|
437 stb ,x+ DP
|
1978
|
438 ldb R$CC,y
|
1995
|
439 stb ,x+ CC
|
1978
|
440 ldd R$PC,y
|
|
441 exg a,b
|
1995
|
442 std ,x++ PC
|
1978
|
443 ldy <D.Proc get SP from proc desc
|
|
444 ldd P$SP,y
|
|
445 exg a,b
|
|
446 std combuff+4,u
|
|
447 bsr _sendtohost
|
|
448 lbra mainloop
|
|
449
|
|
450
|
|
451 _writeregs
|
|
452 ldy callregs,u get caller's reg ptr
|
1995
|
453 leax combuff+6,u
|
1978
|
454 * lda D.Debug
|
|
455 * anda #D_BRKPT
|
|
456 * sta <D.Debug
|
1995
|
457 ldd ,x++
|
1978
|
458 exg a,b
|
|
459 std R$U,y
|
1995
|
460 ldd ,x++
|
1978
|
461 exg a,b
|
|
462 std R$Y,y
|
1995
|
463 ldd ,x++
|
1978
|
464 exg a,b
|
|
465 std R$X,y
|
1995
|
466 IFNE H6309
|
|
467 ldd ,x++
|
|
468 exg a,b
|
|
469 std R$E,y
|
|
470 ENDC
|
|
471 ldd ,x++
|
1978
|
472 exg a,b
|
|
473 std R$A,y
|
1995
|
474 ldb ,x+
|
1978
|
475 stb R$DP,y
|
1995
|
476 ldb ,x+
|
1978
|
477 stb R$CC,y
|
1995
|
478 ldd ,x++
|
1978
|
479 exg a,b
|
|
480 std R$PC,y
|
|
481 ldd combuff+4,u
|
|
482 exg a,b
|
|
483 ldy <D.Proc
|
|
484 std P$SP,y
|
|
485 ldd #$0100
|
|
486 std combuff+1,u
|
|
487 lbsr _sendtohost
|
|
488 lbra mainloop
|
|
489
|
|
490
|
|
491
|
|
492 ********** I/O ROUTINES **********
|
|
493
|
|
494 * 6551 Parameters
|
|
495 ADDR EQU $FF68
|
|
496
|
|
497 A_RXD EQU ADDR+$00
|
|
498 A_TXD EQU ADDR+$00
|
|
499 A_STATUS EQU ADDR+$01
|
|
500 A_RESET EQU ADDR+$01
|
|
501 A_CMD EQU ADDR+$02
|
|
502 A_CTRL EQU ADDR+$03
|
|
503
|
|
504 * Baud rates
|
|
505 _B2400 EQU $1A 2400 bps, 8-N-1
|
|
506 _B4800 EQU $1C 4800 bps, 8-N-1
|
|
507 _B9600 EQU $1E 9600 bps, 8-N-1
|
|
508 _B19200 EQU $1F 19200 bps, 8-N-1
|
|
509
|
|
510 BAUD EQU _B9600
|
|
511
|
|
512 * llinit - Initialize the low-level I/O
|
|
513 * Exit: Carry = 0: Init success; Carry = 1; Init failed
|
|
514 llinit
|
1995
|
515 IFNE MPI
|
|
516 pshs a
|
|
517 lda MPICTRL
|
|
518 sta slot,u
|
|
519 lda #RS232SLOT
|
|
520 sta MPICTRL
|
|
521 puls a
|
|
522 ENDC
|
1978
|
523 sta A_RESET soft reset (value not important)
|
|
524 * Set specific modes and functions:
|
|
525 * - no parity, no echo, no Tx interrupt
|
|
526 * - no Rx interrupt, enable Tx/Rx
|
|
527 lda #$0B
|
|
528 sta A_CMD save to command register
|
|
529 lda #BAUD
|
|
530 sta A_CTRL select proper baud rate
|
|
531 * Read any junk rx byte that may be in the register
|
|
532 lda A_RXD
|
1995
|
533 IFNE MPI
|
|
534 pshs a
|
|
535 lda slot,u
|
|
536 sta MPICTRL
|
|
537 puls a
|
|
538 ENDC
|
1978
|
539 rts
|
|
540
|
|
541
|
|
542 * llread - Read one character from 6551
|
|
543 *
|
|
544 * Entry: None
|
|
545 * Exit: A = character that was read
|
|
546 *
|
|
547 * Note, this routine currently doesn't timeout
|
|
548 llread
|
1992
|
549 IFNE MPI
|
1995
|
550 lda MPICTRL
|
1992
|
551 sta slot,u
|
|
552 lda #RS232SLOT
|
|
553 sta $FF7F
|
|
554 ENDC
|
1978
|
555 r@ lda A_STATUS get status byte
|
|
556 anda #$08 mask rx buffer status flag
|
|
557 beq r@ loop if rx buffer empty
|
|
558 lda A_RXD get byte from ACIA data port
|
1992
|
559 IFNE MPI
|
|
560 pshs b
|
|
561 ldb slot,u
|
1995
|
562 stb MPICTRL
|
1992
|
563 puls b,pc
|
|
564 ELSE
|
1978
|
565 rts
|
1992
|
566 ENDC
|
1978
|
567
|
|
568 * llwrite - Write one character to 6551
|
|
569 *
|
|
570 * Entry: A = character to write
|
|
571 * Exit: None
|
|
572 llwrite
|
1992
|
573 IFNE MPI
|
|
574 pshs d
|
1995
|
575 ldb MPICTRL
|
1992
|
576 stb slot,u
|
|
577 ldb #RS232SLOT
|
1995
|
578 stb MPICTRL
|
1992
|
579 ELSE
|
1978
|
580 pshs a save byte to write
|
1992
|
581 ENDC
|
1978
|
582 w@ lda A_STATUS get status byte
|
|
583 anda #$10 mask tx buffer status flag
|
|
584 beq w@ loop if tx buffer full
|
1992
|
585 IFNE MPI
|
|
586 puls d get byte
|
|
587 sta A_TXD save to ACIA data port
|
|
588 lda slot,u
|
1995
|
589 sta MPICTRL
|
1992
|
590 ELSE
|
1978
|
591 puls a get byte
|
|
592 sta A_TXD save to ACIA data port
|
1992
|
593 ENDC
|
1978
|
594 rts
|
|
595
|
|
596 * llterm - Terminate
|
|
597 *llterm
|
|
598 * rts
|
|
599
|
|
600
|
|
601 IFNE 0
|
|
602 * llwout - Write an entire string
|
|
603 * llwerr - Write an entire string
|
|
604 llwerr
|
|
605 llwout
|
|
606 pshs a
|
|
607 l@ lda ,x+
|
|
608 cmpa #C$CR
|
|
609 beq e@
|
|
610 leay -1,y
|
|
611 beq f@
|
|
612 bsr Write
|
|
613 bra l@
|
|
614 e@ bsr Write
|
|
615 lda #C$LF
|
|
616 bsr Write
|
|
617 f@ ldx <buffptr
|
|
618 clrb
|
|
619 puls a,pc
|
|
620
|
|
621 * ReadLine - Read an entire string, up to CR
|
|
622 * Entry: X = address to place string being read (CR terminated)
|
|
623 * Y = maximum number of bytes to read (including nul byte)
|
|
624 ReadLine
|
|
625 ldx <buffptr
|
|
626 pshs y,x,a
|
|
627 ldy #80
|
|
628 l@ bsr Read read 1 character
|
|
629 cmpa #C$CR carriage return?
|
|
630 beq e@ branch if so...
|
|
631 cmpa #$08 backspace?
|
|
632 beq bs@
|
|
633 cmpy #$0000 anymore room?
|
|
634 beq l@
|
|
635 leay -1,y back up one char
|
|
636 sta ,x+ and save in input buffer
|
|
637 m@ bsr Write echo back out
|
|
638 bra l@
|
|
639 e@ sta ,x
|
|
640 bsr Write
|
|
641 lda #C$LF
|
|
642 bsr Write
|
|
643 clrb
|
|
644 puls a,x,y,pc
|
|
645 bs@ cmpx 1,s are we at start
|
|
646 beq l@ if so, do nothing
|
|
647 clr ,-x else erase last byte
|
|
648 lbsr Write write backspace
|
|
649 lda #C$SPAC a space...
|
|
650 lbsr Write write it
|
|
651 leay 1,y count back up free char
|
|
652 lda #$08 another backspace
|
|
653 bra m@
|
|
654 ENDC
|
|
655
|
|
656 EMOD
|
|
657 eom EQU *
|
|
658 END
|