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