1;*                    BUFFALO
2;* "Bit User's Fast Friendly Aid to Logical Operation"
3;*
4;* Rev 2.0 - 4/23/85 - added disassembler.
5;*                     - variables now PTRn and TMPn.
6;* Rev 2.1 - 4/29/85 - added byte erase to chgbyt routine.
7;* Rev 2.2 - 5/16/85 - added hooks for evb board - acia
8;*                       drivers, init and host routines.
9;*            7/8/85  - fixed dump wraparound problem.
10;*            7/10/85 - added evm board commands.
11;*                     - added fill instruction.
12;*            7/18/85 - added jump to EEPROM.
13;* Rev 2.3 - 8/22/85 - call targco to disconnect sci from host
14;*                       in reset routine for evb board.
15;*            10/3/85 - modified load for download through terminal.
16;* Rev 2.4 - 7/1/86  - Changed DFLOP address to fix conflicts with
17;*                       EEPROM.  (was at A000)
18;* Rev 2.5 - 9/8/86  - Modified to provide additional protection from
19;*                       program run-away on power down.  Also fixed bugs
20;*                       in MM and MOVE.  Changed to 1 stop bit from 2.
21;* Rev 2.6 - 9/25/86 - Modified boot routine for variable length download
22;*                       for use with 'HC11E8.
23;* Rev 3.0   1/15/87 - EEPROM programming routines consolidated into WRITE.
24;*                       Fill, Assem, and breakpoints will now do EEPROM.
25;*                     - Added compare a to $0D to WSKIP routine.
26;*            2/11/87 - Set up load to detect receiver error.
27;* Rev 3.2   7/7/87  - Add disassembly to trace.
28;*                     - Add entries to jump table.
29;*            9/20/87 - Rewrote trace to use XIRQ, added STOPAT Command
30;*            11/24/87- Write block protect reg for 'E9 version
31;*                     - Modified variable length download for use
32;*                          with 'E9 bootloader (XBOOT command)
33;*
34;*
35;****************************************************
36;*    Although the information contained herein,    *
37;*    as well as any information provided relative  *
38;*    thereto, has been carefully reviewed and is   *
39;*    believed accurate, Motorola assumes no     *
40;*    liability arising out of its application or   *
41;*    use, neither does it convey any license under *
42;*    its patent rights nor the rights of others.   *
43;****************************************************
44
45         CPU  6811
46
47;***************
48;*   EQUATES   *
49;***************
50RAMBS    EQU  $0000             ; start of ram
51REGBS    EQU  $1000             ; start of registers
52ROMBS    EQU  $E000             ; start of rom
53STREE    EQU  $B600             ; start of eeprom
54ENDEE    EQU  $B7FF             ; end of eeprom
55PORTE    EQU  REGBS+$0A         ; port e
56CFORC    EQU  REGBS+$0B         ; force output compare
57TCNT     EQU  REGBS+$0E         ; timer count
58TOC5     EQU  REGBS+$1E         ; oc5 reg
59TCTL1    EQU  REGBS+$20         ; timer control 1
60TMSK1    EQU  REGBS+$22         ; timer mask 1
61TFLG1    EQU  REGBS+$23         ; timer flag 1
62TMSK2    EQU  REGBS+$24         ; timer mask 2
63BAUD     EQU  REGBS+$2B         ; sci baud reg
64SCCR1    EQU  REGBS+$2C         ; sci control1 reg
65SCCR2    EQU  REGBS+$2D         ; sci control2 reg
66SCSR     EQU  REGBS+$2E         ; sci status reg
67SCDAT    EQU  REGBS+$2F         ; sci data reg
68BPROT    EQU  REGBS+$35         ; block protect reg
69OPTION   EQU  REGBS+$39         ; option reg
70COPRST   EQU  REGBS+$3A         ; cop reset reg
71PPROG    EQU  REGBS+$3B         ; ee prog reg
72HPRIO    EQU  REGBS+$3C         ; hprio reg
73CONFIG   EQU  REGBS+$3F         ; config register
74DFLOP    EQU  $4000             ; evb d flip flop
75DUART    EQU  $D000             ; duart address
76PORTA    EQU  DUART
77PORTB    EQU  DUART+8
78ACIA     EQU  $9800             ; acia address
79PROMPT   EQU  '>'
80BUFFLNG  EQU  35
81CTLA     EQU  $01               ; exit host or assembler
82CTLB     EQU  $02               ; send break to host
83CTLW     EQU  $17               ; wait
84CTLX     EQU  $18               ; abort
85DEL      EQU  $7F               ; abort
86EOT      EQU  $04               ; end of text/table
87SWI      EQU  $3F
88
89;***************
90;*     RAM     *
91;***************
92         ORG  $33
93;*** Buffalo ram space ***
94         RMB  20                ; user stack area
95USTACK   RMB  30                ; monitor stack area
96STACK    RMB  1
97REGS     RMB  9                 ; user's pc,y,x,a,b,c
98SP       RMB  2                 ; user's sp
99INBUFF   RMB  BUFFLNG           ; input buffer
100ENDBUFF  EQU  *
101COMBUFF  RMB  8                 ; command buffer
102SHFTREG  RMB  2                 ; input shift register
103BRKTABL  RMB  8                 ; breakpoint table
104AUTOLF   RMB  1                 ; auto lf flag for i/o
105IODEV    RMB  1                 ; 0=sci,  1=acia, 2=duartA, 3=duartB
106EXTDEV   RMB  1                 ; 0=none, 1=acia, 2=duart,
107HOSTDEV  RMB  1                 ; 0=sci,  1=acia,              3=duartB
108COUNT    RMB  1                 ; # characters read
109CHRCNT   RMB  1                 ; # characters output on current line
110PTRMEM   RMB  2                 ; current memory location
111
112;*** Buffalo variables - used by: ***
113PTR0     RMB  2                 ; main,readbuff,incbuff,AS
114PTR1     RMB  2                 ; main,BR,DU,MO,AS,EX
115PTR2     RMB  2                 ; EX,DU,MO,AS
116PTR3     RMB  2                 ; EX,HO,MO,AS
117PTR4     RMB  2                 ; EX,AS
118PTR5     RMB  2                 ; EX,AS,BOOT
119PTR6     RMB  2                 ; EX,AS,BOOT
120PTR7     RMB  2                 ; EX,AS
121PTR8     RMB  2                 ; AS
122TMP1     RMB  1                 ; main,hexbin,buffarg,termarg
123TMP2     RMB  1                 ; GO,HO,AS,LOAD
124TMP3     RMB  1                 ; AS,LOAD
125TMP4     RMB  1                 ; TR,HO,ME,AS,LOAD
126;*** Vector jump table ***
127JSCI     RMB   3
128JSPI     RMB   3
129JPAIE    RMB   3
130JPAO     RMB   3
131JTOF     RMB   3
132JTOC5    RMB   3
133JTOC4    RMB   3
134JTOC3    RMB   3
135JTOC2    RMB   3
136JTOC1    RMB   3
137JTIC3    RMB   3
138JTIC2    RMB   3
139JTIC1    RMB   3
140JRTI     RMB   3
141JIRQ     RMB   3
142JXIRQ    RMB   3
143JSWI     RMB   3
144JILLOP   RMB   3
145JCOP     RMB   3
146JCLM     RMB   3
147
148;*****************
149;*
150;* ROM starts here *
151;*
152;*****************
153
154        ORG  ROMBS
155
156;*****************
157;**  BUFFALO - This is where Buffalo starts
158;** out of reset.  All initialization is done
159;** here including determination of where the
160;** user terminal is (SCI,ACIA, or DUART).
161;*****************
162
163BUFFALO  LDX  #PORTE
164         BRCLR 0,X,#01,BUFISIT  ; if bit 0 of port e is 1
165         JMP  $B600             ; then jump to the start of EEPROM
166BUFISIT  LDAA #$93
167         STAA OPTION            ; adpu, dly, irqe, cop
168         LDAA #$00
169         STAA TMSK2             ; timer pre = %1 for trace
170         LDAA #$00
171         STAA BPROT             ; clear 'E9 eeprom block protect
172         LDS  #STACK            ; monitor stack pointer
173         JSR  VECINIT
174         LDX  #USTACK
175         STX  SP                ; default user stack
176         LDAA TCTL1
177         ORAA #$03
178         STAA TCTL1             ; force oc5 pin high for trace
179         LDAA #$D0
180         STAA REGS+8            ; default user ccr
181         LDD  #$3F0D            ; initial command is ?
182         STD  INBUFF
183         JSR  BPCLR             ; clear breakpoints
184         CLR  AUTOLF
185         INC  AUTOLF            ; auto cr/lf = on
186
187;* Determine type of external comm device - none, or acia *
188
189         CLR  EXTDEV            ; default is none
190         LDAA HPRIO
191         ANDA #$20
192         BEQ  BUFF2             ; jump if single chip mode
193         LDAA #$03              ; see if external acia exists
194         STAA ACIA              ; master reset
195         LDAA ACIA
196         ANDA #$7F              ; mask irq bit from status register
197         BNE  BUFF1             ; jump if status reg not 0
198         LDAA #$12
199         STAA ACIA              ; turn on acia
200         LDAA ACIA
201         ANDA #$02
202         BEQ  BUFF1             ; jump if tdre not set
203         LDAA #$01
204         STAA EXTDEV            ; external device is acia
205         BRA  BUFF2
206
207BUFF1    EQU  *                 ; see if duart exists
208         LDAA DUART+$0C        ; read IRQ vector register
209         CMPA #$0F             ; should be out of reset
210         BNE  BUFF2
211         LDAA #$AA
212         STAA DUART+$0C         ; write irq vector register
213         LDAA DUART+$0C         ; read irq vector register
214         CMPA #$AA
215         BNE  BUFF2
216         LDAA #$02
217         STAA EXTDEV            ; external device is duart A
218
219;* Find terminal port - SCI or external. *
220
221BUFF2    CLR  IODEV
222         JSR  TARGCO            ; disconnect sci for evb board
223         JSR  SIGNON            ; initialize sci
224         LDAA EXTDEV
225         BEQ  BUFF3             ; jump if no external device
226         STAA IODEV
227         JSR  SIGNON            ; initialize external device
228BUFF3    CLR  IODEV
229         JSR  INPUT             ; get input from sci port
230         CMPA #$0D
231         BEQ  BUFF4             ; jump if cr - sci is terminal port
232         LDAA EXTDEV
233         BEQ  BUFF3             ; jump if no external device
234         STAA IODEV
235         JSR  INPUT             ; get input from external device
236         CMPA #$0D
237         BEQ  BUFF4             ; jump if cr - terminal found ext
238         BRA  BUFF3
239
240SIGNON   JSR  INIT              ; initialize device
241         LDX  #MSG1             ; buffalo message
242         JSR  OUTSTRG
243         RTS
244
245;* Determine where host port should be. *
246
247BUFF4    CLR  HOSTDEV           ; default - host = sci port
248         LDAA IODEV
249         CMPA #$01
250         BEQ  BUFF5             ; default host if term = acia
251         LDAA #$03
252         STAA HOSTDEV           ;  else host is duart port b
253BUFF5    EQU  *
254
255;*****************
256;**  MAIN - This module reads the user's input into
257;** a buffer called INBUFF.  The first field (assumed
258;** to be the command field) is then parsed into a
259;** second buffer called COMBUFF.  The command table
260;** is then searched for the contents of COMBUFF and
261;** if found, the address of the corresponding task
262;** routine is fetched from the command table.  The
263;** task is then called as a subroutine so that
264;** control returns back to here upon completion of
265;** the task.  Buffalo expects the following format
266;** for commands:
267;**     <cmd>[<wsp><arg><wsp><arg>...]<cr>
268;** [] implies contents optional.
269;** <wsp> means whitespace character (space,comma,tab).
270;** <cmd> = command string of 1-8 characters.
271;** <arg> = Argument particular to the command.
272;** <cr> = Carriage return signifying end of input string.
273;*****************
274;* Prompt user
275;*do
276;*   a=input();
277;*   if(a==(cntlx or del)) continue;
278;*   elseif(a==backspace)
279;*      b--;
280;*      if(b<0) b=0;
281;*   else
282;*      if(a==cr && buffer empty)
283;*          repeat last command;
284;*      else put a into buffer;
285;*          check if buffer full;
286;*while(a != (cr or /)
287
288MAIN     LDS  #STACK            ; initialize sp every time
289         CLR  AUTOLF
290         INC  AUTOLF            ; auto cr/lf = on
291         JSR  OUTCRLF
292         LDAA #PROMPT           ; prompt user
293         JSR  OUTPUT
294         CLRB
295MAIN1    JSR  INCHAR            ; read terminal
296         LDX  #INBUFF
297         ABX                    ; pointer into buffer
298         CMPA #CTLX
299         BEQ  MAIN              ; jump if cntl X
300         CMPA #DEL
301         BEQ  MAIN              ; jump if del
302         CMPA #$08
303         BNE  MAIN2             ; jump if not bckspc
304         DECB
305         BLT  MAIN              ; jump if buffer empty
306         BRA  MAIN1
307MAIN2    CMPA #$D
308         BNE  MAIN3             ; jump if not cr
309         TSTB
310         BEQ  COMM0             ; jump if buffer empty
311         STAA ,X                ; put a in buffer
312         BRA  COMM0
313MAIN3    STAA ,X                ; put a in buffer
314         INCB
315         CMPB #BUFFLNG
316         BLE  MAIN4             ; jump if not long
317         LDX  #MSG3             ; "long"
318         JSR  OUTSTRG
319         BRA  MAIN
320MAIN4     CMPA #'/'
321         BNE  MAIN1             ; jump if not "/"
322;*         *******************
323
324;*****************
325;*  Parse out and evaluate the command field.
326;*****************
327;*Initialize
328
329COMM0    EQU  *
330         CLR  TMP1              ; Enable "/" command
331         CLR  SHFTREG
332         CLR  SHFTREG+1
333         CLRB
334         LDX  #INBUFF           ; ptrbuff[] = inbuff[]
335         STX  PTR0
336         JSR  WSKIP             ; find first char
337
338;*while((a=readbuff) != (cr or wspace))
339;*     upcase(a);
340;*     buffptr[b] = a
341;*     b++
342;*     if (b > 8) error(too long);
343;*     if(a == "/")
344;*           if(enabled) mslash();
345;*           else error(command?);
346;*     else hexbin(a);
347
348COMM1    EQU  *
349         JSR  READBUFF          ; read from buffer
350         LDX  #COMBUFF
351         ABX
352         JSR  UPCASE            ; convert to upper case
353         STAA ,X                ; put in command buffer
354         CMPA #$0D
355         BEQ  SRCH              ; jump if cr
356         JSR  WCHEK
357         BEQ  SRCH              ; jump if wspac
358         JSR  INCBUFF           ; move buffer pointer
359         INCB
360         CMPB #$8
361         BLE  COMM2
362         LDX  #MSG3             ; "long"
363         JSR  OUTSTRG
364         JMP  MAIN
365
366COMM2    EQU  *
367         CMPA #'/'
368         BNE  COMM4             ; jump if not "/"
369         TST  TMP1
370         BNE  COMM3             ; jump if not enabled
371         DECB
372         STAB COUNT
373         LDX  #MSLASH
374         JMP  EXEC              ; execute "/"
375COMM3    LDX  #MSG8             ; "command?"
376         JSR  OUTSTRG
377         JMP  MAIN
378COMM4    EQU  *
379         JSR  HEXBIN
380         BRA  COMM1
381
382;*****************
383;*   Search tables for command.      At this point,
384;* COMBUFF holds the command field to be executed,
385;* and B = # of characters in the command field.
386;* The command table holds the whole command name
387;* but only the first n characters of the command
388;* must match what is in COMBUFF where n is the
389;* number of characters entered by the user.
390;*****************
391;*count = b;
392;*ptr1 = comtabl;
393;*while(ptr1[0] != end of table)
394;*   ptr1 = next entry
395;*   for(b=1; b=count; b++)
396;*      if(ptr1[b] == combuff[b]) continue;
397;*      else error(not found);
398;*   execute task;
399;*  return();
400;*return(command not found);
401
402SRCH    STAB COUNT              ; size of command entered
403        LDX  #COMTABL           ; pointer to table
404        STX  PTR1               ; pointer to next entry
405SRCH1   LDX  PTR1
406        LDY  #COMBUFF           ; pointer to command buffer
407        LDAB 0,X
408        CMPB #$FF
409        BNE  SRCH2
410        LDX  #MSG2              ; "command not found"
411        JSR  OUTSTRG
412        JMP  MAIN
413SRCH2   PSHX                    ; compute next table entry
414        ADDB #$3
415        ABX
416        STX  PTR1
417        PULX
418        CLRB
419SRCHLP  INCB                    ; match characters loop
420        LDAA 1,X                ; read table
421        CMPA 0,Y                ; compare to combuff
422        BNE  SRCH1              ; try next entry
423        INX                     ; move pointers
424        INY
425        CMPB COUNT
426        BLT  SRCHLP             ; loop countu1 times
427        LDX  PTR1
428        DEX
429        DEX
430        LDX  0,X                ; jump address from table
431EXEC    JSR  0,X                ; call task as subroutine
432        JMP  MAIN
433;*
434;*****************
435;*   UTILITY SUBROUTINES - These routines
436;* are called by any of the task routines.
437;*****************
438;*****************
439;*  UPCASE(a) - If the contents of A is alpha,
440;* returns a converted to uppercase.
441;*****************
442UPCASE   CMPA #'a'
443         BLT  UPCASE1           ; jump if < a
444         CMPA #'z'
445         BGT  UPCASE1           ; jump if > z
446         SUBA #$20              ; convert
447UPCASE1  RTS
448
449;*****************
450;*  BPCLR() - Clear all entries in the
451;* table of breakpoints.
452;*****************
453BPCLR    LDX  #BRKTABL
454         LDAB #8
455BPCLR1   CLR  0,X
456         INX
457         DECB
458         BGT  BPCLR1            ; loop 8 times
459         RTS
460
461;*****************
462;*  RPRNT1(x) - Prints name and contents of a single
463;* user register. On entry X points to name of register
464;* in reglist.  On exit, a=register name.
465;*****************
466REGLIST  FCC  "PYXABCS"         ; names
467         FCB  0,2,4,6,7,8,9     ; offset
468         FCB  1,1,1,0,0,0,1     ; size
469RPRNT1   LDAA 0,X
470         PSHA
471         PSHX
472         JSR  OUTPUT            ; name
473         LDAA #'-'
474         JSR  OUTPUT            ; dash
475         LDAB 7,X               ; contents offset
476         LDAA 14,X              ; bytesize
477         LDX  #REGS             ; address
478         ABX
479         TSTA
480         BEQ  RPRN2             ; jump if 1 byte
481         JSR  OUT1BYT           ; 2 bytes
482RPRN2    JSR  OUT1BSP
483         PULX
484         PULA
485         RTS
486
487;*****************
488;*  RPRINT() - Print the name and contents
489;* of all the user registers.
490;*****************
491RPRINT   PSHX
492         LDX  #REGLIST
493RPRI1    JSR  RPRNT1            ; print name
494         INX
495         CMPA #'S'              ; s is last register
496         BNE  RPRI1             ; jump if not done
497         PULX
498         RTS
499
500;*****************
501;*   HEXBIN(a) - Convert the ASCII character in a
502;* to binary and shift into shftreg.  Returns value
503;* in tmp1 incremented if a is not hex.
504;*****************
505HEXBIN  PSHA
506        PSHB
507        PSHX
508        JSR  UPCASE             ; convert to upper case
509        CMPA #'0'
510        BLT  HEXNOT             ; jump if a < $30
511        CMPA #'9'
512        BLE  HEXNMB             ; jump if 0-9
513        CMPA #'A'
514        BLT  HEXNOT             ; jump if $39> a <$41
515        CMPA #'F'
516        BGT  HEXNOT             ; jump if a > $46
517        ADDA #$9                ; convert $A-$F
518HEXNMB  ANDA #$0F               ; convert to binary
519        LDX  #SHFTREG
520        LDAB #4
521HEXSHFT ASL  1,X                ; 2 byte shift through
522        ROL  0,X                ; carry bit
523        DECB
524        BGT  HEXSHFT            ; shift 4 times
525        ORAA 1,X
526        STAA 1,X
527        BRA  HEXRTS
528HEXNOT  INC  TMP1               ; indicate not hex
529HEXRTS  PULX
530        PULB
531        PULA
532        RTS
533
534;*****************
535;*  BUFFARG() - Build a hex argument from the
536;* contents of the input buffer. Characters are
537;* converted to binary and shifted into shftreg
538;* until a non-hex character is found.  On exit
539;* shftreg holds the last four digits read, count
540;* holds the number of digits read, ptrbuff points
541;* to the first non-hex character read, and A holds
542;* that first non-hex character.
543;*****************
544;*Initialize
545;*while((a=readbuff()) not hex)
546;*     hexbin(a);
547;*return();
548
549BUFFARG  CLR  TMP1              ; not hex indicator
550         CLR  COUNT             ; # or digits
551         CLR  SHFTREG
552         CLR  SHFTREG+1
553         JSR  WSKIP
554BUFFLP   JSR  READBUFF          ; read char
555         JSR  HEXBIN
556         TST  TMP1
557         BNE  BUFFRTS           ; jump if not hex
558         INC  COUNT
559         JSR  INCBUFF           ; move buffer pointer
560         BRA  BUFFLP
561BUFFRTS  RTS
562
563;*****************
564;*  TERMARG() - Build a hex argument from the
565;* terminal.  Characters are converted to binary
566;* and shifted into shftreg until a non-hex character
567;* is found.  On exit shftreg holds the last four
568;* digits read, count holds the number of digits
569;* read, and A holds the first non-hex character.
570;*****************
571;*initialize
572;*while((a=inchar()) == hex)
573;*     if(a = cntlx or del)
574;*           abort;
575;*     else
576;*           hexbin(a); countu1++;
577;*return();
578
579TERMARG  CLR  COUNT
580         CLR  SHFTREG
581         CLR  SHFTREG+1
582TERM0    JSR  INCHAR
583         CMPA #CTLX
584         BEQ  TERM1             ; jump if controlx
585         CMPA #DEL
586         BNE  TERM2             ; jump if not delete
587TERM1    JMP  MAIN              ; abort
588TERM2    CLR  TMP1              ; hex indicator
589         JSR  HEXBIN
590         TST  TMP1
591         BNE  TERM3             ; jump if not hex
592         INC  COUNT
593         BRA  TERM0
594TERM3    RTS
595
596;*****************
597;*   CHGBYT() - If shftreg is not empty, put
598;* contents of shftreg at address in X.       If X
599;* is an address in EEPROM then program it.
600;*****************
601;*if(count != 0)
602;*   (x) = a;
603CHGBYT   TST  COUNT
604         BEQ  CHGBYT4           ; quit if shftreg empty
605         LDAA SHFTREG+1         ; get data into a
606         JSR  WRITE
607CHGBYT4  RTS
608
609
610;*****************
611;* WRITE() - This routine is used to write the
612;*contents of A to the address of X.  If the
613;*address is in EEPROM, it will be programmed
614;*and if it is already programmed, it will be
615;*byte erased first.
616;******************
617;*if(X is eeprom)then
618;*   if(not erased) then erase;
619;*   program (x) = A;
620;*write (x) = A;
621;*if((x) != A) error(rom);
622WRITE   EQU  *
623        CPX  #CONFIG
624        BEQ  WRITE1             ; jump if config
625        CPX  #STREE             ; start of EE
626        BLO  WRITE2             ; jump if not EE
627        CPX  #ENDEE             ; end of EE
628        BHI  WRITE2             ; jump if not EE
629WRITEE  PSHB
630        LDAB 0,X
631        CMPB #$FF
632        PULB
633        BEQ  WRITE1             ; jump if erased
634        JSR  EEBYTE             ; byte erase
635WRITE1  JSR  EEWRIT             ; byte program
636WRITE2  STAA 0,X                ; write for non EE
637        CMPA 0,X
638        BEQ  WRITE3             ; jump if write ok
639        PSHX
640        LDX  #MSG6              ; "rom"
641        JSR  OUTSTRG
642        PULX
643WRITE3  RTS
644
645
646;*****************
647;*   EEWRIT(), EEBYTE(), EEBULK() -
648;* These routines are used to program and eeprom
649;*locations.  eewrite programs the address in X with
650;*the value in A, eebyte does a byte address at X,
651;*and eebulk does a bulk of eeprom.  Whether eebulk
652;*erases the config or not depends on the address it
653;*receives in X.
654;****************
655EEWRIT  EQU  *                  ; program one byte at x
656        PSHB
657        LDAB #$02
658        STAB PPROG
659        STAA 0,X
660        LDAB #$03
661        BRA  EEPROG
662;***
663EEBYTE  EQU  *                  ; byte erase address x
664        PSHB
665        LDAB #$16
666        STAB PPROG
667        LDAB #$FF
668        STAB 0,X
669        LDAB #$17
670        BRA  EEPROG
671;***
672EEBULK  EQU  *                  ; bulk erase eeprom
673        PSHB
674        LDAB #$06
675        STAB PPROG
676        LDAB #$FF
677        STAB 0,X                ; erase config or not
678        LDAB #$07               ; depends on X addr
679EEPROG  BNE  ACL1
680        CLRB                    ; fail safe
681ACL1    STAB PPROG
682        PULB
683;***
684DLY10MS EQU  *                  ; delay 10ms at E = 2MHz
685        PSHX
686        LDX  #$0D06
687DLYLP   DEX
688        BNE  DLYLP
689        PULX
690        CLR  PPROG
691        RTS
692
693
694;*****************
695;*  READBUFF() -  Read the character in INBUFF
696;* pointed at by ptrbuff into A.  Returns ptrbuff
697;* unchanged.
698;*****************
699READBUFF PSHX
700         LDX  PTR0
701         LDAA 0,X
702         PULX
703         RTS
704
705;*****************
706;*  INCBUFF(), DECBUFF() - Increment or decrement
707;* ptrbuff.
708;*****************
709INCBUFF  PSHX
710         LDX  PTR0
711         INX
712         BRA  INCDEC
713DECBUFF  PSHX
714         LDX  PTR0
715         DEX
716INCDEC   STX  PTR0
717         PULX
718         RTS
719
720;*****************
721;*  WSKIP() - Read from the INBUFF until a
722;* non whitespace (space, comma, tab) character
723;* is found.  Returns ptrbuff pointing to the
724;* first non-whitespace character and a holds
725;* that character.  WSKIP also compares a to
726;* $0D (CR) and cond codes indicating the
727;* results of that compare.
728;*****************
729WSKIP    JSR  READBUFF          ; read character
730         JSR  WCHEK
731         BNE  WSKIP1            ; jump if not wspc
732         JSR  INCBUFF           ; move pointer
733         BRA  WSKIP             ; loop
734WSKIP1   CMPA #$0D
735         RTS
736
737;*****************
738;*  WCHEK(a) - Returns z=1 if a holds a
739;* whitespace character, else z=0.
740;*****************
741WCHEK    CMPA #$2C              ; comma
742         BEQ  WCHEK1
743         CMPA #$20              ; space
744         BEQ  WCHEK1
745         CMPA #$09              ; tab
746WCHEK1   RTS
747
748;*****************
749;*   DCHEK(a) - Returns Z=1 if a = whitespace
750;* or carriage return.  Else returns z=0.
751;*****************
752DCHEK   JSR  WCHEK
753        BEQ  DCHEK1             ; jump if whitespace
754        CMPA #$0D
755DCHEK1  RTS
756
757;*****************
758;*  CHKABRT() - Checks for a control x or delete
759;* from the terminal.  If found, the stack is
760;* reset and the control is transferred to main.
761;* Note that this is an abnormal termination.
762;*   If the input from the terminal is a control W
763;* then this routine keeps waiting until any other
764;* character is read.
765;*****************
766;*a=input();
767;*if(a=cntl w) wait until any other key;
768;*if(a = cntl x or del) abort;
769
770CHKABRT  JSR  INPUT
771         BEQ  CHK4              ; jump if no input
772         CMPA #CTLW
773         BNE  CHK2              ; jump in not cntlw
774CHKABRT1 JSR  INPUT
775         BEQ  CHKABRT1          ; jump if no input
776CHK2     CMPA #DEL
777         BEQ  CHK3              ; jump if delete
778         CMPA #CTLX
779         BEQ  CHK3              ; jump if control x
780         CMPA #CTLA
781         BNE  CHK4              ; jump not control a
782CHK3     JMP  MAIN              ; abort
783CHK4     RTS                    ; return
784
785;***********************
786;*  HOSTCO - connect sci to host for evb board.
787;*  TARGCO - connect sci to target for evb board.
788;***********************
789HOSTCO   PSHA
790         LDAA #$01
791         STAA DFLOP             ; send 1 to d-flop
792         PULA
793         RTS
794
795TARGCO   PSHA
796         LDAA #$00
797         STAA DFLOP             ; send 0 to d-flop
798         PULA
799         RTS
800
801;*
802;**********
803;*
804;*     VECINIT - This routine checks for
805;*         vectors in the RAM table.  All
806;*         uninitialized vectors are programmed
807;*         to JMP STOPIT
808;*
809;**********
810;*
811VECINIT  LDX  #JSCI             ; Point to First RAM Vector
812         LDY  #STOPIT           ; Pointer to STOPIT routine
813         LDD  #$7E03            ; A=JMP opcode; B=offset
814VECLOOP  CMPA 0,X
815         BEQ  VECNEXT           ; If vector already in
816         STAA 0,X               ; install JMP
817         STY  1,X               ; to STOPIT routine
818VECNEXT  ABX                    ; Add 3 to point at next vector
819         CPX  #JCLM+3           ; Done?
820         BNE  VECLOOP           ; If not, continue loop
821         RTS
822;*
823STOPIT   LDAA #$50              ; Stop-enable; IRQ, XIRQ-Off
824         TAP
825         STOP                   ; You are lost!  Shut down
826         JMP  STOPIT            ; In case continue by XIRQ
827
828;**********
829;*
830;*   I/O MODULE
831;*     Communications with the outside world.
832;* 3 I/O routines (INIT, INPUT, and OUTPUT) call
833;* drivers specified by IODEV (0=SCI, 1=ACIA,
834;* 2=DUARTA, 3=DUARTB).
835;*
836;**********
837;*   INIT() - Initialize device specified by iodev.
838;*********
839;*
840INIT     EQU  *
841         PSHA                   ; save registers
842         PSHX
843         LDAA IODEV
844         CMPA #$00
845         BNE  INIT1             ; jump not sci
846         JSR  ONSCI             ; initialize sci
847         BRA  INIT4
848INIT1    CMPA #$01
849         BNE  INIT2             ; jump not acia
850         JSR  ONACIA            ; initialize acia
851         BRA  INIT4
852INIT2    LDX  #PORTA
853         CMPA #$02
854         BEQ  INIT3             ; jump duart a
855         LDX  #PORTB
856INIT3    JSR  ONUART            ; initialize duart
857INIT4    PULX                   ; restore registers
858         PULA
859         RTS
860
861;**********
862;*  INPUT() - Read device. Returns a=char or 0.
863;*    This routine also disarms the cop.
864;**********
865INPUT    EQU  *
866         PSHX
867         LDAA #$55              ; reset cop
868         STAA COPRST
869         LDAA #$AA
870         STAA COPRST
871         LDAA IODEV
872         BNE  INPUT1            ; jump not sci
873         JSR  INSCI             ; read sci
874         BRA  INPUT4
875INPUT1   CMPA #$01
876         BNE  INPUT2            ; jump not acia
877         JSR  INACIA            ; read acia
878         BRA  INPUT4
879INPUT2   LDX  #PORTA
880         CMPA #$02
881         BEQ  INPUT3            ; jump if duart a
882         LDX  #PORTB
883INPUT3   JSR  INUART            ; read uart
884INPUT4   PULX
885         RTS
886
887;**********
888;*   OUTPUT() - Output character in A.
889;* chrcnt indicates the current column on the
890;*output display.  It is incremented every time
891;*a character is outputted, and cleared whenever
892;*the subroutine outcrlf is called.
893;**********
894
895OUTPUT   EQU  *
896         PSHA                   ; save registers
897         PSHB
898         PSHX
899         LDAB IODEV
900         BNE  OUTPUT1           ; jump not sci
901         JSR  OUTSCI            ; write sci
902         BRA  OUTPUT4
903OUTPUT1  CMPB #$01
904         BNE  OUTPUT2           ; jump not acia
905         JSR  OUTACIA           ; write acia
906         BRA  OUTPUT4
907OUTPUT2  LDX  #PORTA
908         CMPB #$02
909         BEQ  OUTPUT3           ; jump if duart a
910         LDX  #PORTB
911OUTPUT3  JSR  OUTUART           ; write uart
912OUTPUT4  PULX
913         PULB
914         PULA
915         INC  CHRCNT            ; increment column count
916         RTS
917
918;**********
919;*   ONUART(port) - Initialize a duart port.
920;* Sets duart to internal clock, divide by 16,
921;* 8 data + 1 stop bits.
922;**********
923
924ONUART   LDAA #$22
925         STAA 2,X               ; reset receiver
926         LDAA #$38
927         STAA 2,X               ; reset transmitter
928         LDAA #$40
929         STAA 2,X               ; reset error status
930         LDAA #$10
931         STAA 2,X               ; reset pointer
932         LDAA #$00
933         STAA DUART+4           ; clock source
934         LDAA #$00
935         STAA DUART+5           ; interrupt mask
936         LDAA #$13
937         STAA 0,X               ; 8 data, no parity
938         LDAA #$07
939         STAA 0,X               ; 1 stop bits
940         LDAA #$BB              ; baud rate (9600)
941         STAA 1,X               ; tx and rcv baud rate
942         LDAA #$05
943         STAA 2,X               ; enable tx and rcv
944         RTS
945
946;**********
947;*   INUART(port) - Check duart for any input.
948;**********
949INUART    LDAA 1,X              ; read status
950         ANDA #$01              ; check rxrdy
951         BEQ  INUART1           ; jump if no data
952         LDAA 3,X               ; read data
953         ANDA #$7F              ; mask parity
954INUART1  RTS
955
956;**********
957;*   OUTUART(port) - Output the character in a.
958;*         if autolf=1, transmits cr or lf as crlf.
959;**********
960OUTUART  TST  AUTOLF
961         BEQ  OUTUART2          ; jump if no autolf
962         BSR  OUTUART2
963         CMPA #$0D
964         BNE  OUTUART1
965         LDAA #$0A              ; if cr, output lf
966         BRA  OUTUART2
967OUTUART1 CMPA #$0A
968         BNE  OUTUART3
969         LDAA #$0D              ; if lf, output cr
970OUTUART2 LDAB 1,X               ; check status
971         ANDB #$4
972         BEQ  OUTUART2          ; loop until tdre=1
973         ANDA #$7F              ; mask parity
974         STAA 3,X               ; send character
975OUTUART3 RTS
976
977;**********
978;*   ONSCI() - Initialize the SCI for 9600
979;*                   baud at 8 MHz Extal.
980;**********
981ONSCI    LDAA #$30
982         STAA BAUD              ; baud register
983         LDAA #$00
984         STAA SCCR1
985         LDAA #$0C
986         STAA SCCR2             ; enable
987         RTS
988
989;**********
990;*   INSCI() - Read from SCI.  Return a=char or 0.
991;**********
992INSCI    LDAA SCSR              ; read status reg
993         ANDA #$20              ; check rdrf
994         BEQ  INSCI1            ; jump if no data
995         LDAA SCDAT             ; read data
996         ANDA #$7F              ; mask parity
997INSCI1   RTS
998
999;**********
1000;*  OUTSCI() - Output A to sci. IF autolf = 1,
1001;*                 cr and lf sent as crlf.
1002;**********
1003OUTSCI   TST  AUTOLF
1004         BEQ  OUTSCI2           ; jump if autolf=0
1005         BSR  OUTSCI2
1006         CMPA #$0D
1007         BNE  OUTSCI1
1008         LDAA #$0A              ; if cr, send lf
1009         BRA  OUTSCI2
1010OUTSCI1  CMPA #$0A
1011         BNE  OUTSCI3
1012         LDAA #$0D              ; if lf, send cr
1013OUTSCI2  LDAB SCSR              ; read status
1014         BITB #$80
1015         BEQ  OUTSCI2           ; loop until tdre=1
1016         ANDA #$7F              ; mask parity
1017         STAA SCDAT             ; send character
1018OUTSCI3  RTS
1019
1020;**********
1021;*   ONACIA - Initialize the ACIA for
1022;* 8 data bits, 1 stop bit, divide by 64 clock.
1023;**********
1024ONACIA   LDX  #ACIA
1025         LDAA #$03
1026         STAA 0,X               ; master reset
1027         LDAA #$16
1028         STAA 0,X               ; setup
1029         RTS
1030
1031;**********
1032;*   INACIA - Read from the ACIA, Return a=char or 0.
1033;* Tmp3 is used to flag overrun or framing error.
1034;**********
1035INACIA   LDX  #ACIA
1036         LDAA 0,X               ; read status register
1037         PSHA
1038         ANDA #$30              ; check ov, fe
1039         PULA
1040         BEQ  INACIA1           ; jump - no error
1041         LDAA #$01
1042         STAA TMP3              ; flag receiver error
1043         BRA  INACIA2           ; read data to clear status
1044INACIA1  ANDA #$01              ; check rdrf
1045         BEQ  INACIA3           ; jump if no data
1046INACIA2  LDAA 1,X               ; read data
1047         ANDA #$7F              ; mask parity
1048INACIA3  RTS
1049
1050;**********
1051;*  OUTACIA - Output A to acia. IF autolf = 1,
1052;*                 cr or lf sent as crlf.
1053;**********
1054OUTACIA  BSR  OUTACIA3          ; output char
1055         TST  AUTOLF
1056         BEQ  OUTACIA2          ; jump no autolf
1057         CMPA #$0D
1058         BNE  OUTACIA1
1059         LDAA #$0A
1060         BSR  OUTACIA3          ; if cr, output lf
1061         BRA  OUTACIA2
1062OUTACIA1 CMPA #$0A
1063         BNE  OUTACIA2
1064         LDAA #$0D
1065         BSR  OUTACIA3          ; if lf, output cr
1066OUTACIA2 RTS
1067
1068OUTACIA3 LDX  #ACIA
1069         LDAB 0,X
1070         BITB #$2
1071         BEQ  OUTACIA3          ; loop until tdre
1072         ANDA #$7F              ; mask parity
1073         STAA 1,X               ; output
1074         RTS
1075;*
1076;*         Space for modifying OUTACIA routine
1077;*
1078         FDB  $FFFF,$FFFF,$FFFF,$FFFF
1079;*******************************
1080;*** I/O UTILITY SUBROUTINES ***
1081;***These subroutines perform the neccesary
1082;* data I/O operations.
1083;* OUTLHLF-Convert left 4 bits of A from binary
1084;*             to ASCII and output.
1085;* OUTRHLF-Convert right 4 bits of A from binary
1086;*             to ASCII and output.
1087;* OUT1BYT-Convert byte addresed by X from binary
1088;*            to ASCII and output.
1089;* OUT1BSP-Convert byte addressed by X from binary
1090;*            to ASCII and output followed by a space.
1091;* OUT2BSP-Convert 2 bytes addressed by X from binary
1092;*             to ASCII and  output followed by a space.
1093;* OUTSPAC-Output a space.
1094;*
1095;* OUTCRLF-Output a line feed and carriage return.
1096;*
1097;* OUTSTRG-Output the string of ASCII bytes addressed
1098;*             by X until $04.
1099;* OUTA-Output the ASCII character in A.
1100;*
1101;* TABTO-Output spaces until column 20 is reached.
1102;*
1103;* INCHAR-Input to A and echo one character.  Loops
1104;*             until character read.
1105;*         *******************
1106;
1107;**********
1108;*  OUTRHLF(), OUTLHLF(), OUTA()
1109;*Convert A from binary to ASCII and output.
1110;*Contents of A are destroyed..
1111;**********
1112OUTLHLF  LSRA                   ; shift data to right
1113         LSRA
1114         LSRA
1115         LSRA
1116OUTRHLF  ANDA #$0F              ; mask top half
1117         ADDA #$30              ; convert to ascii
1118         CMPA #$39
1119         BLE  OUTA              ; jump if 0-9
1120         ADDA #$07              ; convert to hex A-F
1121OUTA     JSR  OUTPUT            ; output character
1122         RTS
1123
1124;**********
1125;*  OUT1BYT(x) - Convert the byte at X to two
1126;* ASCII characters and output. Return X pointing
1127;* to next byte.
1128;**********
1129OUT1BYT  PSHA
1130         LDAA 0,X               ; get data in a
1131         PSHA                   ; save copy
1132         BSR  OUTLHLF           ; output left half
1133         PULA                   ; retrieve copy
1134         BSR  OUTRHLF           ; output right half
1135         PULA
1136         INX
1137         RTS
1138
1139;**********
1140;*  OUT1BSP(x), OUT2BSP(x) - Output 1 or 2 bytes
1141;* at x followed by a space.  Returns x pointing to
1142;* next byte.
1143;**********
1144OUT2BSP  JSR  OUT1BYT           ; do first byte
1145OUT1BSP  JSR  OUT1BYT           ; do next byte
1146OUTSPAC  LDAA #$20              ; output a space
1147         JSR  OUTPUT
1148         RTS
1149
1150;**********
1151;*  OUTCRLF() - Output a Carriage return and
1152;* a line feed.    Returns a = cr.
1153;**********
1154OUTCRLF  LDAA #$0D              ; cr
1155         JSR  OUTPUT            ; output a
1156         LDAA #$00
1157         JSR  OUTPUT            ; output padding
1158         LDAA #$0D
1159         CLR  CHRCNT            ; zero the column counter
1160         RTS
1161
1162;**********
1163;*  OUTSTRG(x) - Output string of ASCII bytes
1164;* starting at x until end of text ($04).  Can
1165;* be paused by control w (any char restarts).
1166;**********
1167OUTSTRG  JSR  OUTCRLF
1168OUTSTRG0 PSHA
1169OUTSTRG1 LDAA 0,X               ; read char into a
1170         CMPA #EOT
1171         BEQ  OUTSTRG3          ; jump if eot
1172         JSR  OUTPUT            ; output character
1173         INX
1174         JSR  INPUT
1175         BEQ  OUTSTRG1          ; jump if no input
1176         CMPA #CTLW
1177         BNE  OUTSTRG1          ; jump if not cntlw
1178OUTSTRG2 JSR  INPUT
1179         BEQ  OUTSTRG2          ; jump if any input
1180         BRA  OUTSTRG1
1181OUTSTRG3 PULA
1182         RTS
1183
1184
1185;*********
1186;*  TABTO() - move cursor over to column 20.
1187;*while(chrcnt < 16) outspac.
1188TABTO    EQU  *
1189        PSHA
1190TABTOLP JSR  OUTSPAC
1191        LDAA CHRCNT
1192        CMPA #20
1193        BLE  TABTOLP
1194        PULA
1195        RTS
1196
1197;**********
1198;*  INCHAR() - Reads input until character sent.
1199;*    Echoes char and returns with a = char.
1200INCHAR    JSR  INPUT
1201         TSTA
1202         BEQ  INCHAR            ; jump if no input
1203         JSR  OUTPUT            ; echo
1204         RTS
1205
1206;*********************
1207;*** COMMAND TABLE ***
1208COMTABL  EQU  *
1209         FCB  5
1210         FCC  "ASSEM"
1211         FDB  ASSEM
1212         FCB  5
1213         FCC  "BREAK"
1214         FDB  BREAK
1215         FCB  4
1216         FCC  "BULK"
1217         FDB  BULK
1218         FCB  7
1219         FCC  "BULKALL"
1220         FDB  BULKALL
1221         FCB  4
1222         FCC  "CALL"
1223         FDB  CALL
1224         FCB  4
1225         FCC  "DUMP"
1226         FDB  DUMP
1227         FCB  4
1228         FCC  "FILL"
1229         FDB  FILL
1230         FCB  2
1231         FCC  "GO"
1232         FDB  GO
1233         FCB  4
1234         FCC  "HELP"
1235         FDB  HELP
1236         FCB  4
1237         FCC  "HOST"
1238         FDB  HOST
1239         FCB  4
1240         FCC  "LOAD"
1241         FDB  LOAD
1242         FCB  6                 ; LENGTH OF COMMAND
1243         FCC  "MEMORY"          ; ASCII COMMAND
1244         FDB  MEMORY            ; COMMAND ADDRESS
1245         FCB  4
1246         FCC  "MOVE"
1247         FDB  MOVE
1248         FCB  7
1249         FCC  "PROCEED"
1250         FDB  PROCEED
1251         FCB  8
1252         FCC  "REGISTER"
1253         FDB  REGISTER
1254         FCB  6
1255         FCC  "STOPAT"
1256         FDB  STOPAT
1257         FCB  5
1258         FCC  "TRACE"
1259         FDB  TRACE
1260         FCB  6
1261         FCC  "VERIFY"
1262         FDB  VERIFY
1263         FCB  1
1264         FCC  "?"               ; initial command
1265         FDB  HELP
1266         FCB  5
1267         FCC  "XBOOT"
1268         FDB  BOOT
1269;*
1270;*** Command names for evm compatability ***
1271;*
1272         FCB  3
1273         FCC  "ASM"
1274         FDB  ASSEM
1275         FCB  2
1276         FCC  "BF"
1277         FDB  FILL
1278         FCB  4
1279         FCC  "COPY"
1280         FDB  MOVE
1281         FCB  5
1282         FCC  "ERASE"
1283         FDB  BULK
1284         FCB  2
1285         FCC  "MD"
1286         FDB  DUMP
1287         FCB  2
1288         FCC  "MM"
1289         FDB  MEMORY
1290         FCB  2
1291         FCC  "RD"
1292         FDB  REGISTER
1293         FCB  2
1294         FCC  "RM"
1295         FDB  REGISTER
1296         FCB  4
1297         FCC  "READ"
1298         FDB  MOVE
1299         FCB  2
1300         FCC  "TM"
1301         FDB  HOST
1302         FCB  4
1303         FCC  "TEST"
1304         FDB  EVBTEST
1305         FCB  $FF
1306
1307;*******************
1308;*** TEXT TABLES ***
1309
1310MSG1    FCC   "BUFFALO 3.2 (int) - Bit User Fast Friendly Aid to Logical Operation"
1311        FCB   EOT
1312MSG2    FCC   "What?"
1313        FCB   EOT
1314MSG3    FCC   "Too Long"
1315        FCB   EOT
1316MSG4    FCC   "Full"
1317        FCB   EOT
1318MSG5    FCC   "Op- "
1319        FCB   EOT
1320MSG6    FCC   "rom-"
1321        FCB   EOT
1322MSG8    FCC   "Command?"
1323        FCB   EOT
1324MSG9    FCC   "Bad argument"
1325        FCB   EOT
1326MSG10   FCC   "No host port available"
1327        FCB   EOT
1328MSG11   FCC   "done"
1329        FCB   EOT
1330MSG12   FCC   "checksum error"
1331        FCB   EOT
1332MSG13   FCC   "error addr "
1333        FCB   EOT
1334MSG14   FCC   "receiver error"
1335        FCB   EOT
1336
1337;**********
1338;*   break [-][<addr>] . . .
1339;* Modifies the breakpoint table.  More than
1340;* one argument can be entered on the command
1341;* line but the table will hold only 4 entries.
1342;* 4 types of arguments are implied above:
1343;* break    Prints table contents.
1344;* break <addr>      Inserts <addr>.
1345;* break -<addr>   Deletes <addr>.
1346;* break -           Clears all entries.
1347;**********
1348;* while 1
1349;*     a = wskip();
1350;*     switch(a)
1351;*           case(cr):
1352;*                 bprint(); return;
1353
1354BREAK   JSR  WSKIP
1355        BNE  BRKDEL             ; jump if not cr
1356        JSR  BPRINT             ; print table
1357        RTS
1358
1359;*           case("-"):
1360;*                 incbuff(); readbuff();
1361;*                 if(dchek(a))            /* look for wspac or cr */
1362;*                      bpclr();
1363;*                      breaksw;
1364;*                 a = buffarg();
1365;*                 if( !dchek(a) ) return(bad argument);
1366;*                 b = bpsrch();
1367;*                 if(b >= 0)
1368;*                      brktabl[b] = 0;
1369;*                 breaksw;
1370
1371BRKDEL  CMPA #'-'
1372        BNE  BRKDEF             ; jump if not -
1373        JSR  INCBUFF
1374        JSR  READBUFF
1375        JSR  DCHEK
1376        BNE  BRKDEL1            ; jump if not delimeter
1377        JSR  BPCLR              ; clear table
1378        JMP  BREAK              ; do next argument
1379BRKDEL1 JSR  BUFFARG            ; get address to delete
1380        JSR  DCHEK
1381        BEQ  BRKDEL2            ; jump if delimeter
1382        LDX  #MSG9              ; "bad argument"
1383        JSR  OUTSTRG
1384        RTS
1385BRKDEL2 JSR  BPSRCH             ; look for addr in table
1386        TSTB
1387        BMI  BRKDEL3            ; jump if not found
1388        LDX  #BRKTABL
1389        ABX
1390        CLR  0,X                ; clear entry
1391        CLR  1,X
1392BRKDEL3 JMP  BREAK              ; do next argument
1393
1394;*           default:
1395;*                 a = buffarg();
1396;*                 if( !dchek(a) ) return(bad argument);
1397;*                 b = bpsrch();
1398;*                 if(b < 0)              /* not already in table */
1399;*                      x = shftreg;
1400;*                      shftreg = 0;
1401;*                      a = x[0]; x[0] = $3F
1402;*                      b = x[0]; x[0] = a;
1403;*                      if(b != $3F) return(rom);
1404;*                      b = bpsrch();   /* look for hole */
1405;*                      if(b >= 0) return(table full);
1406;*                      brktabl[b] = x;
1407;*                 breaksw;
1408
1409BRKDEF  JSR  BUFFARG            ; get argument
1410        JSR  DCHEK
1411        BEQ  BRKDEF1            ; jump if delimiter
1412        LDX  #MSG9              ; "bad argument"
1413        JSR  OUTSTRG
1414        RTS
1415BRKDEF1 JSR  BPSRCH             ; look for entry in table
1416        TSTB
1417        BGE  BREAK              ; jump if already in table
1418
1419        LDX  SHFTREG            ; x = new entry addr
1420        LDAA 0,X                ; save original contents
1421        PSHA
1422        LDAA #SWI
1423        JSR  WRITE              ; write to entry addr
1424        LDAB 0,X                ; read back
1425        PULA
1426        JSR  WRITE              ; restore original
1427        CMPB #SWI
1428        BEQ  BRKDEF2            ; jump if writes ok
1429        STX  PTR1               ; save address
1430        LDX  #PTR1
1431        JSR  OUT2BSP            ; print address
1432        JSR  BPRINT
1433        RTS
1434BRKDEF2 CLR  SHFTREG
1435        CLR  SHFTREG+1
1436        PSHX
1437        JSR  BPSRCH             ; look for 0 entry
1438        PULX
1439        TSTB
1440        BPL  BRKDEF3            ; jump if table not full
1441        LDX  #MSG4              ; "full"
1442        JSR  OUTSTRG
1443        JSR  BPRINT
1444        RTS
1445BRKDEF3 LDY  #BRKTABL
1446        ABY
1447        STX  0,Y                ; put new entry in
1448        JMP  BREAK              ; do next argument
1449
1450;**********
1451;*   bprint() - print the contents of the table.
1452;**********
1453BPRINT  JSR  OUTCRLF
1454        LDX  #BRKTABL
1455        LDAB #4
1456BPRINT1 JSR  OUT2BSP
1457        DECB
1458        BGT  BPRINT1           ; loop 4 times
1459        RTS
1460
1461;**********
1462;*   bpsrch() - search table for address in
1463;* shftreg. Returns b = index to entry or
1464;* b = -1 if not found.
1465;**********
1466;*for(b=0; b=6; b=+2)
1467;*     x[] = brktabl + b;
1468;*     if(x[0] = shftreg)
1469;*           return(b);
1470;*return(-1);
1471
1472BPSRCH   CLRB
1473BPSRCH1  LDX  #BRKTABL
1474         ABX
1475         LDX  0,X               ; get table entry
1476         CPX  SHFTREG
1477         BNE  BPSRCH2           ; jump if no match
1478         RTS
1479BPSRCH2  INCB
1480         INCB
1481         CMPB #$6
1482         BLE  BPSRCH1           ; loop 4 times
1483         LDAB #$FF
1484         RTS
1485
1486
1487;**********
1488;*  bulk  - Bulk erase the eeprom not config.
1489;* bulkall - Bulk erase eeprom and config.
1490;*********
1491BULK    EQU  *
1492        LDX  #$B600
1493        BRA  BULK1
1494BULKALL LDX  #CONFIG
1495BULK1   LDAA #$FF
1496        JSR  EEBULK
1497        RTS
1498
1499
1500
1501;**********
1502;*  dump [<addr1> [<addr2>]]  - Dump memory
1503;* in 16 byte lines from <addr1> to <addr2>.
1504;*   Default starting address is "current
1505;* location" and default number of lines is 8.
1506;**********
1507;*ptr1 = ptrmem;        /* default start address */
1508;*ptr2 = ptr1 + $80;    /* default end address */
1509;*a = wskip();
1510;*if(a != cr)
1511;*     a = buffarg();
1512;*     if(countu1 = 0) return(bad argument);
1513;*     if( !dchek(a) ) return(bad argument);
1514;*     ptr1 = shftreg;
1515;*     ptr2 = ptr1 + $80;  /* default end address */
1516;*     a = wskip();
1517;*     if(a != cr)
1518;*           a = buffarg();
1519;*           if(countu1 = 0) return(bad argument);
1520;*           a = wskip();
1521;*           if(a != cr) return(bad argument);
1522;*           ptr2 = shftreg;
1523
1524DUMP     LDX  PTRMEM            ; current location
1525         STX  PTR1              ; default start
1526         LDAB #$80
1527         ABX
1528         STX  PTR2              ; default end
1529         JSR  WSKIP
1530         BEQ  DUMP1             ; jump - no arguments
1531         JSR  BUFFARG           ; read argument
1532         TST  COUNT
1533         BEQ  DUMPERR           ; jump if no argument
1534         JSR  DCHEK
1535         BNE  DUMPERR           ; jump if delimiter
1536         LDX  SHFTREG
1537         STX  PTR1
1538         LDAB #$80
1539         ABX
1540         STX  PTR2              ; default end address
1541         JSR  WSKIP
1542         BEQ  DUMP1             ; jump - 1 argument
1543         JSR  BUFFARG           ; read argument
1544         TST  COUNT
1545         BEQ  DUMPERR           ; jump if no argument
1546         JSR  WSKIP
1547         BNE  DUMPERR           ; jump if not cr
1548         LDX  SHFTREG
1549         STX  PTR2
1550         BRA  DUMP1             ; jump - 2 arguments
1551DUMPERR  LDX  #MSG9             ; "bad argument"
1552         JSR  OUTSTRG
1553         RTS
1554
1555;*ptrmem = ptr1;
1556;*ptr1 = ptr1 & $fff0;
1557
1558DUMP1    LDD  PTR1
1559         STD  PTRMEM            ; new current location
1560         ANDB #$F0
1561         STD  PTR1              ; start dump at 16 byte boundary
1562
1563;*** dump loop starts here ***
1564;*do:
1565;*     output address of first byte;
1566
1567DUMPLP   JSR  OUTCRLF
1568         LDX  #PTR1
1569         JSR  OUT2BSP           ; first address
1570
1571;*     x = ptr1;
1572;*     for(b=0; b=16; b++)
1573;*           output contents;
1574
1575         LDX  PTR1              ; base address
1576         CLRB                   ; loop counter
1577DUMPDAT  JSR  OUT1BSP           ; hex value loop
1578         INCB
1579         CMPB #$10
1580         BLT  DUMPDAT           ; loop 16 times
1581
1582;*     x = ptr1;
1583;*     for(b=0; b=16; b++)
1584;*           a = x[b];
1585;*           if($7A < a < $20)  a = $20;
1586;*           output ascii contents;
1587
1588         CLRB                   ; loop counter
1589DUMPASC  LDX  PTR1              ; base address
1590         ABX
1591         LDAA ,X                ; ascii value loop
1592         CMPA #$20
1593         BLO  DUMP3             ; jump if non printable
1594         CMPA #$7A
1595         BLS  DUMP4             ; jump if printable
1596DUMP3    LDAA #$20              ; space for non printables
1597DUMP4    JSR  OUTPUT            ; output ascii value
1598         INCB
1599         CMPB #$10
1600         BLT  DUMPASC           ; loop 16 times
1601
1602;*     chkabrt();
1603;*     ptr1 = ptr1 + $10;
1604;*while(ptr1 <= ptr2);
1605;*return;
1606
1607         JSR  CHKABRT           ; check abort or wait
1608         LDD  PTR1
1609         ADDD #$10              ; point to next 16 byte bound
1610         STD  PTR1              ; update ptr1
1611         CPD  PTR2
1612         BHI  DUMP5             ; quit if ptr1 > ptr2
1613         CPD  #$00              ; check wraparound at $ffff
1614         BNE  DUMPLP            ; jump - no wraparound
1615         LDD  PTR2
1616         CPD  #$FFF0
1617         BLO  DUMPLP            ; upper bound not at top
1618DUMP5    RTS                    ; quit
1619
1620
1621
1622;**********
1623;*  fill <addr1> <addr2> [<data>]  - Block fill
1624;*memory from addr1 to addr2 with data.       Data
1625;*defaults to $FF.
1626;**********
1627;*get addr1 and addr2
1628FILL    EQU  *
1629        JSR  WSKIP
1630        JSR  BUFFARG
1631        TST  COUNT
1632        BEQ  FILLERR            ; jump if no argument
1633        JSR  WCHEK
1634        BNE  FILLERR            ; jump if bad argument
1635        LDX  SHFTREG
1636        STX  PTR1               ; address1
1637        JSR  WSKIP
1638        JSR  BUFFARG
1639        TST  COUNT
1640        BEQ  FILLERR            ; jump if no argument
1641        JSR  DCHEK
1642        BNE  FILLERR            ; jump if bad argument
1643        LDX  SHFTREG
1644        STX  PTR2               ; address2
1645
1646;*Get data if it exists
1647        LDAA #$FF
1648        STAA TMP2               ; default data
1649        JSR  WSKIP
1650        BEQ  FILL1              ; jump if default data
1651        JSR  BUFFARG
1652        TST  COUNT
1653        BEQ  FILLERR            ; jump if no argument
1654        JSR  WSKIP
1655        BNE  FILLERR            ; jump if bad argument
1656        LDAA SHFTREG+1
1657        STAA TMP2
1658
1659;*while(ptr1 <= ptr2)
1660;*   *ptr1 = data
1661;*   if(*ptr1 != data) abort
1662
1663FILL1   EQU  *
1664        JSR  CHKABRT            ; check for abort
1665        LDX  PTR1               ; starting address
1666        LDAA TMP2               ; data
1667        JSR  WRITE              ; write the data to x
1668        CMPA 0,X
1669        BNE  FILLBAD            ; jump if no write
1670        CPX  PTR2
1671        BEQ  FILL2              ; quit yet?
1672        INX
1673        STX  PTR1
1674        BRA  FILL1              ; loop
1675FILL2   RTS
1676
1677FILLERR LDX  #MSG9              ; "bad argument"
1678        JSR  OUTSTRG
1679        RTS
1680
1681FILLBAD EQU  *
1682        LDX  #PTR1              ; output bad address
1683        JSR  OUT2BSP
1684        RTS
1685
1686
1687
1688;**********
1689;*   call [<addr>] - Execute a jsr to <addr> or user
1690;*pc value.  Return to monitor via  rts or breakpoint.
1691;**********
1692;*a = wskip();
1693;*if(a != cr)
1694;*     a = buffarg();
1695;*     a = wskip();
1696;*     if(a != cr) return(bad argument)
1697;*     pc = shftreg;
1698CALL     JSR  WSKIP
1699         BEQ  CALL3             ; jump if no arg
1700         JSR  BUFFARG
1701         JSR  WSKIP
1702         BEQ  CALL2             ; jump if cr
1703         LDX  #MSG9             ; "bad argument"
1704         JSR  OUTSTRG
1705         RTS
1706CALL2    LDX  SHFTREG
1707         STX  REGS              ; pc = <addr>
1708
1709;*put return address on user stack
1710;*setbps();
1711;*restack();       /* restack and go*/
1712CALL3    LDX  SP
1713         DEX                    ; user stack pointer
1714         LDD  #RETURN           ; return address
1715         STD  0,X
1716         DEX
1717         STX  SP                ; new user stack pointer
1718         JSR  SETBPS
1719         CLR  TMP2              ; 1=go, 0=call
1720         JMP  RESTACK           ; go to user code
1721
1722;**********
1723;*   return() - Return here from rts after
1724;*call command.
1725;**********
1726RETURN   PSHA                   ; save a register
1727         TPA
1728         STAA REGS+8            ; cc register
1729         PULA
1730         STD  REGS+6            ; a and b registers
1731         STX  REGS+4            ; x register
1732         STY  REGS+2            ; y register
1733         STS  SP                ; user stack pointer
1734         LDS  PTR2              ; monitor stack pointer
1735         JSR  REMBPS            ; remove breakpoints
1736         JSR  OUTCRLF
1737         JSR  RPRINT            ; print user registers
1738         RTS
1739
1740
1741;**********
1742;*   proceed - Same as go except it ignores
1743;*a breakpoint at the first opcode.  Calls
1744;*runone for the first instruction only.
1745;**********
1746PROCEED  EQU  *
1747         JSR  RUNONE            ; run one instruction
1748         JSR  CHKABRT           ; check for abort
1749         CLR  TMP2              ; flag for breakpoints
1750         INC  TMP2              ; 1=go 0=call
1751         JSR  SETBPS
1752         JMP  RESTACK           ; go execute
1753
1754;**********
1755;*   go [<addr>] - Execute starting at <addr> or
1756;*user's pc value.  Executes an rti to user code.
1757;*Returns to monitor via an swi through swiin.
1758;**********
1759;*a = wskip();
1760;*if(a != cr)
1761;*     a = buffarg();
1762;*     a = wskip();
1763;*     if(a != cr) return(bad argument)
1764;*     pc = shftreg;
1765;*setbps();
1766;*restack();       /* restack and go*/
1767GO       JSR  WSKIP
1768         BEQ  GO2               ; jump if no arg
1769         JSR  BUFFARG
1770         JSR  WSKIP
1771         BEQ  GO1               ; jump if cr
1772         LDX  #MSG9             ; "bad argument"
1773         JSR  OUTSTRG
1774         RTS
1775GO1      LDX  SHFTREG
1776         STX  REGS              ; pc = <addr>
1777GO2      CLR  TMP2
1778         INC  TMP2              ; 1=go, 0=call
1779         JSR  SETBPS
1780         JMP  RESTACK           ; go to user code
1781
1782;*****
1783;** SWIIN - Breakpoints from go or call commands enter here.
1784;*Remove breakpoints, save user registers, return
1785SWIIN    EQU  *                 ; swi entry point
1786         TSX                    ; user sp -> x
1787         LDS  PTR2              ; restore monitor sp
1788         JSR  SAVSTACK          ; save user regs
1789         JSR  REMBPS            ; remove breakpoints from code
1790         LDX  REGS
1791         DEX
1792         STX  REGS              ; save user pc value
1793
1794;*if(call command) remove call return addr from user stack;
1795         TST  TMP2              ; 1=go, 0=call
1796         BNE  GO3               ; jump if go command
1797         LDX  SP                ; remove return address
1798         INX                    ; user stack pointer
1799         INX
1800         STX  SP
1801GO3      JSR  OUTCRLF           ; print register values
1802         JSR  RPRINT
1803         RTS                    ; done
1804
1805;**********
1806;*  setbps - Replace user code with swi's at
1807;*breakpoint addresses.
1808;**********
1809;*for(b=0; b=6; b =+ 2)
1810;*     x = brktabl[b];
1811;*     if(x != 0)
1812;*           optabl[b] = x[0];
1813;*           x[0] = $3F;
1814;*Put monitor SWI vector into jump table
1815
1816SETBPS   CLRB
1817SETBPS1  LDX  #BRKTABL
1818         LDY  #PTR4
1819         ABX
1820         ABY
1821         LDX  0,X               ; breakpoint table entry
1822         BEQ  SETBPS2           ; jump if 0
1823         LDAA 0,X               ; save user opcode
1824         STAA 0,Y
1825         LDAA #SWI
1826         JSR  WRITE             ; insert swi into code
1827SETBPS2  ADDB #$2
1828         CMPB #$6
1829         BLE  SETBPS1           ; loop 4 times
1830         LDX  JSWI+1
1831         STX  PTR3              ; save user swi vector
1832         LDAA #$7E              ; jmp opcode
1833         STAA JSWI
1834         LDX  #SWIIN
1835         STX  JSWI+1            ; monitor swi vector
1836         RTS
1837
1838;**********
1839;*   rembps - Remove breakpoints from user code.
1840;**********
1841;*for(b=0; b=6; b =+ 2)
1842;*     x = brktabl[b];
1843;*     if(x != 0)
1844;*           x[0] = optabl[b];
1845;*Replace user's SWI vector
1846REMBPS   CLRB
1847REMBPS1  LDX  #BRKTABL
1848         LDY  #PTR4
1849         ABX
1850         ABY
1851         LDX  0,X               ; breakpoint table entry
1852         BEQ  REMBPS2           ; jump if 0
1853         LDAA 0,Y
1854         JSR  WRITE             ; restore user opcode
1855REMBPS2  ADDB #$2
1856         CMPB #$6
1857         BLE  REMBPS1           ; loop 4 times
1858         LDX  PTR3              ; restore user swi vector
1859         STX  JSWI+1
1860         RTS
1861
1862
1863;**********
1864;*   trace <n> - Trace n instructions starting
1865;*at user's pc value. n is a hex number less than
1866;*$FF (defaults to 1).
1867;**********
1868;*a = wskip();
1869;*if(a != cr)
1870;*     a = buffarg(); a = wskip();
1871;*     if(a != cr) return(bad argument);
1872;*     countt1 = n
1873TRACE    CLR  TMP4
1874         INC  TMP4              ; default count=1
1875         CLR  CHRCNT            ; set up for display
1876         JSR  WSKIP
1877         BEQ  TRACE2            ; jump if cr
1878         JSR  BUFFARG
1879         JSR  WSKIP
1880         BEQ  TRACE1            ; jump if cr
1881         LDX  #MSG9             ; "bad argument"
1882         JSR  OUTSTRG
1883         RTS
1884TRACE1   LDAA SHFTREG+1         ; n
1885         STAA TMP4
1886
1887;*Disassemble the line about to be traced
1888TRACE2   EQU  *
1889         LDAB TMP4
1890         PSHB
1891         LDX  REGS
1892         STX  PTR1              ; pc value for disass
1893         JSR  DISASSM
1894         PULB
1895         STAB TMP4
1896
1897;*run one instruction
1898;*rprint();
1899;*while(count > 0) continue trace;
1900         JSR  RUNONE
1901         JSR  CHKABRT           ; check for abort
1902         JSR  TABTO             ; print registers for
1903         JSR  RPRINT            ; result of trace
1904         DEC  TMP4
1905         BEQ  TRACDON           ; quit if count=0
1906TRACE3   JSR  OUTCRLF
1907         BRA  TRACE2
1908TRACDON  RTS
1909
1910
1911;**********
1912;*   stopat <addr> - Trace instructions until <addr>
1913;*is reached.
1914;**********
1915;*if((a=wskip) != cr)
1916;*     a = buffarg(); a = wskip();
1917;*     if(a != cr) return(bad argument);
1918;*else return(bad argument);
1919STOPAT   EQU  *
1920         JSR  WSKIP
1921         BEQ  STOPGO            ; jump if cr - no argument
1922         JSR  BUFFARG
1923         JSR  WSKIP
1924         BEQ  STOPAT1           ; jump if cr
1925         LDX  #MSG9             ; "bad argument"
1926         JSR  OUTSTRG
1927         RTS
1928STOPAT1  TST  COUNT
1929         BEQ  STOPGO            ; jump if no argument
1930         LDX  SHFTREG
1931         STX  PTRMEM            ; update "current location"
1932
1933;*while(!(ptrmem <= userpc < ptrmem+10)) runone();
1934;*rprint();
1935STOPGO   LDD  REGS              ; userpc
1936         CPD  PTRMEM
1937         BLO  STOPNEXT          ; if(userpc < ptrmem) runone
1938         LDD  PTRMEM
1939         ADDD #10
1940         CPD  REGS
1941         BHI  STOPDON           ; quit if ptrmem+10 > userpc
1942STOPNEXT JSR  RUNONE
1943         JSR  CHKABRT           ; check for abort
1944         BRA  STOPGO
1945STOPDON  JSR  OUTCRLF
1946         JSR  RPRINT            ; result of trace
1947         RTS                    ; done
1948
1949
1950;*************************
1951;* runone - This routine is used by the trace and
1952;* execute commands to run one only one user instruction.
1953;*   Control is passed to the user code via an RTI.  OC5
1954;* is then used to trigger an XIRQ as soon as the first user
1955;* opcode is fetched.  Control then returns to the monitor
1956;* through XIRQIN.
1957;*  Externally, the OC5 pin must be wired to the XIRQ pin.
1958;************************
1959;* Disable oc5 interrupts
1960;* Put monitor XIRQ vector into jump table
1961;* Unmask x bit in user ccr
1962;* Setup OC5 to go low when first user instruction executed
1963RUNONE  EQU  *
1964        LDAA #$7E               ; put "jmp xirqin" in jump table
1965        STAA JTOC5
1966        LDX  #XIRQIN
1967        STX  JXIRQ+1
1968        LDAA REGS+8             ; x bit will be cleared when
1969        ANDA #$BF               ; rti is executed below
1970        STAA REGS+8
1971        LDAB #87                ; cycles to end of rti
1972        LDX  TCNT
1973        ABX                     ;                     3~
1974        STX  TOC5               ; oc5 match register         5~
1975        LDAA TCTL1              ;                     4~
1976        ANDA #$FE               ; set up oc5 low on match 2~
1977        STAA TCTL1              ; enable oc5 interrupt       4~    / 86~
1978
1979;** RESTACK - Restore user stack and RTI to user code.
1980;* This code is the pathway to execution of user code.
1981;*(Force extended addressing to maintain cycle count)
1982;*Restore user stack and rti to user code
1983RESTACK EQU  *                  ;                     68~
1984        STS  >PTR2              ; save monitor sp
1985        LDS  >SP                ; user stack pointer
1986        LDX  >REGS
1987        PSHX                    ; pc
1988        LDX  >REGS+2
1989        PSHX                    ; y
1990        LDX  >REGS+4
1991        PSHX                    ; x
1992        LDD  >REGS+6
1993        PSHA                    ; a
1994        PSHB                    ; b
1995        LDAA >REGS+8
1996        PSHA                    ; ccr
1997        RTI
1998
1999;** Return here from run one line of user code.
2000XIRQIN  EQU  *
2001        TSX                     ; user sp -> x
2002        LDS  PTR2               ; restore monitor sp
2003
2004;** SAVSTACK - Save user's registers.
2005;* On entry - x points to top of user stack.
2006SAVSTACK EQU *
2007        LDAA 0,X
2008        STAA REGS+8             ; user ccr
2009        LDD  1,X
2010        STAA REGS+7             ; b
2011        STAB REGS+6             ; a
2012        LDD  3,X
2013        STD  REGS+4             ; x
2014        LDD  5,X
2015        STD  REGS+2             ; y
2016        LDD  7,X
2017        STD  REGS               ; pc
2018        LDAB #8
2019        ABX
2020        STX  SP                 ; user stack pointer
2021        LDAA TCTL1              ; force oc5 pin high which
2022        ORAA #$03               ; is tied to xirq line
2023        STAA TCTL1
2024        LDAA #$08
2025        STAA CFORC
2026        RTS
2027
2028
2029;**********
2030;*   help  -  List buffalo commands to terminal.
2031;**********
2032HELP     EQU  *
2033         LDX  #HELPMSG1
2034         JSR  OUTSTRG           ; print help screen
2035         RTS
2036
2037HELPMSG1 EQU  *
2038         FCC  "ASM [<addr>]  Line assembler/disassembler."
2039         FCB  $0D
2040         FCC  "    /        Do same address.           ^        Do previous address."
2041         FCB  $0D
2042         FCC  "    CTRL-J   Do next address.           RETURN   Do next opcode."
2043         FCB  $0D
2044         FCC  "    CTRL-A   Quit."
2045         FCB  $0D
2046         FCC  "BF <addr1> <addr2> [<data>]  Block fill."
2047         FCB  $0D
2048         FCC  "BR [-][<addr>]  Set up breakpoint table."
2049         FCB  $0D
2050         FCC  "BULK  Erase the EEPROM.                   BULKALL  Erase EEPROM and CONFIG."
2051         FCB  $0D
2052         FCC  "CALL [<addr>]  Call user subroutine.      G [<addr>]  Execute user code."
2053         FCB  $0D
2054         FCC  "LOAD, VERIFY [T] <host download command>  Load or verify S-records."
2055         FCB  $0D
2056         FCC  "MD [<addr1> [<addr2>]]  Memory dump."
2057         FCB  $0D
2058         FCC  "MM [<addr>]  Memory modify."
2059         FCB  $0D
2060         FCC  "    /        Open same address.         CTRL-H or ^   Open previous address."
2061         FCB  $0D
2062         FCC  "    CTRL-J   Open next address.         SPACE         Open next address."
2063         FCB  $0D
2064         FCC  "    RETURN   Quit.                      <addr>O       Compute offset to <addr>."
2065         FCB  $0D
2066         FCC  "MOVE <s1> <s2> [<d>]  Block move."
2067         FCB  $0D
2068         FCC  "P  Proceed/continue execution."
2069         FCB  $0D
2070         FCC  "RM [P, Y, X, A, B, C, or S]  Register modify."
2071         FCB  $0D
2072         FCC  "T [<n>]  Trace n instructions."
2073         FCB  $0D
2074         FCC  "TM  Transparent mode (CTRL-A = exit, CTRL-B = send break)."
2075         FCB  $0D
2076         FCC  "CTRL-H  Backspace.                      CTRL-W  Wait for any key."
2077         FCB  $0D
2078         FCC  "CTRL-X or DELETE  Abort/cancel command."
2079         FCB  $0D
2080         FCC  "RETURN  Repeat last command."
2081         FCB  4
2082
2083;**********
2084;*   HOST() - Establishes transparent link between
2085;*        terminal and host.  Port used for host is
2086;*        determined in the reset initialization routine
2087;*        and stored in HOSTDEV.
2088;*           To exit type control A.
2089;*           To send break to host type control B.
2090;*if(no external device) return;
2091;*initialize host port;
2092;*While( !(control A))
2093;*     input(terminal); output(host);
2094;*     input(host); output(terminal);
2095
2096HOST      LDAA EXTDEV
2097          BNE  HOST0            ; jump if host port avail.
2098          LDX  #MSG10           ; "no host port avail"
2099          JSR  OUTSTRG
2100          RTS
2101HOST0     CLR  AUTOLF           ; turn off autolf
2102          JSR  HOSTCO           ; connect sci (evb board)
2103          JSR  HOSTINIT         ; initialize host port
2104HOST1     JSR  INPUT            ; read terminal
2105          TSTA
2106          BEQ  HOST3            ; jump if no char
2107          CMPA #CTLA
2108          BEQ  HOSTEND          ; jump if control a
2109          CMPA #CTLB
2110          BNE  HOST2            ; jump if not control b
2111          JSR  TXBREAK          ; send break to host
2112          BRA  HOST3
2113HOST2     JSR  HOSTOUT          ; echo to host
2114HOST3     JSR  HOSTIN           ; read host
2115          TSTA
2116          BEQ  HOST1            ; jump if no char
2117          JSR  OUTPUT           ; echo to terminal
2118          BRA  HOST1
2119HOSTEND   INC  AUTOLF           ; turn on autolf
2120          JSR  TARGCO           ; disconnect sci (evb board)
2121          RTS                   ; return
2122
2123;**********
2124;* txbreak() - transmit break to host port.
2125;* The duration of the transmitted break is
2126;* approximately 200,000 E-clock cycles, or
2127;* 100ms at 2.0 MHz.
2128;***********
2129TXBREAK   EQU  *
2130          LDAA HOSTDEV
2131          CMPA #$03
2132          BEQ  TXBDU            ; jump if duartb is host
2133
2134TXBSCI    LDX  #SCCR2           ; sci is host
2135          BSET 0,X,#01          ; set send break bit
2136          BSR  TXBWAIT
2137          BCLR 0,X,#01          ; clear send break bit
2138          BRA TXB1
2139
2140TXBDU     LDX  #PORTB           ; duart host port
2141          LDAA #$60             ; start break cmd
2142          STAA 2,X              ; port b command register
2143          BSR  TXBWAIT
2144          LDAA #$70             ; stop break cmd
2145          STAA 2,X              ; port b command register
2146
2147TXB1      LDAA #$0D
2148          JSR  HOSTOUT          ; send carriage return
2149          LDAA #$0A
2150          JSR  HOSTOUT          ; send linefeed
2151          RTS
2152
2153TXBWAIT   LDY  #$6F9B           ; loop count = 28571
2154TXBWAIT1  DEY                   ; 7 cycle loop
2155          BNE  TXBWAIT1
2156          RTS
2157
2158
2159;**********
2160;*   hostinit(), hostin(), hostout() - host i/o
2161;*routines.  Restores original terminal device.
2162;**********
2163HOSTINIT  LDAB IODEV            ; save terminal
2164          PSHB
2165          LDAB HOSTDEV
2166          STAB IODEV            ; point to host
2167          JSR  INIT             ; initialize host
2168          BRA  TERMRES          ; restore terminal
2169HOSTIN    LDAB IODEV            ; save terminal
2170          PSHB
2171          LDAB HOSTDEV
2172          STAB IODEV            ; point to host
2173          JSR  INPUT            ; read host
2174          BRA  TERMRES          ; restore terminal
2175HOSTOUT   LDAB IODEV            ; save terminal
2176          PSHB
2177          LDAB HOSTDEV
2178          STAB IODEV            ; point to host
2179          JSR  OUTPUT           ; write to host
2180TERMRES   PULB                  ; restore terminal device
2181          STAB IODEV
2182          RTS
2183
2184
2185;**********
2186;*   load(ptrbuff[]) - Load s1/s9 records from
2187;*host to memory.  Ptrbuff[] points to string in
2188;*input buffer which is a command to output s1/s9
2189;*records from the host ("cat filename" for unix).
2190;*    Returns error and address if it can't write
2191;*to a particular location.
2192;**********
2193;*   verify(ptrbuff[]) - Verify memory from load
2194;*command.  Ptrbuff[] is same as for load.
2195;* tmp3 is used as an error indication, 0=no errors,
2196;* 1=receiver, 2=rom error, 3=checksum error.
2197;**********
2198VERIFY    CLR  TMP2
2199          INC  TMP2             ; TMP2=1=verify
2200          BRA  LOAD1
2201LOAD      CLR  TMP2             ; 0=load
2202
2203;*a=wskip();
2204;*if(a = cr) goto transparent mode;
2205;*if(t option) hostdev = iodev;
2206LOAD1      CLR  TMP3            ; clear error flag
2207          JSR  WSKIP
2208          BNE  LOAD2
2209          JMP  HOST             ; go to host if no args
2210LOAD2     JSR  UPCASE
2211          CMPA #'T'             ; look for t option
2212          BNE  LOAD3            ; jump not t option
2213          JSR  INCBUFF
2214          JSR  READBUFF         ; get next character
2215          JSR  DECBUFF
2216          CMPA #$0D
2217          BNE  LOAD3            ; jump if not t option
2218          CLR  AUTOLF
2219          LDAA IODEV
2220          STAA HOSTDEV          ; set host port = terminal
2221          BRA  LOAD10           ; go wait for s1 records
2222
2223;*else while(not cr)
2224;*     read character from input buffer;
2225;*     send character to host;
2226LOAD3     CLR  AUTOLF
2227          JSR  HOSTCO           ; connect sci (evb board)
2228          JSR  HOSTINIT         ; initialize host port
2229LOAD4     JSR  READBUFF         ; get next char
2230          JSR  INCBUFF
2231          PSHA                  ; save char
2232          JSR  HOSTOUT          ; output to host
2233          JSR  OUTPUT           ; echo to terminal
2234          PULA
2235          CMPA #$0D
2236          BNE  LOAD4            ; jump if not cr
2237
2238;*repeat:                      /* look for s records */
2239;*      if(hostdev != iodev) check abort;
2240;*      a = hostin();
2241;*      if(a = 'S')
2242;*           a = hostin;
2243;*           if(a = '1')
2244;*               checksum = 0;
2245;*               get byte count in b;
2246;*               get base address in x;
2247;*               while(byte count > 0)
2248;*                    byte();
2249;*                    x++; b--;
2250;*                    if(tmp3=0)              /* no error */
2251;*                        if(load) x[0] = shftreg+1;
2252;*                        if(x[0] != shftreg+1)
2253;*                             tmp3 = 2;      /* rom error */
2254;*                             ptr3 = x;      /* save address */
2255;*               if(tmp3 = 0) do checksum;
2256;*               if(checksum err) tmp3 = 3; /* checksum error */
2257LOAD10    EQU  *
2258          LDAA HOSTDEV
2259          CMPA IODEV
2260          BEQ  LOAD11           ; jump if hostdev=iodev
2261          JSR  CHKABRT          ; check for abort
2262LOAD11    JSR  HOSTIN           ; read host
2263          TSTA
2264          BEQ  LOAD10           ; jump if no input
2265          CMPA #'S'
2266          BNE  LOAD10           ; jump if not S
2267LOAD12    JSR  HOSTIN           ; read host
2268          TSTA
2269          BEQ  LOAD12           ; jump if no input
2270          CMPA #'9'
2271          BEQ  LOAD90           ; jump if S9 record
2272          CMPA #'1'
2273          BNE  LOAD10           ; jump if not S1
2274          CLR  TMP4             ; clear checksum
2275          JSR  BYTE
2276          LDAB SHFTREG+1
2277          SUBB #$2              ; b = byte count
2278          JSR  BYTE
2279          JSR  BYTE
2280          LDX  SHFTREG          ; x = base address
2281          DEX
2282LOAD20    JSR  BYTE             ; get next byte
2283          INX
2284          DECB                  ; check byte count
2285          BEQ  LOAD30           ; if b=0, go do checksum
2286          TST  TMP3
2287          BNE  LOAD10           ; jump if error flagged
2288          TST  TMP2
2289          BNE  LOAD21           ; jump if verify
2290          LDAA SHFTREG+1
2291          JSR  WRITE            ; load only
2292LOAD21    CMPA 0,X              ; verify ram location
2293          BEQ  LOAD20           ; jump if ram ok
2294          LDAA #$02
2295          STAA TMP3             ; indicate rom error
2296          STX  PTR3             ; save error address
2297          BRA  LOAD20           ; finish download
2298
2299;* calculate checksum
2300LOAD30    TST  TMP3
2301          BNE  LOAD10           ; jump if error already
2302          LDAA TMP4
2303          INCA                  ; do checksum
2304          BEQ  LOAD10           ; jump if s1 record okay
2305          LDAA #$03
2306          STAA TMP3             ; indicate checksum error
2307          BRA  LOAD10
2308
2309;*           if(a = '9')
2310;*               read rest of record;
2311;*               if(tmp3=2) return("[ptr3]");
2312;*               if(tmp3=1) return("rcv error");
2313;*               if(tmp3=3) return("checksum err");
2314;*               else return("done");
2315LOAD90    JSR  BYTE
2316          LDAB SHFTREG+1        ; b = byte count
2317LOAD91    JSR  BYTE
2318          DECB
2319          BNE  LOAD91           ; loop until end of record
2320          INC  AUTOLF           ; turn on autolf
2321          JSR  TARGCO           ; disconnect sci (evb)
2322          LDX  #MSG11           ; "done" default msg
2323          LDAA TMP3
2324          CMPA #$02
2325          BNE  LOAD92           ; jump not rom error
2326          LDX  #PTR3
2327          JSR  OUT2BSP          ; address of rom error
2328          BRA  LOAD95
2329LOAD92    CMPA #$01
2330          BNE  LOAD93           ; jump not rcv error
2331          LDX  #MSG14           ; "rcv error"
2332          BRA  LOAD94
2333LOAD93    CMPA #$03
2334          BNE  LOAD94           ; jump not checksum error
2335          LDX  #MSG12           ; "checksum error"
2336LOAD94    JSR  OUTSTRG
2337LOAD95    RTS
2338
2339
2340;**********
2341;*  byte() -  Read 2 ascii bytes from host and
2342;*convert to one hex byte.  Returns byte
2343;*shifted into shftreg and added to tmp4.
2344;**********
2345BYTE      PSHB
2346          PSHX
2347BYTE0     JSR  HOSTIN           ; read host (1st byte)
2348          TSTA
2349          BEQ  BYTE0            ; loop until input
2350          JSR  HEXBIN
2351BYTE1     JSR  HOSTIN           ; read host (2nd byte)
2352          TSTA
2353          BEQ  BYTE1            ; loop until input
2354          JSR  HEXBIN
2355          LDAA SHFTREG+1
2356          ADDA TMP4
2357          STAA TMP4             ; add to checksum
2358          PULX
2359          PULB
2360          RTS
2361
2362
2363;*******************************************
2364;*   MEMORY [<addr>]
2365;*   [<addr>]/
2366;* Opens memory and allows user to modify the
2367;*contents at <addr> or the last opened location.
2368;*    Subcommands:
2369;* [<data>]<cr> - Close current location and exit.
2370;* [<data>]<lf> - Close current and open next.
2371;* [<data>]<^> - Close current and open previous.
2372;* [<data>]<sp> - Close current and open next.
2373;* [<data>]/ - Reopen current location.
2374;*     The contents of the current location is only
2375;*  changed if valid data is entered before each
2376;*  subcommand.
2377;* [<addr>]O - Compute relative offset from current
2378;*     location to <addr>.  The current location must
2379;*     be the address of the offset byte.
2380;**********
2381;*a = wskip();
2382;*if(a != cr)
2383;*     a = buffarg();
2384;*     if(a != cr) return(bad argument);
2385;*     if(countu1 != 0) ptrmem[] = shftreg;
2386
2387MEMORY   JSR  WSKIP
2388         BEQ  MEM1              ; jump if cr
2389         JSR  BUFFARG
2390         JSR  WSKIP
2391         BEQ  MSLASH            ; jump if cr
2392         LDX  #MSG9             ; "bad argument"
2393         JSR  OUTSTRG
2394         RTS
2395MSLASH   TST  COUNT
2396         BEQ  MEM1              ; jump if no argument
2397         LDX  SHFTREG
2398         STX  PTRMEM            ; update "current location"
2399
2400;**********
2401;* Subcommands
2402;**********
2403;*outcrlf();
2404;*out2bsp(ptrmem[]);
2405;*out1bsp(ptrmem[0]);
2406
2407MEM1     JSR  OUTCRLF
2408MEM2     LDX  #PTRMEM
2409         JSR  OUT2BSP           ; output address
2410MEM3     LDX  PTRMEM
2411         JSR  OUT1BSP           ; output contents
2412         CLR  SHFTREG
2413         CLR  SHFTREG+1
2414;*while 1
2415;*a = termarg();
2416;*     switch(a)
2417;*           case(space):
2418;*              chgbyt();
2419;*              ptrmem[]++;
2420;*           case(linefeed):
2421;*              chgbyt();
2422;*              ptrmem[]++;
2423;*           case(up arrow):
2424;*           case(backspace):
2425;*                 chgbyt();
2426;*                 ptrmem[]--;
2427;*           case("/"):
2428;*                 chgbyt();
2429;*                 outcrlf();
2430;*           case(O):
2431;*                 d = ptrmem[0] - (shftreg);
2432;*                 if($80 < d < $ff81)
2433;*                      print(out of range);
2434;*                 countt1 = d-1;
2435;*                 out1bsp(countt1);
2436;*           case(carriage return):
2437;*                 chgbyt();
2438;*                 return;
2439;*           default: return(command?)
2440
2441MEM4     JSR  TERMARG
2442         JSR  UPCASE
2443         LDX  PTRMEM
2444         CMPA #$20
2445         BEQ  MEMSP             ; jump if space
2446         CMPA #$0A
2447         BEQ  MEMLF             ; jump if linefeed
2448         CMPA #$5E
2449         BEQ  MEMUA             ; jump if up arrow
2450         CMPA #$08
2451         BEQ  MEMBS             ; jump if backspace
2452         CMPA #'/'
2453         BEQ  MEMSL             ; jump if /
2454         CMPA #'O'
2455         BEQ  MEMOFF            ; jump if O
2456         CMPA #$0D
2457         BEQ  MEMCR             ; jump if carriage ret
2458         LDX  #MSG8             ; "command?"
2459         JSR  OUTSTRG
2460         JMP  MEM1
2461MEMSP    JSR  CHGBYT
2462         INX
2463         STX  PTRMEM
2464         JMP  MEM3              ; output contents
2465MEMLF    JSR  CHGBYT
2466         INX
2467         STX  PTRMEM
2468         JMP  MEM2              ; output addr, contents
2469MEMUA    EQU  *
2470MEMBS    JSR  CHGBYT
2471         DEX
2472         STX  PTRMEM
2473         JMP  MEM1              ; output cr, addr, contents
2474MEMSL    JSR  CHGBYT
2475         JMP  MEM1              ; output cr, addr, contents
2476MEMOFF   LDD  SHFTREG           ; destination addr
2477         SUBD PTRMEM
2478         CMPA #$0
2479         BNE  MEMOFF1           ; jump if not 0
2480         CMPB #$80
2481         BLS  MEMOFF3           ; jump if in range
2482         BRA  MEMOFF2           ; out of range
2483MEMOFF1  CMPA #$FF
2484         BNE  MEMOFF2           ; out of range
2485         CMPB #$81
2486         BHS  MEMOFF3           ; in range
2487MEMOFF2  LDX  #MSG3             ; "Too long"
2488         JSR  OUTSTRG
2489         JMP  MEM1              ; output cr, addr, contents
2490MEMOFF3  SUBD #$1               ; b now has offset
2491         STAB TMP4
2492         JSR  OUTSPAC
2493         LDX  #TMP4
2494         JSR  OUT1BSP           ; output offset
2495         JMP  MEM1              ; output cr, addr, contents
2496MEMCR    JSR  CHGBYT
2497         RTS                    ; exit task
2498
2499
2500;**********
2501;*   move <src1> <src2> [<dest>]  - move
2502;*block at <src1> to <src2> to <dest>.
2503;*  Moves block 1 byte up if no <dest>.
2504;**********
2505;*a = buffarg();
2506;*if(countu1 = 0) return(bad argument);
2507;*if( !wchek(a) ) return(bad argument);
2508;*ptr1 = shftreg;   /* src1 */
2509
2510MOVE     EQU  *
2511         JSR  BUFFARG
2512         TST  COUNT
2513         BEQ  MOVERR            ; jump if no arg
2514         JSR  WCHEK
2515         BNE  MOVERR            ; jump if no delim
2516         LDX  SHFTREG           ; src1
2517         STX  PTR1
2518
2519;*a = buffarg();
2520;*if(countu1 = 0) return(bad argument);
2521;*if( !dchek(a) ) return(bad argument);
2522;*ptr2 = shftreg;   /* src2 */
2523
2524         JSR  BUFFARG
2525         TST  COUNT
2526         BEQ  MOVERR            ; jump if no arg
2527         JSR  DCHEK
2528         BNE  MOVERR            ; jump if no delim
2529         LDX  SHFTREG           ; src2
2530         STX  PTR2
2531
2532;*a = buffarg();
2533;*a = wskip();
2534;*if(a != cr) return(bad argument);
2535;*if(countu1 != 0) tmp2 = shftreg;  /* dest */
2536;*else tmp2 = ptr1 + 1;
2537
2538         JSR  BUFFARG
2539         JSR  WSKIP
2540         BNE  MOVERR            ; jump if not cr
2541         TST  COUNT
2542         BEQ  MOVE1             ; jump if no arg
2543         LDX  SHFTREG           ; dest
2544         BRA  MOVE2
2545MOVERR   LDX  #MSG9             ; "bad argument"
2546         JSR  OUTSTRG
2547         RTS
2548
2549MOVE1    LDX  PTR1
2550         INX                    ; default dest
2551MOVE2    STX  PTR3
2552
2553;*if(src1 < dest <= src2)
2554;*     dest = dest+(src2-src1);
2555;*     for(x = src2; x = src1; x--)
2556;*           dest[0]-- = x[0]--;
2557         LDX  PTR3              ; dest
2558         CPX  PTR1              ; src1
2559         BLS  MOVE3             ; jump if dest =< src1
2560         CPX  PTR2              ; src2
2561         BHI  MOVE3             ; jump if dest > src2
2562         LDD  PTR2
2563         SUBD PTR1
2564         ADDD PTR3
2565         STD  PTR3              ; dest = dest+(src2-src1)
2566         LDX  PTR2
2567MOVELP1  JSR  CHKABRT           ; check for abort
2568         LDAA ,X                ; char at src2
2569         PSHX
2570         LDX  PTR3
2571         JSR  WRITE             ; write a to x
2572         CMPA 0,X
2573         BNE  MOVEBAD           ; jump if no write
2574         DEX
2575         STX  PTR3
2576         PULX
2577         CPX  PTR1
2578         BEQ  MOVRTS
2579         DEX
2580         BRA  MOVELP1           ; Loop SRC2 - SRC1 times
2581;*
2582;* else
2583;*     for(x=src1; x=src2; x++)
2584;*           dest[0]++ = x[0]++;
2585
2586
2587MOVE3    LDX  PTR1              ; srce1
2588MOVELP2  JSR  CHKABRT           ; check for abort
2589         LDAA ,X
2590         PSHX
2591         LDX  PTR3              ; dest
2592         JSR  WRITE             ; write a to x
2593         CMPA 0,X
2594         BNE  MOVEBAD           ; jump if no write
2595         INX
2596         STX  PTR3
2597         PULX
2598         CPX  PTR2
2599         BEQ  MOVRTS
2600         INX
2601         BRA  MOVELP2           ; Loop SRC2-SRC1 times
2602MOVRTS   RTS
2603
2604MOVEBAD  LDX  #PTR3
2605         JSR  OUT2BSP           ; output bad address
2606         RTS
2607
2608;**********
2609;*   register [<name>]  - prints the user regs
2610;*and opens them for modification.  <name> is
2611;*the first register opened (default = P).
2612;*   Subcommands:
2613;* [<nn>]<space>  Opens the next register.
2614;* [<nn>]<cr>       Return.
2615;*    The register value is only changed if
2616;*    <nn> is entered before the subcommand.
2617;**********
2618;*x[] = reglist
2619;*a = wskip(); a = upcase(a);
2620;*if(a != cr)
2621;*     while( a != x[0] )
2622;*           if( x[0] = "s") return(bad argument);
2623;*           x[]++;
2624;*     incbuff(); a = wskip();
2625;*     if(a != cr) return(bad argument);
2626
2627REGISTER LDX  #REGLIST
2628         JSR  WSKIP             ; a = first char of arg
2629         JSR  UPCASE            ; convert to upper case
2630         CMPA #$D
2631         BEQ  REG4              ; jump if no argument
2632REG1     CMPA 0,X
2633         BEQ  REG3
2634         LDAB 0,X
2635         INX
2636         CMPB #'S'
2637         BNE  REG1              ; jump if not "s"
2638REG2     LDX  #MSG9             ; "bad argument"
2639         JSR  OUTSTRG
2640         RTS
2641REG3     PSHX
2642         JSR  INCBUFF
2643         JSR  WSKIP             ; next char after arg
2644         PULX
2645         BNE  REG2              ; jump if not cr
2646
2647;*rprint();
2648;*     while(x[0] != "s")
2649;*           rprnt1(x);
2650;*           a = termarg();    /* read from terminal */
2651;*           if( ! dchek(a) ) return(bad argument);
2652;*           if(countu1 != 0)
2653;*                 if(x[14] = 1)
2654;*                      regs[x[7]++ = shftreg;
2655;*                 regs[x[7]] = shftreg+1;
2656;*           if(a = cr) break;
2657;*return;
2658
2659REG4     JSR  RPRINT            ; print all registers
2660REG5     JSR  OUTCRLF
2661         JSR  RPRNT1            ; print reg name
2662         CLR  SHFTREG
2663         CLR  SHFTREG+1
2664         JSR  TERMARG           ; read subcommand
2665         JSR  DCHEK
2666         BEQ  REG6              ; jump if delimeter
2667         LDX  #MSG9             ; "bad argument"
2668         JSR  OUTSTRG
2669         RTS
2670REG6     PSHA
2671         PSHX
2672         TST  COUNT
2673         BEQ  REG8              ; jump if no input
2674         LDAB 7,X               ; get reg offset
2675         LDAA 14,X              ; byte size
2676         LDX  #REGS             ; user registers
2677         ABX
2678         TSTA
2679         BEQ  REG7              ; jump if 1 byte reg
2680         LDAA SHFTREG
2681         STAA 0,X               ; put in top byte
2682         INX
2683REG7     LDAA SHFTREG+1
2684         STAA 0,X               ; put in bottom byte
2685REG8     PULX
2686         PULA
2687         LDAB 0,X               ; CHECK FOR REGISTER S
2688         CMPB #'S'
2689         BEQ  REG9              ; jump if "s"
2690         INX                    ; point to next register
2691         CMPA #$D
2692         BNE  REG5              ; jump if not cr
2693REG9     RTS
2694
2695PAGE1    EQU  $00               ; values for page opcodes
2696PAGE2    EQU  $18
2697PAGE3    EQU  $1A
2698PAGE4    EQU  $CD
2699IMMED    EQU  $0                ; addressing modes
2700INDX     EQU  $1
2701INDY     EQU  $2
2702LIMMED   EQU  $3                ; (long immediate)
2703OTHER    EQU  $4
2704
2705;*** Rename variables for assem/disassem ***
2706AMODE    EQU  TMP2              ; addressing mode
2707YFLAG    EQU  TMP3
2708PNORM    EQU  TMP4              ; page for normal opcode
2709OLDPC    EQU  PTR8
2710PC       EQU  PTR1              ; program counter
2711PX       EQU  PTR2              ; page for x indexed
2712PY       EQU  PTR2+1            ; page for y indexed
2713BASEOP   EQU  PTR3              ; base opcode
2714CLASS    EQU  PTR3+1            ; class
2715DISPC    EQU  PTR4              ; pc for disassembler
2716BRADDR   EQU  PTR5              ; relative branch offset
2717MNEPTR   EQU  PTR6              ; pointer to table for dis
2718ASSCOMM  EQU  PTR7              ; subcommand for assembler
2719
2720;*** Error messages for assembler ***
2721MSGDIR   FDB  MSGA1             ; message table index
2722         FDB  MSGA2
2723         FDB  MSGA3
2724         FDB  MSGA4
2725         FDB  MSGA5
2726         FDB  MSGA6
2727         FDB  MSGA7
2728         FDB  MSGA8
2729         FDB  MSGA9
2730MSGA1    FCC  "Immediate mode illegal"
2731         FCB  EOT
2732MSGA2    FCC  "Error in mnemonic table"
2733         FCB  EOT
2734MSGA3    FCC  "Illegal bit op"
2735         FCB  EOT
2736MSGA4    FCC  "Bad argument"
2737         FCB  EOT
2738MSGA5    FCC  "Mnemonic not found"
2739         FCB  EOT
2740MSGA6    FCC  "Unknown addressing mode"
2741         FCB  EOT
2742MSGA7    FCC  "Indexed addressing assumed"
2743         FCB  EOT
2744MSGA8    FCC  "Syntax error"
2745         FCB  EOT
2746MSGA9    FCC  "Branch out of range"
2747         FCB  EOT
2748
2749;****************
2750;*  assem(addr) -68HC11 line assembler/disassembler.
2751;*        This routine will disassemble the opcode at
2752;*<addr> and then allow the user to enter a line for
2753;*assembly. Rules for assembly are as follows:
2754;* -A '#' sign indicates immediate addressing.
2755;* -A ',' (comma) indicates indexed addressing
2756;*        and the next character must be X or Y.
2757;* -All arguments are assumed to be hex and the
2758;*        '$' sign shouldn't be used.
2759;* -Arguments should be separated by 1 or more
2760;*        spaces or tabs.
2761;* -Any input after the required number of
2762;*        arguments is ignored.
2763;* -Upper or lower case makes no difference.
2764;*
2765;*        To signify end of input line, the following
2766;*commands are available and have the indicated action:
2767;*   <cr>  -Carriage return finds the next opcode for
2768;*           assembly.  If there was no assembly input,
2769;*           the next opcode disassembled is retrieved
2770;*           from the disassembler.
2771;*   <lf>  -Linefeed works the same as carriage return
2772;*           except if there was no assembly input, the
2773;*           <addr> is incremented and the next <addr> is
2774;*           disassembled.
2775;*    '^'  -Up arrow decrements <addr> and the previous
2776;*           address is then disassembled.
2777;*    '/'  -Slash redisassembles the current address.
2778;*
2779;*        To exit the assembler use CONTROL A.  Of course
2780;*control X and DEL will also allow you to abort.
2781;**********
2782;*oldpc = rambase;
2783;*a = wskip();
2784;*if (a != cr)
2785;*   buffarg()
2786;*   a = wskip();
2787;*   if ( a != cr ) return(error);
2788;*   oldpc = a;
2789
2790ASSEM   EQU  *
2791        LDX  #RAMBS
2792        STX  OLDPC
2793        JSR  WSKIP
2794        BEQ  ASSLOOP            ; jump if no argument
2795        JSR  BUFFARG
2796        JSR  WSKIP
2797        BEQ  ASSEM1             ; jump if argument ok
2798        LDX  #MSGA4             ; "bad argument"
2799        JSR  OUTSTRG
2800        RTS
2801ASSEM1  LDX  SHFTREG
2802        STX  OLDPC
2803
2804;*repeat
2805;*  pc = oldpc;
2806;*  out2bsp(pc);
2807;*  disassem();
2808;*  a=readln();
2809;*  asscomm = a;  /* save command */
2810;*  if(a == ('^' or '/')) outcrlf;
2811;*  if(a == 0) return(error);
2812
2813ASSLOOP LDX  OLDPC
2814        STX  PC
2815        JSR  OUTCRLF
2816        LDX  #PC
2817        JSR  OUT2BSP            ; output the address
2818        JSR  DISASSM            ; disassemble opcode
2819        JSR  TABTO
2820        LDAA #PROMPT            ; prompt user
2821        JSR  OUTA               ; output prompt character
2822        JSR  READLN             ; read input for assembly
2823        STAA ASSCOMM
2824        CMPA #'^'
2825        BEQ  ASSLP0             ; jump if up arrow
2826        CMPA #'/'
2827        BEQ  ASSLP0             ; jump if slash
2828        CMPA #$00
2829        BNE  ASSLP1             ; jump if none of above
2830        RTS                     ; return if bad input
2831ASSLP0  JSR  OUTCRLF
2832ASSLP1  EQU  *
2833        JSR  OUTSPAC
2834        JSR  OUTSPAC
2835        JSR  OUTSPAC
2836        JSR  OUTSPAC
2837        JSR  OUTSPAC
2838
2839;*  b = parse(input); /* get mnemonic */
2840;*  if(b > 5) print("not found"); asscomm='/';
2841;*  elseif(b >= 1)
2842;*     msrch();
2843;*     if(class==$FF)
2844;*         print("not found"); asscomm='/';
2845;*     else
2846;*         a = doop(opcode,class);
2847;*         if(a == 0) dispc=0;
2848;*         else process error; asscomm='/';
2849
2850        JSR  PARSE
2851        CMPB #$5
2852        BLE  ASSLP2             ; jump if mnemonic <= 5 chars
2853        LDX  #MSGA5             ; "mnemonic not found"
2854        JSR  OUTSTRG
2855        BRA  ASSLP5
2856ASSLP2  EQU  *
2857        CMPB #$0
2858        BEQ  ASSLP10            ; jump if no input
2859        JSR  MSRCH
2860        LDAA CLASS
2861        CMPA #$FF
2862        BNE  ASSLP3
2863        LDX  #MSGA5             ; "mnemonic not found"
2864        JSR  OUTSTRG
2865        BRA  ASSLP5
2866ASSLP3  JSR  DOOP
2867        CMPA #$00
2868        BNE  ASSLP4             ; jump if doop error
2869        LDX  #$00
2870        STX  DISPC              ; indicate good assembly
2871        BRA  ASSLP10
2872ASSLP4  DECA                    ; a = error message index
2873        TAB
2874        LDX  #MSGDIR
2875        ABX
2876        ABX
2877        LDX  0,X
2878        JSR  OUTSTRG            ; output error message
2879ASSLP5  CLR  ASSCOMM            ; error command
2880
2881;*  /* compute next address - asscomm holds subcommand
2882;*     and dispc indicates if valid assembly occured. */
2883;*  if(asscomm=='^') oldpc -= 1;
2884;*  if(asscomm==(lf or cr)
2885;*     if(dispc==0) oldpc=pc;
2886;*     else
2887;*         if(asscomm==lf) dispc=oldpc+1;
2888;*         oldpc=dispc;
2889;*until(eot)
2890
2891
2892ASSLP10 EQU  *
2893        LDAA ASSCOMM
2894        CMPA #'^'
2895        BNE  ASSLP11            ; jump if not up arrow
2896        LDX  OLDPC
2897        DEX
2898        STX  OLDPC              ; back up
2899        BRA  ASSLP15
2900ASSLP11 CMPA #$0A
2901        BEQ  ASSLP12            ; jump if linefeed
2902        CMPA #$0D
2903        BNE  ASSLP15            ; jump if not cr
2904ASSLP12 LDX  DISPC
2905        BNE  ASSLP13            ; jump if dispc != 0
2906        LDX  PC
2907        STX  OLDPC
2908        BRA  ASSLP15
2909ASSLP13 CMPA #$0A
2910        BNE  ASSLP14            ; jump if not linefeed
2911        LDX  OLDPC
2912        INX
2913        STX  DISPC
2914ASSLP14 LDX  DISPC
2915        STX  OLDPC
2916ASSLP15 JMP  ASSLOOP
2917
2918;****************
2919;*  readln() --- Read input from terminal into buffer
2920;* until a command character is read (cr,lf,/,^).
2921;* If more chars are typed than the buffer will hold,
2922;* the extra characters are overwritten on the end.
2923;*  On exit: b=number of chars read, a=0 if quit,
2924;* else a=next command.
2925;****************
2926;*for(b==0;b<=bufflng;b++) inbuff[b] = cr;
2927
2928READLN  CLRB
2929        LDAA #$0D               ; carriage ret
2930RLN0    LDX  #INBUFF
2931        ABX
2932        STAA 0,X                ; initialize input buffer
2933        INCB
2934        CMPB #BUFFLNG
2935        BLT  RLN0
2936;*b=0;
2937;*repeat
2938;*  if(a == (ctla, cntlc, cntld, cntlx, del))
2939;*     return(a=0);
2940;*  if(a == backspace)
2941;*     if(b > 0) b--;
2942;*     else b=0;
2943;*  else  inbuff[b] = upcase(a);
2944;*  if(b < bufflng) b++;
2945;*until (a == (cr,lf,^,/))
2946;*return(a);
2947
2948        CLRB
2949RLN1    JSR  INCHAR
2950        CMPA #DEL               ; Delete
2951        BEQ  RLNQUIT
2952        CMPA #CTLX              ; Control X
2953        BEQ  RLNQUIT
2954        CMPA #CTLA              ; Control A
2955        BEQ  RLNQUIT
2956        CMPA #$03               ; Control C
2957        BEQ  RLNQUIT
2958        CMPA #$04               ; Control D
2959        BEQ  RLNQUIT
2960        CMPA #$08               ; backspace
2961        BNE  RLN2
2962        DECB
2963        BGT  RLN1
2964        BRA  READLN             ; start over
2965RLN2    LDX  #INBUFF
2966        ABX
2967        JSR  UPCASE
2968        STAA 0,X                ; put char in buffer
2969        CMPB #BUFFLNG           ; max buffer length
2970        BGE  RLN3               ; jump if buffer full
2971        INCB                    ; move buffer pointer
2972RLN3    JSR  ASSCHEK            ; check for subcommand
2973        BNE  RLN1
2974        RTS
2975RLNQUIT CLRA                    ; quit
2976        RTS                     ; return
2977
2978
2979;**********
2980;*  parse() -parse out the mnemonic from INBUFF
2981;* to COMBUFF. on exit: b=number of chars parsed.
2982;**********
2983;*combuff[3] = <space>;      initialize 4th character to space.
2984;*ptrbuff[] = inbuff[];
2985;*a=wskip();
2986;*for (b = 0; b = 5; b++)
2987;*   a=readbuff(); incbuff();
2988;*   if (a = (cr,lf,^,/,wspace)) return(b);
2989;*   combuff[b] = upcase(a);
2990;*return(b);
2991
2992PARSE   LDAA #$20
2993        STAA COMBUFF+3
2994        LDX  #INBUFF            ; initialize buffer ptr
2995        STX  PTR0
2996        JSR  WSKIP              ; find first character
2997        CLRB
2998PARSLP  JSR  READBUFF           ; read character
2999        JSR  INCBUFF
3000        JSR  WCHEK
3001        BEQ  PARSRT             ; jump if whitespace
3002        JSR  ASSCHEK
3003        BEQ  PARSRT             ; jump if end of line
3004        JSR  UPCASE             ; convert to upper case
3005        LDX  #COMBUFF
3006        ABX
3007        STAA 0,X                ; store in combuff
3008        INCB
3009        CMPB #$5
3010        BLE  PARSLP             ; loop 6 times
3011PARSRT  RTS
3012
3013
3014;****************
3015;*  asschek() -perform compares for
3016;* cr, lf, ^, /
3017;****************
3018ASSCHEK CMPA #$0A               ; linefeed
3019        BEQ  ASSCHK1
3020        CMPA #$0D               ; carriage ret
3021        BEQ  ASSCHK1
3022        CMPA #'^'               ; up arrow
3023        BEQ  ASSCHK1
3024        CMPA #'/'               ; slash
3025ASSCHK1 RTS
3026
3027
3028;*********
3029;*  msrch() --- Search MNETABL for mnemonic in COMBUFF.
3030;*stores base opcode at baseop and class at class.
3031;*  Class = FF if not found.
3032;**********
3033;*while ( != EOF )
3034;*   if (COMBUFF[0-3] = MNETABL[0-3])
3035;*      return(MNETABL[4],MNETABL[5]);
3036;*   else *MNETABL =+ 6
3037
3038MSRCH   LDX  #MNETABL           ; pointer to mnemonic table
3039        LDY  #COMBUFF           ; pointer to string
3040        BRA  MSRCH1
3041MSNEXT  EQU  *
3042        LDAB #6
3043        ABX                     ; point to next table entry
3044MSRCH1  LDAA 0,X                ; read table
3045        CMPA #EOT
3046        BNE  MSRCH2             ; jump if not end of table
3047        LDAA #$FF
3048        STAA CLASS              ; FF = not in table
3049        RTS
3050MSRCH2  CMPA 0,Y                ; op[0] = tabl[0] ?
3051        BNE  MSNEXT
3052        LDAA 1,X
3053        CMPA 1,Y                ; op[1] = tabl[1] ?
3054        BNE  MSNEXT
3055        LDAA 2,X
3056        CMPA 2,Y                ; op[2] = tabl[2] ?
3057        BNE  MSNEXT
3058        LDAA 3,X
3059        CMPA 3,Y                ; op[2] = tabl[2] ?
3060        BNE  MSNEXT
3061        LDD  4,X                ; opcode, class
3062        STAA BASEOP
3063        STAB CLASS
3064        RTS
3065
3066;**********
3067;**   doop(baseop,class) --- process mnemonic.
3068;**   on exit: a=error code corresponding to error
3069;**                                         messages.
3070;**********
3071;*amode = OTHER; /* addressing mode */
3072;*yflag = 0;       /* ynoimm, nlimm, and cpd flag */
3073;*x[] = ptrbuff[]
3074
3075DOOP    EQU  *
3076        LDAA #OTHER
3077        STAA AMODE              ; mode
3078        CLR  YFLAG
3079        LDX  PTR0
3080
3081;*while (*x != end of buffer)
3082;*   if (x[0]++ == ',')
3083;*      if (x[0] == 'y') amode = INDY;
3084;*      else amod = INDX;
3085;*      break;
3086;*a = wskip()
3087;*if( a == '#' ) amode = IMMED;
3088
3089DOPLP1  CPX  #ENDBUFF           ; (end of buffer)
3090        BEQ  DOOP1              ; jump if end of buffer
3091        LDD  0,X                ; read 2 chars from buffer
3092        INX                     ; move pointer
3093        CMPA #','
3094        BNE  DOPLP1
3095        CMPB #'Y'               ; look for ",y"
3096        BNE  DOPLP2
3097        LDAA #INDY
3098        STAA AMODE
3099        BRA  DOOP1
3100DOPLP2  CMPB #'X'               ; look for ",x"
3101        BNE  DOOP1              ; jump if not x
3102        LDAA #INDX
3103        STAA AMODE
3104        BRA  DOOP1
3105DOOP1   JSR  WSKIP
3106        CMPA #'#'               ; look for immediate mode
3107        BNE  DOOP2
3108        JSR  INCBUFF            ; point at argument
3109        LDAA #IMMED
3110        STAA AMODE
3111DOOP2   EQU  *
3112
3113;*switch(class)
3114        LDAB CLASS
3115        CMPB #P2INH
3116        BNE  DOSW1
3117        JMP  DOP2I
3118DOSW1   CMPB #INH
3119        BNE  DOSW2
3120        JMP  DOINH
3121DOSW2   CMPB #REL
3122        BNE  DOSW3
3123        JMP  DOREL
3124DOSW3   CMPB #LIMM
3125        BNE  DOSW4
3126        JMP  DOLIM
3127DOSW4   CMPB #NIMM
3128        BNE  DOSW5
3129        JMP  DONOI
3130DOSW5   CMPB #GEN
3131        BNE  DOSW6
3132        JMP  DOGENE
3133DOSW6   CMPB #GRP2
3134        BNE  DOSW7
3135        JMP  DOGRP
3136DOSW7   CMPB #CPD
3137        BNE  DOSW8
3138        JMP  DOCPD
3139DOSW8   CMPB #XNIMM
3140        BNE  DOSW9
3141        JMP  DOXNOI
3142DOSW9   CMPB #XLIMM
3143        BNE  DOSW10
3144        JMP  DOXLI
3145DOSW10  CMPB #YNIMM
3146        BNE  DOSW11
3147        JMP  DOYNOI
3148DOSW11  CMPB #YLIMM
3149        BNE  DOSW12
3150        JMP  DOYLI
3151DOSW12  CMPB #BTB
3152        BNE  DOSW13
3153        JMP  DOBTB
3154DOSW13  CMPB #SETCLR
3155        BNE  DODEF
3156        JMP  DOSET
3157
3158;*   default: return("error in mnemonic table");
3159
3160DODEF   LDAA #$2
3161        RTS
3162
3163;*  case P2INH: emit(PAGE2)
3164
3165DOP2I   LDAA #PAGE2
3166        JSR  EMIT
3167
3168;*  case INH: emit(baseop);
3169;*        return(0);
3170
3171DOINH   LDAA BASEOP
3172        JSR  EMIT
3173        CLRA
3174        RTS
3175
3176;*  case REL: a = assarg();
3177;*             if(a=4) return(a);
3178;*             d = address - pc + 2;
3179;*             if ($7f >= d >= $ff82)
3180;*                 return (out of range);
3181;*             emit(opcode);
3182;*             emit(offset);
3183;*             return(0);
3184
3185DOREL   JSR  ASSARG
3186        CMPA #$04
3187        BNE  DOREL1             ; jump if arg ok
3188        RTS
3189DOREL1  LDD  SHFTREG            ; get branch address
3190        LDX  PC                 ; get program counter
3191        INX
3192        INX                     ; point to end of opcode
3193        STX  BRADDR
3194        SUBD BRADDR             ; calculate offset
3195        STD  BRADDR             ; save result
3196        CPD #$7F                ; in range ?
3197        BLS  DOREL2             ; jump if in range
3198        CPD #$FF80
3199        BHS  DOREL2             ; jump if in range
3200        LDAA #$09               ; 'Out of range'
3201        RTS
3202DOREL2  LDAA BASEOP
3203        JSR  EMIT               ; emit opcode
3204        LDAA BRADDR+1
3205        JSR  EMIT               ; emit offset
3206        CLRA                    ; normal return
3207        RTS
3208
3209;*  case LIMM: if (amode == IMMED) amode = LIMMED;
3210
3211DOLIM   LDAA AMODE
3212        CMPA #IMMED
3213        BNE  DONOI
3214        LDAA #LIMMED
3215        STAA AMODE
3216
3217;*  case NIMM: if (amode == IMMED)
3218;*                  return("Immediate mode illegal");
3219
3220DONOI   LDAA AMODE
3221        CMPA #IMMED
3222        BNE  DOGENE             ; jump if not immediate
3223        LDAA #$1                ; "immediate mode illegal"
3224        RTS
3225
3226;*  case GEN: dogen(baseop,amode,PAGE1,PAGE1,PAGE2);
3227;*             return;
3228
3229DOGENE  LDAA #PAGE1
3230        STAA PNORM
3231        STAA PX
3232        LDAA #PAGE2
3233        STAA PY
3234        JSR  DOGEN
3235        RTS
3236
3237;*  case GRP2: if (amode == INDY)
3238;*                  emit(PAGE2);
3239;*                  amode = INDX;
3240;*              if( amode == INDX )
3241;*                  doindx(baseop);
3242;*              else a = assarg();
3243;*                  if(a=4) return(a);
3244;*                  emit(opcode+0x10);
3245;*                  emit(extended address);
3246;*              return;
3247
3248DOGRP   LDAA AMODE
3249        CMPA #INDY
3250        BNE  DOGRP1
3251        LDAA #PAGE2
3252        JSR  EMIT
3253        LDAA #INDX
3254        STAA AMODE
3255DOGRP1  EQU  *
3256        LDAA AMODE
3257        CMPA #INDX
3258        BNE  DOGRP2
3259        JSR  DOINDEX
3260        RTS
3261DOGRP2  EQU  *
3262        LDAA BASEOP
3263        ADDA #$10
3264        JSR  EMIT
3265        JSR  ASSARG
3266        CMPA #$04
3267        BEQ  DOGRPRT            ; jump if bad arg
3268        LDD  SHFTREG            ; extended address
3269        JSR  EMIT
3270        TBA
3271        JSR  EMIT
3272        CLRA
3273DOGRPRT RTS
3274
3275;*  case CPD: if (amode == IMMED)
3276;*                 amode = LIMMED; /* cpd */
3277;*             if( amode == INDY ) yflag = 1;
3278;*             dogen(baseop,amode,PAGE3,PAGE3,PAGE4);
3279;*             return;
3280
3281DOCPD   LDAA AMODE
3282        CMPA #IMMED
3283        BNE  DOCPD1
3284        LDAA #LIMMED
3285        STAA AMODE
3286DOCPD1  LDAA AMODE
3287        CMPA #INDY
3288        BNE  DOCPD2
3289        INC  YFLAG
3290DOCPD2  LDAA #PAGE3
3291        STAA PNORM
3292        STAA PX
3293        LDAA #PAGE4
3294        STAA PY
3295        JSR  DOGEN
3296        RTS
3297
3298;*  case XNIMM: if (amode == IMMED)  /* stx */
3299;*                   return("Immediate mode illegal");
3300
3301DOXNOI  LDAA AMODE
3302        CMPA #IMMED
3303        BNE  DOXLI
3304        LDAA #$1               ; "immediate mode illegal"
3305        RTS
3306
3307;*  case XLIMM: if (amode == IMMED)  /* cpx, ldx */
3308;*                   amode = LIMMED;
3309;*               dogen(baseop,amode,PAGE1,PAGE1,PAGE4);
3310;*               return;
3311
3312DOXLI   LDAA AMODE
3313        CMPA #IMMED
3314        BNE  DOXLI1
3315        LDAA #LIMMED
3316        STAA AMODE
3317DOXLI1  LDAA #PAGE1
3318        STAA PNORM
3319        STAA PX
3320        LDAA #PAGE4
3321        STAA PY
3322        JSR  DOGEN
3323        RTS
3324
3325;*  case YNIMM: if (amode == IMMED)  /* sty */
3326;*                   return("Immediate mode illegal");
3327
3328DOYNOI  LDAA AMODE
3329        CMPA #IMMED
3330        BNE  DOYLI
3331        LDAA #$1                ; "immediate mode illegal"
3332        RTS
3333
3334;*  case YLIMM: if (amode == INDY) yflag = 1;/* cpy, ldy */
3335;*               if(amode == IMMED) amode = LIMMED;
3336;*               dogen(opcode,amode,PAGE2,PAGE3,PAGE2);
3337;*               return;
3338
3339DOYLI   LDAA AMODE
3340        CMPA #INDY
3341        BNE  DOYLI1
3342        INC  YFLAG
3343DOYLI1  CMPA #IMMED
3344        BNE  DOYLI2
3345        LDAA #LIMMED
3346        STAA AMODE
3347DOYLI2  LDAA #PAGE2
3348        STAA PNORM
3349        STAA PY
3350        LDAA #PAGE3
3351        STAA PX
3352        JSR  DOGEN
3353        RTS
3354
3355;*  case BTB:          /* bset, bclr */
3356;*  case SETCLR: a = bitop(baseop,amode,class);
3357;*                 if(a=0) return(a = 3);
3358;*                 if( amode == INDY )
3359;*                    emit(PAGE2);
3360;*                    amode = INDX;
3361
3362DOBTB   EQU  *
3363DOSET   JSR  BITOP
3364        CMPA #$00
3365        BNE  DOSET1
3366        LDAA #$3                ; "illegal bit op"
3367        RTS
3368DOSET1  LDAA AMODE
3369        CMPA #INDY
3370        BNE  DOSET2
3371        LDAA #PAGE2
3372        JSR  EMIT
3373        LDAA #INDX
3374        STAA AMODE
3375DOSET2  EQU  *
3376
3377;*                 emit(baseop);
3378;*                 a = assarg();
3379;*                 if(a = 4) return(a);
3380;*                 emit(index offset);
3381;*                 if( amode == INDX )
3382;*                    Buffptr += 2;      /* skip ,x or ,y */
3383
3384        LDAA BASEOP
3385        JSR  EMIT
3386        JSR  ASSARG
3387        CMPA #$04
3388        BNE  DOSET22            ; jump if arg ok
3389        RTS
3390DOSET22 LDAA SHFTREG+1          ; index offset
3391        JSR  EMIT
3392        LDAA AMODE
3393        CMPA #INDX
3394        BNE  DOSET3
3395        JSR  INCBUFF
3396        JSR  INCBUFF
3397DOSET3  EQU  *
3398
3399;*                 a = assarg();
3400;*                 if(a = 4) return(a);
3401;*                 emit(mask);   /* mask */
3402;*                 if( class == SETCLR )
3403;*                    return;
3404
3405        JSR  ASSARG
3406        CMPA #$04
3407        BNE  DOSET33            ; jump if arg ok
3408        RTS
3409DOSET33 LDAA SHFTREG+1          ; mask
3410        JSR  EMIT
3411        LDAA CLASS
3412        CMPA #SETCLR
3413        BNE  DOSET4
3414        CLRA
3415        RTS
3416DOSET4  EQU  *
3417
3418;*                 a = assarg();
3419;*                 if(a = 4) return(a);
3420;*                 d = (pc+1) - shftreg;
3421;*                 if ($7f >= d >= $ff82)
3422;*                    return (out of range);
3423;*                 emit(branch offset);
3424;*                 return(0);
3425
3426        JSR  ASSARG
3427        CMPA #$04
3428        BNE  DOSET5             ; jump if arg ok
3429        RTS
3430DOSET5  LDX  PC                 ; program counter
3431        INX                     ; point to next inst
3432        STX  BRADDR             ; save pc value
3433        LDD  SHFTREG            ; get branch address
3434        SUBD BRADDR             ; calculate offset
3435        CPD #$7F
3436        BLS  DOSET6             ; jump if in range
3437        CPD #$FF80
3438        BHS  DOSET6             ; jump if in range
3439        CLRA
3440        JSR  EMIT
3441        LDAA #$09               ; 'out of range'
3442        RTS
3443DOSET6  TBA                     ; offset
3444        JSR  EMIT
3445        CLRA
3446        RTS
3447
3448
3449;**********
3450;**   bitop(baseop,amode,class) --- adjust opcode on bit
3451;**        manipulation instructions.  Returns opcode in a
3452;**        or a = 0 if error
3453;**********
3454;*if( amode == INDX || amode == INDY ) return(op);
3455;*if( class == SETCLR ) return(op-8);
3456;*else if(class==BTB) return(op-12);
3457;*else fatal("bitop");
3458
3459BITOP   EQU  *
3460        LDAA AMODE
3461        LDAB CLASS
3462        CMPA #INDX
3463        BNE  BITOP1
3464        RTS
3465BITOP1  CMPA #INDY
3466        BNE  BITOP2             ; jump not indexed
3467        RTS
3468BITOP2  CMPB #SETCLR
3469        BNE  BITOP3             ; jump not bset,bclr
3470        LDAA BASEOP             ; get opcode
3471        SUBA #8
3472        STAA BASEOP
3473        RTS
3474BITOP3  CMPB #BTB
3475        BNE  BITOP4             ; jump not bit branch
3476        LDAA BASEOP             ; get opcode
3477        SUBA #12
3478        STAA BASEOP
3479        RTS
3480BITOP4  CLRA                    ; 0 = fatal bitop
3481        RTS
3482
3483;**********
3484;**   dogen(baseop,mode,pnorm,px,py) - process
3485;** general addressing modes. Returns a = error #.
3486;**********
3487;*pnorm = page for normal addressing modes: IMM,DIR,EXT
3488;*px = page for INDX addressing
3489;*py = page for INDY addressing
3490;*switch(amode)
3491DOGEN   LDAA AMODE
3492        CMPA #LIMMED
3493        BEQ  DOGLIM
3494        CMPA #IMMED
3495        BEQ  DOGIMM
3496        CMPA #INDY
3497        BEQ  DOGINDY
3498        CMPA #INDX
3499        BEQ  DOGINDX
3500        CMPA #OTHER
3501        BEQ  DOGOTH
3502
3503;*default: error("Unknown Addressing Mode");
3504
3505DOGDEF  LDAA #$06               ; unknown addre...
3506        RTS
3507
3508;*case LIMMED: epage(pnorm);
3509;*              emit(baseop);
3510;*              a = assarg();
3511;*              if(a = 4) return(a);
3512;*              emit(2 bytes);
3513;*              return(0);
3514
3515DOGLIM  LDAA PNORM
3516        JSR  EPAGE
3517DOGLIM1 LDAA BASEOP
3518        JSR  EMIT
3519        JSR  ASSARG             ; get next argument
3520        CMPA #$04
3521        BNE  DOGLIM2            ; jump if arg ok
3522        RTS
3523DOGLIM2 LDD  SHFTREG
3524        JSR  EMIT
3525        TBA
3526        JSR  EMIT
3527        CLRA
3528        RTS
3529
3530;*case IMMED: epage(pnorm);
3531;*             emit(baseop);
3532;*             a = assarg();
3533;*             if(a = 4) return(a);
3534;*             emit(lobyte);
3535;*             return(0);
3536
3537DOGIMM  LDAA PNORM
3538        JSR  EPAGE
3539        LDAA BASEOP
3540        JSR  EMIT
3541        JSR  ASSARG
3542        CMPA #$04
3543        BNE  DOGIMM1            ; jump if arg ok
3544        RTS
3545DOGIMM1 LDAA SHFTREG+1
3546        JSR  EMIT
3547        CLRA
3548        RTS
3549
3550;*case INDY: epage(py);
3551;*            a=doindex(op+0x20);
3552;*            return(a);
3553
3554DOGINDY LDAA PY
3555        JSR  EPAGE
3556        LDAA BASEOP
3557        ADDA #$20
3558        STAA BASEOP
3559        JSR  DOINDEX
3560        RTS
3561
3562;*case INDX: epage(px);
3563;*            a=doindex(op+0x20);
3564;*            return(a);
3565
3566DOGINDX LDAA PX
3567        JSR  EPAGE
3568        LDAA BASEOP
3569        ADDA #$20
3570        STAA BASEOP
3571        JSR  DOINDEX
3572        RTS
3573
3574;*case OTHER: a = assarg();
3575;*             if(a = 4) return(a);
3576;*             epage(pnorm);
3577;*             if(countu1 <= 2 digits)   /* direct */
3578;*                 emit(op+0x10);
3579;*                 emit(lobyte(Result));
3580;*                 return(0);
3581;*             else    emit(op+0x30);    /* extended */
3582;*                 eword(Result);
3583;*                 return(0)
3584
3585DOGOTH  JSR  ASSARG
3586        CMPA #$04
3587        BNE  DOGOTH0            ; jump if arg ok
3588        RTS
3589DOGOTH0 LDAA PNORM
3590        JSR  EPAGE
3591        LDAA COUNT
3592        CMPA #$2
3593        BGT  DOGOTH1
3594        LDAA BASEOP
3595        ADDA #$10               ; direct mode opcode
3596        JSR  EMIT
3597        LDAA SHFTREG+1
3598        JSR  EMIT
3599        CLRA
3600        RTS
3601DOGOTH1 LDAA BASEOP
3602        ADDA #$30               ; extended mode opcode
3603        JSR  EMIT
3604        LDD  SHFTREG
3605        JSR  EMIT
3606        TBA
3607        JSR  EMIT
3608        CLRA
3609        RTS
3610
3611;**********
3612;**  doindex(op) --- handle all wierd stuff for
3613;**   indexed addressing. Returns a = error number.
3614;**********
3615;*emit(baseop);
3616;*a=assarg();
3617;*if(a = 4) return(a);
3618;*if( a != ',' ) return("Syntax");
3619;*buffptr++
3620;*a=readbuff()
3621;*if( a != 'x' &&  != 'y') warn("Ind Addr Assumed");
3622;*emit(lobyte);
3623;*return(0);
3624
3625DOINDEX LDAA BASEOP
3626        JSR  EMIT
3627        JSR  ASSARG
3628        CMPA #$04
3629        BNE  DOINDX0            ; jump if arg ok
3630        RTS
3631DOINDX0 CMPA #','
3632        BEQ  DOINDX1
3633        LDAA #$08               ; "syntax error"
3634        RTS
3635DOINDX1 JSR  INCBUFF
3636        JSR  READBUFF
3637        CMPA #'Y'
3638        BEQ  DOINDX2
3639        CMPA #'X'
3640        BEQ  DOINDX2
3641        LDX  MSGA7              ; "index addr assumed"
3642        JSR  OUTSTRG
3643DOINDX2 LDAA SHFTREG+1
3644        JSR  EMIT
3645        CLRA
3646        RTS
3647
3648;**********
3649;**   assarg(); - get argument.      Returns a = 4 if bad
3650;** argument, else a = first non hex char.
3651;**********
3652;*a = buffarg()
3653;*if(asschk(aa) && countu1 != 0) return(a);
3654;*return(bad argument);
3655
3656ASSARG  JSR  BUFFARG
3657        JSR  ASSCHEK            ; check for command
3658        BEQ  ASSARG1            ; jump if ok
3659        JSR  WCHEK              ; check for whitespace
3660        BNE  ASSARG2            ; jump if not ok
3661ASSARG1 TST  COUNT
3662        BEQ  ASSARG2            ; jump if no argument
3663        RTS
3664ASSARG2 LDAA #$04               ; bad argument
3665        RTS
3666
3667;**********
3668;**  epage(a) --- emit page prebyte
3669;**********
3670;*if( a != PAGE1 ) emit(a);
3671
3672EPAGE   CMPA #PAGE1
3673        BEQ  EPAGRT             ; jump if page 1
3674        JSR  EMIT
3675EPAGRT  RTS
3676
3677;**********
3678;*   emit(a) --- emit contents of a
3679;**********
3680EMIT    LDX  PC
3681        JSR  WRITE              ; write a to x
3682        JSR  OUT1BSP
3683        STX  PC
3684        RTS
3685
3686;*Mnemonic table for hc11 line assembler
3687NULL     EQU  $0                ; nothing
3688INH      EQU  $1                ; inherent
3689P2INH    EQU  $2                ; page 2 inherent
3690GEN      EQU  $3                ; general addressing
3691GRP2     EQU  $4                ; group 2
3692REL      EQU  $5                ; relative
3693IMM      EQU  $6                ; immediate
3694NIMM     EQU  $7                ; general except for immediate
3695LIMM     EQU  $8                ; 2 byte immediate
3696XLIMM    EQU  $9                ; longimm for x
3697XNIMM    EQU  $10               ; no immediate for x
3698YLIMM    EQU  $11               ; longimm for y
3699YNIMM    EQU  $12               ; no immediate for y
3700BTB      EQU  $13               ; bit test and branch
3701SETCLR   EQU  $14               ; bit set or clear
3702CPD      EQU  $15               ; compare d
3703BTBD     EQU  $16               ; bit test and branch direct
3704SETCLRD  EQU  $17               ; bit set or clear direct
3705
3706;**********
3707;*   mnetabl - includes all '11 mnemonics, base opcodes,
3708;* and type of instruction.  The assembler search routine
3709;*depends on 4 characters for each mnemonic so that 3 char
3710;*mnemonics are extended with a space and 5 char mnemonics
3711;*are truncated.
3712;**********
3713
3714MNETABL EQU  *
3715        FCC  "ABA "             ; Mnemonic
3716        FCB  $1B                ; Base opcode
3717        FCB  INH                ; Class
3718        FCC  "ABX "
3719        FCB  $3A
3720        FCB  INH
3721        FCC  "ABY "
3722        FCB  $3A
3723        FCB  P2INH
3724        FCC  "ADCA"
3725        FCB  $89
3726        FCB  GEN
3727        FCC  "ADCB"
3728        FCB  $C9
3729        FCB  GEN
3730        FCC  "ADDA"
3731        FCB  $8B
3732        FCB  GEN
3733        FCC  "ADDB"
3734        FCB  $CB
3735        FCB  GEN
3736        FCC  "ADDD"
3737        FCB  $C3
3738        FCB  LIMM
3739        FCC  "ANDA"
3740        FCB  $84
3741        FCB  GEN
3742        FCC  "ANDB"
3743        FCB  $C4
3744        FCB  GEN
3745        FCC  "ASL "
3746        FCB  $68
3747        FCB  GRP2
3748        FCC  "ASLA"
3749        FCB  $48
3750        FCB  INH
3751        FCC  "ASLB"
3752        FCB  $58
3753        FCB  INH
3754        FCC  "ASLD"
3755        FCB  $05
3756        FCB  INH
3757        FCC  "ASR "
3758        FCB  $67
3759        FCB  GRP2
3760        FCC  "ASRA"
3761        FCB  $47
3762        FCB  INH
3763        FCC  "ASRB"
3764        FCB  $57
3765        FCB  INH
3766        FCC  "BCC "
3767        FCB  $24
3768        FCB  REL
3769        FCC  "BCLR"
3770        FCB  $1D
3771        FCB  SETCLR
3772        FCC  "BCS "
3773        FCB  $25
3774        FCB  REL
3775        FCC  "BEQ "
3776        FCB  $27
3777        FCB  REL
3778        FCC  "BGE "
3779        FCB  $2C
3780        FCB  REL
3781        FCC  "BGT "
3782        FCB  $2E
3783        FCB  REL
3784        FCC  "BHI "
3785        FCB  $22
3786        FCB  REL
3787        FCC  "BHS "
3788        FCB  $24
3789        FCB  REL
3790        FCC  "BITA"
3791        FCB  $85
3792        FCB  GEN
3793        FCC  "BITB"
3794        FCB  $C5
3795        FCB  GEN
3796        FCC  "BLE "
3797        FCB  $2F
3798        FCB  REL
3799        FCC  "BLO "
3800        FCB  $25
3801        FCB  REL
3802        FCC  "BLS "
3803        FCB  $23
3804        FCB  REL
3805        FCC  "BLT "
3806        FCB  $2D
3807        FCB  REL
3808        FCC  "BMI "
3809        FCB  $2B
3810        FCB  REL
3811        FCC  "BNE "
3812        FCB  $26
3813        FCB  REL
3814        FCC  "BPL "
3815        FCB  $2A
3816        FCB  REL
3817        FCC  "BRA "
3818        FCB  $20
3819        FCB  REL
3820        FCC  "BRCL"             ; (BRCLR)
3821        FCB  $1F
3822        FCB  BTB
3823        FCC  "BRN "
3824        FCB  $21
3825        FCB  REL
3826        FCC  "BRSE"             ; (BRSET)
3827        FCB  $1E
3828        FCB  BTB
3829        FCC  "BSET"
3830        FCB  $1C
3831        FCB  SETCLR
3832        FCC  "BSR "
3833        FCB  $8D
3834        FCB  REL
3835        FCC  "BVC "
3836        FCB  $28
3837        FCB  REL
3838        FCC  "BVS "
3839        FCB  $29
3840        FCB  REL
3841        FCC  "CBA "
3842        FCB  $11
3843        FCB  INH
3844        FCC  "CLC "
3845        FCB  $0C
3846        FCB  INH
3847        FCC  "CLI "
3848        FCB  $0E
3849        FCB  INH
3850        FCC  "CLR "
3851        FCB  $6F
3852        FCB  GRP2
3853        FCC  "CLRA"
3854        FCB  $4F
3855        FCB  INH
3856        FCC  "CLRB"
3857        FCB  $5F
3858        FCB  INH
3859        FCC  "CLV "
3860        FCB  $0A
3861        FCB  INH
3862        FCC  "CMPA"
3863        FCB  $81
3864        FCB  GEN
3865        FCC  "CMPB"
3866        FCB  $C1
3867        FCB  GEN
3868        FCC  "COM "
3869        FCB  $63
3870        FCB  GRP2
3871        FCC  "COMA"
3872        FCB  $43
3873        FCB  INH
3874        FCC  "COMB"
3875        FCB  $53
3876        FCB  INH
3877        FCC  "CPD "
3878        FCB  $83
3879        FCB  CPD
3880        FCC  "CPX "
3881        FCB  $8C
3882        FCB  XLIMM
3883        FCC  "CPY "
3884        FCB  $8C
3885        FCB  YLIMM
3886        FCC  "DAA "
3887        FCB  $19
3888        FCB  INH
3889        FCC  "DEC "
3890        FCB  $6A
3891        FCB  GRP2
3892        FCC  "DECA"
3893        FCB  $4A
3894        FCB  INH
3895        FCC  "DECB"
3896        FCB  $5A
3897        FCB  INH
3898        FCC  "DES "
3899        FCB  $34
3900        FCB  INH
3901        FCC  "DEX "
3902        FCB  $09
3903        FCB  INH
3904        FCC  "DEY "
3905        FCB  $09
3906        FCB  P2INH
3907        FCC  "EORA"
3908        FCB  $88
3909        FCB  GEN
3910        FCC  "EORB"
3911        FCB  $C8
3912        FCB  GEN
3913        FCC  "FDIV"
3914        FCB  $03
3915        FCB  INH
3916        FCC  "IDIV"
3917        FCB  $02
3918        FCB  INH
3919        FCC  "INC "
3920        FCB  $6C
3921        FCB  GRP2
3922        FCC  "INCA"
3923        FCB  $4C
3924        FCB  INH
3925        FCC  "INCB"
3926        FCB  $5C
3927        FCB  INH
3928        FCC  "INS "
3929        FCB  $31
3930        FCB  INH
3931        FCC  "INX "
3932        FCB  $08
3933        FCB  INH
3934        FCC  "INY "
3935        FCB  $08
3936        FCB  P2INH
3937        FCC  "JMP "
3938        FCB  $6E
3939        FCB  GRP2
3940        FCC  "JSR "
3941        FCB  $8D
3942        FCB  NIMM
3943        FCC  "LDAA"
3944        FCB  $86
3945        FCB  GEN
3946        FCC  "LDAB"
3947        FCB  $C6
3948        FCB  GEN
3949        FCC  "LDD "
3950        FCB  $CC
3951        FCB  LIMM
3952        FCC  "LDS "
3953        FCB  $8E
3954        FCB  LIMM
3955        FCC  "LDX "
3956        FCB  $CE
3957        FCB  XLIMM
3958        FCC  "LDY "
3959        FCB  $CE
3960        FCB  YLIMM
3961        FCC  "LSL "
3962        FCB  $68
3963        FCB  GRP2
3964        FCC  "LSLA"
3965        FCB  $48
3966        FCB  INH
3967        FCC  "LSLB"
3968        FCB  $58
3969        FCB  INH
3970        FCC  "LSLD"
3971        FCB  $05
3972        FCB  INH
3973        FCC  "LSR "
3974        FCB  $64
3975        FCB  GRP2
3976        FCC  "LSRA"
3977        FCB  $44
3978        FCB  INH
3979        FCC  "LSRB"
3980        FCB  $54
3981        FCB  INH
3982        FCC  "LSRD"
3983        FCB  $04
3984        FCB  INH
3985        FCC  "MUL "
3986        FCB  $3D
3987        FCB  INH
3988        FCC  "NEG "
3989        FCB  $60
3990        FCB  GRP2
3991        FCC  "NEGA"
3992        FCB  $40
3993        FCB  INH
3994        FCC  "NEGB"
3995        FCB  $50
3996        FCB  INH
3997        FCC  "NOP "
3998        FCB  $01
3999        FCB  INH
4000        FCC  "ORAA"
4001        FCB  $8A
4002        FCB  GEN
4003        FCC  "ORAB"
4004        FCB  $CA
4005        FCB  GEN
4006        FCC  "PSHA"
4007        FCB  $36
4008        FCB  INH
4009        FCC  "PSHB"
4010        FCB  $37
4011        FCB  INH
4012        FCC  "PSHX"
4013        FCB  $3C
4014        FCB  INH
4015        FCC  "PSHY"
4016        FCB  $3C
4017        FCB  P2INH
4018        FCC  "PULA"
4019        FCB  $32
4020        FCB  INH
4021        FCC  "PULB"
4022        FCB  $33
4023        FCB  INH
4024        FCC  "PULX"
4025        FCB  $38
4026        FCB  INH
4027        FCC  "PULY"
4028        FCB  $38
4029        FCB  P2INH
4030        FCC  "ROL "
4031        FCB  $69
4032        FCB  GRP2
4033        FCC  "ROLA"
4034        FCB  $49
4035        FCB  INH
4036        FCC  "ROLB"
4037        FCB  $59
4038        FCB  INH
4039        FCC  "ROR "
4040        FCB  $66
4041        FCB  GRP2
4042        FCC  "RORA"
4043        FCB  $46
4044        FCB  INH
4045        FCC  "RORB"
4046        FCB  $56
4047        FCB  INH
4048        FCC  "RTI "
4049        FCB  $3B
4050        FCB  INH
4051        FCC  "RTS "
4052        FCB  $39
4053        FCB  INH
4054        FCC  "SBA "
4055        FCB  $10
4056        FCB  INH
4057        FCC  "SBCA"
4058        FCB  $82
4059        FCB  GEN
4060        FCC  "SBCB"
4061        FCB  $C2
4062        FCB  GEN
4063        FCC  "SEC "
4064        FCB  $0D
4065        FCB  INH
4066        FCC  "SEI "
4067        FCB  $0F
4068        FCB  INH
4069        FCC  "SEV "
4070        FCB  $0B
4071        FCB  INH
4072        FCC  "STAA"
4073        FCB  $87
4074        FCB  NIMM
4075        FCC  "STAB"
4076        FCB  $C7
4077        FCB  NIMM
4078        FCC  "STD "
4079        FCB  $CD
4080        FCB  NIMM
4081        FCC  "STOP"
4082        FCB  $CF
4083        FCB  INH
4084        FCC  "STS "
4085        FCB  $8F
4086        FCB  NIMM
4087        FCC  "STX "
4088        FCB  $CF
4089        FCB  XNIMM
4090        FCC  "STY "
4091        FCB  $CF
4092        FCB  YNIMM
4093        FCC  "SUBA"
4094        FCB  $80
4095        FCB  GEN
4096        FCC  "SUBB"
4097        FCB  $C0
4098        FCB  GEN
4099        FCC  "SUBD"
4100        FCB  $83
4101        FCB  LIMM
4102        FCC  "SWI "
4103        FCB  $3F
4104        FCB  INH
4105        FCC  "TAB "
4106        FCB  $16
4107        FCB  INH
4108        FCC  "TAP "
4109        FCB  $06
4110        FCB  INH
4111        FCC  "TBA "
4112        FCB  $17
4113        FCB  INH
4114        FCC  "TPA "
4115        FCB  $07
4116        FCB  INH
4117        FCC  "TEST"
4118        FCB  $00
4119        FCB  INH
4120        FCC  "TST "
4121        FCB  $6D
4122        FCB  GRP2
4123        FCC  "TSTA"
4124        FCB  $4D
4125        FCB  INH
4126        FCC  "TSTB"
4127        FCB  $5D
4128        FCB  INH
4129        FCC  "TSX "
4130        FCB  $30
4131        FCB  INH
4132        FCC  "TSY "
4133        FCB  $30
4134        FCB  P2INH
4135        FCC  "TXS "
4136        FCB  $35
4137        FCB  INH
4138        FCC  "TYS "
4139        FCB  $35
4140        FCB  P2INH
4141        FCC  "WAI "
4142        FCB  $3E
4143        FCB  INH
4144        FCC  "XGDX"
4145        FCB  $8F
4146        FCB  INH
4147        FCC  "XGDY"
4148        FCB  $8F
4149        FCB  P2INH
4150        FCC  "BRSE"             ; bit direct modes for
4151        FCB  $12                ; disassembler.
4152        FCB  BTBD
4153        FCC  "BRCL"
4154        FCB  $13
4155        FCB  BTBD
4156        FCC  "BSET"
4157        FCB  $14
4158        FCB  SETCLRD
4159        FCC  "BCLR"
4160        FCB  $15
4161        FCB  SETCLRD
4162        FCB  EOT                ; End of table
4163
4164;**********************************************
4165PG1      EQU      $0
4166PG2      EQU      $1
4167PG3      EQU      $2
4168PG4      EQU      $3
4169
4170;******************
4171;*disassem() - disassemble the opcode.
4172;******************
4173;*(check for page prebyte)
4174;*baseop=pc[0];
4175;*pnorm=PG1;
4176;*if(baseop==$18) pnorm=PG2;
4177;*if(baseop==$1A) pnorm=PG3;
4178;*if(baseop==$CD) pnorm=PG4;
4179;*if(pnorm != PG1) dispc=pc+1;
4180;*else dispc=pc; (dispc points to next byte)
4181
4182DISASSM EQU  *
4183        LDX  PC                 ; address
4184        LDAA 0,X                ; opcode
4185        LDAB #PG1
4186        CMPA #$18
4187        BEQ  DISP2              ; jump if page2
4188        CMPA #$1A
4189        BEQ  DISP3              ; jump if page3
4190        CMPA #$CD
4191        BNE  DISP1              ; jump if not page4
4192DISP4   INCB                    ; set up page value
4193DISP3   INCB
4194DISP2   INCB
4195        INX
4196DISP1   STX  DISPC              ; point to opcode
4197        STAB PNORM              ; save page
4198
4199;*If(opcode == ($00-$5F or $8D or $8F or $CF))
4200;*  if(pnorm == (PG3 or PG4))
4201;*      disillop(); return();
4202;*  b=disrch(opcode,NULL);
4203;*  if(b==0) disillop(); return();
4204
4205        LDAA 0,X                ; get current opcode
4206        STAA BASEOP
4207        INX
4208        STX  DISPC              ; point to next byte
4209        CMPA #$5F
4210        BLS  DIS1               ; jump if in range
4211        CMPA #$8D
4212        BEQ  DIS1               ; jump if bsr
4213        CMPA #$8F
4214        BEQ  DIS1               ; jump if xgdx
4215        CMPA #$CF
4216        BEQ  DIS1               ; jump if stop
4217        JMP  DISGRP             ; try next part of map
4218DIS1    LDAB PNORM
4219        CMPB #PG3
4220        BLO  DIS2               ; jump if page 1 or 2
4221        JSR  DISILLOP           ; "illegal opcode"
4222        RTS
4223DIS2    LDAB BASEOP             ; opcode
4224        CLRB                    ; class=null
4225        JSR  DISRCH
4226        TSTB
4227        BNE  DISPEC             ; jump if opcode found
4228        JSR  DISILLOP           ; "illegal opcode"
4229        RTS
4230
4231;*   if(opcode==$8D) dissrch(opcode,REL);
4232;*   if(opcode==($8F or $CF)) disrch(opcode,INH);
4233
4234DISPEC  LDAA BASEOP
4235        CMPA #$8D
4236        BNE  DISPEC1
4237        LDAB #REL
4238        BRA  DISPEC3            ; look for BSR opcode
4239DISPEC1 CMPA #$8F
4240        BEQ  DISPEC2            ; jump if XGDX opcode
4241        CMPA #$CF
4242        BNE  DISINH             ; jump not STOP opcode
4243DISPEC2 LDAB #INH
4244DISPEC3 JSR  DISRCH             ; find other entry in table
4245
4246;*   if(class==INH)              /* INH */
4247;*      if(pnorm==PG2)
4248;*          b=disrch(baseop,P2INH);
4249;*          if(b==0) disillop(); return();
4250;*      prntmne();
4251;*      return();
4252
4253DISINH  EQU  *
4254        LDAB CLASS
4255        CMPB #INH
4256        BNE  DISREL             ; jump if not inherent
4257        LDAB PNORM
4258        CMPB #PG1
4259        BEQ  DISINH1            ; jump if page1
4260        LDAA BASEOP             ; get opcode
4261        LDAB #P2INH             ; class=p2inh
4262        JSR  DISRCH
4263        TSTB
4264        BNE  DISINH1            ; jump if found
4265        JSR  DISILLOP           ; "illegal opcode"
4266        RTS
4267DISINH1 JSR  PRNTMNE
4268        RTS
4269
4270;*   elseif(class=REL)          /* REL */
4271;*      if(pnorm != PG1)
4272;*          disillop(); return();
4273;*      prntmne();
4274;*      disrelad();
4275;*      return();
4276
4277DISREL  EQU  *
4278        LDAB CLASS
4279        CMPB #REL
4280        BNE  DISBTD
4281        TST  PNORM
4282        BEQ  DISREL1            ; jump if page1
4283        JSR  DISILLOP           ; "illegal opcode"
4284        RTS
4285DISREL1 JSR  PRNTMNE            ; output mnemonic
4286        JSR  DISRELAD           ; compute relative address
4287        RTS
4288
4289;*   else    /* SETCLR,SETCLRD,BTB,BTBD */
4290;*      if(class == (SETCLRD or BTBD))
4291;*          if(pnorm != PG1)
4292;*             disillop(); return();   /* illop */
4293;*          prntmne();             /* direct */
4294;*          disdir();             /* output $byte */
4295;*      else (class == (SETCLR or BTB))
4296;*          prntmne();             /* indexed */
4297;*          disindx();
4298;*      outspac();
4299;*      disdir();
4300;*      outspac();
4301;*      if(class == (BTB or BTBD))
4302;*          disrelad();
4303;*   return();
4304
4305DISBTD  EQU  *
4306        LDAB CLASS
4307        CMPB #SETCLRD
4308        BEQ  DISBTD1
4309        CMPB #BTBD
4310        BNE  DISBIT             ; jump not direct bitop
4311DISBTD1 TST  PNORM
4312        BEQ  DISBTD2            ; jump if page 1
4313        JSR  DISILLOP
4314        RTS
4315DISBTD2 JSR  PRNTMNE
4316        JSR  DISDIR             ; operand(direct)
4317        BRA  DISBIT1
4318DISBIT  EQU  *
4319        JSR  PRNTMNE
4320        JSR  DISINDX            ; operand(indexed)
4321DISBIT1 JSR  OUTSPAC
4322        JSR  DISDIR             ; mask
4323        LDAB CLASS
4324        CMPB #BTB
4325        BEQ  DISBIT2            ; jump if btb
4326        CMPB #BTBD
4327        BNE  DISBIT3            ; jump if not bit branch
4328DISBIT2 JSR  DISRELAD           ; relative address
4329DISBIT3 RTS
4330
4331
4332;*Elseif($60 <= opcode <= $7F)  /*  GRP2 */
4333;*   if(pnorm == (PG3 or PG4))
4334;*      disillop(); return();
4335;*   if((pnorm==PG2) and (opcode != $6x))
4336;*      disillop(); return();
4337;*   b=disrch(baseop & $6F,NULL);
4338;*   if(b==0) disillop(); return();
4339;*   prntmne();
4340;*   if(opcode == $6x)
4341;*      disindx();
4342;*   else
4343;*      disext();
4344;*   return();
4345
4346DISGRP  EQU  *
4347        CMPA #$7F               ; a=opcode
4348        BHI  DISNEXT            ; try next part of map
4349        LDAB PNORM
4350        CMPB #PG3
4351        BLO  DISGRP2            ; jump if page 1 or 2
4352        JSR  DISILLOP           ; "illegal opcode"
4353        RTS
4354DISGRP2 ANDA #$6F               ; mask bit 4
4355        CLRB                    ; class=null
4356        JSR  DISRCH
4357        TSTB
4358        BNE  DISGRP3            ; jump if found
4359        JSR  DISILLOP           ; "illegal opcode"
4360        RTS
4361DISGRP3 JSR  PRNTMNE
4362        LDAA BASEOP             ; get opcode
4363        ANDA #$F0
4364        CMPA #$60
4365        BNE  DISGRP4            ; jump if not 6x
4366        JSR  DISINDX            ; operand(indexed)
4367        RTS
4368DISGRP4 JSR  DISEXT             ; operand(extended)
4369        RTS
4370
4371;*Else  ($80 <= opcode <= $FF)
4372;*   if(opcode == ($87 or $C7))
4373;*      disillop(); return();
4374;*   b=disrch(opcode&$CF,NULL);
4375;*   if(b==0) disillop(); return();
4376
4377DISNEXT EQU  *
4378        CMPA #$87               ; a=opcode
4379        BEQ  DISNEX1
4380        CMPA #$C7
4381        BNE  DISNEX2
4382DISNEX1 JSR  DISILLOP           ; "illegal opcode"
4383        RTS
4384DISNEX2 ANDA #$CF
4385        CLRB                    ; class=null
4386        JSR  DISRCH
4387        TSTB
4388        BNE  DISNEW             ; jump if mne found
4389        JSR  DISILLOP           ; "illegal opcode"
4390        RTS
4391
4392;*   if(opcode&$CF==$8D) disrch(baseop,NIMM; (jsr)
4393;*   if(opcode&$CF==$8F) disrch(baseop,NIMM; (sts)
4394;*   if(opcode&$CF==$CF) disrch(baseop,XNIMM; (stx)
4395;*   if(opcode&$CF==$83) disrch(baseop,LIMM); (subd)
4396
4397DISNEW  LDAA BASEOP
4398        ANDA #$CF
4399        CMPA #$8D
4400        BNE  DISNEW1            ; jump not jsr
4401        LDAB #NIMM
4402        BRA  DISNEW4
4403DISNEW1 CMPA #$8F
4404        BNE  DISNEW2            ; jump not sts
4405        LDAB #NIMM
4406        BRA  DISNEW4
4407DISNEW2 CMPA #$CF
4408        BNE  DISNEW3            ; jump not stx
4409        LDAB #XNIMM
4410        BRA  DISNEW4
4411DISNEW3 CMPA #$83
4412        BNE  DISGEN             ; jump not subd
4413        LDAB #LIMM
4414DISNEW4 JSR  DISRCH
4415        TSTB
4416        BNE  DISGEN             ; jump if found
4417        JSR  DISILLOP           ; "illegal opcode"
4418        RTS
4419
4420;*   if(class == (GEN or NIMM or LIMM   ))   /* GEN,NIMM,LIMM,CPD */
4421;*      if(opcode&$CF==$83)
4422;*          if(pnorm==(PG3 or PG4)) disrch(opcode#$CF,CPD)
4423;*          class=LIMM;
4424;*      if((pnorm == (PG2 or PG4) and (opcode != ($Ax or $Ex)))
4425;*          disillop(); return();
4426;*      disgenrl();
4427;*      return();
4428
4429DISGEN  LDAB CLASS              ; get class
4430        CMPB #GEN
4431        BEQ  DISGEN1
4432        CMPB #NIMM
4433        BEQ  DISGEN1
4434        CMPB #LIMM
4435        BNE  DISXLN             ; jump if other class
4436DISGEN1 LDAA BASEOP
4437        ANDA #$CF
4438        CMPA #$83
4439        BNE  DISGEN3            ; jump if not #$83
4440        LDAB PNORM
4441        CMPB #PG3
4442        BLO  DISGEN3            ; jump not pg3 or 4
4443        LDAB #CPD
4444        JSR  DISRCH             ; look for cpd mne
4445        LDAB #LIMM
4446        STAB CLASS              ; set class to limm
4447DISGEN3 LDAB PNORM
4448        CMPB #PG2
4449        BEQ  DISGEN4            ; jump if page 2
4450        CMPB #PG4
4451        BNE  DISGEN5            ; jump not page 2 or 4
4452DISGEN4 LDAA BASEOP
4453        ANDA #$B0               ; mask bits 6,3-0
4454        CMPA #$A0
4455        BEQ  DISGEN5            ; jump if $Ax or $Ex
4456        JSR  DISILLOP           ; "illegal opcode"
4457        RTS
4458DISGEN5 JSR  DISGENRL           ; process general class
4459        RTS
4460
4461;*   else       /* XLIMM,XNIMM,YLIMM,YNIMM */
4462;*      if(pnorm==(PG2 or PG3))
4463;*          if(class==XLIMM) disrch(opcode&$CF,YLIMM);
4464;*          else disrch(opcode&$CF,YNIMM);
4465;*      if((pnorm == (PG3 or PG4))
4466;*          if(opcode != ($Ax or $Ex))
4467;*             disillop(); return();
4468;*      class=LIMM;
4469;*      disgen();
4470;*   return();
4471
4472DISXLN  LDAB PNORM
4473        CMPB #PG2
4474        BEQ  DISXLN1            ; jump if page2
4475        CMPB #PG3
4476        BNE  DISXLN4            ; jump not page3
4477DISXLN1 LDAA BASEOP
4478        ANDA #$CF
4479        LDAB CLASS
4480        CMPB #XLIMM
4481        BNE  DISXLN2
4482        LDAB #YLIMM
4483        BRA  DISXLN3            ; look for ylimm
4484DISXLN2 LDAB #YNIMM             ; look for ynimm
4485DISXLN3 JSR  DISRCH
4486DISXLN4 LDAB PNORM
4487        CMPB #PG3
4488        BLO  DISXLN5            ; jump if page 1 or 2
4489        LDAA BASEOP             ; get opcode
4490        ANDA #$B0               ; mask bits 6,3-0
4491        CMPA #$A0
4492        BEQ  DISXLN5            ; jump opcode = $Ax or $Ex
4493        JSR  DISILLOP           ; "illegal opcode"
4494        RTS
4495DISXLN5 LDAB #LIMM
4496        STAB CLASS
4497        JSR  DISGENRL           ; process general class
4498        RTS
4499
4500
4501;******************
4502;*disrch(a=opcode,b=class)
4503;*return b=0 if not found
4504;*  else mneptr=points to mnemonic
4505;*         class=class of opcode
4506;******************
4507;*x=#MNETABL
4508;*while(x[0] != eot)
4509;*   if((opcode==x[4]) && ((class=NULL) || (class=x[5])))
4510;*      mneptr=x;
4511;*      class=x[5];
4512;*      return(1);
4513;*   x += 6;
4514;*return(0);        /* not found */
4515
4516DISRCH  EQU  *
4517        LDX  #MNETABL           ; point to top of table
4518DISRCH1 CMPA 4,X                ; test opcode
4519        BNE  DISRCH3            ; jump not this entry
4520        TSTB
4521        BEQ  DISRCH2            ; jump if class=null
4522        CMPB 5,X                ; test class
4523        BNE  DISRCH3            ; jump not this entry
4524DISRCH2 LDAB 5,X
4525        STAB CLASS
4526        STX  MNEPTR             ; return ptr to mnemonic
4527        INCB
4528        RTS                     ; return found
4529DISRCH3 PSHB                    ; save class
4530        LDAB #6
4531        ABX
4532        LDAB 0,X
4533        CMPB #EOT               ; test end of table
4534        PULB
4535        BNE  DISRCH1
4536        CLRB
4537        RTS                     ; return not found
4538
4539;******************
4540;*prntmne() - output the mnemonic pointed
4541;*at by mneptr.
4542;******************
4543;*outa(mneptr[0-3]);
4544;*outspac;
4545;*return();
4546
4547PRNTMNE EQU  *
4548        LDX  MNEPTR
4549        LDAA 0,X
4550        JSR  OUTA               ; output char1
4551        LDAA 1,X
4552        JSR  OUTA               ; output char2
4553        LDAA 2,X
4554        JSR  OUTA               ; output char3
4555        LDAA 3,X
4556        JSR  OUTA               ; output char4
4557        JSR  OUTSPAC
4558        RTS
4559
4560;******************
4561;*disindx() - process indexed mode
4562;******************
4563;*disdir();
4564;*outa(',');
4565;*if(pnorm == (PG2 or PG4)) outa('Y');
4566;*else outa('X');
4567;*return();
4568
4569DISINDX EQU  *
4570        JSR  DISDIR             ; output $byte
4571        LDAA #','
4572        JSR  OUTA               ; output ,
4573        LDAB PNORM
4574        CMPB #PG2
4575        BEQ  DISIND1            ; jump if page2
4576        CMPB #PG4
4577        BNE  DISIND2            ; jump if not page4
4578DISIND1 LDAA #'Y'
4579        BRA DISIND3
4580DISIND2 LDAA #'X'
4581DISIND3 JSR  OUTA               ; output x or y
4582        RTS
4583
4584;******************
4585;*disrelad() - compute and output relative address.
4586;******************
4587;* braddr = dispc[0] + (dispc++);( 2's comp arith)
4588;*outa('$');
4589;*out2bsp(braddr);
4590;*return();
4591
4592DISRELAD EQU *
4593        LDX  DISPC
4594        LDAB 0,X                ; get relative offset
4595        INX
4596        STX  DISPC
4597        TSTB
4598        BMI  DISRLD1            ; jump if negative
4599        ABX
4600        BRA  DISRLD2
4601DISRLD1 DEX
4602        INCB
4603        BNE  DISRLD1            ; subtract
4604DISRLD2 STX  BRADDR             ; save address
4605        JSR  OUTSPAC
4606        LDAA #'$'
4607        JSR  OUTA
4608        LDX  #BRADDR
4609        JSR  OUT2BSP            ; output address
4610        RTS
4611
4612
4613;******************
4614;*disgenrl() - output data for the general cases which
4615;*includes immediate, direct, indexed, and extended modes.
4616;******************
4617;*prntmne();
4618;*if(baseop == ($8x or $Cx))   /* immediate */
4619;*   outa('#');
4620;*   disdir();
4621;*   if(class == LIMM)
4622;*      out1byt(dispc++);
4623;*elseif(baseop == ($9x or $Dx))  /* direct */
4624;*   disdir();
4625;*elseif(baseop == ($Ax or $Ex)) /* indexed */
4626;*   disindx();
4627;*else  (baseop == ($Bx or $Fx)) /* extended */
4628;*   disext();
4629;*return();
4630
4631DISGENRL EQU *
4632        JSR  PRNTMNE            ; print mnemonic
4633        LDAA BASEOP             ; get opcode
4634        ANDA #$B0               ;  mask bits 6,3-0
4635        CMPA #$80
4636        BNE  DISGRL2            ; jump if not immed
4637        LDAA #'#'               ; do immediate
4638        JSR  OUTA
4639        JSR  DISDIR
4640        LDAB CLASS
4641        CMPB #LIMM
4642        BEQ  DISGRL1            ; jump class = limm
4643        RTS
4644DISGRL1 LDX  DISPC
4645        JSR  OUT1BYT
4646        STX  DISPC
4647        RTS
4648DISGRL2 CMPA #$90
4649        BNE  DISGRL3            ; jump not direct
4650        JSR  DISDIR             ; do direct
4651        RTS
4652DISGRL3 CMPA #$A0
4653        BNE  DISGRL4            ; jump not indexed
4654        JSR  DISINDX            ; do extended
4655        RTS
4656DISGRL4 JSR  DISEXT             ; do extended
4657        RTS
4658
4659;*****************
4660;*disdir() - output "$ next byte"
4661;*****************
4662DISDIR  EQU  *
4663        LDAA #'$'
4664        JSR  OUTA
4665        LDX  DISPC
4666        JSR  OUT1BYT
4667        STX  DISPC
4668        RTS
4669
4670;*****************
4671;*disext() - output "$ next 2 bytes"
4672;*****************
4673DISEXT  EQU  *
4674        LDAA #'$'
4675        JSR  OUTA
4676        LDX  DISPC
4677        JSR  OUT2BSP
4678        STX  DISPC
4679        RTS
4680
4681
4682;*****************
4683;*disillop() - output "illegal opcode"
4684;*****************
4685DISMSG1 FCC  "ILLOP"
4686        FCB  EOT
4687DISILLOP EQU *
4688        PSHX
4689        LDX  #DISMSG1
4690        JSR  OUTSTRG0           ; no cr
4691        PULX
4692        RTS
4693
4694;* Equates
4695JPORTD   EQU   $08
4696JDDRD    EQU   $09
4697JBAUD    EQU   $2B
4698JSCCR1   EQU   $2C
4699JSCCR2   EQU   $2D
4700JSCSR    EQU   $2E
4701JSCDAT   EQU   $2F
4702;*
4703
4704;************
4705;*  xboot [<addr1> [<addr2>]] - Use SCI to talk to an 'hc11 in
4706;* boot mode.  Downloads bytes from addr1 thru addr2.
4707;* Default addr1 = $C000 and addr2 = $C0ff.
4708;*
4709;* IMPORTANT:
4710;* if talking to an 'A8 or 'A2: use either default addresses or ONLY
4711;*    addr1 - this sends 256 bytes
4712;* if talking to an 'E9: include BOTH addr1 and addr2 for variable
4713;*    length
4714;************
4715
4716;*Get arguments
4717;*If no args, default $C000
4718BOOT    JSR   WSKIP
4719        BNE   BOT1              ; jump if arguments
4720        LDX   #$C0FF            ; addr2 default
4721        STX   PTR5
4722        LDY   #$C000            ; addr1 default
4723        BRA   BOT2              ; go - use default address
4724
4725;*Else get arguments
4726BOT1    JSR   BUFFARG
4727        TST   COUNT
4728        BEQ   BOTERR            ; jump if no address
4729        LDY   SHFTREG           ; start address (addr1)
4730        JSR   WSKIP
4731        BNE   BOT1A             ; go get addr2
4732        STY   PTR5              ; default addr2...
4733        LDD   PTR5              ; ...by taking addr1...
4734        ADDD  #$FF              ; ...and adding 255 to it...
4735        STD   PTR5              ; ...for a total download of 256
4736        BRA   BOT2              ; continue
4737;*
4738BOT1A   JSR   BUFFARG
4739        TST   COUNT
4740        BEQ   BOTERR            ; jump if no address
4741        LDX   SHFTREG           ; end address (addr2)
4742        STX   PTR5
4743        JSR   WSKIP
4744        BNE   BOTERR            ; go use addr1 and addr2
4745        BRA   BOT2
4746
4747;*
4748BOTERR  LDX   #MSG9             ; "bad argument"
4749        JSR   OUTSTRG
4750        RTS
4751
4752;*Boot routine
4753BOT2    LDAB  #$FF              ; control character ($ff -> download)
4754        JSR   BTSUB             ; set up SCI and send control char
4755;*                                initializes X as register pointer
4756;*Download block
4757BLOP    LDAA  0,Y
4758        STAA  JSCDAT,X          ; write to transmitter
4759        BRCLR JSCSR,X,#80,*     ; wait for TDRE
4760        CPY   PTR5              ; if last...
4761        BEQ   BTDONE            ; ...quit
4762        INY                     ; else...
4763        BRA   BLOP              ; ...send next
4764BTDONE  RTS
4765
4766;************************************************
4767;*Subroutine
4768;*  btsub   - sets up SCI and outputs control character
4769;* On entry, B = control character
4770;* On exit,  X = $1000
4771;*            A = $0C
4772;***************************
4773
4774BTSUB   EQU   *
4775        LDX   #$1000            ; to use indexed addressing
4776        LDAA  #$02
4777        STAA  JPORTD,X          ; drive transmitter line
4778        STAA  JDDRD,X           ; high
4779        CLR   JSCCR2,X          ; turn off XMTR and RCVR
4780        LDAA  #$22              ; BAUD = /16
4781        STAA  JBAUD,X
4782        LDAA  #$0C              ; TURN ON XMTR & RCVR
4783        STAA  JSCCR2,X
4784        STAB  JSCDAT,X
4785        BRCLR JSCSR,X,#80,*     ; wait for TDRE
4786        RTS
4787
4788;******************
4789;*
4790;*        EVBTEST - This routine makes it a little easier
4791;*        on us to test this board.
4792;*
4793;******************
4794
4795EVBTEST  LDAA  #$FF
4796         STAA  $1000            ; Write ones to port A
4797         CLR  AUTOLF            ; Turn off auto lf
4798         JSR  HOSTCO            ; Connect host
4799         JSR  HOSTINIT          ; Initialize host
4800         LDAA #$7f
4801         JSR  HOSTOUT           ; Send Delete to Altos
4802         LDAA #$0d
4803         JSR  HOSTOUT           ; Send <CR>
4804         INC  AUTOLF            ; Turn on Auto LF
4805         LDX  #INBUFF+5         ; Point at Load message
4806         STX  PTR0              ; Set pointer for load command
4807         LDY  #MSGEVB           ; Point at cat line
4808LOOP     LDAA 0,Y               ; Loop to xfer command line
4809         CMPA #04               ; Into buffalo line buffer
4810         BEQ  DONE              ; Quit on $04
4811         STAA 0,X
4812         INX                    ; next character
4813         INY
4814         BRA  LOOP
4815DONE     CLR  TMP2              ; Set load vs. verify
4816         JSR  LOAD3             ; Jmp into middle of load
4817         LDS  #STACK            ; Reset Stack
4818         JMP  $C0B3             ; Jump to Downloaded code
4819
4820MSGEVB   FCC  "cat evbtest.out"
4821         FCB  $0D
4822         FCB  $04
4823
4824
4825
4826;*** Jump table ***
4827        ORG      ROMBS+$1F7C
4828.WARMST JMP       MAIN
4829.BPCLR  JMP       BPCLR
4830.RPRINT JMP       RPRINT
4831.HEXBIN JMP       HEXBIN
4832.BUFFAR JMP       BUFFARG
4833.TERMAR JMP       TERMARG
4834.CHGBYT JMP       CHGBYT
4835.READBU JMP       READBUFF
4836.INCBUF JMP       INCBUFF
4837.DECBUF JMP       DECBUFF
4838.WSKIP  JMP       WSKIP
4839.CHKABR JMP       CHKABRT
4840
4841        ORG      ROMBS+$1FA0
4842.UPCASE JMP       UPCASE
4843.WCHEK  JMP       WCHEK
4844.DCHEK  JMP       DCHEK
4845.INIT   JMP       INIT
4846.INPUT  JMP       INPUT
4847.OUTPUT JMP       OUTPUT
4848.OUTLHL JMP       OUTLHLF
4849.OUTRHL JMP       OUTRHLF
4850.OUTA   JMP       OUTA
4851.OUT1BY JMP       OUT1BYT
4852.OUT1BS JMP       OUT1BSP
4853.OUT2BS JMP       OUT2BSP
4854.OUTCRL JMP       OUTCRLF
4855.OUTSTR JMP       OUTSTRG
4856.OUTST0 JMP       OUTSTRG0
4857.INCHAR JMP       INCHAR
4858.VECINT JMP       VECINIT
4859
4860         ORG     ROMBS+$1FD6
4861;*** Vectors ***
4862VSCI      FDB     JSCI
4863VSPI      FDB     JSPI
4864VPAIE     FDB     JPAIE
4865VPAO      FDB     JPAO
4866VTOF      FDB     JTOF
4867VTOC5     FDB     JTOC5
4868VTOC4     FDB     JTOC4
4869VTOC3     FDB     JTOC3
4870VTOC2     FDB     JTOC2
4871VTOC1     FDB     JTOC1
4872VTIC3     FDB     JTIC3
4873VTIC2     FDB     JTIC2
4874VTIC1     FDB     JTIC1
4875VRTI      FDB     JRTI
4876VIRQ      FDB     JIRQ
4877VXIRQ     FDB     JXIRQ
4878VSWI      FDB     JSWI
4879VILLOP    FDB     JILLOP
4880VCOP      FDB     JCOP
4881VCLM      FDB     JCLM
4882VRST      FDB     BUFFALO
4883          END
4884