-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbufk42asmfw.asm
5396 lines (4922 loc) · 206 KB
/
bufk42asmfw.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
; BUFFALO
; "Bit User's Fast Friendly Aid to Logical Operation"
;
; Rev 2.0 - 4/23/85 - added disassembler.
; - variables now PTRn and TMPn.
; Rev 2.1 - 4/29/85 - added byte erase to chgbyt routine.
; Rev 2.2 - 5/16/85 - added hooks for evb board - acia
; drivers, init and host routines.
; 7/8/85 - fixed dump wraparound problem.
; 7/10/85 - added evm board commands.
; - added fill instruction.
; 7/18/85 - added jump to EEPROM.
; Rev 2.3 - 8/22/85 - call targco to disconnect sci from host
; in reset routine for evb board.
; 10/3/85 - modified load for download through terminal.
; Rev 2.4 - 7/1/86 - Changed DFLOP address to fix conflicts with
; EEPROM. (was at A000)
; Rev 2.5 - 9/8/86 - Modified to provide additional protection from
; program run-away on power down. Also fixed bugs
; in MM and MOVE. Changed to 1 stop bit from 2.
; Rev 2.6 - 9/25/86 - Modified boot routine for variable length download
; for use with 'HC11E8.
; Rev 3.0 1/15/87 - EEPROM programming routines consolidated into WRITE.
; Fill, Assem, and breakpoints will now do EEPROM.
; - Added compare a to $0D to WSKIP routine.
; 2/11/87 - Set up load to detect receiver error.
; Rev 3.2 7/7/87 - Add disassembly to trace.
; - Add entries to jump table.
; 9/20/87 - Rewrote trace to use XIRQ, added STOPAT Command
; 11/24/87- Write block protect reg for 'E9 version
; - Modified variable length download for use
; with 'E9 bootloader (XBOOT command)
; Rev 3.3 3/17/88 - Set I bit to block interrupts on Warm Start and
; return from CALL command.
; - Added EEMOD Command.
; - Rearranged source so that HELP command overlaps
; EEPROM in test mode.
; 3/24/88 - Added '+', '-', '=', '.' to MEM and ASM commands.
; - Added check for 16 byte boundary to MEM
; space sub-command.
; - LOAD command now puts dummy (~) command into
; inbuff so that any stray cr's won`t hang.
; Rev 3.4 8/15/88 - Changed WRITE subroutine so that config register
; gets byte erased before programmed. The original
; value of config is used for EEBYTE so that config
; RAM value doesn't get changed in test mode.
; 8/17/88 - Fixed MOVE command so that it doesn't hang when move
; is done to a ROM location.
; - Added OFFSET command for download offset capability.
;
; Rev K4.0 2/17/90 - Changes for 711K4 (KOI) changes marked by '**K4'
;
; Rev K4.1 - Unreleased version with EEPROM cycling code for
; factory testing
;
; Rev K4.2 9/9/91 - Changed jump to EEPROM to jump to PCBUG11 talker
;
;****************************************************
;* Although the information contained herein, *
;* as well as any information provided relative *
;* thereto, has been carefully reviewed and is *
;* believed accurate, Motorola assumes no *
;* liability arising out of its application or *
;* use, neither does it convey any license under *
;* its patent rights nor the rights of others. *
;****************************************************
;***************
; EQUATES *
;***************
; *Author EQU Tony Fourcroy
RAMBS equ $0080 ; start of ram **K4
REGBS equ $0000 ; start of registers **K4
ROMBS equ $DF00 ; start of rom **K4
DSTREE equ $0D80 ; start of eeprom **K4
DENDEE equ $0FFF ; end of eeprom **K4
PORTE equ REGBS+$0A ; port e
CFORC equ REGBS+$0B ; force output compare
TCNT equ REGBS+$0E ; timer count
TOC5 equ REGBS+$1E ; oc5 reg
TCTL1 equ REGBS+$20 ; timer control 1
TMSK1 equ REGBS+$22 ; timer mask 1
TFLG1 equ REGBS+$23 ; timer flag 1
TMSK2 equ REGBS+$24 ; timer mask 2
BAUD equ REGBS+$70 ; sci baud reg hi byte **K4
SCCR1 equ REGBS+$72 ; sci control1 reg **K4
SCCR2 equ REGBS+$73 ; sci control2 reg **K4
SCSR equ REGBS+$74 ; sci status reg **K4
SCDAT equ REGBS+$77 ; sci data reg **K4
BPROT equ REGBS+$35 ; block protect reg
OPTION equ REGBS+$39 ; option reg
COPRST equ REGBS+$3A ; cop reset reg
PPROG equ REGBS+$3B ; ee prog reg
HPRIO equ REGBS+$3C ; hprio reg
CONFIG equ REGBS+$3F ; config register
DFLOP equ $4000 ; evb d flip flop
DUART equ $D000 ; duart address
PORTA equ DUART
PORTB equ DUART+8
ACIA equ $9800 ; acia address
PROMPT equ '>'
BUFFLNG equ 35
CTLA equ $01 ; exit host or assembler
CTLB equ $02 ; send break to host
CTLW equ $17 ; wait
CTLX equ $18 ; abort
DEL equ $7F ; abort
EOT equ $04 ; end of text/table
SWI equ $3F
;***************
; RAM *
;***************
org $2AD ;**K4
;*** Buffalo ram space ***
rmb 20 ; user stack area
USTACK rmb 30 ; monitor stack area
STACK rmb 1
REGS rmb 9 ; user's pc,y,x,a,b,c
SP rmb 2 ; user's sp
INBUFF rmb BUFFLNG ; input buffer
ENDBUFF equ *
COMBUFF rmb 8 ; command buffer
SHFTREG rmb 2 ; input shift register
STREE rmb 2 ; eeprom start address
ENDEE rmb 2 ; eeprom end address
BRKTABL rmb 8 ; breakpoint table
AUTOLF rmb 1 ; auto lf flag for i/o
IODEV rmb 1 ; 0=sci, 1=acia, 2=duartA, 3=duartB
EXTDEV rmb 1 ; 0=none, 1=acia, 2=duart,
HOSTDEV rmb 1 ; 0=sci, 1=acia, 3=duartB
COUNT rmb 1 ; # characters read
CHRCNT rmb 1 ; # characters output on current line
PTRMEM rmb 2 ; current memory location
LDOFFST rmb 2 ; offset for download
;*** Buffalo variables - used by: ***
PTR0 rmb 2 ; main,readbuff,incbuff,AS
PTR1 rmb 2 ; main,BR,DU,MO,AS,EX
PTR2 rmb 2 ; EX,DU,MO,AS
PTR3 rmb 2 ; EX,HO,MO,AS
PTR4 rmb 2 ; EX,AS
PTR5 rmb 2 ; EX,AS,BOOT
PTR6 rmb 2 ; EX,AS,BOOT
PTR7 rmb 2 ; EX,AS
PTR8 rmb 2 ; AS
TMP1 rmb 1 ; main,hexbin,buffarg,termarg
TMP2 rmb 1 ; GO,HO,AS,LOAD
TMP3 rmb 1 ; AS,LOAD
TMP4 rmb 1 ; TR,HO,ME,AS,LOAD
;*** Vector jump table ***
JSCI rmb 3
JSPI rmb 3
JPAIE rmb 3
JPAO rmb 3
JTOF rmb 3
JTOC5 rmb 3
JTOC4 rmb 3
JTOC3 rmb 3
JTOC2 rmb 3
JTOC1 rmb 3
JTIC3 rmb 3
JTIC2 rmb 3
JTIC1 rmb 3
JRTI rmb 3
JIRQ rmb 3
JXIRQ rmb 3
JSWI rmb 3
JILLOP rmb 3
JCOP rmb 3
JCLM rmb 3
ENDVECT equ *
;*****************
;
; ROM starts here *
;
;*****************
;**************************** TALKKBUF.ASC 24/4/90 ************************
; Motorola Copyright 1991 *
; MCU resident, Interrupt driven Communication routines for 68HC11 *
; monitor. Provides low level memory and stack read/write operations. *
; *
; This talker DOES NOT use XIRQ *
; ----------------------------- *
; *
; N.B. TALKKBUF.ASC is intended to be placed in the excess ROM area of *
; a K4 with Buffalo, selection of this code is at the user's *
; discretion. *
; This bootloader has a default baud rate of 19200 Baud *
; IMPORTANT - use with the TALKKBUF.MAP file *
;
; CONSTANTS
TALKBASE equ $D000 ; Start of code - can be changed
BUFFVECT equ $0344 ; Start of BUFFALO vector jump table.
;
JMPEXT equ $7E ; Mnemonic for jump extended instruction
BRKCODE equ $4A ; Break point signal code to host.
BRKACK equ $4A ; Break point acknowledge code from host.
;
; REGISTERS
SCDRH equ $76
SCDRL equ $77 ; SCI data register
;
RDRF equ $20 ; Masks for checking
TDRE equ $80 ; status of SCI
; PROGRAM
org TALKBASE
TLKRSTART equ *
lds #STACK ; Initialise stack
clr BPROT ; clear block protect for debug in normal modes
ldaa #JMPEXT
ldy #NULLSRV
ldx #BUFFVECT
SETVECT equ *
staa ,x
inx
sty ,x
inx
inx
cpx #ENDVECT
bne SETVECT
ldx #SCISRV
stx JSCI+1
ldx #TLKRSTART
stx JILLOP+1
ldx #TLKRSTART
stx JCOP+1
ldx #TLKRSTART
stx JCLM+1
;
; Now initialise communications
;
ldd #26
std BAUD ; Initialise SCI to 9600 baud @ 8MHz EXTAL (SCBDH=0)
ldaa #0
staa SCCR1 ; No LOOPS,WOMS,parity. Idle line wake up+8 bits
staa SCDRH ; No data in bit 8
ldab #$2C
stab SCCR2 ; and enable SCI Rx interrupt & Tx.
ldaa #$40 ; Enable STOP, and I bit interrupts, disable XIRQ.
tap ; Set up CCR
;
IDLE bra IDLE ; Now hang around for SCI interrupt from host.
;
; A RESET from host changes above jump destination to start of user code.
;
SCISRV equ * ; On detecting interrupt,
brclr SCSR,RDRF,SCISRV
;
RXSRV equ * ; Talker code processes received data.
ldaa SCDRL ; Read command byte, & echo it as acknowledge
coma ; inverted
bsr OUTSC ; to host.
bpl INH1 ; If command bit 7 set, then process inherent command
bsr INSC ; else read byte count from host into ACCB.(0=256)
xgdx ; Save command and byte count.
bsr INSC ; Read high address byte
tba ; into ACCA
bsr INSC ; then low address byte into ACCB
xgdx ; Restore command in ACCA,count in ACCB,address in X
cmpa #$FE
bne RXSRV1 ; If command is not memory read then RXSRV1
;
TREADMEM equ * ; REPEAT
ldaa ,x ; read required address
bsr OUTSC ; send it to host
tba ; (save byte count)
bsr INSC ; and wait for acknowledge
tab ; (restore byte count)
inx ; Increment address
decb ; Decrement byte count
bne TREADMEM ; UNTIL all done
rti
;
INSC equ *
brset SCSR,$0A,TLKRSTART ; Restart talker if break detected
brclr SCSR,RDRF,INSC ; Loop to INSC if no character received
ldab SCDRL ; then read data received from host
EPRG rts ; and return with data in ACCB
;
OUTSC equ * ; Only register Y modified.
OUTSC1 brclr SCSR,$80,OUTSC1 ; Loop until set before storing next byte
staa SCDRL ; Important - Updates CCR!
rts
;
RXSRV1 equ *
cmpa #$BE
bne RXSRVEX ; If command is memory write then
;
tba ; move byte count to ACCA
TWRITMEM equ * ; REPEAT
bsr INSC ; Read next byte from host into ACCB,
stab ,x ; and store at required address.
bsr EPRG ; Dummy jump - used as hook for EPROM prog
ldab ,x ; Read stored byte and
stab SCDRL ; echo it back to host,
inx
deca ; Decrement byte count
bne TWRITMEM ; UNTIL all done
RXSRVEX equ * ; and return
NULLSRV rti
;
INH1 equ *
cmpa #$7E ; If command is read MCU registers then INH1A
bne INH2 ; else jump to INH2
;
INH1A tsx ; Move stack pointer to X
xgdx ; then to ACCD
bsr OUTSC ; send stack pointer to host (high byte first)
tba
bsr OUTSC ; then low byte
tsx ; Restore X (=stack pointer)
ldab #9 ; then return 9 bytes on stack
bra TREADMEM ; i.e. CCR,ACCB,ACCA,IXH,IXL,IYH,IYL,PCH,PCL
;
INH2 equ *
cmpa #$3E ; If command is write MCU registers then don't jump
bne SWISRV1 ; else quit processing
;
bsr INSC ; get stack pointer from host (High byte first)
tba
bsr INSC
xgdx ; Move to X reg
txs ; and copy to stack pointer
ldaa #9 ; Then put next 9 bytes from host on to stack
bra TWRITMEM
;
SWISRV equ * ; Breakpoints generated by host-placed SWI instruction.
ldaa #BRKCODE ; Force host to process breakpoints
bsr OUTSC ; by sending it the break signal
SWIIDLE cli
bra SWIIDLE ; then wait for response from host. (Ibit=,x bit=1)
;
SWISRV1 equ *
cmpa #BRKACK ; If host has acknowledged breakpoint state then
bne RXSRVEX
tsx ; move stack pointer to SWI stack frame and
ldab #9
abx
txs
ldd 7,x ; Send user code breakpoint return address to host
bsr OUTSC ; (high byte first)
tba
bsr OUTSC ; (low byte next)
ldd #SWIIDLE ; force idle loop on return from breakpoint processing
std 7,x
bra INH1A ; but first return all MCU registers to host
;
; END of talker
;*****************
;** BUFFALO - This is where Buffalo starts
;** out of reset. All initialization is done
;** here including determination of where the
;** user terminal is (SCI,ACIA, or DUART).
;*****************
org ROMBS
BUFFALO ldx #PORTE
brclr ,x,$01,BUFISIT ; if bit 0 of port e is 1
ldaa DSTREE ; then test if EEPROM is erased
cmpa #$FF
beq TALKJMP ; if it is erased, jump to talker
jmp DSTREE ; if anything else, then jump to EEPROM
TALKJMP jmp TLKRSTART ; jump to the start of talker
BUFISIT ldaa #$93
staa OPTION ; adpu, dly, irqe, cop
ldaa #$00
staa TMSK2 ; timer pre = %1 for trace
ldaa #$00
staa BPROT ; clear 'E9 eeprom block protect
ldx #DSTREE ; set up default eeprom address range
stx STREE
ldx #DENDEE
stx ENDEE
ldx #$0000 ; set up default download offset
stx LDOFFST
lds #STACK ; monitor stack pointer
jsr VECINIT
ldx #USTACK
stx SP ; default user stack
ldaa TCTL1
oraa #$03
staa TCTL1 ; force oc5 pin high for trace
ldaa #$D0
staa REGS+8 ; default user ccr
ldd #$3F0D ; initial command is ?
std INBUFF
jsr BPCLR ; clear breakpoints
clr AUTOLF
inc AUTOLF ; auto cr/lf = on
; Determine type of external comm device - none, or acia *
clr EXTDEV ; default is none
ldaa HPRIO
anda #$20
beq BUFF2 ; jump if single chip mode
ldaa #$03 ; see if external acia exists
staa ACIA ; master reset
ldaa ACIA
anda #$7F ; mask irq bit from status register
bne BUFF1 ; jump if status reg not 0
ldaa #$12
staa ACIA ; turn on acia
ldaa ACIA
anda #$02
beq BUFF1 ; jump if tdre not set
ldaa #$01
staa EXTDEV ; external device is acia
bra BUFF2
BUFF1 equ * ; see if duart exists
ldaa DUART+$0C ; read IRQ vector register
cmpa #$0F ; should be out of reset
bne BUFF2
ldaa #$AA
staa DUART+$0C ; write irq vector register
ldaa DUART+$0C ; read irq vector register
cmpa #$AA
bne BUFF2
ldaa #$02
staa EXTDEV ; external device is duart A
; Find terminal port - SCI or external. *
BUFF2 clr IODEV
jsr TARGCO ; disconnect sci for evb board
bsr SIGNON ; initialize sci
ldaa EXTDEV
beq BUFF3 ; jump if no external device
staa IODEV
bsr SIGNON ; initialize external device
BUFF3 clr IODEV
jsr INPUT ; get input from sci port
cmpa #$0D
beq BUFF4 ; jump if cr - sci is terminal port
ldaa EXTDEV
beq BUFF3 ; jump if no external device
staa IODEV
jsr INPUT ; get input from external device
cmpa #$0D
beq BUFF4 ; jump if cr - terminal found ext
bra BUFF3
SIGNON jsr INIT ; initialize device
ldx #MSG1 ; buffalo message
jsr OUTSTRG
rts
; Determine where host port should be. *
BUFF4 clr HOSTDEV ; default - host = sci port
ldaa IODEV
cmpa #$01
beq BUFF5 ; default host if term = acia
ldaa #$03
staa HOSTDEV ; else host is duart port b
BUFF5 equ *
;*****************
;** MAIN - This module reads the user's input into
;** a buffer called INBUFF. The first field (assumed
;** to be the command field) is then parsed into a
;** second buffer called COMBUFF. The command table
;** is then searched for the contents of COMBUFF and
;** if found, the address of the corresponding task
;** routine is fetched from the command table. The
;** task is then called as a subroutine so that
;** control returns back to here upon completion of
;** the task. Buffalo expects the following format
;** for commands:
;** <cmd>[<wsp><arg><wsp><arg>...]<cr>
;** [] implies contents optional.
;** <wsp> means whitespace character (space,comma,tab).
;** <cmd> = command string of 1-8 characters.
;** <arg> = Argument particular to the command.
;** <cr> = Carriage return signifying end of input string.
;*****************
; Prompt user
; *do
; a=input();
; if(a==(cntlx or del)) continue;
; elseif(a==backspace)
; b--;
; if(b<0) b=0;
; else
; if(a==cr && buffer empty)
; repeat last command;
; else put a into buffer;
; check if buffer full;
; *while(a != (cr or /)
MAIN sei ; block interrupts
lds #STACK ; initialize sp every time
clr AUTOLF
inc AUTOLF ; auto cr/lf = on
jsr OUTCRLF
ldaa #PROMPT ; prompt user
jsr OUTPUT
clrb
MAIN1 jsr INCHAR ; read terminal
ldx #INBUFF
abx ; pointer into buffer
cmpa #CTLX
beq MAIN ; jump if cntl X
cmpa #DEL
beq MAIN ; jump if del
cmpa #$08
bne MAIN2 ; jump if not bckspc
decb
blt MAIN ; jump if buffer empty
bra MAIN1
MAIN2 cmpa #$D
bne MAIN3 ; jump if not cr
tstb
beq COMM0 ; jump if buffer empty
staa ,x ; put a in buffer
bra COMM0
MAIN3 staa ,x ; put a in buffer
incb
cmpb #BUFFLNG
ble MAIN4 ; jump if not long
ldx #MSG3 ; "long"
jsr OUTSTRG
bra MAIN
MAIN4 cmpa #'/'
bne MAIN1 ; jump if not "/"
; *******************
;*****************
; Parse out and evaluate the command field.
;*****************
; *Initialize
COMM0 equ *
clr TMP1 ; Enable "/" command
clr SHFTREG
clr SHFTREG+1
clrb
ldx #INBUFF ; ptrbuff[] = inbuff[]
stx PTR0
jsr WSKIP ; find first char
; *while((a=readbuff) != (cr or wspace))
; upcase(a);
; buffptr[b] = a
; b++
; if (b > 8) error(too long);
; if(a == "/")
; if(enabled) mslash();
; else error(command?);
; else hexbin(a);
COMM1 equ *
jsr READBUFF ; read from buffer
ldx #COMBUFF
abx
jsr UPCASE ; convert to upper case
staa ,x ; put in command buffer
cmpa #$0D
beq SRCH ; jump if cr
jsr WCHEK
beq SRCH ; jump if wspac
jsr INCBUFF ; move buffer pointer
incb
cmpb #$8
ble COMM2
ldx #MSG3 ; "long"
jsr OUTSTRG
jmp MAIN
COMM2 equ *
cmpa #'/'
bne COMM4 ; jump if not "/"
tst TMP1
bne COMM3 ; jump if not enabled
decb
stab COUNT
ldx #MSLASH
bra EXEC ; execute "/"
COMM3 ldx #MSG8 ; "command?"
jsr OUTSTRG
jmp MAIN
COMM4 equ *
jsr HEXBIN
bra COMM1
;*****************
; Search tables for command. At this point,
; COMBUFF holds the command field to be executed,
; and B = # of characters in the command field.
; The command table holds the whole command name
; but only the first n characters of the command
; must match what is in COMBUFF where n is the
; number of characters entered by the user.
;*****************
; *count = b;
; *ptr1 = comtabl;
; *while(ptr1[0] != end of table)
; ptr1 = next entry
; for(b=1; b=count; b++)
; if(ptr1[b] == combuff[b]) continue;
; else error(not found);
; execute task;
; return();
; *return(command not found);
SRCH stab COUNT ; size of command entered
ldx #COMTABL ; pointer to table
stx PTR1 ; pointer to next entry
SRCH1 ldx PTR1
ldy #COMBUFF ; pointer to command buffer
ldab ,x
cmpb #$FF
bne SRCH2
ldx #MSG2 ; "command not found"
jsr OUTSTRG
jmp MAIN
SRCH2 pshx ; compute next table entry
addb #$3
abx
stx PTR1
pulx
clrb
SRCHLP incb ; match characters loop
ldaa 1,x ; read table
cmpa ,y ; compare to combuff
bne SRCH1 ; try next entry
inx ; move pointers
iny
cmpb COUNT
blt SRCHLP ; loop countu1 times
ldx PTR1
dex
dex
ldx ,x ; jump address from table
EXEC jsr ,x ; call task as subroutine
jmp MAIN
;
;*****************
; UTILITY SUBROUTINES - These routines
; are called by any of the task routines.
;*****************
;*****************
; UPCASE(a) - If the contents of A is alpha,
; returns a converted to uppercase.
;*****************
UPCASE cmpa #'a'
blt UPCASE1 ; jump if < a
cmpa #'z'
bgt UPCASE1 ; jump if > z
suba #$20 ; convert
UPCASE1 rts
;*****************
; BPCLR() - Clear all entries in the
; table of breakpoints.
;*****************
BPCLR ldx #BRKTABL
ldab #8
BPCLR1 clr ,x
inx
decb
bgt BPCLR1 ; loop 8 times
rts
;*****************
; RPRNT1(x) - Prints name and contents of a single
; user register. On entry X points to name of register
; in reglist. On exit, a=register name.
;*****************
REGLIST fcc 'PYXABCS' ; names
fcb 0,2,4,6,7,8,9 ; offset
fcb 1,1,1,0,0,0,1 ; size
RPRNT1 ldaa ,x
psha
pshx
jsr OUTPUT ; name
ldaa #'-'
jsr OUTPUT ; dash
ldab 7,x ; contents offset
ldaa 14,x ; bytesize
ldx #REGS ; address
abx
tsta
beq RPRN2 ; jump if 1 byte
jsr OUT1BYT ; 2 bytes
RPRN2 jsr OUT1BSP
pulx
pula
rts
;*****************
; RPRINT() - Print the name and contents
; of all the user registers.
;*****************
RPRINT pshx
ldx #REGLIST
RPRI1 bsr RPRNT1 ; print name
inx
cmpa #'S' ; s is last register
bne RPRI1 ; jump if not done
pulx
rts
;*****************
; HEXBIN(a) - Convert the ASCII character in a
; to binary and shift into shftreg. Returns value
; in tmp1 incremented if a is not hex.
;*****************
HEXBIN psha
pshb
pshx
bsr UPCASE ; convert to upper case
cmpa #'0'
blt HEXNOT ; jump if a < $30
cmpa #'9'
ble HEXNMB ; jump if 0-9
cmpa #'A'
blt HEXNOT ; jump if $39> a <$41
cmpa #'F'
bgt HEXNOT ; jump if a > $46
adda #$9 ; convert $A-$F
HEXNMB anda #$0F ; convert to binary
ldx #SHFTREG
ldab #4
HEXSHFT asl 1,x ; 2 byte shift through
rol ,x ; carry bit
decb
bgt HEXSHFT ; shift 4 times
oraa 1,x
staa 1,x
bra HEXRTS
HEXNOT inc TMP1 ; indicate not hex
HEXRTS pulx
pulb
pula
rts
;*****************
; BUFFARG() - Build a hex argument from the
; contents of the input buffer. Characters are
; converted to binary and shifted into shftreg
; until a non-hex character is found. On exit
; shftreg holds the last four digits read, count
; holds the number of digits read, ptrbuff points
; to the first non-hex character read, and A holds
; that first non-hex character.
;*****************
; *Initialize
; *while((a=readbuff()) not hex)
; hexbin(a);
; *return();
BUFFARG clr TMP1 ; not hex indicator
clr COUNT ; # or digits
clr SHFTREG
clr SHFTREG+1
jsr WSKIP
BUFFLP jsr READBUFF ; read char
bsr HEXBIN
tst TMP1
bne BUFFRTS ; jump if not hex
inc COUNT
jsr INCBUFF ; move buffer pointer
bra BUFFLP
BUFFRTS rts
;*****************
; TERMARG() - Build a hex argument from the
; terminal. Characters are converted to binary
; and shifted into shftreg until a non-hex character
; is found. On exit shftreg holds the last four
; digits read, count holds the number of digits
; read, and A holds the first non-hex character.
;*****************
; *initialize
; *while((a=inchar()) == hex)
; if(a = cntlx or del)
; abort;
; else
; hexbin(a); countu1++;
; *return();
TERMARG clr COUNT
clr SHFTREG
clr SHFTREG+1
TERM0 jsr INCHAR
cmpa #CTLX
beq TERM1 ; jump if controlx
cmpa #DEL
bne TERM2 ; jump if not delete
TERM1 jmp MAIN ; abort
TERM2 clr TMP1 ; hex indicator
bsr HEXBIN
tst TMP1
bne TERM3 ; jump if not hex
inc COUNT
bra TERM0
TERM3 rts
;*****************
; CHGBYT() - If shftreg is not empty, put
; contents of shftreg at address in X. If X
; is an address in EEPROM then program it.
;*****************
; *if(count != 0)
; (x) = a;
CHGBYT tst COUNT
beq CHGBYT4 ; quit if shftreg empty
ldaa SHFTREG+1 ; get data into a
bsr WRITE
CHGBYT4 rts
;*****************
; WRITE() - This routine is used to write the
; *contents of A to the address of X. If the
; *address is in EEPROM, it will be programmed
; *and if it is already programmed, it will be
; *byte erased first.
;******************
; *if(X == config) then
; byte erase config;
; *if(X is eeprom)then
; if(not erased) then erase;
; program (x) = A;
; *write (x) = A;
; *if((x) != A) error(rom);
WRITE equ *
cpx #CONFIG
beq WRITE0 ; jump if config
cpx STREE ; start of EE
blo WRITE2 ; jump if not EE
cpx ENDEE ; end of EE
bhi WRITE2 ; jump if not EE
WRITEE pshb ; check if byte erased
ldab ,x
cmpb #$FF
pulb
beq WRITE1 ; jump if erased
WRITE0 bsr EEBYTE ; byte erase
WRITE1 bsr EEWRIT ; byte program
WRITE2 staa ,x ; write for non EE
cmpa ,x
beq WRITE3 ; jump if write ok
pshx
ldx #MSG6 ; "rom"
jsr OUTSTRG
pulx
WRITE3 rts
;*****************
; EEWRIT(), EEBYTE(), EEBULK() -
; These routines are used to program and eeprom
; *locations. eewrite programs the address in X with
; *the value in A, eebyte does a byte address at X,
; *and eebulk does a bulk of eeprom. Whether eebulk
; *erases the config or not depends on the address it
; *receives in X.
;****************
EEWRIT equ * ; program one byte at x
pshb
ldab #$02
stab PPROG
staa ,x
ldab #$03
bra EEPROG
;***
EEBYTE equ * ; byte erase address x
pshb
ldab #$16
stab PPROG
ldab #$FF
stab ,x
ldab #$17
bra EEPROG
;***
EEBULK equ * ; bulk erase eeprom
pshb
ldab #$06
stab PPROG
staa ,x ; erase config or not ...
ldab #$07 ; ... depends on X addr
EEPROG bne ACL1
clrb ; fail safe
ACL1 stab PPROG
pulb
;***
DLY10MS equ * ; delay 10ms at E = 2MHz
pshx
ldx #$0D06
DLYLP dex
bne DLYLP
pulx
clr PPROG
rts
;*****************
; READBUFF() - Read the character in INBUFF
; pointed at by ptrbuff into A. Returns ptrbuff
; unchanged.
;*****************
READBUFF pshx
ldx PTR0
ldaa ,x
pulx
rts
;*****************
; INCBUFF(), DECBUFF() - Increment or decrement
; ptrbuff.
;*****************
INCBUFF pshx
ldx PTR0
inx
bra INCDEC
DECBUFF pshx
ldx PTR0
dex
INCDEC stx PTR0
pulx
rts
;*****************
; WSKIP() - Read from the INBUFF until a
; non whitespace (space, comma, tab) character
; is found. Returns ptrbuff pointing to the
; first non-whitespace character and a holds
; that character. WSKIP also compares a to
; $0D (CR) and cond codes indicating the
; results of that compare.
;*****************
WSKIP bsr READBUFF ; read character
bsr WCHEK
bne WSKIP1 ; jump if not wspc
bsr INCBUFF ; move pointer
bra WSKIP ; loop
WSKIP1 cmpa #$0D
rts
;*****************
; WCHEK(a) - Returns z=1 if a holds a
; whitespace character, else z=0.
;*****************
WCHEK cmpa #$2C ; comma
beq WCHEK1
cmpa #$20 ; space
beq WCHEK1