xa_asm: fixed parsing of symbols used with DS directive in BSEG (pass 2&3).
[fw/sdcc] / as / xa51 / paulmon2.xa
1 ; this copy is hacked to write to page 0Fxxxx when receiving
2 ; an intel-hex download... so it hopefully work on Matt's
3 ; 16-bit board layout.
4
5 ;$pagewidth 132t
6
7 ; This is a hacked copy of paulmon2 which is intended to work
8 ; with the XA processor.  Automatic baud rate detection is not
9 ; supported, and the extras package is not avaialble.  Flash
10 ; ROM is not supported.  Paulmon2 only understands the first 64k
11 ; of memory, and only recognizes intel-hex with 64k address
12 ; space.  Due to differences in arrangement of the XA, Paulmon2
13 ; may crash if it receives invalid intel-hex code (untested).
14 ; See comments in "dnld_ghex" for details about this.
15
16 ; Other bugs may exist, but the system seems to work.
17
18 ; Paulmon2 does NOT run in the XA's special 8051 compatibility
19 ; mode.  Paulmon2 shuts off the watchdog timer and runs all
20 ; code in system mode (highest priority).
21
22 ;$include xa-g3.equ
23
24 acc     reg     R4L
25 dpl     reg     R6L
26 dph     reg     R6H
27 s0con   sfr     420h
28 ri_0    bit     s0con.0
29 ti_0    bit     s0con.1
30 pswl    sfr     400h
31 psw51   sfr     402h
32 tcon    sfr     410h
33 tr1     bit     tcon.6
34 s0buf   sfr     460h
35 wdcon   sfr     41fh
36 wfeed1  sfr     45dh
37 wfeed2  sfr     45eh
38 tl1     sfr     452h
39 tmod    sfr     45ch
40 rtl1    sfr     456h
41 ssel    sfr     403h
42 cs      sfr     443h
43
44
45 ; PAULMON2, a user-friendly 8051 monitor, by Paul Stoffregen
46 ; Please email comments, suggestions, bugs to paul@ece.orst.edu
47
48 ; It's free.  You may copy sections of code from PAULMON2
49 ; into your own programs, even for commercial purposes.
50 ; PAULMON2 should only be distributed free of charge, but may
51 ; be bundled as 'value-added' with other products, such as
52 ; development boards, CDROMs, etc.  Please distribute the
53 ; PAULMON2.DOC file and other files, not just the object code!
54
55 ; The PAULMON2.EQU and PAULMON2.HDR files contain valuable
56 ; information that could help you to write programs for use
57 ; with PAULMON2.
58
59 ; PAULMON2 is in the public domain. PAULMON2 is distributed in
60 ; the hope that it will be useful, but without any warranty;
61 ; without even the implied warranty of merchantability or fitness
62 ; for a particular purpose.
63
64
65 carry   bit     pswl.7
66 flag0   bit     psw51.5
67 flag1   bit     psw51.1
68
69 ;---------------------------------------------------------;
70 ;                                                         ;
71 ;           PAULMON2's default configuration              ;
72 ;                                                         ;
73 ;---------------------------------------------------------;
74
75 ; PAULMON2 should be assembled using the modified AS31 assembler,
76 ; originally written by Ken Stauffer, many small changes by Paul
77 ; Stoffregen.  This free assembler is available on the web at
78 ; http://www.ece.orst.edu/~paul/8051-goodies/goodies-index.html
79 ; As well, these web pages have a fill-out form which makes it
80 ; very easy to custom configure PAULMON2.  Using this form will
81 ; edit the code for you, run the AS31 assmebler, and send you the
82 ; object code to program into your chip.
83
84
85 vector          equ     $8000
86
87 ; These three parameters tell PAULMON2 where the user's memory is
88 ; installed.  "bmem" and "emem" define the space that will be searched
89 ; for program headers, user installed commands, start-up programs, etc.
90 ; "bmem" and "emem" should be use so they exclude memory areas where
91 ; perphreal devices may be mapped, as reading memory from an io chip
92 ; may reconfigure it unexpectedly.  If flash rom is used, "bmem" and "emem"
93 ; should also include the space where the flash rom is mapped.
94
95 pgm        EQU     $F000            ;default location for the user program
96 bmem       EQU     $0000            ;where is the beginning of memory
97 emem       EQU     $FFFF            ;end of the memory
98
99
100 ; Please note... much of the memory management code only looks at the
101 ; upper 8 bits of an address, so it's not a good idea to somehow map
102 ; your memory chips (with complex address decoding logic) into chunks
103 ; less than 256 bytes.  In other words, only using a piece of a flash
104 ; rom chip and mapping it between C43A to F91B would confuse PAULMON2
105 ; (as well as require quit a bit of address decoding logic circuitry)
106
107 ; To set the baud rate, use this formula or set to 0 for auto detection
108 ; baud_const = 256 - (crystal / (4 * 16 * baud))  <-- for XA chip
109
110 ;baud_const EQU         247             ;19200 baud w/ 11.0592 MHz (XA)
111 ;baud_const EQU         253             ;57600 baud w/ 11.0592 MHz (XA)
112 baud_const EQU          251             ;57600 baud w/ 18.432 MHz (XA)
113 ;baud_const EQU         241             ;19200 baud w/ 18.432 MHz (XA)
114 ;baud_const EQU         236             ;19531 baud w/ 25 MHz (XA)
115
116
117 ; About download speed: when writing to ram, PAULMON2 can accept data
118 ; at the maximum baud rate (baud_const=255 or 57600 baud w/ 11.0592 MHz).
119 ; Most terminal emulation programs introduce intentional delays when
120 ; sending ascii data, which you would want to turn off for downloading
121 ; larger programs into ram.  For Flash ROM, the maximum speed is set by
122 ; the time it takes to program each location... 9600 baud seems to work
123 ; nicely for the AMD 28F256 chip.  The "character pacing" delay in a
124 ; terminal emulation program should be sufficient to download to flash
125 ; rom and any baud rate.
126
127
128 ; Several people didn't like the key definations in PAULMON1.
129 ; Actually, I didn't like 'em either, but I never took the time
130 ; to change it.  Eventually I got used to them, but now it's
131 ; really easy to change which keys do what in PAULMON2.  You
132 ; can guess what to do below, but don't use lowercase.
133
134 help_key   EQU     '?'              ;help screen
135 dir_key    EQU     'M'              ;directory
136 run_key    EQU     'R'              ;run program
137 dnld_key   EQU     'D'              ;download
138 upld_key   EQU     'U'              ;upload
139 nloc_key   EQU     'N'              ;new memory location
140 jump_key   EQU     'J'              ;jump to memory location
141 dump_key   EQU     'H'              ;hex dump memory
142 intm_key   EQU     'I'              ;hex dump internal memory
143 edit_key   EQU     'E'              ;edit memory
144 clrm_key   EQU     'C'              ;clear memory
145 erfr_key   EQU     'Z'              ;erase flash rom
146 xdump_key  EQU     'X'              ;hex dump ext data memory
147
148
149 ;location of parameter table used by download command
150 ;sixteen bytes of internal memory are required beginning at this
151 ;location
152
153 dnld_parm  EQU     $01F0
154 stack      EQU     $01EE
155
156 ;---------------------------------------------------------;
157 ;                                                         ;
158 ;                    Interrupt Vectors                    ;
159 ;  (and little bits of code crammed in the empty spaces)  ;
160 ;                                                         ;
161 ;---------------------------------------------------------;
162
163            ORG     0
164
165                         dw      $8f00, poweron
166 breakvec:       dw      $8f00, vector + breakvec
167 tracevec:       dw      $8f00, vector + tracevec
168 stackovvec:     dw      $8f00, vector + stackovvec
169 div0vec:        dw      $8f00, vector + div0vec
170 uretivec:       dw      $8f00, vector + uretivec
171                         org     $40
172 trap0vec:       dw      $8800, vector + trap0vec
173 trap1vec:       dw      $8800, vector + trap1vec
174 trap2vec:       dw      $8800, vector + trap2vec
175 trap3vec:       dw      $8800, vector + trap3vec
176 trap4vec:       dw      $8800, vector + trap4vec
177 trap5vec:       dw      $8800, vector + trap5vec
178 trap6vec:       dw      $8800, vector + trap6vec
179 trap7vec:       dw      $8800, vector + trap7vec
180 trap8vec:       dw      $8800, vector + trap8vec
181 trap9vec:       dw      $8800, vector + trap9vec
182 trap10vec:      dw      $8800, vector + trap10vec
183 trap11vec:      dw      $8800, vector + trap11vec
184 trap12vec:      dw      $8800, vector + trap12vec
185 trap13vec:      dw      $8800, vector + trap13vec
186 trap14vec:      dw      $8800, vector + trap14vec
187 trap15vec:      dw      $8800, vector + trap15vec
188                         org     $80
189 int0vec:        dw      $8900, vector + int0vec
190 tmr0vec:        dw      $8900, vector + tmr0vec
191 int1vec:        dw      $8900, vector + int1vec
192 tmr1vec:        dw      $8900, vector + tmr1vec
193 tmr2vec:        dw      $8900, vector + tmr2vec
194                         org     $A0
195 rxd0vec:        dw      $8900, vector + rxd0vec
196 txd0vec:        dw      $8900, vector + txd0vec
197 rxd1vec:        dw      $8900, vector + rxd1vec
198 txd1vec:        dw      $8900, vector + txd1vec
199                         org     $100
200 swi1vec:        dw      $8100, vector + swi1vec
201 swi2vec:        dw      $8200, vector + swi2vec
202 swi3vec:        dw      $8300, vector + swi3vec
203 swi4vec:        dw      $8400, vector + swi4vec
204 swi5vec:        dw      $8500, vector + swi5vec
205 swi6vec:        dw      $8600, vector + swi6vec
206 swi7vec:        dw      $8700, vector + swi7vec
207
208            org     $120
209
210                 jmp             poweron
211
212
213 space:     MOV.B   R4L,#' '
214            CALL    cout
215            RET
216
217 dash:      MOV.B   R4L,#'-'
218            CALL    cout
219            RET
220
221
222 ;---------------------------------------------------------;
223 ;                                                         ;
224 ;       The jump table for user programs to call          ;
225 ;             subroutines within PAULMON                  ;
226 ;                                                         ;
227 ;---------------------------------------------------------;
228
229 ; no jump table anymore... use TRAP or conditional assembly.
230
231
232 ;---------------------------------------------------------;
233 ;                                                         ;
234 ;              Subroutines for serial I/O                 ;
235 ;                                                         ;
236 ;---------------------------------------------------------;
237
238
239 ;these are the only three routines which access the serial port directly
240 ;but poweron/autobaud to the initial setup
241
242 cin:       JNB     ri_0,cin
243            CLR     ri_0
244            MOV.B   R4L,s0buf
245            RET
246 cout:      JNB     ti_0,cout
247            CLR     ti_0               ;clr ti before the mov to sbuf!
248            MOV.B   s0buf,R4L
249            RET
250 esc:  ;checks to see if <ESC> is waiting on serial port
251       ;C=clear if no <ESC>, C=set if <ESC> pressed
252       ;buffer is flushed
253            PUSH.B  acc
254            CLR     carry
255            JNB     ri_0,esc2
256            clr     ri_0
257            MOV.B   R4L, s0buf
258            CJNE.B  R4L,#27,esc2
259            SETB    carry
260 esc2:      POP.B   acc
261            RET
262
263
264 ;everything else from here on should only access the serial
265 ;port using cin/cout/etc
266
267
268 newline:   PUSH.B  acc
269            MOV.B   R4L,#13
270            CALL    cout
271            MOV.B   R4L,#10
272            CALL    cout
273            POP.B   acc
274            RET
275
276         ;get 2 digit hex number from serial port
277         ; c = set if ESC pressed, clear otherwise
278         ; flag0 = set if return w/ no input, clear otherwise
279 ghex:
280 ghex8:     CLR     flag0
281 ghex8c:
282            CALL    cin              ;get first digit
283            CALL    upper
284            CJNE.B  R4L,#27,ghex8f
285 ghex8d:    SETB    carry
286            MOVS    R4L,#0
287            RET
288 ghex8f:    CJNE.B  R4L,#13,ghex8h
289            SETB    flag0
290            CLR     carry
291            MOVS    R4L,#0
292            RET
293 ghex8h:    MOV.B   R1L,R4L
294            CALL    asc2hex
295            BCS     ghex8c
296            XCH.B   R4L,R1L          ;r2 will hold hex value of 1st digit
297            CALL    cout
298 ghex8j:
299            CALL    cin              ;get second digit
300            CALL    upper
301            CJNE.B  R4L,#27,ghex8k
302            BR      ghex8d
303 ghex8k:    CJNE.B  R4L,#13,ghex8m
304            MOV.B   R4L,R1L
305            CLR     carry
306            RET
307 ghex8m:    CJNE.B  R4L,#8,ghex8p
308 ghex8n:    CALL    cout
309            BR      ghex8c
310 ghex8p:    CJNE.B  R4L,#21,ghex8q
311            BR      ghex8n
312 ghex8q:    MOV.B   R1H,R4L
313            CALL    asc2hex
314            BCS     ghex8j
315            XCH.B   R4L,R1H
316            CALL    cout
317            MOV.B   R4L,R1L
318            RL.B R4L,#4
319            OR.B    R4L,R1H
320            CLR     carry
321            RET
322
323
324
325
326         ;carry set if esc pressed
327         ;flag0 set if return pressed w/ no input
328 ghex16:
329            MOV.B   R1L,#0           ;start out with 0
330            MOV.B   R1H,#0
331            MOV.B   R2L,#4           ;number of digits left
332            CLR     flag0
333
334 ghex16c:
335            CALL    cin
336            CALL    upper
337            CJNE.B  R4L,#27,ghex16d
338            SETB    carry            ;handle esc key
339            MOVS    R4L,#0
340            MOV.B   dph,R4L
341            MOV.B   dpl,R4L
342            RET
343 ghex16d:   CJNE.B  R4L,#8,ghex16f
344            BR      ghex16k
345 ghex16f:   CJNE.B  R4L,#127,ghex16g ;handle backspace
346 ghex16k:   CJNE.B  R2L,#4,ghex16e   ;have they entered anything yet?
347            BR      ghex16c
348 ghex16e:   CALL    cout
349            CALL    ghex16y
350            ADDS.B  R2L,#1
351            BR      ghex16c
352 ghex16g:   CJNE.B  R4L,#13,ghex16i  ;return key
353            MOV.B   dph,R1H
354            MOV.B   dpl,R1L
355            CJNE.B  R2L,#4,ghex16h
356            MOVS    R4L,#0
357            MOV.B   dph,R4L
358            MOV.B   dpl,R4L
359            SETB    flag0
360 ghex16h:   CLR     carry
361            RET
362 ghex16i:   MOV.B   R2H,R4L          ;keep copy of original keystroke
363            CALL    asc2hex
364            BCS     ghex16c
365            XCH.B   R4L,R2H
366            CALL    cout
367            MOV.B   R4L,R2H
368            PUSH.B  acc
369            CALL    ghex16x
370            POP.B   acc
371            ADD.B   R4L,R1L
372            MOV.B   R1L,R4L
373            MOVS    R4L,#0
374            ADDC.B  R4L,R1H
375            MOV.B   R1H,R4L
376            DJNZ.B  R2L,ghex16c
377            CLR     carry
378            MOV.B   dpl,R1L
379            MOV.B   dph,R1H
380            RET
381
382 ghex16x:  ;multiply r3-r2 by 16 (shift left by 4)
383            MOV.B   R4L,R1H
384            RL.B R4L,#4
385            AND.B   R4L,#11110000Q
386            MOV.B   R1H,R4L
387            MOV.B   R4L,R1L
388            RL.B R4L,#4
389            AND.B   R4L,#00001111Q
390            OR.B    R4L,R1H
391            MOV.B   R1H,R4L
392            MOV.B   R4L,R1L
393            RL.B R4L,#4
394            AND.B   R4L,#11110000Q
395            MOV.B   R1L,R4L
396            RET
397
398 ghex16y:  ;divide r3-r2 by 16 (shift right by 4)
399            MOV.B   R4L,R1L
400            RL.B R4L,#4
401            AND.B   R4L,#00001111Q
402            MOV.B   R1L,R4L
403            MOV.B   R4L,R1H
404            RL.B R4L,#4
405            AND.B   R4L,#11110000Q
406            OR.B    R4L,R1L
407            MOV.B   R1L,R4L
408            MOV.B   R4L,R1H
409            RL.B R4L,#4
410            AND.B   R4L,#00001111Q
411            MOV.B   R1H,R4L
412            RET
413
414 asc2hex:             ;carry set if invalid input
415            CLR     carry
416            PUSH.B  R4H
417            SUBB.B  R4L,#'0'
418            MOV.B   R4H,R4L
419            SUBB.B  R4L,#10
420            BCS     a2h1
421            MOV.B   R4L,R4H
422            SUBB.B  R4L,#7
423            MOV.B   R4H,R4L
424 a2h1:      MOV.B   R4L,R4H
425            CLR     carry
426            AND.B   R4L,#11110000Q   ;just in case
427            JZ      a2h2
428            SETB    carry
429 a2h2:      MOV.B   R4L,R4H
430            POP.B   R4H
431            RET
432
433
434 phex:
435 phex8:
436            PUSH.B  acc
437            RL.B R4L,#4
438            AND.B   R4L,#15
439            ADD.B   R4L,#246
440            BCC     phex_b
441            ADD.B   R4L,#7
442 phex_b:    ADD.B   R4L,#58
443            CALL    cout
444            POP.B   acc
445 phex1:     PUSH.B  acc
446            AND.B   R4L,#15
447            ADD.B   R4L,#246
448            BCC     phex_c
449            ADD.B   R4L,#7
450 phex_c:    ADD.B   R4L,#58
451            CALL    cout
452            POP.B   acc
453            RET
454
455
456 phex16:
457            PUSH.B  acc
458            MOV.B   R4L,dph
459            CALL    phex
460            MOV.B   R4L,dpl
461            CALL    phex
462            POP.B   acc
463            RET
464
465
466 ;a not so well documented feature of pstr is that you can print
467 ;multiple consecutive strings without needing to reload dptr
468 ;(which takes 3 bytes of code!)... this is useful for inserting
469 ;numbers or spaces between strings.
470
471 pstr:      PUSH.B  acc
472 pstr1:     MOVS    R4L,#0
473            MOVC.B  A,[A+dptr]
474            ADDS.W  R6,#1
475            JZ      pstr2
476            MOV     C,R4L.7
477            AND.B   R4L,#0x7F
478            CALL    cout
479            BCS     pstr2
480            BR      pstr1
481 pstr2:     POP.B   acc
482            RET
483
484
485
486 ;---------------------------------------------------------;
487 ;                                                         ;
488 ;    The 'high-level' stuff to interact with the user     ;
489 ;                                                         ;
490 ;---------------------------------------------------------;
491
492
493 menu: ;first we print out the prompt
494            MOV.W   R6,#prompt1      ;give 'em the first part of prompt
495            CALL    pcstr
496            MOV.B   R4L,R3H
497            CALL    phex
498            MOV.B   R4L,R3L
499            CALL    phex
500            CALL    space
501         MOV.W   R6,#prompt2
502            CALL    pstr
503
504
505 ;now we're past the prompt, so let's get some input
506            CALL    cin              ;get the input
507            CALL    upper
508
509
510 menu1a:    CJNE.B  R4L,#help_key,menu1b
511            MOV.W   R6,#help_cmd2
512            CALL    pcstr
513            call     help
514                 jmp     menu
515 menu1b:    CJNE.B  R4L,#dir_key,menu1c
516            MOV.W   R6,#dir_cmd
517            CALL    pcstr
518            call     dir
519                 jmp     menu
520 menu1c:    CJNE.B  R4L,#run_key,menu1d
521            MOV.W   R6,#run_cmd
522            CALL    pcstr
523            call run
524                 jmp     menu
525 menu1d:    CJNE.B  R4L,#dnld_key,menu1e
526            MOV.W   R6,#dnld_cmd
527            CALL    pcstr
528            call     dnld
529                 jmp             menu
530 menu1e:    CJNE.B  R4L,#upld_key,menu1f
531            MOV.W   R6,#upld_cmd
532            CALL    pcstr
533            call     upld
534                 jmp             menu
535 menu1f:    CJNE.B  R4L,#nloc_key,menu1g
536            MOV.W   R6,#nloc_cmd
537            CALL    pcstr
538            call     nloc
539                 jmp             menu
540 menu1g:    CJNE.B  R4L,#jump_key,menu1h
541            MOV.W   R6,#jump_cmd
542            CALL    pcstr
543            call jump
544                 jmp             menu
545 menu1h:    CJNE.B  R4L,#dump_key,menu1i
546            MOV.W   R6,#dump_cmd
547            CALL    pcstr
548            call dump
549                 jmp             menu
550 menu1i:    CJNE.B  R4L,#edit_key,menu1j
551            MOV.W   R6,#edit_cmd
552            CALL    pcstr
553            call edit
554                 jmp             menu
555 menu1j:    CJNE.B  R4L,#clrm_key,menu1l
556            MOV.W   R6,#clrm_cmd
557            CALL    pcstr
558            call   clrm
559                 jmp             menu
560 menu1l:    CJNE.B  R4L,#intm_key,menu1m
561            MOV.W   R6,#intm_cmd
562            CALL    pcstr
563            call intm
564                 jmp             menu
565 menu1m:    CJNE.B  R4L,#xdump_key,menu1n
566            MOV.W   R6,#xdump_cmd
567            CALL    pcstr
568            call xdump
569                 jmp             menu
570 menu1n:
571
572     ;invalid input, no commands to run...
573 menu_end:                       ;at this point, we have not found
574            CALL    newline          ;anything to run, so we give up.
575                 jmp             menu
576
577 ;..........................................................
578
579 ;---------------------------------------------------------;
580
581 ;dnlds1 = "Begin sending Intel HEX format file <ESC> to abort"
582 ;dnlds2 = "Download aborted"
583 ;dnlds3 = "Download completed"
584
585
586 ;16 byte parameter table: (eight 16 bit values)
587 ;  *   0 = lines received
588 ;  *   1 = bytes received
589 ;  *   2 = bytes written
590 ;  *   3 = bytes unable to write
591 ;  *   4 = incorrect checksums
592 ;  *   5 = unexpected begin of line
593 ;  *   6 = unexpected hex digits (while waiting for bol)
594 ;  *   7 = unexpected non-hex digits (in middle of a line)
595
596 dnld:
597            MOV.W   R6,#dnlds1
598            CALL    pcstr          ;"begin sending file <ESC> to abort"
599         mov.w   r5,#dnld_parm
600         mov.b   R1L,#8
601 dnld0:  movs.w  [r5+],#0          ;initialize all parameters to 0
602         DJNZ.B  R1L,dnld0
603
604           ;look for begining of line marker ':'
605 dnld1:     CALL    cin
606            CJNE.B  R4L,#27,dnld2    ;Test for escape
607            BR      dnld_esc
608 dnld2:     CJNE.B  R4L,#':',dnld2b
609         mov.w   r5, #dnld_parm
610         adds.w  [r5+0], #1
611            BR      dnld3
612 dnld2b:   ;check to see if it's a hex digit, error if it is
613            CALL    asc2hex
614            BCS     dnld1
615         mov.w   r5, #dnld_parm
616         adds.w  [r5+12], #1
617            BR      dnld1
618           ;begin taking in the line of data
619 dnld3:     MOV.B   R4L,#'.'
620            CALL    cout
621            MOV.B   R2L,#0           ;r4 will count up checksum
622            CALL    dnld_ghex
623            MOV.B   R0L,R4L          ;R0 = # of data bytes
624            MOV.B   R2L,R4L
625            CALL    dnld_ghex
626            MOV.B   dph,R4L          ;High byte of load address
627            ADD.B   R4L,R2L
628            MOV.B   R2L,R4L
629            CALL    dnld_ghex
630            MOV.B   dpl,R4L          ;Low byte of load address
631            ADD.B   R4L,R2L
632            MOV.B   R2L,R4L
633            CALL    dnld_ghex        ;Record type
634            MOV.B   R1L,R4L
635            ADD.B   R4L,R2L
636            MOV.B   R2L,R4L
637            MOV.B   R4L,R1L
638            CJNE.B  R4L,#1,dnld4     ;End record?
639            BR      dnld_end
640 dnld4:
641 dnld5:     CALL    dnld_ghex        ;Get data byte
642            MOV.B   R1L,R4L
643         mov.w   r5, #dnld_parm
644         adds.w  [r5+2], #1
645            MOV.B   R4L,R1L
646            ADD.B   R4L,R2L
647            MOV.B   R2L,R4L
648            MOV.B   R4L,R1L
649            CALL    smart_wr         ;c=1 if an error writing
650            MOVS    R4L,#0
651            ADDC.B  R4L,#2
652            MOV.B   R0H,R4L
653 ;     2 = bytes written
654 ;     3 = bytes unable to write
655         rl.b    r4l, #1
656         movs.b  r4h, #0
657         mov.w   r5, #dnld_parm
658         add.w   r5, r4
659         adds.w  [r5], #1
660
661            ADDS.W  R6,#1
662            DJNZ.B  R0L,dnld5
663
664            CALL    dnld_ghex        ;get checksum
665            ADD.B   R4L,R2L
666            JZ      dnld1            ;should always add to zero
667 dnld_sumerr:
668         mov.w   r5, #dnld_parm
669         adds.w  [r5+8], #1
670            BR      dnld1
671
672 dnld_end:   ;handles the proper end-of-download marker
673            CALL    dnld_ghex        ;get the last checksum
674         ;assume no data in this line.
675            ADD.B   R4L,R2L
676            JNZ     dnld_sumerr
677            CALL    dnld_dly
678            MOV.W   R6,#dnlds3
679            CALL    pcstr          ;"download went ok..."
680         ;consume any cr or lf character that may have been
681         ;on the end of the last line
682            JNB     ri_0,dnld_sum
683            CALL    cin
684            BR      dnld_sum
685
686 dnld_esc:   ;handle esc received in the download stream
687            CALL    dnld_dly
688            MOV.W   R6,#dnlds2
689            CALL    pcstr          ;"download aborted."
690            BR      dnld_sum
691
692 dnld_dly:   ;a short delay since most terminal emulation programs
693             ;won't be ready to receive anything immediately after
694             ;they've transmitted a file... even on a fast Pentium(tm)
695             ;machine with 16550 uarts!
696            MOV.B   R0L,#0
697 dnlddly2:  MOV.B   R0H,#0
698 dnlddly3:  DJNZ.B  R0H,dnlddly3       ;roughly 128k cycles, appox 0.1 sec
699            DJNZ.B  R0L,dnlddly2
700            RET
701
702
703
704
705
706
707 ;a special version of ghex just for the download.  Does not
708 ;look for carriage return or backspace.  Handles ESC key by
709 ;poping the return address (I know, nasty, but it saves many
710 ;bytes of code in this 4k ROM) and then jumps to the esc
711 ;key handling.  This ghex doesn't echo characters, and if it
712 ;sees ':', it pops the return and jumps to an error handler
713 ;for ':' in the middle of a line.  Non-hex digits also jump
714 ;to error handlers, depending on which digit.
715
716 ; XA compatibility issue: This code pops the return address
717 ; off the stack and does a jump to an error handler.  The
718 ; code should examine the mode bit to see if return addresses
719 ; are 16 or 32 bits on the stack.  As it is, it will probably
720 ; work in non 16-bit mode (default), but this code could
721 ; use some attention to this detail nonetheless.
722
723 dnld_ghex:
724 dnldgh1:   CALL    cin
725            CALL    upper
726            CJNE.B  R4L,#27,dnldgh3
727 dnldgh2:   POP.B   acc                  ;<-- compatibility problem!!!  Check XA mode
728            POP.B   acc                  ;<-- and pop correct number of words off stack
729            BR      dnld_esc
730 dnldgh3:   CJNE.B  R4L,#':',dnldgh5
731 dnldgh4:
732         mov.w   r5, #dnld_parm
733         adds.w  [r5+10], #1     ;handle unexpected beginning of line
734            POP.B   acc                  ;<-- compatibility problem!!!  Check XA mode
735            POP.B   acc                  ;<-- and pop correct number of words off stack
736            JMP     dnld3            ;and now we're on a new line!
737 dnldgh5:   CALL    asc2hex
738            BCC     dnldgh6
739         mov.w   r5, #dnld_parm
740         adds.w  [r5+14], #1
741            BR      dnldgh1
742 dnldgh6:   MOV.B   R1L,R4L          ;keep first digit in r2
743 dnldgh7:   CALL    cin
744            CALL    upper
745            CJNE.B  R4L,#27,dnldgh8
746            BR      dnldgh2
747 dnldgh8:   CJNE.B  R4L,#':',dnldgh9
748            BR      dnldgh4
749 dnldgh9:   CALL    asc2hex
750            BCC     dnldghA
751         mov.w   r5, #dnld_parm
752         adds.w  [r5+14], #1
753            BR      dnldgh7
754 dnldghA:   XCH.B   R4L,R1L
755            RL.B R4L,#4
756            OR.B    R4L,R1L
757            RET
758
759 ;dnlds4 =  "Summary:"
760 ;dnlds5 =  " lines received"
761 ;dnlds6a = " bytes received"
762 ;dnlds6b = " bytes written"
763
764 dnld_sum:    ;print out download summary
765            MOV.W   R6,#dnlds4
766            CALL    pcstr
767         MOV.w   r5, #dnld_parm
768         mov.w   r6, [r5+]
769            CALL    space
770            CALL    pint16u
771            MOV.W   R6,#dnlds5
772            CALL    pcstr
773         mov.w   r6, [r5+]
774            CALL    space
775            CALL    pint16u
776            MOV.W   R6,#dnlds6a
777            CALL    pcstr
778         mov.w   r6, [r5+]
779            CALL    space
780            CALL    pint16u
781            MOV.W   R6,#dnlds6b
782            CALL    pcstr
783 dnld_err:    ;now print out error summary
784            MOV.w   r5, #dnld_parm + 6
785                         mov     r1l, #5
786 dnlder2:
787                 mov.w   r6, [r5+]
788            bne     dnlder3          ;any errors?
789            DJNZ.B  R1L,dnlder2
790          ;no errors, so we print the nice message
791            MOV.W   R6,#dnlds13
792            CALL    pcstr
793            RET
794 dnlder3:  ;there were errors, so now we print 'em
795            MOV.W   R6,#dnlds7
796            CALL    pcstr
797           ;but let's not be nasty... only print if necessary
798                 mov             r5, #dnld_parm+6
799                 mov             r6, [r5+]
800         beq     dnlder4
801            CALL    space
802            CALL    pint16u
803            MOV.W   R6,#dnlds8
804            CALL    pcstr
805 dnlder4:
806                 mov             r6, [r5+]
807                 beq             dnlder5
808            CALL    space
809            CALL    pint16u
810            MOV.W   R6,#dnlds9
811            CALL    pcstr
812 dnlder5:
813                 mov             r6, [r5+]
814         beq     dnlder6
815            CALL    space
816            CALL    pint16u
817            MOV.W   R6,#dnlds10
818            CALL    pcstr
819 dnlder6:
820         mov     r6, [r5+]
821         beq     dnlder7
822            CALL    space
823            CALL    pint16u
824            MOV.W   R6,#dnlds11
825            CALL    pcstr
826 dnlder7:
827         mov     r6, [r5+]
828         beq     dnlder8
829            CALL    space
830            CALL    pint16u
831            MOV.W   R6,#dnlds12
832            CALL    pcstr
833 dnlder8:   CALL    newline
834            RET
835
836 ;dnlds7:  = "Errors:"
837 ;dnlds8:  = " bytes unable to write"
838 ;dnlds9:  = " incorrect checksums"
839 ;dnlds10: = " unexpected begin of line"
840 ;dnlds11: = " unexpected hex digits"
841 ;dnlds12: = " unexpected non-hex digits"
842 ;dnlds13: = "No errors detected"
843
844
845
846 ;---------------------------------------------------------;
847
848
849 jump:
850            MOV.W   R6,#prompt8
851            CALL    pcstr
852         mov.w   r6, r3
853            CALL    phex16
854            MOV.W   R6,#prompt4
855            CALL    pcstr
856            CALL    ghex16
857            JB      flag0,jump3
858            BCC     jump2
859            MOV.W   R6,#abort
860            CALL    pcstr
861            CALL    newline
862            RET
863 jump2:          mov.w   r3, r6
864 jump3:     CALL    newline
865            MOV.W   R6,#runs1
866            CALL    pcstr
867                         mov.w   r6, r3
868                         call    phex16
869                         call    newline
870                         mov.w   r6, r3
871
872 jump_doit:  ;jump to user code @dptr (this used by run command also)
873         movs.w  r0, #0
874         push.w  r0
875         mov.w  r0, #$120
876         push.w  r0
877         jmp     [r6]
878
879
880 ;---------------------------------------------------------;
881
882 dump:
883            MOV.B   R1L,#16          ;number of lines to print
884            CALL    newline
885            CALL    newline
886 dump1:
887         push    r6
888         mov     r6, #msg_code
889         call    pstr
890         pop     r6
891            MOV.B   dpl,R3L
892            MOV.B   dph,R3H
893            CALL    phex16           ;tell 'em the memory location
894            MOV.B   R4L,#':'
895            CALL    cout
896            CALL    space
897            MOV.B   R1H,#16          ;r3 counts # of bytes to print
898            MOV.B   dpl,R3L
899            MOV.B   dph,R3H
900 dump2:     MOVS    R4L,#0
901            MOVC.B  A,[A+dptr]
902            ADDS.W  R6,#1
903            CALL    phex             ;print each byte in hex
904            CALL    space
905            DJNZ.B  R1H,dump2
906            CALL    space            ;print a couple extra space
907            CALL    space
908            MOV.B   R1H,#16
909            MOV.B   dpl,R3L
910            MOV.B   dph,R3H
911 dump3:     MOVS    R4L,#0
912            MOVC.B  A,[A+dptr]
913            ADDS.W  R6,#1
914            AND.B   R4L,#01111111Q   ;avoid unprintable characters
915            CLR     carry
916            SUBB.B  R4L,#20h
917            BCC     dump4            ;avoid control characters
918            MOV.B   R4L,#(' ' - 20h)
919 dump4:     ADD.B   R4L,#20h
920            CALL    cout
921            DJNZ.B  R1H,dump3
922            CALL    newline
923            MOV.B   R3L,dpl
924            MOV.B   R3H,dph
925            CALL    esc
926            BCS     dump5
927            DJNZ.B  R1L,dump1        ;loop back up to print next line
928 dump5:     CALL    newline
929            RET
930
931 msg_code: db "Code:",0
932 msg_xram: db "Xram:",0
933
934 ;---------------------------------------------------------;
935
936
937 xdump:
938            MOV.B   R1L,#16          ;number of lines to print
939            CALL    newline
940            CALL    newline
941 xdump1: 
942         push    r6
943         mov     r6, #msg_xram
944         call    pstr
945         pop     r6
946         MOV.B   dpl,R3L
947            MOV.B   dph,R3H
948            CALL    phex16           ;tell 'em the memory location
949            MOV.B   R4L,#':'
950            CALL    cout
951            CALL    space
952            MOV.B   R1H,#16          ;r3 counts # of bytes to print
953            MOV.B   dpl,R3L
954            MOV.B   dph,R3H
955 xdump2:    MOVS    R4L,#0
956            MOVX           r4l,[r6]
957            ADDS.W  R6,#1
958            CALL    phex             ;print each byte in hex
959            CALL    space
960            DJNZ.B  R1H,xdump2
961            CALL    space            ;print a couple extra space
962            CALL    space
963            MOV.B   R1H,#16
964            MOV.B   dpl,R3L
965            MOV.B   dph,R3H
966 xdump3:    MOVS    R4L,#0
967            MOVX           r4l,[r6]
968            ADDS.W  R6,#1
969            AND.B   R4L,#01111111Q   ;avoid unprintable characters
970            CLR     carry
971            SUBB.B  R4L,#20h
972            BCC     xdump4            ;avoid control characters
973            MOV.B   R4L,#(' ' - 20h)
974 xdump4:    ADD.B   R4L,#20h
975            CALL    cout
976            DJNZ.B  R1H,xdump3
977            CALL    newline
978            MOV.B   R3L,dpl
979            MOV.B   R3H,dph
980            CALL    esc
981            BCS     xdump5
982            DJNZ.B  R1L,xdump1        ;loop back up to print next line
983 xdump5:    CALL    newline
984            RET
985
986
987
988
989 ;---------------------------------------------------------;
990
991 nloc:
992            MOV.W   R6,#prompt6
993            CALL    pcstr
994            CALL    ghex16
995            BCS     nloc2
996            JB      flag0,nloc2
997            MOV.B   R3L,dpl
998            MOV.B   R3H,dph
999            CALL    newline
1000            CALL    newline
1001            RET
1002 nloc2:     MOV.W   R6,#abort
1003            CALL    pcstr
1004            CALL    newline
1005            RET
1006
1007 ;---------------------------------------------------------;
1008
1009
1010 edit:      ;edit external ram...
1011            MOV.W   R6,#edits1
1012            CALL    pcstr
1013            MOV.B   dpl,R3L
1014            MOV.B   dph,R3H
1015 edit1:     CALL    phex16
1016            MOV.B   R4L,#':'
1017            CALL    cout
1018            CALL    space
1019            MOV.B   R4L,#'('
1020            CALL    cout
1021            MOV.B   R3L,dpl
1022            MOV.B   R3H,dph
1023            MOVS    R4L,#0
1024            MOVC.B  A,[A+dptr]
1025            CALL    phex
1026            MOV.W   R6,#prompt10
1027            CALL    pcstr
1028            CALL    ghex
1029            JB      flag0,edit2
1030            BCS     edit2
1031            MOV.B   dpl,R3L
1032            MOV.B   dph,R3H
1033            MOVX.B  [R6],R4L
1034            CALL    newline
1035            ADDS.W  R6,#1
1036            MOV.B   R3L,dpl
1037            MOV.B   R3H,dph
1038            JMP     edit1
1039 edit2:     MOV.W   R6,#edits2
1040            CALL    pcstr
1041            RET
1042
1043 ;---------------------------------------------------------;
1044
1045 dir:
1046            MOV.W   R6,#prompt9
1047            CALL    pcstr
1048            MOV.B   R0L,#21
1049 dir0a:     CALL    space
1050            DJNZ.B  R0L,dir0a
1051            MOV.W   R6,#prompt9b
1052            CALL    pcstr
1053
1054            MOV.B   dph,#high bmem
1055 dir1:      CALL    find             ;find the next program in memory
1056            BCS     dir2
1057 dir_end:   CALL    newline          ;we're done if no more found
1058            RET
1059 dir2:
1060            CALL    space
1061            CALL    space
1062            MOV.B   dpl,#32          ;print its name
1063            CALL    pstr
1064            MOV.B   dpl,#32          ;how long is the name
1065            CALL    lenstr
1066            MOV.B   R4L,#33
1067            CLR     carry
1068            SUBB.B  R4L,R0L
1069            MOV.B   R0L,R4L
1070            MOV.B   R4L,#' '         ;print the right # of spaces
1071 dir3:      CALL    cout
1072            DJNZ.B  R0L,dir3
1073            MOV.B   dpl,#0
1074            CALL    phex16           ;print the memory location
1075            MOV.B   R0L,#6
1076            MOV.B   R4L,#' '
1077 dir4:      CALL    cout
1078            DJNZ.B  R0L,dir4
1079            MOV.B   dpl,#4           ;now figure out what type it is
1080            MOVS    R4L,#0
1081            MOVC.B  A,[A+dptr]
1082            MOV.B   R1L,dph          ;save this, we're inside a search
1083
1084 dir5:      CJNE.B  R4L,#254,dir5b
1085            MOV.W   R6,#type1        ;it's an external command
1086            BR      dir7
1087 dir5b:     CJNE.B  R4L,#255,dir5c
1088            MOV.W   R6,#type1a       ;it's some system thing
1089            BR      dir7
1090 dir5c:     CJNE.B  R4L,#253,dir5d
1091            MOV.W   R6,#type1b       ;it's a startup routine
1092            BR      dir7
1093 dir5d:     CJNE.B  R4L,#35,dir5e
1094            MOV.W   R6,#type2        ;it's an ordinary program
1095            BR      dir7
1096 dir5e:     CJNE.B  R4L,#143,dir5f
1097            MOV.W   R6,#type3        ;it's a background task
1098            BR      dir7
1099 dir5f:     CJNE.B  R4L,#69,dir5g
1100            MOV.W   R6,#type4        ;it's a data file
1101            BR      dir7
1102 dir5g:
1103 dir6:      MOV.W   R6,#type5        ;who knows what the hell it is
1104
1105 dir7:      CALL    pcstr          ;print out the type
1106            MOV.B   dph,R1L          ;go back and find the next one
1107            CALL    newline
1108            CJNE.B  dph,#high emem, dir8     ;did we just print the last one?
1109            JMP     dir_end
1110 dir8:      ADDS.B  dph,#1
1111            JMP     dir1
1112
1113
1114 ;   type1=Ext Command
1115 ;  type1a=Misc System Thing
1116 ;  type1b=Power-Up Code
1117 ;   type2=Program
1118 ;   type3=Background Task
1119 ;   type4=Data File
1120 ;   type5=???????
1121
1122 ;---------------------------------------------------------;
1123
1124
1125 run:
1126            CALL    newline
1127            CALL    newline
1128         jmp     0xF000
1129
1130
1131 ;---------------------------------------------------------;
1132
1133 help:
1134            MOV.W   R6,#help1txt
1135            CALL    pcstr
1136            MOV.B   R2L,#help_key
1137            MOV.W   R6,#help_cmd
1138            CALL    help2
1139            MOV.B   R2L,#dir_key
1140            MOV.W   R6,#dir_cmd
1141            CALL    help2
1142            MOV.B   R2L,#run_key
1143            MOV.W   R6,#run_cmd
1144            CALL    help2
1145            MOV.B   R2L,#dnld_key
1146            MOV.W   R6,#dnld_cmd
1147            CALL    help2
1148            MOV.B   R2L,#upld_key
1149            MOV.W   R6,#upld_cmd
1150            CALL    help2
1151            MOV.B   R2L,#nloc_key
1152            MOV.W   R6,#nloc_cmd
1153            CALL    help2
1154            MOV.B   R2L,#jump_key
1155            MOV.W   R6,#jump_cmd
1156            CALL    help2
1157            MOV.B   R2L,#dump_key
1158            MOV.W   R6,#dump_cmd
1159            CALL    help2
1160            MOV.B   R2L,#xdump_key
1161            MOV.W   R6,#xdump_cmd
1162            CALL    help2
1163            MOV.B   R2L,#intm_key
1164            MOV.W   R6,#intm_cmd
1165            CALL    help2
1166            MOV.B   R2L,#edit_key
1167            MOV.W   R6,#edit_cmd
1168            CALL    help2
1169            MOV.B   R2L,#clrm_key
1170            MOV.W   R6,#clrm_cmd
1171            CALL    help2
1172            MOV.W   R6,#help2txt
1173            CALL    pcstr
1174            MOV.W   R6,#bmem
1175 help3:     CALL    find
1176            BCC     help4
1177            MOV.B   dpl,#4
1178            MOVS    R4L,#0
1179            MOVC.B  A,[A+dptr]
1180            CJNE.B  R4L,#254,help3a  ;only FE is an ext command
1181            CALL    space
1182            CALL    space
1183            ADDS.B  dpl,#1
1184            MOVS    R4L,#0
1185            MOVC.B  A,[A+dptr]
1186            CALL    cout
1187            CALL    dash
1188            CALL    space
1189            MOV.B   dpl,#32
1190            CALL    pstr
1191            CALL    newline
1192 help3a:    ADDS.B  dph,#1
1193            BR      help3
1194 help4:
1195            CALL    newline
1196            RET
1197
1198 help2:                          ;print 11 standard lines
1199            CALL    space            ;given key in R4 and name in dptr
1200            CALL    space
1201            MOV.B   R4L,R2L
1202            CALL    cout
1203            CALL    dash
1204            CALL    space
1205            CALL    pcstr
1206            CALL    newline
1207            RET
1208
1209 ;---------------------------------------------------------;
1210
1211 upld:
1212
1213            CALL    get_mem
1214         ;assume we've got the beginning address in r3/r2
1215         ;and the final address in r5/r4 (r4=lsb)...
1216
1217         ;print out what we'll be doing
1218            MOV.W   R6,#uplds3
1219            CALL    pcstr
1220            MOV.B   R4L,R1H
1221            CALL    phex
1222            MOV.B   R4L,R1L
1223            CALL    phex
1224            MOV.W   R6,#uplds4
1225            CALL    pcstr
1226            MOV.B   R4L,R2H
1227            CALL    phex
1228            MOV.B   R4L,R2L
1229            CALL    phex
1230            CALL    newline
1231
1232         ;need to adjust end location by 1...
1233            MOV.B   dph,R2H
1234            MOV.B   dpl,R2L
1235            ADDS.W  R6,#1
1236            MOV.B   R2L,dpl
1237            MOV.B   R2H,dph
1238
1239            MOV.W   R6,#prompt7
1240            CALL    pcstr
1241            CALL    cin
1242            CJNE.B  R4L,#27,upld2e
1243            JMP     abort_it
1244 upld2e:    CALL    newline
1245            MOV.B   dpl,R1L
1246            MOV.B   dph,R1H
1247
1248 upld3:     MOV.B   R4L,R2L          ;how many more bytes to output??
1249            CLR     carry
1250            SUBB.B  R4L,dpl
1251            MOV.B   R1L,R4L
1252            MOV.B   R4L,R2H
1253            SUBB.B  R4L,dph
1254            JNZ     upld4            ;if >256 left, then do next 16
1255            MOV.B   R4L,R1L
1256            JZ      upld7            ;if we're all done
1257            AND.B   R4L,#11110000Q
1258            JNZ     upld4            ;if >= 16 left, then do next 16
1259            BR      upld5            ;otherwise just finish it off
1260 upld4:     MOV.B   R1L,#16
1261 upld5:     MOV.B   R4L,#':'         ;begin the line
1262            CALL    cout
1263            MOV.B   R4L,R1L
1264            CALL    phex             ;output # of data bytes
1265            CALL    phex16           ;output memory location
1266            MOV.B   R4L,dph
1267            ADD.B   R4L,dpl
1268            ADD.B   R4L,R1L
1269            MOV.B   R1H,R4L          ;r3 will become checksum
1270            MOVS    R4L,#0
1271            CALL    phex             ;output 00 code for data
1272 upld6:     MOVS    R4L,#0
1273            MOVC.B  A,[A+dptr]
1274            CALL    phex             ;output each byte
1275            ADD.B   R4L,R1H
1276            MOV.B   R1H,R4L
1277            ADDS.W  R6,#1
1278            DJNZ.B  R1L,upld6        ;do however many bytes we need
1279            MOV.B   R4L,R1H
1280            CPL.B   R4L
1281            ADDS.B  R4L,#1
1282            CALL    phex             ;and finally the checksum
1283            CALL    newline
1284            CALL    esc
1285            BCC     upld3            ;keep working if no esc pressed
1286            BR      abort_it
1287 upld7:     MOV.B   R4L,#':'
1288            CALL    cout
1289            MOVS    R4L,#0
1290            CALL    phex
1291            CALL    phex
1292            CALL    phex
1293            ADDS.B  R4L,#1
1294            CALL    phex
1295            MOV.B   R4L,#255
1296            CALL    phex
1297 upld8:     CALL    newline
1298            CALL    newline
1299            RET
1300
1301
1302 ;---------------------------------------------------------;
1303
1304 get_mem:     ;this thing gets the begin and end locations for
1305              ;a few commands.  If an esc or enter w/ no input,
1306              ;it pops it's own return and returns to the menu
1307              ;(nasty programming, but we need tight code for 4k rom)
1308            CALL    newline
1309            CALL    newline
1310            MOV.W   R6,#beg_str
1311            CALL    pcstr
1312            CALL    ghex16
1313            BCS     pop_it
1314            JB      flag0,pop_it
1315            PUSH.B  dph
1316            PUSH.B  dpl
1317            CALL    newline
1318            MOV.W   R6,#end_str
1319            CALL    pcstr
1320            CALL    ghex16
1321            MOV.B   R2H,dph
1322            MOV.B   R2L,dpl
1323            POP.B   acc
1324            MOV.B   R1L,R4L
1325            POP.B   acc
1326            MOV.B   R1H,R4L
1327            BCS     pop_it
1328            JB      flag0,pop_it
1329            CALL    newline
1330            RET
1331
1332 pop_it:    POP.B   acc
1333            POP.B   acc
1334 abort_it:
1335            CALL    newline
1336            MOV.W   R6,#abort
1337            CALL    pcstr
1338            CALL    newline
1339            RET
1340
1341 clrm:
1342            CALL    get_mem
1343            MOV.W   R6,#sure
1344            CALL    pcstr
1345            CALL    cin
1346            CALL    upper
1347            CJNE.B  R4L,#'Y',abort_it
1348            CALL    newline
1349            CALL    newline
1350      ;now we actually do it
1351
1352 clrm2:     MOV.B   dph,R1H
1353            MOV.B   dpl,R1L
1354 clrm3:     MOVS    R4L,#0
1355            CALL    smart_wr
1356                 cmp.w   r6, r2
1357                 bne             clrm4
1358            RET
1359 clrm4:     ADDS.W  R6,#1
1360            BR      clrm3
1361
1362
1363
1364 ;---------------------------------------------------------;
1365
1366 intm:      CALL    newline
1367            MOVs.w   r5,#0
1368 intm2:     CALL    newline
1369            CJNE.w  r5, #512, intm3
1370            CALL    newline
1371            RET
1372 intm3:  mov.b   r4l,r5h
1373         call    phex   
1374         MOV.B   R4L,R5L
1375            CALL    phex
1376            MOV.B   R4L,#':'
1377            CALL    cout
1378 intm4:     CALL    space
1379            MOV.B   R4L,[r5+]
1380            CALL    phex
1381            MOV.B   R4L,R5L
1382            AND.B   R4L,#00001111Q
1383            JNZ     intm4
1384            BR      intm2
1385
1386
1387
1388 ;---------------------------------------------------------;
1389 ;                                                         ;
1390 ;   Subroutines for memory managment and non-serial I/O   ;
1391 ;                                                         ;
1392 ;---------------------------------------------------------;
1393
1394
1395 ;finds the next header in the external memory.
1396 ;  Input DPTR=point to start search (only MSB used)
1397 ;  Output DPTR=location of next module
1398 ;    C=set if a header found, C=clear if no more headers
1399 find:      MOV.B   dpl,#0
1400            MOVS    R4L,#0
1401            MOVC.B  A,[A+dptr]
1402            CJNE.B  R4L,#0xA5,find3
1403            ADDS.W  R6,#1
1404            MOVS    R4L,#0
1405            MOVC.B  A,[A+dptr]
1406            CJNE.B  R4L,#0xE5,find3
1407            ADDS.W  R6,#1
1408            MOVS    R4L,#0
1409            MOVC.B  A,[A+dptr]
1410            CJNE.B  R4L,#0xE0,find3
1411            ADDS.W  R6,#1
1412            MOVS    R4L,#0
1413            MOVC.B  A,[A+dptr]
1414            CJNE.B  R4L,#0xA5,find3
1415            MOV.B   dpl,#0           ;found one here!
1416            SETB    carry
1417            RET
1418 find3:
1419            CJNE.B  dph, #high emem, find4    ;did we just check the end
1420            CLR     carry
1421            RET
1422 find4:     ADDS.B  dph,#1           ;keep on searching
1423            BR      find
1424
1425
1426
1427
1428 ;Write to ordinary RAM.  Carry bit will indicate
1429 ;if the value was successfully written, C=1 if not written.
1430
1431
1432 smart_wr:
1433            PUSH.B  acc
1434            PUSH.B  R4H
1435            MOV.B   R4H,R4L
1436 wr_ram:    MOV.B   R4L,R4H
1437            MOVX.B  [R6],R4L         ;write the value to memory
1438            MOVS    R4L,#0
1439            MOVC.B  A,[A+dptr]       ;read it back from code memory
1440            CLR     carry
1441            SUBB.B  R4L,R4H
1442            JZ      smwrok
1443            MOVX.B  R4L,[R6]         ;read it back from data memory
1444            CLR     carry
1445            SUBB.B  R4L,R4H
1446            JZ      smwrok
1447 smwrbad:   SETB    carry
1448            BR      smwrxit
1449 smwrok:    CLR     carry
1450 smwrxit:   POP.B   R4H
1451            POP.B   acc
1452            RET
1453
1454
1455
1456 ;---------------------------------------------------------;
1457 ;                                                         ;
1458 ;       Power-On initialization code and such...          ;
1459 ;                                                         ;
1460 ;---------------------------------------------------------;
1461
1462 ;first the hardware has to get initialized.
1463
1464 poweron:
1465         mov.w   r7, #stack
1466         mov.b   wdcon, #0       ;shut off watchdog
1467         mov.b   wfeed1, #$a5
1468         mov.b   wfeed2, #$5a
1469
1470         ;or.b   p1cfga, #$C0            ;for testing
1471         ;or.b   p1cfgb, #$C0            ;for testing
1472
1473         ;clr            p1.7            ;for testing
1474
1475         ;no automatic baud rate detection anymore
1476 autobaud:
1477            MOV.B   tcon,#0
1478            MOV.B   R4L,#baud_const
1479            MOV.B   tl1,R4L
1480            MOV.B   rtl1,R4L
1481            MOV.B   tmod,#$22       ;set timer #1 for 8 bit auto-reload
1482            MOV.B   s0con,#$52
1483            SETB    tr1              ;start the baud rate timer
1484            MOV.w   r5, #2000
1485 ab_loop1:  DJNZ.w  r5, ab_loop1
1486
1487         ;clr            p1.6            ;for testing
1488
1489
1490 welcome:
1491            MOV.B   R0L,#24
1492 welcm2:    CALL    newline
1493            DJNZ.B  R0L,welcm2
1494
1495         ;setb   p1.7            ;for testing
1496
1497            MOV.B   R0L,#15
1498            MOV.B   R4L,#' '
1499 welcm4:    CALL    cout
1500            DJNZ.B  R0L,welcm4
1501            MOV.W   R6,#logon1
1502            CALL    pcstr
1503            MOV.W   R6,#logon2
1504            CALL    pcstr
1505            ;CALL    dir              ;skip dir for now
1506                 mov.w   r3, #pgm
1507            JMP     menu
1508
1509
1510
1511
1512
1513
1514 ;---------------------------------------------------------;
1515 ;                                                         ;
1516 ;     More subroutines, but less frequent used            ;
1517 ;                                                         ;
1518 ;---------------------------------------------------------;
1519
1520
1521
1522
1523
1524 pint8u: ;prints the unsigned 8 bit value in Acc in base 10
1525            PUSH.B  R4H
1526            PUSH.B  acc
1527            BR      pint8b
1528
1529 pint8:  ;prints the signed 8 bit value in Acc in base 10
1530            PUSH.B  R4H
1531            PUSH.B  acc
1532            JNB     R4L.7,pint8b
1533            MOV.B   R4L,#'-'
1534            CALL    cout
1535            POP.B   acc
1536            PUSH.B  acc
1537            CPL.B   R4L
1538            ADD.B   R4L,#1
1539 pint8b:    MOV.B   R4H,#100
1540            DIVU.B R4L,R4H
1541            SETB    flag0
1542            JZ      pint8c
1543            CLR     flag0
1544            ADD.B   R4L,#'0'
1545            CALL    cout
1546 pint8c:    MOV.B   R4L,R4H
1547            MOV.B   R4H,#10
1548            DIVU.B R4L,R4H
1549            JNB     flag0,pint8d
1550            JZ      pint8e
1551 pint8d:    ADD.B   R4L,#'0'
1552            CALL    cout
1553 pint8e:    MOV.B   R4L,R4H
1554            ADD.B   R4L,#'0'
1555            CALL    cout
1556            POP.B   acc
1557            POP.B   R4H
1558            RET
1559
1560
1561
1562         ;print 16 bit unsigned integer in DPTR (r6), using base 10.
1563 pint16u:  
1564                         push.w  r2, r3, r4
1565            CLR     flag0
1566 pint16a:   ;ten-thousands digit
1567                         mov.w   r2, r6
1568                         movs.w  r3, #0
1569                         div.d   r2, #10000
1570                         xch             r2, r3
1571                         mov.b   r4l, r3l
1572             JZ      pint16b
1573            ADD.B   R4L,#'0'
1574            CALL    cout
1575            SETB    flag0
1576 pint16b:   ;thousands digit
1577                         movs.w  r3, #0
1578                         div.d   r2, #1000
1579                         xch             r2, r3
1580                         mov.b   r4l, r3l
1581            JNZ     pint16c
1582            JNB     flag0,pint16d
1583 pint16c:   ADD.B   R4L,#'0'
1584            CALL    cout
1585            SETB    flag0
1586 pint16d:   ;hundreds digit
1587                         div.w   r2, #100
1588                         xch             r2h, r2l
1589                         mov.b   r4l, r2h
1590            JNZ     pint16e
1591            JNB     flag0,pint16f
1592 pint16e:   ADD.B   R4L,#'0'
1593            CALL    cout
1594            SETB    flag0
1595 pint16f:    ;tens digit
1596            DIVU.B R2L, #10
1597                         mov.b   r4l, r2l
1598            JNZ     pint16g
1599            JNB     flag0,pint16h
1600 pint16g:   ADD.B   R4L,#'0'
1601            CALL    cout
1602 pint16h:  ;ones digit
1603                    MOV.B   R4L,R2h          ;and finally the ones digit
1604            ADD.B   R4L,#'0'
1605            CALL    cout
1606            pop.w        r2, r3, r4
1607            RET
1608
1609
1610
1611 upper:  ;converts the ascii code in Acc to uppercase, if it is lowercase
1612            PUSH.B  acc
1613            CLR     carry
1614            SUBB.B  R4L,#97
1615            BCS     upper2           ;is it a lowercase character
1616            SUBB.B  R4L,#26
1617            BCC     upper2
1618            POP.B   acc
1619            ADD.B   R4L,#224         ;convert to uppercase
1620            RET
1621 upper2:    POP.B   acc              ;don't change anything
1622            RET
1623
1624
1625 lenstr:    MOV.B   R0L,#0           ;returns length of a string in r0
1626            PUSH.B  acc
1627 lenstr1:   MOVS    R4L,#0
1628            MOVC.B  A,[A+dptr]
1629            JZ      lenstr2
1630            MOV     C,R4L.7
1631            ADDS.B  R0L,#1
1632            BCS     lenstr2
1633            ADDS.W  R6,#1
1634            BR      lenstr1
1635 lenstr2:   POP.B   acc
1636            RET
1637
1638
1639 ;pcstr prints the compressed strings.  A dictionary of 128 words is
1640 ;stored in 4 bit packed binary format.  When pcstr finds a byte in
1641 ;a string with the high bit set, it prints the word from the dictionary.
1642 ;A few bytes have special functions and everything else prints as if
1643 ;it were an ordinary string.
1644
1645 ; special codes for pcstr:
1646 ;    0 = end of string
1647 ;   13 = CR/LF
1648 ;   14 = CR/LF and end of string
1649 ;   31 = next word code should be capitalized
1650
1651 pcstr:          push    r0, r2, r4
1652            SETB    flag1
1653            SETB    flag0
1654 pcstr1:    MOVS    R4L,#0
1655            MOVC.B  A,[A+dptr]
1656            ADDS.W  R6,#1
1657            JZ      pcstr2
1658            JB      R4L.7,decomp
1659            AND.B   R4L,#0x7F
1660 pcstrs1:   CJNE.B  R4L,#13,pcstrs2
1661            CALL    newline
1662            SETB    flag1
1663            BR      pcstr1
1664 pcstrs2:   CJNE.B  R4L,#31,pcstrs3
1665            CLR     flag0
1666            BR      pcstr1
1667 pcstrs3:   CJNE.B  R4L,#14,pcstrs4
1668            CALL    newline
1669            BR      pcstr2
1670 pcstrs4:
1671            CLR     flag1
1672            CALL    cout
1673            BR      pcstr1
1674 pcstr2:    pop          r0, r2, r4
1675            RET
1676
1677 ;dcomp actually takes care of printing a word from the dictionary
1678
1679 ; dptr = position in packed words table
1680 ; r4=0 if next nibble is low, r4=255 if next nibble is high
1681
1682 decomp:    AND.B   R4L,#0x7F
1683            MOV.B   R0L,R4L          ;r0 counts which word
1684            JB      flag1,decomp1    ;avoid leading space if first word
1685            CALL    space
1686 decomp1:   CLR     flag1
1687                         push    r6
1688            MOV.W   R6,#words
1689            MOV.B   R2L,#0
1690            MOV.B   R4L,R0L
1691            JZ      dcomp3
1692         ;here we must seek past all the words in the table
1693         ;that come before the one we're supposed to print
1694            MOV.B   R0H,R4L
1695 dcomp2:    CALL    get_next_nibble
1696            JNZ     dcomp2
1697         ;when we get here, a word has been skipped... keep doing
1698         ;this until we're pointing to the correct one
1699            DJNZ.B  R0H,dcomp2
1700 dcomp3: ;now we're pointing to the correct word, so all we have
1701         ;to do is print it out
1702            CALL    get_next_nibble
1703            JZ      dcomp_end
1704            CJNE.B  R4L,#15,dcomp4
1705         ;the character is one of the 12 least commonly used
1706            CALL    get_next_nibble
1707            ADDS.B  R4L,#1
1708            MOVC.B  A,[A+pc]
1709            BR      dcomp5
1710            DB      "hfwgybxvkqjz"
1711 dcomp4: ;the character is one of the 14 most commonly used
1712            ADDS.B  R4L,#1
1713            MOVC.B  A,[A+pc]
1714            BR      dcomp5
1715            DB      "etarnisolumpdc"
1716 dcomp5: ;decide if it should be uppercase or lowercase
1717            MOV     C,flag0
1718            MOV     R4L.5,C
1719            SETB    flag0
1720            CJNE.B  R0L,#20,dcomp6
1721            CLR     R4L.5
1722 dcomp6:    CJNE.B  R0L,#12,dcomp7
1723            CLR     R4L.5
1724 dcomp7:    CALL    cout
1725            BR      dcomp3
1726 dcomp_end:
1727                         pop             r6
1728            JMP     pcstr1
1729
1730 get_next_nibble:        ;...and update dptr and r4, of course
1731            MOVS    R4L,#0
1732            MOVC.B  A,[A+dptr]
1733            CJNE.B  R2L,#0,gnn2
1734            MOV.B   R2L,#255
1735            AND.B   R4L,#00001111Q
1736            RET
1737 gnn2:      MOV.B   R2L,#0
1738            ADDS.W  R6,#1
1739            RL.B R4L,#4
1740            AND.B   R4L,#00001111Q
1741            RET
1742
1743
1744 ;---------------------------------------------------------;
1745 ;                                                         ;
1746 ;        Here begins the data tables and strings          ;
1747 ;                                                         ;
1748 ;---------------------------------------------------------;
1749
1750 ;this is the dictionary of 128 words used by pcstr.
1751
1752 words:
1753            DB      0x82,0x90,0xE8,0x23,0x86,0x05,0x4C,0xF8
1754            DB      0x44,0xB3,0xB0,0xB1,0x48,0x5F,0xF0,0x11
1755            DB      0x7F,0xA0,0x15,0x7F,0x1C,0x2E,0xD1,0x40
1756            DB      0x5A,0x50,0xF1,0x03,0xBF,0xBA,0x0C,0x2F
1757            DB      0x96,0x01,0x8D,0x3F,0x95,0x38,0x0D,0x6F
1758            DB      0x5F,0x12,0x07,0x71,0x0E,0x56,0x2F,0x48
1759            DB      0x3B,0x62,0x58,0x20,0x1F,0x76,0x70,0x32
1760            DB      0x24,0x40,0xB8,0x40,0xE1,0x61,0x8F,0x01
1761            DB      0x34,0x0B,0xCA,0x89,0xD3,0xC0,0xA3,0xB9
1762            DB      0x58,0x80,0x04,0xF8,0x02,0x85,0x60,0x25
1763            DB      0x91,0xF0,0x92,0x73,0x1F,0x10,0x7F,0x12
1764            DB      0x54,0x93,0x10,0x44,0x48,0x07,0xD1,0x26
1765            DB      0x56,0x4F,0xD0,0xF6,0x64,0x72,0xE0,0xB8
1766            DB      0x3B,0xD5,0xF0,0x16,0x4F,0x56,0x30,0x6F
1767            DB      0x48,0x02,0x5F,0xA8,0x20,0x1F,0x01,0x76
1768            DB      0x30,0xD5,0x60,0x25,0x41,0xA4,0x2C,0x60
1769            DB      0x05,0x6F,0x01,0x3F,0x26,0x1F,0x30,0x07
1770            DB      0x8E,0x1D,0xF0,0x63,0x99,0xF0,0x42,0xB8
1771            DB      0x20,0x1F,0x23,0x30,0x02,0x7A,0xD1,0x60
1772            DB      0x2F,0xF0,0xF6,0x05,0x8F,0x93,0x1A,0x50
1773            DB      0x28,0xF0,0x82,0x04,0x6F,0xA3,0x0D,0x3F
1774            DB      0x1F,0x51,0x40,0x23,0x01,0x3E,0x05,0x43
1775            DB      0x01,0x7A,0x01,0x17,0x64,0x93,0x30,0x2A
1776            DB      0x08,0x8C,0x24,0x30,0x99,0xB0,0xF3,0x19
1777            DB      0x60,0x25,0x41,0x35,0x09,0x8E,0xCB,0x19
1778            DB      0x12,0x30,0x05,0x1F,0x31,0x1D,0x04,0x14
1779            DB      0x4F,0x76,0x12,0x04,0xAB,0x27,0x90,0x56
1780            DB      0x01,0x2F,0xA8,0xD5,0xF0,0xAA,0x26,0x20
1781            DB      0x5F,0x1C,0xF0,0xF3,0x61,0xFE,0x01,0x41
1782            DB      0x73,0x01,0x27,0xC1,0xC0,0x84,0x8F,0xD6
1783            DB      0x01,0x87,0x70,0x56,0x4F,0x19,0x70,0x1F
1784            DB      0xA8,0xD9,0x90,0x76,0x02,0x17,0x43,0xFE
1785            DB      0x01,0xC1,0x84,0x0B,0x15,0x7F,0x02,0x8B
1786            DB      0x14,0x30,0x8F,0x63,0x39,0x6F,0x19,0xF0
1787            DB      0x11,0xC9,0x10,0x6D,0x02,0x3F,0x91,0x09
1788            DB      0x7A,0x41,0xD0,0xBA,0x0C,0x1D,0x39,0x5F
1789            DB      0x07,0xF2,0x11,0x17,0x20,0x41,0x6B,0x35
1790            DB      0x09,0xF7,0x75,0x12,0x0B,0xA7,0xCC,0x48
1791            DB      0x02,0x3F,0x64,0x12,0xA0,0x0C,0x27,0xE3
1792            DB      0x9F,0xC0,0x14,0x77,0x70,0x11,0x40,0x71
1793            DB      0x21,0xC0,0x68,0x25,0x41,0xF0,0x62,0x7F
1794            DB      0xD1,0xD0,0x21,0xE1,0x62,0x58,0xB0,0xF3
1795            DB      0x05,0x1F,0x73,0x30,0x77,0xB1,0x6F,0x19
1796            DB      0xE0,0x19,0x43,0xE0,0x58,0x2F,0xF6,0xA4
1797            DB      0x14,0xD0,0x23,0x03,0xFE,0x31,0xF5,0x14
1798            DB      0x30,0x99,0xF8,0x03,0x3F,0x64,0x22,0x51
1799            DB      0x60,0x25,0x41,0x2F,0xE3,0x01,0x56,0x27
1800            DB      0x93,0x09,0xFE,0x11,0xFE,0x79,0xBA,0x60
1801            DB      0x75,0x42,0xEA,0x62,0x58,0xA0,0xE5,0x1F
1802            DB      0x53,0x4F,0xD1,0xC0,0xA3,0x09,0x42,0x53
1803            DB      0xF7,0x12,0x04,0x62,0x1B,0x30,0xF5,0x05
1804            DB      0xF7,0x69,0x0C,0x35,0x1B,0x70,0x82,0x2F
1805            DB      0x2F,0x14,0x4F,0x51,0xC0,0x64,0x25,0x00
1806
1807 ;STR
1808
1809 logon1:    DB      "Welcome",128,148,"2 (beta7,XA) by",31,248,31,254,13,14
1810 logon2:    DB      32,32,"See",148,"2.DOC,",148,"2.EQU",164
1811            DB      148,"2.HDR",180,213,141,".",14
1812 abort:     DB      " ",31,158,31,160,"!",14
1813 prompt1:   DB      148,"2 (beta7,XA) Loc:",0
1814 prompt2:   DB      ">",160
1815 prompt3:   DB      134,202,130,'(',0
1816 prompt4:   DB      "),",149,140,128,200,": ",0
1817 prompt5:   DB      31,151,130,195,"s",199,166,131,","
1818            DB      186," JUMP",128,134,161,"r",130,13,14
1819 prompt6:   DB      13,13,31,135,131,129,": ",0
1820 prompt7:   DB      31,228,251," key: ",0
1821 prompt8:   DB      13,13,31,136,128,131,129," (",0
1822 prompt9:   DB      13,13,31,130,31,253,0
1823 prompt9b:  DB      31,129,32,32,32,32,32,31,201,14
1824 prompt10:  DB      ") ",31,135,31,178,": ",0
1825 beg_str:   DB      "First",31,129,": ",0
1826 end_str:   DB      "Last",31,129,":",32,32,0
1827 sure:      DB      31,185,161," sure?",0
1828 edits1:    DB      13,13,31,156,154,146,",",140,128,200,14
1829 edits2:    DB      "  ",31,156,193,",",142,129,247,13,14
1830 dnlds1:    DB      13,13,31,159," ascii",249,150,31,152,132,137
1831            DB      ",",149,140,128,160,13,14
1832 dnlds2:    DB      13,31,138,160,"ed",13,14
1833 dnlds3:    DB      13,31,138,193,"d",13,14
1834 dnlds4:    DB      "Summary:",14
1835 dnlds5:    DB      " ",198,"s",145,"d",14
1836 dnlds6a:   DB      " ",139,145,"d",14
1837 dnlds6b:   DB      " ",139," written",14
1838 dnlds7:    DB      31,155,":",14
1839 dnlds8:    DB      " ",139," unable",128," write",14
1840 dnlds9:    DB      32,32,"bad",245,"s",14
1841 dnlds10:   DB      " ",133,159,150,198,14
1842 dnlds11:   DB      " ",133,132,157,14
1843 dnlds12:   DB      " ",133," non",132,157,14
1844 dnlds13:   DB      31,151,155," detected",13,14
1845 runs1:     DB      13,134,"ning",130,":",13,14
1846 uplds3:    DB      13,13,"Sending",31,152,132,137,172,32,32,0
1847 uplds4:    DB      " ",128,32,32,0
1848 help1txt:  DB      13,13,"Standard",31,158,"s",14
1849 help2txt:  DB      31,218,31,244,"ed",31,158,"s",14
1850 type1:     DB      31,154,158,0
1851 type1a:    DB      31,223,0
1852 type1b:    DB      31,143,31,226,31,170,0
1853 type2:     DB      31,130,0
1854 type3:     DB      "Reserved",0
1855 type4:     DB      31,239,137,0
1856 type5:     DB      "???",0
1857 help_cmd:  DB      31,142,215,209,0
1858 help_cmd2: DB      31,215,0
1859 dir_cmd:   DB      31,209,130,"s",0
1860 run_cmd:   DB      31,134,130,0
1861 dnld_cmd:  DB      31,138,0
1862 upld_cmd:  DB      31,147,0
1863 nloc_cmd:  DB      31,135,129,0
1864 jump_cmd:  DB      31,136,128,131,129,0
1865 dump_cmd:  DB   31,132,219,154," code",131,0
1866 xdump_cmd: db   31,132,219,154," data",131,0
1867 intm_cmd:  DB      31,132,219,192,131,0
1868 edit_cmd:  DB      31,156,154,146,0
1869 clrm_cmd:  DB      31,237,131,0
1870 erfr_cmd:  DB      31,203,153,144,0
1871
1872
1873
1874
1875 ;this code attempts to switch from development mode to run mode
1876 ;on the xa_tiny (8-bit data bus) development board.
1877
1878         org     0x7000
1879
1880 es      sfr     442h
1881 pswh    sfr     401h
1882
1883         ; a bunch of nops, to hopefully flush the xa prefetch buffer
1884         nop
1885         nop
1886         nop
1887         nop
1888         nop
1889         nop
1890         nop
1891         nop
1892         nop
1893         nop
1894         nop
1895         nop
1896         nop
1897         nop
1898         nop
1899         nop
1900         nop
1901         nop
1902         nop
1903         nop
1904         nop
1905         nop
1906         nop
1907         nop
1908         nop
1909         nop
1910         nop
1911         nop
1912         nop
1913         nop
1914         nop
1915         nop
1916         nop
1917
1918         ;make a read from location 0x0EF000 to switch modes
1919         mov.b   es, #0x0E
1920         mov     r0, #0xF000
1921         setb    ssel.0
1922         mov.b   r4l, [r0]       ;make the mode switch
1923         mov.b   r4l, [r0]       ;make the mode switch
1924         mov.b   r4l, [r0]       ;make the mode switch
1925         mov.b   r4l, [r0]       ;make the mode switch
1926
1927         ;now read the start vector from location zero
1928         movs.b  es, #0
1929         movs    r0, #0
1930         movc    r1l, [r0+]      ;read psw value into r1
1931         movc    r1h, [r0+]
1932         movc    r2l, [r0+]      ;read start address into r2
1933         movc    r2h, [r0+]
1934
1935         movs.b  ssel, #0
1936         mov.b   pswl, r1l
1937         mov.b   pswh, r1h
1938         jmp     [r2]
1939
1940
1941