Imported Upstream version 2.3.1
[debian/as31] / examples / extra.asm
1 ; User installable disassembler and single-step run for paulmon2
2
3 ; Please email comments, suggestions, bugs to paul@pjrc.com
4
5 ; This code is in the public domain. It is distributed in
6 ; the hope that it will be useful, but without any warranty;
7 ; without even the implied warranty of merchantability or fitness
8 ; for a particular purpose.
9
10 ; For more information, please see
11
12 ; http://www.pjrc.com/tech/8051/pm2_docs/index.html
13
14 .equ    locat, 0x1000           ;location for these commands (usually 1000)
15 .equ    paulmon2, 0x0000        ;location where paulmon2 is at (usually 0000)
16
17 .equ    phex1, 0x2E+paulmon2
18 .equ    cout, 0x30+paulmon2             ;send acc to uart
19 .equ    phex, 0x34+paulmon2             ;print acc in hex
20 .equ    phex16, 0x36+paulmon2           ;print dptr in hex
21 .equ    pstr, 0x38+paulmon2             ;print string @dptr
22 .equ    ghex, 0x3A+paulmon2             ;get two-digit hex (acc)
23 .equ    ghex16, 0x3C+paulmon2           ;get four-digit hex (dptr)
24 .equ    upper, 0x40+paulmon2            ;convert acc to uppercase
25 .equ    newline, 0x48+paulmon2
26 .equ    pcstr, 0x45+paulmon2
27 .equ    pint, 0x50+paulmon2
28 .equ    smart_wr, 0x56+paulmon2
29 .equ    cin_filter, 0x62+paulmon2
30 .equ    asc2hex, 0x65+paulmon2
31
32
33 .equ    list_key, 'L'           ;list (disassemble)
34 .equ    step_key, 'S'           ;single step run
35 .equ    vtedit_key, 'E'           ;memory editor
36
37 ;for testing in ram
38 ;.equ    list_key, 'K'           ;list (disassemble)
39 ;.equ    step_key, 'W'           ;single step run
40 ;.equ    vtedit_key, 'E'           ;memory editor
41
42
43
44 ;location of two bytes used by single-step in internal ram which we
45 ;hope the user's program won't write over while it's running.  These
46 ;two bytes hold the address of the previous instruction, so we can
47 ;show the last executed instruction with the current value of the
48 ;registers, which is much more intuitive than displaying the next
49 ;instruction by grabbing the program counter from the stack as was
50 ;done in PAULMON1's single step.
51
52 .equ    lastpc, 0x7C            ;don't forget to update the docs below
53
54
55
56 ;DIS
57 ;---------------------------------------------------------;
58 ;                                                         ;
59 ;                      list command                       ;
60 ;                                                         ;
61 ;---------------------------------------------------------;
62
63
64 .org    locat
65 .db     0xA5,0xE5,0xE0,0xA5     ;signiture
66 .db     254,list_key,0,0                ;id (254=user installed command)
67 .db     0,0,0,0                 ;prompt code vector
68 .dB     0,0,0,0                 ;reserved
69 .db     0,0,0,0                 ;reserved
70 .db     0,0,0,0                 ;reserved
71 .db     0,0,0,0                 ;user defined
72 .db     255,255,255,255         ;length and checksum (255=unused)
73 .db     "List",0
74
75 newline_h:ljmp  newline
76
77 .org    locat+64                ;executable code begins here
78
79 ;       disassembler register usage
80 ;       r0 = temporary storage
81 ;       r1 = temporart storage
82 ;       r2 = first instruction byte
83 ;       r3 = second instruction byte
84 ;       r4 = third instruction byte
85 ;       r5 = line count
86 ;       r6 = program counter (lsb)
87 ;       r7 = program counter (msb)
88
89 list:   acall   newline_h
90         mov     r5, #20
91         clr     psw.1           ;use ordinary long format
92 list2:  acall   disasm
93         djnz    r5, list2
94         ajmp    newline_h
95
96 disasm:
97 ;print out the memory location and fetch the next three bytes
98         mov     a, r7
99         mov     dph, a
100         acall   phex_h
101         mov     a, r6
102         mov     dpl, a
103         acall   phex_h
104         clr     a
105         movc    a, @a+dptr
106         mov     r2, a
107         inc     dptr
108         clr     a
109         movc    a, @a+dptr
110         mov     r3, a
111         inc     dptr
112         clr     a
113         movc    a, @a+dptr
114         mov     r4, a
115         mov     a, r2
116         anl     a, #00001000b
117         jnz     lookup2
118
119 ;fetch constants for instructions not using R0-R7
120 lookup1:
121         mov     a, r2
122         rr      a
123         anl     a, #01111000b   ;grab upper 4 bits
124         mov     r0, a           ;keep in r0 for a moment
125         mov     a, r2
126         anl     a, #00000111b   ;get lower 3 bits
127         orl     a, r0           ;combine in upper 4
128         mov     dptr, #opot1    ;opot=operand offset table
129         movc    a, @a+dptr
130         sjmp    unpack
131
132 ;fetch constants for R0-R7 instructions
133 lookup2:
134         mov     a, r2
135         swap    a
136         anl     a, #00001111b
137         mov     dptr, #opot2
138         movc    a, @a+dptr
139
140 ;now we'll unpack the operand code (# bytes and addr mode)
141 unpack: anl     a, #00000011b
142         mov     r0, a
143
144 ;increment the r7/r6 pointer
145         add     a, r6
146         mov     r6, a
147         mov     a, r7
148         addc    a, #0
149         mov     r7, a
150
151 ;now print the bytes and spaces (r0 has # of bytes to print)
152 pbytes: mov     a, #':'
153         acall   cout_h
154         acall   space_h
155         jb      psw.1, pmnu             ;skip bytes if running single-step
156         mov     a, r2
157         acall   phex_h
158         acall   space_h
159         cjne    r0, #1, pbytes2
160         mov     r1, #11
161         sjmp    pbytes4
162 pbytes2:mov     a, r3
163         acall   phex_h
164         acall   space_h
165         cjne    r0, #2, pbytes3
166         mov     r1, #8
167         sjmp    pbytes4
168 pbytes3:mov     a, r4
169         acall   phex_h
170         mov     r1, #6
171 pbytes4:acall   space_h
172         djnz    r1, pbytes4
173
174
175 ;prints the mnunonic name and spaces
176 pmnu:   mov     a, r2
177         anl     a, #00001000b
178         jnz     pmnu_lookup2
179 pmnu_lookup1:
180         mov     dptr, #mnot1    ;mnot=mnunonic offset table
181         mov     a, r2
182         rr      a
183         anl     a, #01111000b   ;grab upper 4 bits
184         mov     r0, a           ;keep in r0 for a moment
185         mov     a, r2
186         anl     a, #00000111b   ;get lower 3 bits
187         orl     a, r0           ;combine in upper 4
188         movc    a, @a+dptr
189         mov     r1, a
190         sjmp    pmnu0
191 pmnu_lookup2:
192         mov     dptr, #mnot2    ;16 byte table for r0-r7 instructions
193         mov     a, r2
194         swap    a
195         anl     a, #00001111b
196         movc    a, @a+dptr
197         mov     r1, a
198 pmnu0:  mov     dptr, #mnu_tbl
199         mov     r0, #8
200         clr     c
201 pmnu1:  mov     a, #' '
202         jc      pmnu2
203         mov     a, r1
204         movc    a, @a+dptr
205         inc     r1
206         mov     c, acc.7
207         anl     a, #0x7F
208 pmnu2:  acall   cout_h
209         djnz    r0, pmnu1
210
211
212
213 ;print the operands
214
215         mov     a, #dasm2 & 255  ;(low)
216         push    acc
217         mov     a, #dasm2 >> 8   ;(high)
218         push    acc
219
220 am_lookup0:
221         mov     a, r2
222         anl     a, #00001000b
223         jnz     am_lookup2
224
225 ;fetch constants for instructions not using R0-R7
226 am_lookup1:
227         mov     a, r2
228         rr      a
229         anl     a, #01111000b   ;grab upper 4 bits
230         mov     r0, a           ;keep in r0 for a moment
231         mov     a, r2
232         anl     a, #00000111b   ;get lower 3 bits
233         orl     a, r0           ;combine in upper 4
234         mov     dptr, #opot1    ;opot=operand offset table
235         movc    a, @a+dptr
236         sjmp    am_unpack
237
238 ;fetch constants for R0-R7 instructions
239 am_lookup2:
240         mov     a, r2
241         swap    a
242         anl     a, #00001111b
243         mov     dptr, #opot2
244         movc    a, @a+dptr
245
246 am_unpack:
247         anl     a, #11111100b
248         rr      a
249         rr      a
250         dec     a
251
252         mov     dptr, #oprt      ;oprt=operand routine table
253         rl      a
254         add     a, dpl
255         mov     dpl, a
256         clr     a
257         addc    a, dph
258         mov     dph, a
259         clr     a
260         jmp     @a+dptr
261 dasm2:  
262         ajmp    newline_h
263
264
265 oprt:   ajmp   opcd1           ;addr11
266         ajmp   opcd2           ;A,Rn
267         ajmp   opcd3           ;A,direct
268         ajmp   opcd4           ;A,@Ri
269         ajmp   opcd5           ;A,#data
270         ajmp   opcd6           ;direct,A
271         ajmp   opcd7           ;direct,#data
272         ajmp   opcd8           ;C,bit
273         ajmp   opcd9           ;C,/bit
274         ajmp   opcd10          ;A,direct,rel
275         ajmp   opcd11          ;A,#data,rel
276         ajmp   opcd12          ;Rn,#data,rel
277         ajmp   opcd13          ;@Ri,#data,rel
278         ajmp   pa              ;A
279         ajmp   prc             ;C
280         ajmp   pbit            ;bit
281         ajmp   pdirect         ;direct
282         ajmp   p_reg_i         ;@Ri
283         ajmp   opcd19          ;AB
284         ajmp   opcd20          ;Rn,rel
285         ajmp   opcd21          ;direct,rel
286         ajmp   p_reg_n         ;Rn
287         ajmp   pdptr           ;DPTR
288         ajmp   opcd24          ;bit,rel
289         ajmp   prel            ;rel
290         ajmp   opcd26          ;@A+DPTR
291         ajmp   opcd27          ;addr16
292         ajmp   opcd28          ;Rn,A
293         ajmp   opcd29          ;Rn,direct
294         ajmp   opcd30          ;Rn,#data
295         ajmp   opcd31          ;direct,Rn
296         ajmp   opcd32          ;direct,direct
297         ajmp   opcd33          ;direct,@Ri
298         ajmp   opcd34          ;@Ri,A
299         ajmp   opcd35          ;@Ri,direct
300         ajmp   opcd36          ;@Ri,#data
301         ajmp   opcd37          ;bit,C
302         ajmp   opcd38          ;DPTR,#data16
303         ajmp   opcd39          ;A,@A+DPTR
304         ajmp   opcd40          ;A,@A+PC
305         ajmp   opcd41          ;A,@DPTR
306         ajmp   opcd42          ;@DPTR,A
307         ret                    ; <nothing>
308
309
310
311 opcd4:                      ;A,@Ri              done
312         acall   pac
313 p_reg_i:mov     a,#'@'
314         acall   cout_h
315         mov     a,#'R'
316         acall   cout_h
317         mov     a, r2
318         anl     a,#00000001b
319         ajmp    phex1_h
320
321 opcd3:                      ;A,direct           done
322         acall   pac
323 pdirect:
324         mov     a, r3
325         jb      acc.7,pdir1
326 pdir0:  mov     a, r3
327         ajmp    phex_h
328 pdir1:  mov     dptr,#sfrmnu
329 pdir2:  clr     a
330         movc    a,@a+dptr
331         inc     dptr
332         jz      pdir0
333         mov     r0,a
334         clr     c
335         subb    a, r3
336         jnz     pdir3
337 pstr_h:
338         ljmp    pstr
339
340 pdir3:  clr     a
341         movc    a,@a+dptr
342         inc     dptr
343         jnb     acc.7,pdir3
344         sjmp    pdir2
345
346                
347 opcd9:                      ;C,/bit             done
348         acall   prc
349         acall   pcomma
350         mov     a, #'/'
351         acall   cout_h
352 pbit: 
353         mov     a, r3
354         anl     a,#01111000b
355         rl      a
356         swap    a
357         mov     r0,a
358         mov     a, r3
359         anl     a,#10000000b
360         jz      pbit1
361         mov     dptr,#bitptr        ;it's a Special Function Reg.
362         mov     a,r0
363         movc    a,@a+dptr
364         mov     dptr,#bitmnu
365         addc    a,dpl
366         mov     dpl,a
367         jnc     pbit0
368         inc     dph
369 pbit0:  acall   pstr_h
370         sjmp    pbit2
371 pbit1:  mov     a,r0            ;it's between 20h and 2Fh
372         add     a,#20h
373         acall   phex_h
374 pbit2:  mov     a,#'.'
375         acall   cout_h
376         mov     a, r3
377         anl     a,#00000111b
378         ajmp    phex1_h
379
380
381 opcd10:                     ;A,direct,rel       done
382         acall   pac
383         acall   pdirect
384 opcd10a:acall   pcomma
385         mov     a, r4
386         mov     r3, a
387 prel:
388         mov     a, r3
389         add     a, r6
390         mov     dpl, a
391         mov     a, r3
392         jb      acc.7, prel2
393         clr     a
394         sjmp    prel3
395 prel2:  clr     a
396         cpl     a
397 prel3:  addc    a, r7
398         mov     dph, a
399         ljmp    phex16
400
401
402 pat:            ;prints the '@' symbol
403         mov     a,#'@'
404         ajmp    cout_h
405
406 pac:            ;print "A,"
407         acall   pa
408 pcomma:         ;prints a comma
409         mov     a,#','
410         acall   cout_h
411 pspace: mov     a, #' '
412         ajmp    cout_h
413
414 plb:            ;prints the '#' symbol
415         mov     a,#'#'
416         ajmp    cout_h
417
418
419 opcd6:                      ;direct,A           done
420         acall   pdirect
421         acall   pcomma
422 pa:             ;prints 'A'
423         mov     a,#'A'
424         ajmp    cout_h
425
426 opcd37:                     ;bit,C              done
427         acall   pbit
428         acall   pcomma
429 prc:             ;prints 'C'
430         mov     a,#'C'
431         ajmp    cout_h
432
433 opcd26:                     ;@A+DPTR            done
434         acall   pat
435         acall   pa
436         mov     a,#'+'
437         acall   cout_h
438 pdptr:          ;prints DPTR
439         mov     a, #'D'
440         acall   cout_h
441         mov     a, #'P'
442         acall   cout_h
443         mov     a, #'T'
444         acall   cout_h
445         mov     a, #'R'
446 cout_h:
447         ljmp    cout
448
449 opcd1:  mov     a, r7       ;addr11             done
450         anl     a, #11111000b
451         mov     r0, a
452         mov     a, r2
453         swap    a
454         rr      a
455         anl     a, #00000111b
456         orl     a, r0
457         acall   phex_h
458         mov     a, r3
459         ajmp    phex_h
460
461 opcd2:                      ;A,Rn               done
462         acall   pac
463 p_reg_n:mov     a,#'R'
464         acall   cout_h
465         mov     a, r2
466         anl     a,#00000111b
467 phex1_h:
468         ljmp    phex1
469
470
471
472 opcd5:                      ;A,#data            done
473         acall   pa
474 pdata:  acall   pcomma
475         acall   plb
476         mov     a, r3
477 phex_h:
478         ljmp    phex
479
480 opcd7:                      ;direct,#data       done
481         acall   pdirect
482         mov     a, r4
483         mov     r3, a
484         ajmp    pdata
485 opcd8:                      ;C,bit              done
486         acall   prc
487         acall   pcomma
488         ajmp    pbit
489
490 opcd11:                     ;A,#data,rel        done
491         acall   pa
492 opcd11a:acall   pcomma
493         acall   plb
494         mov     a, r3
495         acall   phex_h
496         ajmp    opcd10a
497 opcd12:                     ;Rn,#data,rel       done
498         acall   p_reg_n
499         ajmp    opcd11a
500 opcd13:                     ;@Ri,#data,rel      done
501         acall   p_reg_i
502         ajmp    opcd11a
503 opcd19:                     ;AB                 done
504         acall   pa
505         mov     a, #'B'
506         ajmp    cout_h
507 opcd20:                     ;Rn,rel             done
508         acall   p_reg_n
509         acall   pcomma
510         ajmp    prel
511 opcd21:                     ;direct,rel         done
512         acall   pdirect
513         ajmp    opcd10a
514 opcd24:                     ;bit,rel            done
515         acall   pbit
516         ajmp    opcd10a
517 opcd28:                     ;Rn,A               done
518         acall   p_reg_n
519         acall   pcomma
520         ajmp    pa
521 opcd29:                     ;Rn,direct          done
522         acall   p_reg_n
523         acall   pcomma          
524         ajmp    pdirect
525 opcd30:                     ;Rn,#data           done
526         acall   p_reg_n
527         ajmp    pdata
528 opcd31:                     ;direct,Rn          done
529         acall   pdirect
530         acall   pcomma
531         ajmp    p_reg_n
532 opcd32:                     ;direct,direct      done
533         mov     a, r3
534         push    acc
535         mov     a, r4
536         mov     r3, a
537         acall   pdirect
538         acall   pcomma
539         pop     acc
540         mov     r3, a
541         ajmp    pdirect
542 opcd33:                     ;direct,@Ri         done
543         acall   pdirect
544         acall   pcomma
545         ajmp    p_reg_i
546 opcd34:                     ;@Ri,A              done
547         acall   p_reg_i
548         acall   pcomma
549         ajmp    pa
550 opcd35:                     ;@Ri,direct         done
551         acall   p_reg_i
552         acall   pcomma
553         ajmp    pdirect
554 opcd36:                     ;@Ri,#data          done
555         acall   p_reg_i
556         ajmp    pdata
557 opcd38:                     ;DPTR,#data16       done
558         acall   pdptr
559         acall   pcomma
560         acall   plb
561 opcd27: mov     a, r3  ;addr16          done
562         acall   phex_h
563         mov     a, r4
564         ajmp    phex_h
565 opcd39:                     ;A,@A+DPTR          done
566         acall   pac
567         acall   pat
568         acall   pa
569         mov     a,#'+'
570         acall   cout_h
571         ajmp    pdptr
572 opcd40:                     ;A,@A+PC            done
573         acall   pac
574         acall   pat
575         acall   pa
576         mov     a,#'+'
577         acall   cout_h
578         mov     a,#'P'
579         acall   cout_h
580         ajmp    prc
581 opcd41:                     ;A,@DPTR            done
582         acall   pac
583         acall   pat
584         ajmp    pdptr
585 opcd42:                     ;@DPTR,A            done
586         acall   pat
587         acall   pdptr
588         acall   pcomma
589         ajmp    pa
590
591
592
593
594
595 sfrmnu: .db     0xE0,"AC",'C'+128
596         .db     0x81,'S','P'+128
597         .db     0x82,"DP",'L'+128
598         .db     0x83,"DP",'H'+128
599         .db     0x80,'P','0'+128
600         .db     0x90,'P','1'+128
601         .db     0xA0,'P','2'+128
602         .db     0xB0,'P','3'+128
603         .db     0x99,"SBU",'F'+128
604         .db     0xCD,"TH",'2'+128
605         .db     0xC8,"T2CO",'N'+128
606         .db     0xCC,"TL",'2'+128
607         .db     0xCB,"RCAP2",'H'+128
608         .db     0xCA,"RCAP2",'L'+128
609         .db     0x8C,"TH",'0'+128
610         .db     0x8A,"TL",'0'+128
611         .db     0x8D,"TH",'1'+128
612         .db     0x8B,"TL",'1'+128
613 sfr1:   .db     0xF0,'B'+128               ;5
614 sfr2:   .db     0xD0,"PS",'W'+128          ;7
615 sfr3:   .db     0xA8,'I','E'+128
616 sfr4:   .db     0xB8,'I','P'+128
617 sfr5:   .db     0x89,"TMO",'D'+128         ;8
618 sfr6:   .db     0x88,"TCO",'N'+128         ;8
619 sfr7:   .db     0x98,"SCO",'N'+128         ;8
620 sfr8:   .db     0x87,"PCO",'N'+128         ;8
621         .db     0                       ;just in case
622
623
624 opot2:  .db     0x59, 0x59, 0x09, 0x09  ;inc, dec, add, addc
625         .db     0x09, 0x09, 0x09, 0x7A  ;orl, anl, xrl, mov
626         .db     0x7E, 0x09, 0x76, 0x33  ;mov, subb, mov, cjne
627         .db     0x09, 0x52, 0x09, 0x71  ;xch, djnz, mov, mov
628
629 bitptr: .db     0x00, 0x02, 0x06, 0x08, 0x0C, 0x0E, 0x10, 0x12
630         .db     0x14, 0x16, 0x1B, 0x1E, 0x20, 0x23, 0x24, 0x25
631
632
633 ;some stuff used by single step... it's here to fill up some of
634 ;the unused space from the end of the disassembler code and the
635 ;beginning of the single-step header (which must begin on a 256
636 ;byte page boundry)
637
638
639 wr_check:   ;write to memory and check that it worked.
640             ;acc=0 if it worked, nonzero if it didn't write
641         mov     r0, a           ;keep a copy of the data in r0
642         movx    @dptr, a
643         clr     a
644         movc    a, @a+dptr
645         clr     c
646         subb    a, r0
647         ret
648
649 ;delay for approx 1 character transmit time
650 chardly:mov     r1, #80     
651 chdly2: mov     a, th1 
652         cpl     a     
653         inc     a
654         mov     r0, a
655         djnz    r0, *
656         djnz    r1, chdly2
657         ret
658
659 prcolon:acall   phex_h
660         mov     a, #':'
661         ajmp    cout_h
662
663 phexsp: acall   phex_h
664 space_h:
665         mov     a, #' '
666         ajmp    cout_h
667
668
669 ;SINGLE
670 ;---------------------------------------------------------;
671 ;                                                         ;
672 ;                 single step command                     ;
673 ;                                                         ;
674 ;---------------------------------------------------------;
675
676 .org    locat+0x400
677 .db     0xA5,0xE5,0xE0,0xA5     ;signiture
678 .db     254,step_key,0,0             ;id (254=user installed command)
679 .db     0,0,0,0                 ;prompt code vector
680 .dB     0,0,0,0                 ;reserved
681 .db     0,0,0,0                 ;reserved
682 .db     0,0,0,0                 ;reserved
683 .db     0,0,0,0                 ;user defined
684 .db     255,255,255,255         ;length and checksum (255=unused)
685 .db     "Single-Step",0
686 .org    locat+0x440             ;executable code begins here
687
688
689         
690 ssrun:
691         ;first check to make sure they connect int1 low
692         jnb     p3.3, ssrun2
693         mov     dptr, #sserr1   ;give error msg if int1 not grounded
694 pcstr_h:
695         ljmp    pcstr
696
697 ssrun2: ;make sure there's a ljmp at the int1 vector location
698         mov     dptr, #0x0013
699         clr     a
700         movc    a, @a+dptr
701         add     a, #254
702         jz      ssrun3
703         mov     dptr, #sserr2   ;give error that paulmon2 was not found.
704         ajmp    pcstr_h
705 ssrun3: ;now write an ljmp to "step" in the ram and check it.
706         inc     dptr
707         movc    a, @a+dptr
708         mov     r0, a
709         clr     a
710         inc     dptr
711         movc    a, @a+dptr
712         mov     dpl, a
713         mov     dph, r0         ;now data pointer points to int1 target
714         mov     a, #2
715         acall   wr_check
716         jnz     ssrun4
717         inc     dptr
718         mov     a, #(step >> 8)
719         acall   wr_check
720         jnz     ssrun4
721         inc     dptr
722         mov     a, #(step & 255)
723         acall   wr_check
724         jz      ssrun5
725 ssrun4: mov     r0, dpl
726         mov     r1, dph
727         mov     dptr, #sserr3   ;error: couldn't write to memory @xxxx
728         acall   pcstr_h
729         mov     a, r1
730         acall   phex_h
731         mov     a, r0
732         acall   phex_h
733         ajmp    newline_h
734 ssrun5: mov     a, ip           ;set to high priority interrupt
735         anl     a, #00000100b
736         mov     ip, a
737         ;let's not beat around the bush (like paulmon1), all 
738         ;we need to know is where to jump into memory.
739         mov     dptr, #prompt8
740         acall   pcstr_h
741         mov     a, r7
742         acall   phex_h
743         mov     a, r6
744         acall   phex_h
745         mov     dptr,#prompt4
746         acall   pcstr_h
747         lcall   ghex16          ;ask for the jump location
748         jb      psw.5, ssrun7
749         jnc     ssrun6
750         mov     dptr,#abort
751         acall   pstr_h
752         ajmp    newline_h
753 ssrun6: mov     r6, dpl         ;where we'll begin executing
754         mov     r7, dph
755 ssrun7: clr     tcon.2          ;need low-level triggered int1
756         mov     dptr,#ssmsg     ;tell 'em we're starting
757         acall   pcstr_h
758         mov     dptr,#ssnames
759         acall   pstr_h
760         clr     a
761         mov     sp, #8          ;just like after a reset
762         push    acc             ;unlike a 8051 start-up, push return addr
763         push    acc             ;of 0000, just in case they end w/ ret
764         mov     dpl, r6         ;load the program's address into dptr
765         mov     dph, r7
766         mov     psw, a          ;and clear everything to zero
767         mov     r0, a
768         mov     r1, a
769         mov     r2, a
770         mov     r3, a
771         mov     r4, a
772         mov     r5, a
773         mov     r6, a
774         mov     r7, a
775         mov     b, a
776         mov     lastpc, #ssstart & 255
777         mov     (lastpc+1), #ssstart >> 8
778         setb    ie.2
779         setb    ea              ;turn on the interrupt
780 ssstart:jmp     @a+dptr
781
782
783 done:   acall   chardly
784         pop     acc
785         mov     r1, a
786         pop     acc
787         mov     r0, a
788         pop     dpl
789         pop     dph
790         pop     psw
791         pop     acc
792         reti
793
794 step:    ;this is the single step interrupt service code...
795         push    acc
796         push    psw             ;Stack Contents: (in this order)
797         push    dph             ;PC_L PC_H ACC PSW DPH DPL R0 R1
798         push    dpl
799         mov     a, r0
800         push    acc
801         mov     a, r1
802         push    acc
803         ;in case the previous instruction was "clr ti", we
804         ;must wait for a character transmit time "in case it
805         ;was a move to SBUF) and then set ti so that our cout
806         ;doesn't hang when we transmit the first character!
807         acall   chardly
808         setb    ti
809
810         ;now print out a line that looks like this:
811         ;ACC B C DPTR  R0 R1 R2 R3 R4 R5 R6 R7  SP    PC  Instruction
812         ;00 00 0 3F00  00:00:00:00:00:00:00:00  00 - 0000: LJMP    0825
813
814         acall   space_h
815         acall   space_h
816         mov     a, sp
817         add     a, #251
818         mov     r0, a           ;r0 points to user's acc on stack
819         mov     a, @r0
820         acall   phexsp          ;print acc
821         mov     a, b
822         acall   phexsp          ;print b register
823         inc     r0
824         mov     a, @r0
825         rl      a
826         anl     a, #1
827         acall   phex1_h         ;print carry bit
828         acall   space_h
829         inc     r0
830         mov     a, @r0
831         acall   phex_h          ;print dptr (msb)
832         inc     r0
833         mov     a, @r0
834         acall   phexsp          ;print dptr (lsb)
835         acall   space_h
836         inc     r0
837         mov     a, @r0
838         acall   prcolon         ;print r0
839         inc     r0
840         mov     a, @r0
841         acall   prcolon         ;print r1
842         mov     a, r2
843         acall   prcolon         ;print r2
844         mov     a, r3
845         acall   prcolon         ;print r3
846         mov     a, r4
847         acall   prcolon         ;print r4
848         mov     a, r5
849         acall   prcolon         ;print r5
850         mov     a, r6
851         acall   prcolon         ;print r6
852         mov     a, r7
853         acall   phexsp          ;print r7
854         acall   space_h
855         mov     a, r0
856         add     a, #248
857         acall   phexsp          ;print stack pointer
858         acall   space_h
859         acall   space_h
860         ;now the trick is to disassemble the instruction... this isn't
861         ;easy, since the user wants to see the last instruction that
862         ;just executed, but program counter on the stack points to the
863         ;next instruction to be executed.  The dirty trick is to grab
864         ;the program counter from last time where we stashed it in some
865         ;memory that hopefully the user's program hasn't overwritten.
866         mov     a, lastpc
867         mov     lastpc, r6
868         mov     r6, a
869         mov     a, (lastpc+1)
870         mov     (lastpc+1), r7
871         mov     r7, a
872         mov     a, r2
873         push    acc
874         mov     a, r3
875         push    acc
876         mov     a, r4
877         push    acc
878         setb    psw.1           ;tell it to use a compact format
879         ;the disassembler uses quite a bit of stack space... if the
880         ;user didn't leave enough room for the stack to grow with
881         ;all this overhead, it will likely crash somewhere in the
882         ;disassembler... oh well, not much I can do about it.  The
883         ;worst case stack usage for disasm is 9 bytes.  We just
884         ;pushed 5 and 6 at the beginning of step.  With the two
885         ;bytes for the interrupt, a total of 22 bytes of free stack
886         ;space must be available to use the single-step feature.
887         acall   disasm
888         pop     acc
889         mov     r4, a
890         pop     acc
891         mov     r3, a
892         pop     acc
893         mov     r2, a
894         mov     r7, (lastpc+1)
895         mov     r6, lastpc
896         ;now grab the user's PC value to keep it for next time
897         mov     a, sp
898         add     a, #249
899         mov     r0, a           ;r0 points to user's acc on stack
900         mov     a, @r0
901         mov     lastpc, a
902         inc     r0
903         mov     a, @r0
904         mov     (lastpc+1), a
905
906 ;SINGLE STEP
907
908 step1:  lcall   cin_filter
909         lcall   upper
910 step2:  cjne    a, #13, step7
911         ajmp    done
912 step7:  cjne    a, #' ', step8    ;check space
913         ajmp    done
914 step8:  cjne    a,#'?',step10  ;check '?'
915         mov     dptr,#help5txt
916         acall   pcstr_h
917         ajmp    step1
918 step10: cjne    a,#'Q',step11  ;check 'Q'=quit and run normal
919         mov     dptr, #squit
920         acall   pstr_h
921         clr     ie.2
922         acall   chardly
923         mov     8, #0           ;force return to 0000
924         mov     9, #0
925         mov     sp, #9
926         reti
927 step11:
928         cjne    a,#'H',step12  ;check 'H'=hex dump internal ram
929         ajmp    ssdmp
930 step12: cjne    a,#'R',step13  ;check 'R'=print out registers
931         ajmp    ssreg
932 step13: cjne    a,#'S',step14  ;check 'S'=skip next inst
933         ajmp    ssskip
934 step14: cjne    a,#'A',step15  ;check 'A'=change acc value
935         ajmp    sschacc
936 step15: cjne    a,#'.',step20
937         mov     dptr, #ssnames
938         acall   pstr_h
939         ajmp    step1
940
941 step20: ajmp    step1
942  
943   
944 pequal:        ; prints '='
945         mov     a,#'='
946         ajmp    cout_h
947
948 ssdmp:
949         mov     dptr, #ssdmps1
950         acall   pstr_h
951         clr     a
952         acall   prcolon
953         acall   space_h
954         mov     r0, sp
955         dec     r0
956         mov     a, @r0
957         acall   phexsp
958         inc     r0
959         mov     a, @r0
960         acall   phex_h
961         mov     r0, #2
962         mov     r1, #14
963         ajmp    ssdmp2
964 ssdmp1: mov     a, r0
965         acall   prcolon
966         mov     r1, #16
967 ssdmp2: acall   space_h
968         mov     a, @r0
969         acall   phex_h
970         inc     r0
971         djnz    r1, ssdmp2
972         acall   newline_h
973         cjne    r0, #0x80, ssdmp1
974         acall   newline_h
975         ajmp    step1
976
977
978 ssreg:
979         mov     dptr, #sfr2+1
980         acall   pstr_h
981         acall   pequal
982         mov     a, sp
983         add     a, #252
984         mov     r0, a
985         mov     a, @r0
986         acall   phexsp          ;print psw
987         mov     dptr,#sfr3+1
988         mov     r0, 0xA8
989         acall   psfr            ;print ie
990         mov     dptr,#sfr4+1
991         mov     r0, 0xB8
992         acall   psfr            ;print ip
993         mov     dptr,#sfr5+1
994         mov     r0, 0x89
995         acall   psfr            ;print tmod
996         mov     dptr,#sfr6+1
997         mov     r0, 0x88
998         acall   psfr            ;print tcon
999         mov     dptr,#sfr7+1
1000         mov     r0, 0x98
1001         acall   psfr            ;print smod
1002         mov     dptr,#sfr8+1
1003         mov     r0, 0x87
1004         acall   psfr            ;print pcon
1005         mov     a, #'T'
1006         acall   cout_h
1007         mov     a, #'0'
1008         acall   cout_h
1009         acall   pequal
1010         mov     a, 8Ch
1011         acall   phex_h          ;print Timer 0
1012         mov     a, 8Ah
1013         acall   phex_h
1014         acall   space_h
1015         mov     a, #'T'
1016         acall   cout_h
1017         mov     a, #'1'
1018         acall   cout_h
1019         acall   pequal
1020         mov     a, 8Dh          ;print Timer 1
1021         acall   phex_h
1022         mov     a, 8Bh
1023         acall   phex_h
1024         acall   newline_h
1025         ajmp    step1
1026
1027 psfr:   acall   pstr_h
1028         acall   pequal
1029         mov     a, r0
1030         ajmp    phexsp
1031
1032
1033
1034 ;skip the next instruction
1035 ssskip:
1036         mov     r0, #23
1037 ssskip2:acall   space_h
1038         djnz    r0, ssskip2
1039         mov     dptr,#sskip1
1040         acall   pstr_h
1041         mov     a, sp
1042         add     a, #249
1043         mov     r0, a           ;set r0 to point to pc on stack
1044         mov     a, @r0
1045         mov     lastpc, r6      ;keep r6/r7 safe in lastpc
1046         mov     r6, a           ;put user's pc into r6/r7
1047         inc     r0
1048         mov     a, @r0
1049         mov     (lastpc+1), r7
1050         mov     r7, a
1051         mov     a, r2
1052         push    acc
1053         mov     a, r3
1054         push    acc
1055         mov     a, r4
1056         push    acc
1057         setb    psw.1           ;tell it to use a compact format
1058         acall   disasm          ;run disasm to show 'em what was skipped
1059         pop     acc
1060         mov     r4, a
1061         pop     acc
1062         mov     r3, a
1063         pop     acc
1064         mov     r2, a
1065         mov     a, sp
1066         add     a, #249
1067         mov     r0, a           ;set r0 to point to pc on stack
1068         mov     a, r6
1069         mov     r6, lastpc      ;restore r6/r7
1070         mov     lastpc, a       ;update lastpc with next inst addr
1071         mov     @r0, a          ;also update user's pc!!
1072         inc     r0
1073         mov     a, r7
1074         mov     r7, (lastpc+1)
1075         mov     (lastpc+1), a
1076         mov     @r0, a
1077         ajmp    step1
1078
1079 sschacc:
1080         mov     a, sp
1081         add     a, #251
1082         mov     r0, a           ;r0 points to acc on stack
1083         mov     dptr, #chaccs1
1084         acall   pstr_h
1085         lcall   ghex
1086         jc      chacc2
1087         jb      psw.5, chacc2
1088         mov     @r0, a
1089         acall   newline_h
1090         ajmp    step1
1091 chacc2: mov     dptr, #abort
1092         acall   pstr_h
1093         ajmp    step1
1094
1095
1096
1097
1098 ;stuff some of the disassembler tables, strings, etc since we have a
1099 ;bit of space before the beginning of the editor command code
1100
1101
1102        ;opcode offset table (gives #bytes for the instruction
1103        ;and the number of the routine to print the operands)
1104
1105 opot1:  .db     0xAD, 0x06, 0x6F, 0x39, 0x39, 0x46, 0x49, 0x49 ;0
1106         .db     0x63, 0x06, 0x6F, 0x39, 0x39, 0x46, 0x49, 0x49 ;1
1107         .db     0x63, 0x06, 0xAD, 0x39, 0x16, 0x0E, 0x11, 0x11 ;2
1108         .db     0x63, 0x06, 0xAD, 0x39, 0x16, 0x0E, 0x11, 0x11 ;3
1109         .db     0x66, 0x06, 0x1A, 0x1F, 0x16, 0x0E, 0x11, 0x11 ;4
1110         .db     0x66, 0x06, 0x1A, 0x1F, 0x16, 0x0E, 0x11, 0x11 ;5
1111         .db     0x66, 0x06, 0x1A, 0x1F, 0x16, 0x0E, 0x11, 0x11 ;6
1112         .db     0x66, 0x06, 0x22, 0x69, 0x16, 0x1F, 0x92, 0x92 ;7
1113         .db     0x66, 0x06, 0x22, 0xA1, 0x4D, 0x83, 0x86, 0x86 ;8
1114         .db     0x9B, 0x06, 0x96, 0x9D, 0x16, 0x0E, 0x11, 0x11 ;9
1115         .db     0x26, 0x06, 0x22, 0x5D, 0x4D, 0xAD, 0x8E, 0x8E ;A
1116         .db     0x26, 0x06, 0x42, 0x3D, 0x2F, 0x2B, 0x37, 0x37 ;B
1117         .db     0x46, 0x06, 0x42, 0x3D, 0x39, 0x0E, 0x11, 0x11 ;C
1118         .db     0x46, 0x06, 0x42, 0x3D, 0x39, 0x57, 0x11, 0x11 ;D
1119         .db     0xA5, 0x06, 0x11, 0x11, 0x39, 0x0E, 0x11, 0x11 ;E
1120         .db     0xA9, 0x06, 0x89, 0x89, 0x39, 0x1A, 0x89, 0x89 ;F
1121
1122 mnot1:  ;mnunonic offset table (gives offset into above table)
1123
1124         .db     0x5A, 0x0E, 0x48, 0x73  ;nop, ajmp, ljmp, rr
1125         .db     0x2B, 0x2B, 0x2B, 0x2B  ;inc, inc, inc, inc
1126         .db     0x30, 0x00, 0x43, 0x75  ;jbc, acall, lcall rrc
1127         .db     0x21, 0x21, 0x21, 0x21  ;
1128
1129         .db     0x2E, 0x0E, 0x67, 0x6E  ; etc...
1130         .db     0x06, 0x06, 0x06, 0x06  ;
1131         .db     0x38, 0x00, 0x6A, 0x70  ;
1132         .db     0x0A, 0x0A, 0x0A, 0x0A  ;
1133
1134         .db     0x33, 0x0E, 0x5D, 0x5D  ;
1135         .db     0x5D, 0x5D, 0x5D, 0x5D  ;
1136         .db     0x3B, 0x00, 0x12, 0x12  ;
1137         .db     0x12, 0x12, 0x12, 0x12  ;
1138
1139         .db     0x41, 0x0E, 0x8F, 0x8F  ;
1140         .db     0x8F, 0x8F, 0x8F, 0x8F  ;
1141         .db     0x3E, 0x00, 0x5D, 0x35  ;
1142         .db     0x4C, 0x4C, 0x4C, 0x4C  ;
1143
1144         .db     0x7C, 0x0E, 0x12, 0x4F  ;
1145         .db     0x24, 0x4C, 0x4C, 0x4C  ;
1146         .db     0x4C, 0x00, 0x4C, 0x4F  ;
1147         .db     0x80, 0x80, 0x80, 0x80  ;
1148
1149         .db     0x5D, 0x0E, 0x4C, 0x2B  ;
1150         .db     0x57, 0x92, 0x4C, 0x4C  ;
1151         .db     0x12, 0x00, 0x1C, 0x1C  ;
1152         .db     0x15, 0x15, 0x15, 0x15  ;
1153
1154         .db     0x63, 0x0E, 0x19, 0x19  ;
1155         .db     0x84, 0x88, 0x88, 0x88  ;
1156         .db     0x60, 0x00, 0x78, 0x78  ;
1157         .db     0x1F, 0x27, 0x8B, 0x8B  ;
1158
1159         .db     0x53, 0x0E, 0x53, 0x53  ;
1160         .db     0x19, 0x4C, 0x4C, 0x4C  ;
1161         .db     0x53, 0x00, 0x53, 0x53  ;
1162         .db     0x1C, 0x4C, 0x4C, 0x4C  ;
1163
1164
1165 mnot2:  .db     0x2B, 0x21, 0x06, 0x0A  ;inc, dec, add, addc
1166         .db     0x5D, 0x12, 0x8F, 0x4C  ;orl, anl, xlr, mov
1167         .db     0x4C, 0x80, 0x4C, 0x15  ;mov, subb, mov, cjne
1168         .db     0x88, 0x27, 0x4C, 0x4C  ;xch, djnz, mov, mov
1169
1170
1171 ;---------------------------------------------------------;
1172 ;                                                         ;
1173 ;                  External Memory Editor                 ;
1174 ;                                                         ;
1175 ;---------------------------------------------------------;
1176
1177 ;register usage:
1178 ; R4,    Flags:
1179 ;         bit0: 0=display CODE memory, 1=display DATA memory
1180 ;         bit1: 0=editing disabled, 1=editing enabled
1181 ;         bit2: 0=editing in hex, 1=editing in ascii
1182 ;         bit3: 0=normal, 1=in middle of hex entry (value in r5)
1183 ; R6/R7, current memory location
1184 ;
1185
1186 .org    locat+0x800
1187 .db     0xA5,0xE5,0xE0,0xA5     ;signiture
1188 .db     254,vtedit_key,0,0      ;id (254=user installed command)
1189 .db     0,0,0,0                 ;prompt code vector
1190 .dB     0,0,0,0                 ;reserved
1191 .db     0,0,0,0                 ;reserved
1192 .db     0,0,0,0                 ;reserved
1193 .db     0,0,0,0                 ;user defined
1194 .db     255,255,255,255         ;length and checksum (255=unused)
1195 .db     "Memory Editor (VT100)",0
1196
1197 .org    locat+0x0840            ;executable code begins here
1198
1199
1200         mov     r4, #0
1201         acall   redraw
1202 main:
1203         mov     a, r4
1204         clr     acc.3
1205         mov     r4, a
1206 main2:  lcall   cin_filter
1207         acall   input_ck_2nd
1208 cmd1:   cjne    a, #27, cmd2            ;quit
1209         ajmp    quit
1210 cmd2:   cjne    a, #11, cmd3            ;up
1211         ajmp    cmd_up
1212 cmd3:   cjne    a, #10, cmd4            ;down
1213         ajmp    cmd_down
1214 cmd4:   cjne    a, #8, cmd5             ;left
1215         ajmp    cmd_left
1216 cmd5:   cjne    a, #21, cmd6            ;right
1217         ajmp    cmd_right
1218 cmd6:   cjne    a, #12, cmd7            ;redraw
1219         acall   redraw
1220         ajmp    main
1221 cmd7:   cjne    a, #17, cmd8            ;quit
1222         ajmp    quit
1223 cmd8:   cjne    a, #3, cmd9             ;code memory
1224         mov     a, r4
1225         anl     a, #11111110b
1226         mov     r4, a
1227         acall   cursor_home
1228         mov     dptr, #str_code
1229         acall   pstr_hh
1230         acall   redraw_data
1231         ajmp    main
1232 cmd9:   cjne    a, #4, cmd10            ;data memory
1233         mov     a, r4
1234         orl     a, #00000001b
1235         mov     r4, a
1236         acall   cursor_home
1237         mov     dptr, #str_data
1238         acall   pstr_hh
1239         acall   redraw_data
1240         ajmp    main
1241 cmd10:  cjne    a, #7, cmd11            ;goto memory loc
1242         ajmp    cmd_goto
1243 cmd11:  cjne    a, #5, cmd12            ;toggle editing
1244         ajmp    cmd_edit
1245 cmd12:  cjne    a, #6, cmd13            ;fill memory
1246         ajmp    cmd_fill
1247 cmd13:  cjne    a, #1, cmd14            ;edit in ascii
1248         mov     a, r4
1249         jnb     acc.1, main
1250         setb    acc.2
1251         mov     r4, a
1252         acall   erase_commands
1253         acall   print_commands
1254         acall   redraw_cursor
1255         ajmp    main
1256 cmd14:  cjne    a, #24, cmd15           ;edit in hex
1257         mov     a, r4
1258         jnb     acc.1, main
1259         clr     acc.2
1260         mov     r4, a
1261         acall   erase_commands
1262         acall   print_commands
1263         acall   redraw_cursor
1264         ajmp    main
1265 cmd15:  cjne    a, #25, cmd16           ;page up
1266         ajmp    cmd_pgup
1267 cmd16:  cjne    a, #26, cmd17           ;page down
1268         ajmp    cmd_pgdown
1269 cmd17:
1270
1271
1272 cmd_data:       ;the input character wasn't any particular command, so
1273                 ;maybe it's some input data being typed for edit mode
1274         mov     b, a                    ;keep a copy of user data in b
1275         mov     a, r4
1276         jb      acc.1, cmd_data2
1277 cmd_abort:
1278         ajmp    main                    ;ignore if not in edit mode
1279 cmd_data2:
1280         jnb     acc.2, input_hex
1281 input_ascii:
1282         mov     a, b
1283         acall   ascii_only
1284         cjne    a, b, cmd_abort         ;check that input is an ascii char
1285         mov     dph, r7
1286         mov     dpl, r6
1287         lcall   smart_wr                ;write the char to memory
1288         ajmp    cmd_right
1289
1290 input_hex:
1291         mov     a, b
1292         lcall   upper
1293         lcall   asc2hex
1294         jc      cmd_abort               ;ignore if not hex
1295         mov     r0, a                   ;keep hex value of input in r0
1296         mov     dph, r7                 ;load dptr with address
1297         mov     dpl, r6
1298         mov     a, r4
1299         jb      acc.3, input_hex_2nd
1300 input_hex_1st:
1301         mov     a, r0
1302         mov     r5, a
1303         mov     a, r4
1304         setb    acc.3           ;remember that we're waiting for 2nd char
1305         mov     r4, a
1306         acall   redraw_cursor
1307         ajmp    main2
1308 input_hex_2nd:
1309         mov     a, r5                   ;get data from memory
1310         swap    a                       ;shift nibbles
1311         anl     a, #11110000b           ;just in case
1312         add     a, r0                   ;add in this input to lower part
1313         lcall   smart_wr                ;write back to memory
1314         mov     a, r4
1315         clr     acc.3
1316         mov     r4, a
1317         ajmp    cmd_right
1318
1319 input_ck_2nd:
1320         ;the main input routine will always call here when a new
1321         ;byte is entered... so we can do something special if we
1322         ;were waiting for the second character and it is not a
1323         ;legal hex character
1324         push    acc
1325         mov     a, r4
1326         jb      acc.1, inck2d
1327         ;if editing is disabled, don't do anything
1328         clr     acc.3
1329 inck2b: mov     r4, a
1330 inck2c: pop     acc
1331         ret
1332 inck2d: jnb     acc.3, inck2b
1333         ;if we get here, we were actually waiting for the 2nd char
1334         pop     acc
1335         push    acc
1336         lcall   upper
1337         lcall   asc2hex
1338         jnc     inck2c          ;proceed normally if it is valid
1339         ;if we get here, we did not get a hex legal char
1340         pop     acc
1341         push    acc
1342         cjne    a, #esc_char, inck2e
1343         mov     a, r4
1344         clr     acc.3
1345         mov     r4, a
1346         acall   redraw_cursor
1347         pop     acc
1348         pop     acc             ;don't return and do the quit cmd
1349         pop     acc             ;just quit this entry and wait for next cmd
1350         ajmp    main
1351 inck2e: mov     dph, r7                 ;load dptr with address
1352         mov     dpl, r6
1353         mov     a, r5
1354         lcall   smart_wr                ;write to memory
1355         mov     a, r4
1356         clr     acc.3
1357         mov     r4, a
1358         acall   redraw_cursor
1359         sjmp    inck2c
1360
1361 ; R4,    Flags:
1362 ;         bit0: 0=display CODE memory, 1=display DATA memory
1363 ;         bit1: 0=editing disabled, 1=editing enabled
1364 ;         bit2: 0=editing in hex, 1=editing in ascii
1365 ;         bit3: 0=normal, 1=in middle of hex entry (value in r5)
1366
1367
1368 cmd_fill:
1369         mov     a, r4
1370         anl     a, #00000010b
1371         jnz     cmd_fill_ok
1372         ajmp    main                    ;don't allow if not in editing mode
1373 cmd_fill_ok:
1374         acall   erase_commands
1375         mov     a, r4
1376         push    acc
1377         mov     dptr, #fill_prompt1
1378         acall   pcstr_hh
1379         lcall   ghex16
1380         jc      cmd_fill_abort
1381         jb      psw.5, cmd_fill_abort
1382         mov     r0, dpl
1383         mov     r1, dph
1384         mov     dptr, #fill_prompt2
1385         acall   pstr_hh
1386         lcall   ghex16
1387         jc      cmd_fill_abort
1388         jb      psw.5, cmd_fill_abort
1389         mov     r4, dpl
1390         mov     r5, dph
1391         mov     dptr, #fill_prompt3
1392         acall   pcstr_hh
1393         lcall   ghex
1394         jc      cmd_fill_abort
1395         jb      psw.5, cmd_fill_abort
1396         mov     r2, a
1397         mov     a, r4
1398         mov     r6, a
1399         mov     a, r5
1400         mov     r7, a
1401         pop     acc
1402         mov     r4, a
1403         mov     dpl, r0
1404         mov     dph, r1
1405         ;now r4 is restored to its normal value, dptr holds the
1406         ;first location to fill, and r6/r7 holds the last location to
1407         ;fill, and r2 has the fill value.
1408 cmd_fill_loop:
1409         mov     a, r2
1410         lcall   smart_wr
1411         mov     a, r6
1412         cjne    a, dpl, cmd_fill_next
1413         mov     a, r7
1414         cjne    a, dph, cmd_fill_next
1415         ;when we get here, we're done!
1416         acall   erase_commands
1417         acall   print_commands
1418         acall   redraw_data
1419         ajmp    main
1420 cmd_fill_next:
1421         inc     dptr
1422         sjmp    cmd_fill_loop
1423
1424 cmd_fill_abort:
1425         pop     acc
1426         mov     r4, a
1427         acall   erase_commands
1428         acall   print_commands
1429         acall   redraw_cursor
1430         ajmp    main
1431
1432 fill_prompt1:
1433         .db     "Fill",31,131,"; First: ",0
1434 fill_prompt2:
1435         .db     "  Last: ",0
1436 fill_prompt3:
1437         .db     " ",168,": ",0 
1438
1439 cmd_edit:
1440         acall   erase_commands
1441         mov     a, r4
1442         xrl     a, #00000010b
1443         mov     r4, a
1444         acall   print_commands
1445         acall   redraw_cursor
1446         ajmp    main
1447
1448 cmd_goto:
1449         acall   erase_commands
1450         mov     dptr, #goto_prompt
1451         acall   pcstr_hh
1452         mov     a, r4
1453         push    acc
1454         lcall   ghex16
1455         pop     acc
1456         mov     r4, a
1457         jc      cmdgt_abort
1458         jb      psw.5, cmdgt_abort
1459         mov     r6, dpl
1460         mov     r7, dph
1461         acall   cursor_home
1462         mov     a, #20
1463         acall   cursor_down
1464         acall   print_commands
1465         acall   redraw_data
1466         ajmp    main
1467 cmdgt_abort:
1468         acall   cursor_home
1469         mov     a, #20
1470         acall   cursor_down
1471         acall   print_commands
1472         acall   redraw_cursor
1473         ajmp    main
1474
1475
1476 goto_prompt:
1477         .db     31,131,31,129,": ",0
1478
1479 cmd_up:
1480         acall   blank_it
1481         mov     a, r6
1482         clr     c
1483         subb    a, #16
1484         mov     r6, a
1485         mov     a, r7
1486         subb    a, #0
1487         mov     r7, a
1488         mov     a, r6
1489         cpl     a
1490         anl     a, #11110000b
1491         jz      cmd_up_scroll
1492         mov     a, #1
1493         acall   cursor_up
1494         acall   invert_it
1495         ajmp    main
1496 cmd_up_scroll:
1497         acall   redraw_data
1498         ajmp    main
1499
1500 cmd_pgup:
1501         dec     r7
1502         acall   redraw_data
1503         ajmp    main
1504
1505 cmd_pgdown:
1506         inc     r7
1507         acall   redraw_data
1508         ajmp    main
1509
1510 cmd_down:
1511         acall   blank_it
1512         mov     a, r6
1513         add     a, #16
1514         mov     r6, a
1515         mov     a, r7
1516         addc    a, #0
1517         mov     r7, a
1518         mov     a, r6
1519         anl     a, #11110000b
1520         jz      cmd_down_scroll
1521         mov     a, #1
1522         acall   cursor_down
1523         acall   invert_it
1524         ajmp    main
1525 cmd_down_scroll:
1526         acall   redraw_data
1527         ajmp    main
1528
1529
1530 cmd_left:
1531         acall   blank_it
1532         mov     a, #3
1533         acall   cursor_left
1534         mov     a, r6
1535         clr     c
1536         subb    a, #1
1537         mov     r6, a
1538         mov     a, r7
1539         subb    a, #0
1540         mov     r7, a
1541         mov     a, r6
1542         orl     a, #11110000b
1543         cpl     a
1544         jz      cmdlf2
1545         acall   invert_it
1546         ajmp    main
1547 cmdlf2:
1548         mov     a, r6
1549         cpl     a
1550         anl     a, #11110000b
1551         jz      cmd_left_scroll
1552         mov     a, #48
1553         acall   cursor_right
1554         mov     a, #1
1555         acall   cursor_up
1556         acall   invert_it
1557         ajmp    main
1558 cmd_left_scroll:
1559         acall   redraw_data
1560         ajmp    main
1561
1562
1563 cmd_right:
1564         acall   blank_it
1565         mov     a, #3
1566         acall   cursor_right
1567         mov     dpl, r6
1568         mov     dph, r7
1569         inc     dptr
1570         mov     r6, dpl
1571         mov     r7, dph
1572         mov     a, r6
1573         anl     a, #00001111b
1574         jz      cmdrt2
1575         acall   invert_it
1576         ajmp    main
1577
1578 cmdrt2:
1579         mov     a, r6
1580         anl     a, #11110000b
1581         jz      cmd_right_scroll
1582         mov     a, #48
1583         acall   cursor_left
1584         mov     a, #1
1585         acall   cursor_down
1586         acall   invert_it
1587         ajmp    main
1588 cmd_right_scroll:
1589         acall   redraw_data
1590         ajmp    main
1591
1592
1593 space:  mov     a, #' '
1594         ajmp    cout_hh
1595
1596
1597
1598 ;register usage:
1599 ; R4,    Flags:
1600 ;         bit0: 0=display CODE memory, 1=display DATA memory
1601 ;         bit1: 0=editing disabled, 1=editing enabled
1602 ;         bit2: 0=editing in hex, 1=editing in ascii
1603 ;         bit3: 0=normal, 1=in middle of hex entry (value in r5)
1604 ; R6/R7, current memory location
1605 ;
1606
1607
1608 redraw:
1609         mov     dptr, #str_cl           ;clear screen
1610         acall   pstr_hh
1611         acall   print_title_line
1612         acall   newline_hh
1613         acall   print_addr_line
1614         acall   newline_hh
1615         acall   print_dash_line
1616         acall   newline_hh
1617         mov     a, #16
1618         acall   cursor_down
1619         acall   print_dash_line
1620         acall   newline_hh
1621         acall   print_commands
1622 redraw_data:
1623         acall   cursor_home
1624         mov     a, #2
1625         acall   cursor_down
1626         ;compute first byte address to display on the screen
1627         mov     dpl, #0
1628         mov     dph, r7
1629         ;now display the data
1630         mov     r0, #16
1631 rd2:    acall   newline_hh
1632         lcall   phex16
1633         mov     a, #':'
1634         acall   cout_hh
1635         mov     r2, dpl
1636         mov     r3, dph
1637 rd3:    acall   space
1638         acall   read_dptr
1639         acall   phex_hh
1640         inc     dptr
1641         mov     a, dpl
1642         anl     a, #00001111b
1643         jnz     rd3
1644         mov     dpl, r2
1645         mov     dph, r3
1646         acall   space
1647         acall   space
1648         acall   space
1649 rd4:    acall   read_dptr
1650         acall   ascii_only
1651         acall   cout_hh
1652         inc     dptr
1653         mov     a, dpl
1654         anl     a, #00001111b
1655         jnz     rd4
1656         djnz    r0, rd2
1657
1658 redraw_cursor:
1659         acall   cursor_home
1660         mov     a, r6
1661         swap    a
1662         anl     a, #00001111b
1663         add     a, #3
1664         acall   cursor_down
1665         ;make the ascii character inverse
1666         mov     a, r6
1667         anl     a, #00001111b
1668         add     a, #56
1669         acall   cursor_right
1670         acall   inverse_on
1671         acall   read_r6r7
1672         acall   ascii_only
1673         acall   cout_hh
1674         acall   inverse_off
1675
1676         ;now make the hex value inverse
1677         mov     a, r6
1678         anl     a, #00001111b
1679         rl      a
1680         cpl     a
1681         add     a, #52
1682         acall   cursor_left
1683         acall   inverse_on
1684         acall   read_r6r7
1685         acall   phex_hh
1686         ajmp    inverse_off
1687
1688
1689 blank_it:
1690         mov     a, r6
1691         anl     a, #00001111b
1692         rl      a
1693         cpl     a
1694         add     a, #49
1695         acall   cursor_right
1696         acall   read_r6r7
1697         acall   ascii_only
1698         acall   cout_hh
1699         mov     a, r6
1700         anl     a, #00001111b
1701         rl      a
1702         cpl     a
1703         add     a, #52
1704         acall   cursor_left
1705         acall   read_r6r7
1706         ajmp    phex_hh
1707
1708 invert_it:
1709         mov     a, r6
1710         anl     a, #00001111b
1711         rl      a
1712         cpl     a
1713         add     a, #49
1714         acall   cursor_right
1715         acall   read_r6r7
1716         acall   ascii_only
1717         acall   inverse_on
1718         acall   cout_hh
1719         acall   inverse_off
1720         mov     a, r6
1721         anl     a, #00001111b
1722         rl      a
1723         cpl     a
1724         add     a, #52
1725         acall   cursor_left
1726         acall   read_r6r7
1727         acall   inverse_on
1728         acall   phex_hh
1729         ajmp    inverse_off
1730
1731
1732
1733
1734
1735
1736 quit:   mov     a, r6
1737         anl     a, #11110000b
1738         swap    a
1739         cpl     a
1740         add     a, #19
1741         acall   cursor_down
1742         ajmp    newline_hh
1743
1744
1745 ascii_only:
1746         anl     a, #01111111b   ;avoid unprintable characters
1747         cjne    a, #127, aonly2
1748         mov     a, #' '
1749         ret
1750 aonly2: clr     c
1751         subb    a, #32
1752         jnc     aonly3          ;avoid control characters
1753         mov     a, #(' ' - 32)
1754 aonly3: add     a, #32
1755         ret
1756
1757
1758
1759
1760
1761 read_dptr:
1762         mov     a, r4
1763         jb      acc.0, rddptr2
1764         clr     a
1765         movc    a, @a+dptr
1766         ret
1767 rddptr2:movx    a, @dptr
1768         ret
1769
1770 read_r6r7:
1771         push    dph
1772         push    dpl
1773         mov     dph, r7
1774         mov     dpl, r6
1775         mov     a, r4
1776         jb      acc.3, rdr6r7d
1777         jb      acc.0, rdr6r7b
1778         clr     a
1779         movc    a, @a+dptr
1780         sjmp    rdr6r7c
1781 rdr6r7b:movx    a, @dptr
1782 rdr6r7c:pop     dpl
1783         pop     dph
1784         ret
1785 rdr6r7d:mov     a, r5
1786         sjmp    rdr6r7c
1787
1788
1789 .equ    esc_char, 27
1790
1791 cursor_home:
1792         acall   term_esc
1793         mov     a, #'H'
1794         ajmp    cout_hh
1795
1796 cursor_down:    ;acc is # of lines to move down
1797         acall   term_esc
1798         acall   pint_hh
1799         mov     a, #'B'
1800         ajmp    cout_hh
1801
1802 cursor_up:      ;acc is # of lines to move up
1803         acall   term_esc
1804         acall   pint_hh
1805         mov     a, #'A'
1806         ajmp    cout_hh
1807
1808 cursor_left:    ;acc is # of characters to move left
1809         acall   term_esc
1810         acall   pint_hh
1811         mov     a, #'D'
1812         ajmp    cout_hh
1813
1814 cursor_right:   ;acc is # of characters to move right
1815         acall   term_esc
1816         acall   pint_hh
1817         mov     a, #'C'
1818         ajmp    cout_hh
1819
1820 inverse_on:
1821         mov     dptr, #str_so
1822         ajmp    pstr_hh
1823
1824 str_so: .db     esc_char, "[0;7m", 0
1825
1826 inverse_off:
1827         mov     dptr, #str_se
1828         ajmp    pstr_hh
1829
1830 str_se: .db     esc_char, "[0m", 0
1831
1832
1833 term_esc:
1834         push    acc
1835         mov     a, #esc_char
1836         acall   cout_hh
1837         mov     a, #'['
1838         acall   cout_hh
1839         pop     acc
1840         ret
1841         
1842 print_addr_line:
1843         mov     dptr, #str_addr
1844         acall   pstr_hh
1845         mov     r0, #0
1846 paddrl: acall   space
1847         mov     a, #'+'
1848         acall   cout_hh
1849         mov     a, r0
1850         lcall   phex1
1851         inc     r0
1852         cjne    r0, #16, paddrl
1853         mov     dptr, #str_ascii_equiv
1854         ajmp    pstr_hh
1855
1856
1857 print_dash_line:
1858         mov     r0, #72
1859 pdashl: mov     a, #'-'
1860         acall   cout_hh
1861         djnz    r0, pdashl
1862         ret
1863
1864 print_title_line:
1865         mov     a, r4
1866         jb      acc.0, ptitle2
1867         mov     dptr, #str_code
1868         sjmp    ptitle3
1869 ptitle2:mov     dptr, #str_data
1870 ptitle3:acall   pstr_hh
1871         mov     r0, #8
1872 ptitlel:acall   space
1873         djnz    r0, ptitlel
1874         mov     dptr, #str_title
1875         ajmp    pcstr_hh
1876
1877 erase_commands:
1878         acall   cursor_home
1879         mov     a, #20
1880         acall   cursor_down
1881         mov     r2, #72
1882 ercmd2: acall   space
1883         djnz    r2, ercmd2
1884         mov     a, #72
1885         ajmp    cursor_left
1886
1887
1888 ; R4,    Flags:
1889 ;         bit0: 0=display CODE memory, 1=display DATA memory
1890 ;         bit1: 0=editing disabled, 1=editing enabled
1891 ;         bit2: 0=editing in hex, 1=editing in ascii
1892 ;         bit3: 0=normal, 1=in middle of hex entry (value in r5)
1893
1894 print_commands:
1895         mov     a, r4
1896         jnb     acc.1, pcmd_no_edit
1897         mov     dptr, #str_cmd3
1898         jb      acc.2, pcmd_ascii
1899         mov     dptr, #str_cmd4
1900 pcmd_ascii:
1901         acall   pstr_hh
1902         mov     dptr, #str_cmd5
1903         acall   pstr_hh
1904         sjmp    pcmd_finish
1905 pcmd_no_edit:
1906         mov     dptr, #str_cmd2
1907         acall   pstr_hh
1908 pcmd_finish:
1909         mov     dptr, #str_cmd1
1910         ajmp    pstr_hh
1911
1912 str_cmd1: .db "  ^G=Goto  ^C=Code  ^D=Data  ^L=Redraw  ^Q=Quit", 0
1913 str_cmd2: .db "^E-Edit",0
1914 str_cmd3: .db "^A=", esc_char, "[0;7m", "ASCII", esc_char, "[0m", "  ^X=Hex", 0
1915 str_cmd4: .db "^A=ASCII  ^X=", esc_char, "[0;7m", "Hex", esc_char, "[0m", 0
1916 str_cmd5: .db "  ^F=Fill",0
1917
1918
1919 str_cl: .db     esc_char, "[H", esc_char, "[2J", 0
1920
1921 str_addr: .db "ADDR:",0
1922 str_ascii_equiv: .db    "   ASCII EQUIVILANT",0
1923 str_title: .db  "8051",31,154,31,131,31,216,"or,",31,248,31,254,", 1996",0
1924 str_code: .db "CODE",0
1925 str_data: .db "DATA",0
1926
1927
1928 cout_hh:ljmp    cout
1929 phex_hh:ljmp    phex
1930 pstr_hh:ljmp    pstr
1931 newline_hh:ljmp newline
1932 pcstr_hh:ljmp   pcstr
1933 pint_hh:ljmp    pint
1934
1935
1936
1937 ;---------------------------------------------------------;
1938 ;                                                         ;
1939 ;                    single step strings                  ;
1940 ;                                                         ;
1941 ;---------------------------------------------------------;
1942
1943
1944            
1945 prompt4:.db     "), or <ESC> to exit: ",0 
1946 prompt8:.db     13,31,136,128,131,129," (",0 
1947 abort:  .db     " Command Aborted.",13,10,0
1948
1949
1950 sserr1: .db     13,161,197," connect INT1 (pin 13) low"
1951         .db     128,186,207,204,13,0
1952 sserr2: .db     148,"2",179,199,174,129," 0013",13,0
1953 sserr3: .db     31,184,179,255,165," vector",174," ",0
1954 ssmsg:  .db     13,"Now",134,"ning",166,207,204," mode:  "
1955         .db     "<RET>=",204,", ?= Help",13,13,0
1956
1957 sskip1: .db     "Skipping Instruction-> ",0
1958 ssdmps1:.db     13,10,"Loc:  Int RAM Memory Contents",13,10,0
1959 chaccs1:.db     "New Acc Value: ",0
1960
1961 help5txt:.db    13
1962         .db     31,207,31,204,31,158,":",13
1963         .db     "<RET> ",134,212,246,13
1964         .db     " <SP> ",134,212,246,13
1965         .db     " '?'  ",255,142,215,13
1966         .db     " '.'  ",255,196,253,"s",13
1967         .db     " 'R'  ",255," special function",196,"s",13
1968         .db     " 'H'  ",132,219,192,146,13
1969         .db     " 'S'  ",252,212,246,13
1970         .db     " 'A'  ",240,162," Acc value",13
1971         .db     " 'Q'  ",200,207,204,13,14
1972
1973 squit:  .db     "Quit",13,10,0
1974
1975 ssnames:.db     "  ACC B C DPTR  R0 R1 R2 R3 R4 R5 R6 R7  SP"
1976         .db     "   Addr  Instruction",13,10,0
1977
1978
1979 ;---------------------------------------------------------;
1980 ;                                                         ;
1981 ;                    disassembler data                    ;
1982 ;                                                         ;
1983 ;---------------------------------------------------------;
1984
1985
1986
1987 mnu_tbl:.db     "ACAL",'L'+128
1988         .db     0
1989         .db     "AD",'D'+128
1990         .db     0
1991         .db     "ADD",'C'+128
1992         .db     "AJM",'P'+128
1993         .db     "AN",'L'+128
1994         .db     "CJN",'E'+128
1995         .db     "CL",'R'+128
1996         .db     "CP",'L'+128
1997         .db     "D",'A'+128 
1998         .db     "DE",'C'+128
1999         .db     "DI",'V'+128
2000         .db     "DJN",'Z'+128
2001         .db     "IN",'C'+128
2002         .db     "J",'B'+128
2003         .db     "JB",'C'+128
2004         .db     "J",'C'+128
2005         .db     "JM",'P'+128
2006         .db     "JN",'B'+128
2007         .db     "JN",'C'+128
2008         .db     "JN",'Z'+128
2009         .db     "J",'Z'+128
2010         .db     "LCAL",'L'+128
2011         .db     "LJM",'P'+128
2012         .db     "MO",'V'+128
2013         .db     "MOV",'C'+128
2014         .db     "MOV",'X'+128
2015         .db     "MU",'L'+128
2016         .db     "NO",'P'+128
2017         .db     "OR",'L'+128
2018         .db     "PO",'P'+128
2019         .db     "PUS",'H'+128
2020         .db     "RE",'T'+128
2021         .db     "RET",'I'+128
2022         .db     "R",'L'+128
2023         .db     "RL",'C'+128
2024         .db     "R",'R'+128
2025         .db     "RR",'C'+128
2026         .db     "SET",'B'+128
2027         .db     "SJM",'P'+128
2028         .db     "SUB",'B'+128
2029         .db     "SWA",'P'+128
2030         .db     "XC",'H'+128
2031         .db     "XCH",'D'+128
2032         .db     "XR",'L'+128
2033         .db     "??",'?'+128
2034
2035
2036
2037 bitmnu: .db     'P','0'+128
2038         .db     "TCO",'N'+128
2039         .db     'P','1'+128
2040         .db     "SCO",'N'+128
2041         .db     'P','2'+128
2042         .db     'I','E'+128
2043         .db     'P','3'+128
2044         .db     'I','P'+128
2045         .db     'C','0'+128
2046         .db     "T2CO",'N'+128
2047         .db     "PS",'W'+128
2048         .db     'D','8'+128
2049         .db     "AC",'C'+128
2050         .db     'E'+'8'+128
2051         .db     'B'+128
2052         .db     'F'+'8'+128
2053
2054