Smartbug.asm
crsjones_68Retro/6800-BUGS/SMARTBUG/Smartbug.asm
* NAM SMARTBUG
* "SMARTBUG" - AN INTELLIGENT MONITOR
* COPYRIGHT 1977 SMALL SIGNAL BROADCASTING
* OPT O,S
ACIAS EQU $8008
ACIAD EQU $8009
 ORG $E000

* I/O INTERRUPT SEQUENCE
IO LDX IOV
 JMP 0,X
* NMI SEQUENCE
POWDWN LDX NIO GET NMI VECTOR
 JMP 0,X GO TO NMI LOCATION
* LOAD ASCII FORMATTED TAPE
LOAD EQU *
 LDAA #$55 READER RELAY ON, ONE STOP BIT
 STAA ACIAS
 LDAA #$11
 BSR OUTCH AC-30 READ CTRL
LOAD3 BSR INCH GET CHARACTER
 CMPA #'S' IS IT AN "S" 
 BNE LOAD3 NO-LOOP TILL "S" FOOND 
 BSR INCH YES - GET NEXT CHARACTER 
 CMPA #'9' IS IT A "9" 
 BEQ LOAD21 YES - JUMP TO CONTROL 
 CMPA #'1' IS IT A "1" 
 BNE LOAD3 NO - TRY AGAIN 
 CLR CKSM YES - ZERO CHECKSUM 
 BSR BYTE GET A BYTE 
 SUBA #2 
 STAA BYTECT READ THIS MANY BYTES 
* BUILD ADDR 
 BSR BADDR 
* STORE DATA 
LOAD11 BSR BYTE READ NEXT BYTE 
 DEC BYTECT DECREMENT BYTE COUNTER 
 BEQ LOAD15 IF 0, GET NEXT LINE 
 STAA 0,X ELSE, STORE DATA 
 INX 
 BRA LOAD11 
LOAD15 INC CKSM FORM 2'S COMPLEMENT 
 BEQ LOAD3 IT SHOULD BE ZERO 
LOAD19 LDAA #'?' READ ERROR - PRINT 
 BSR OUTCH QUESTION MARK 
LOAD21 EQU * 
C1 JMP CONTRL 

* BUILD ADDRESS 
BADDR BSR  BYTE READ 2 BYTES 
 STAA XHI AND RETURN FROM THIS 
 BSR BYTE SUBROUTINE WITH BOTH 
 STAA XLOW BYTES IN THE INDEX 
 LDX XHI REGISTER. 
 RTS 

* INPUT BYTE (2 HEX CHARACTERS) 
BYTE BSR INHEX GET 1ST HEX CHAR 
 ASLA 
 ASLA 
 ASLA 
 ASLA 
 TAB 
 BSR INHEX GET 2ND HEX CHAR 
 ABA 
 TAB 
 ADDB CKSM UPDATE CHECKSUM AND 
 STAB CKSM RETURN WITH BYTE IN 
 RTS A ACCUMlLATOR 
OUTHL LSRA OUT HEX LEFT BCD DIGIT 
 LSRA 
 LSRA 
 LSRA 

OUTHR ANDA #$0F OUT HEX RIGHT BCD DIGIT 
 ADDA #$30 
 CMPA #$39 
 BLS OUTCH 
 ADDA #7
OUTCH JMP OUTEEE OUTPUT A CHARACTER 
INCH JMP INEEE INPUT A CHARACTER 

* PRINT DATA POINTED TO BY INDEX REGISTER 
PDATA2 BSR OUTCH 
 INX 
PDATA1 LDAA 0,X 
 CMPA #4 END OF STRING CHARACTER 
 BNE PDATA2 
 RTS 

* CHANGE MEMORY 
CHANGE BSR BADDR GET MEMORY ADDRESS 
CHA51 LDX #MCL 
 BSR PDATA1 PRINT C/R L/F 
 LDX #XHI 
 BSR OUT4HS PRINT ADDRESS 
 LDX XHI 
 BSR OUT2HS PRINT OLD DATA 
 STX XHI 
 BSR INCH INPUT A CHARACTER 
 CMPA #$20 IF IT'S A SPACE 
 BEQ CHA51 GET NEXT ADDRESS 
 JMP TDEX ELSE - GO TO TDEX 
CHA61 STAA 0,X STORE NEW DATA 
 CMPA 0,X DID IT STORE CORRECTLY? 
 BEQ CHA51 YES - GET NEXT ADDRESS 
 BRA LOAD19 NO - JUMP CONTROL 
* INPUT HEX CHARACTER 
INHEX BSR INCH 
 SUBA #$30 
 BMI C1 NOT HEX, JUMP CONTROL 
 CMPA #9 
 BLE IN1HG 
 CMPA #$11 
 BMI C1 NOT HEX 
 CMPA #$16 
 BGT C1 NOT HEX 
 SUBA #7 
IN1HG RTS 

OUT2H LDAA 0,X OUTPUT 2 HEX CHAR 
OUT2HA BSR OUTHL OUT LEFT HEX CHAR 
 LDAA 0,X 
 INX 
 BRA OUTHR OUTPUT RIGHT HEX CHAR 
OUT4HS BSR OUT2H OUTPUT 4 HEX CHAR AND SPACE 
OUT2HS BSR OUT2H OUTPUT 2 HEX CHAR AND SPACE 
OUTS LDAA #$20 OUTPUT SPACE 
 BRA OUTCH 

* POWER ON SEQUENCE 
START EQU * 
 LDS #STACK 
 STS SP 
 CLR ECHO ECHO ALL INPUT CHARACTERS 
 LDAA #3 MASTER RESET OF ACIA 
 STAA ACIAS 
INZ LDAA #$15 SET UP FOR 1 STOP BIT 
INZ1 STAA ACIAT 
CONTRL LDAA ACIAT ALLOW FOR SOFTWARE CONTROL 
 STAA ACIAS OF ACIA CONTROL REGISTER 
 LDS #STACK 
 CLR TFLAG TURN OFF TRACE MODE 
 LDX #MCLOFF 
 BSR PDATA1 

 BSR INCH INPUT COMMAND CHARACTER 
 CLR BKFLG CLEAR BREAKPOINT INDICATOR 
 TAB 
 BSR OUTS
 LDX #FUTABL DO TABLE LOOKUP 
NXTCHR CMPB 0,X FOR COMMAND FUNCTIONS 
 BEQ GOODCH MATCH FOUND 
 INX NO MATCH-INC TO NEXT COMMAND 
 INX 
 INX 
 CPX #TBLEND END OF COMMAND TABLE? 
 BNE NXTCHR NO - GET NEXT CHARACTER 
 JMP CKCBA YES - CHECK FOR A,B,C,X CMNDS 
GOODCH LDX 1,X GET COMMAND LOCATION 
 JMP 0,X AND JUMP THERE 
 NOP KEEP SFE AT $E113 

* ENTER FRCJ4 SOFTWARE INTERRUPT
SFE STS SP SAVE PROGRAM'S STACK POINTER 
* DECREMENT PROGRAM COUNTER 
 TSX 
 TST 6,X 
 BNE *+4 
 DEC 5,X 
 DEC 6,X 
 TST TFLAG 
 BEQ PRNT IF TRACE IS OFF 
 JMP SWTURN IF TRACE IS ON 

* PUNCH - OUTPUT HEX FORMATTED TAPE 

PUNCH BSR LIMITS GET LIMITS 
 LDAA #$12 AC-30 CONTRL 
 JSR OUTCH 
 LDX BEGA THE "P" COMMAND JUMPS TO 
 STX TW PUNCH AFTER USING THE LIMITS 
PUN11 LDAA ENDA+1 SUBROUTINE TO ENTER THE 
 SUBA TW+1 START AND STOP ADDRESSES 
 LDAB ENDA 
 SBCB TW 
 BNE PUN22 
 CMPA #16 
 BCS PUN23 
PUN22 LDAA #15 
PUN23 ADDA #4 
 STAA MCONT FRAME COUNT THIS RECORD 
 SUBA #3 
 STAA TEMP BYTE COUNT THIS RECORD 
* PUNCH C/R,L/F,NULL,S,1 
 BSR CRLF 
 INX 
 BSR PDAT1 
 CLRB ZERO CHECKSUM 
* PUNCH FRAME COUNT 
 LDX #MCONT 
 BSR PUNT2 PUNCH 2 HEX CHAR 
* PUNCH ADDR
 LDX #TW 
 BSR PUNT2 
 BSR PUNT2 
* PUNCH DATA 
 LDX TW 
PUN32 BSR PUNT2 PUNCH ONE BYTE 

 DEC TEMP DECREMENT ONE BYTE 
 BNE PUN32 
 STX TW 
 COMB 
 PSHB 
 TSX 
 BSR PUNT2 PUNCH CHECKSUM 
 PULB RESTORE STACK 
 LDX TW 
 DEX 
 CPX ENDA 
 BNE PUN11 
 BRA C3 GO TO CONTROL 
PUNT2 ADDB 0,X 
 JMP OUT2H 
PRNT BRA PRINT 

BKPNT BSR BAD2 GET BREAKPOINT ADDRESS 
 STX PB2 
 LDAA 0,X SAVE INSTRUCTION AND 
 STAA BKFLG SET BREAKPOINT FLAG 
 LDAA #$3F 
 STAA 0,X SET BREAKPOINT 
 BSR CRLF 
CONTG LDS SP RESTORE PGM'S STACK POINTER 
 RTI GO TO USER'S PROGRAM 

LIMITS BSR BAD2 GET FIRST ADDRESS 
 STX BEGA 
 BSR OUS OUTPUT A SPACE 
 BSR BAD2 GET SECOND ADDRESS 
 STX ENDA 
OUS JMP OUTS OUTPUT A SPACE & RETURN 

* INPUT ONE CHARACTER INTO A ACCUMULATOR 
INEEE LDAA ACIAS TEST RECEIVE DATA REG FULL 
 ASRA FLAG AND LOOP TILL IT IS SET 
 BCC INEEE 
 LDAA ACIAD GET DATA 
 ANDA #$7F ELIMINATE PARITY BIT 
 CMPA 1$7F 
 BEQ INEEE IGNORE RUBOOTS 
 TST ECHO 
 BLE OUTEEE 
 RTS 

BAD2 JMP BADDR GET ADDRESS 

ECHON CLRB ECHO ALL INPUT CHARACTERS 
PRNTON NEGB TURN PRINTER ON 
ECHOFF STAB ECHO DO NOT ECHO
C3 BRA C2 GO TO CONTROL 

CRLF LDX #CRLFAS C/R L/F WITHOUT * PROMPT 

PDAT1 JMP PDATA1 SIGNIFIES TRACE MODE 

* OUTPUT ONE CHARACTER FROM A-REG 
OUTEEE TST ECHO IF ECHO IS NEGATIVE, 
 BGE OUTCH2 GO TO PRINTER ROOfINE. 
 JMP PRINTR 
OUTCH2 PSHB 
OUTCH1 LDAB ACIAS TEST TRANSMIT DATA 
 ASRB REGISTER EMPTY FLAG 
 ASRB AND LOOP TILL SET 
 BCC OUTCH1 
 STAA ACIAD OUTPUT DATA TO ACIA 
 PULB RESTORE B-REG 
 RTS 
JUMP BSR BAD2 GET LOCATION OF JUMP 
 JMP 0,X GO TO USER'S PROGRAM 
 
* PRINT CONTENTS OF STACK 
PRINT LDX SP 
 INX 
 BSR OUT2 CONDITION CODES 
 BSR OUT2 B ACCUMULATOR 
 BSR OUT2 A ACCUMULATOR 
 BSR OUTT4 INDEX REGISTER 
 BSR OUTT4 PROGRAM COUNTER 
 LDX #SP 
 TST TFLAG 
 BNE PRINTS IF IN TRACE MODE 
 BSR OUTT4 STACK POINTER 
 LDAA BKFLG GET INSTR TO REPLACE BKPNT 
 BEQ C2 NO BREAKPOINT SET 
 LDX PB2 
 STAA 0,X REPLACE BREAKPOINT 
C2 JMP CONTRL 

IFILL BSR LIMITS GET START & END ADDRESSES 
 BSR BYT GET DESIRED CONTENTS 
 LDX BEGA 1ST ADDRESS TO INDEX REG 
 DEX 
FILLOP INX 
 STAA 0,X FILL MEMORY FROM A REG 
 CPX ENDA 
 BNE FILLOP LOOP UNTIL DONE 
C5 BRA C2 GO TO CONTROL 

PRINTS LDAB 0,X WHEN IN TRACE MODE 
 LDAA 1,X DISPLAY S-POINTER THAT 
 ADDA #7 WILL BE USED WHEN EXECUTING 
 ADCB #0 THE DISPLAYED INSTRUCTION 
 STAB TEMP 
 STAA TEMP+1 
 LDX #TEMP 
OUTT4 BRA OUT4
OUT2 JMP OUT2HS 

* TRACE ROUTINE 
TRACE BSR BAD2 GET START ADDRESS OF TRACE 
 BSR CRLF AND SAVE IN XHI & XLOW 
 LDX SP 
 LDAB XHI PUT START ADDRESS IN 
 STAB 6,X PROGRAM COUNTER POSITION 
 LDAA XLOW IN STACK 
 STAA 7,X 
 INC TFLAG SET TRACE FLAG 
RETURN LDS #TSTACK SEPARATE STACK FOR TRACE 
 BSR PRINT DISPLAY ALL REGISTERS 
 CLR BFLAG CLEAR BRANCH FLAG 
 LDX SP 
 LDX 6,X GET PROGRAM COUNTER FROM STACK 
 STX XHI AND SAVE IN XHI AND XLOW 
 JSR CRLF 
 lDX #XHI 
 BSR OUT4 DISPLAY PROGRAM COUNTER 
 LDX XHI AND FIRST BYTE OF 
 LDAB 0,X INSTRUCTION 
 BSR OUT2 
 LDAA 0,X STORE 2ND BYTE OF INSTRUCTION 
 STAA PB2 IN PB2 AND 3RD BYTE IN PB3 
 LDAA 1,X IF INSTRUCTION IS LONGER 
 STAA PB3 THAN ONE BYTE 
 STAB PB1 
 CMPB #$8D BSR? TEST FOR SPECIAL CODES 
 BEQ BBR 
 CMPB #$8C CPX? 
 BEQ BYT3 
 CMPB #$8E LDS? 
 BEQ BYT3 
 CMPB #$CE LDX? 
 BEQ BYT3 
 ANDB #$F0 
 CMPB #$20 TEST FOR RELATIVE BRANCH 
 BNE NOTB TYPE INSTRUCTIONS 
BBR INC BFLAG SET BRANCH FLAG 
 BRA BYT2 TWO BYTE INSTRUCTION 
BYT JMP BYTE 
C4 BRA C5 GO TO CONTROL 
OUT4 JMP OUT4HS 
NOTB CMPB #$60 IS CODE LESS THAN 60? 
 BCS BYT1 YES - 1 BYTE INSTRUCTION 
 ANDB #$30 
 CMPB #$30 
 BNE BYT2 ONLY 3 BYTE WILL FALL THRU 
BYT3 BSR OUT4 DISPLAY 2 BYTE OPERAND 
 BRA BYT1 
BYT2 BSR OUT2 DISPLAY 1 BYTE OPERAND 
BYT1 STX XHI SAVE LOCATION OF NEXT INSTR 
* XHI NOW CONTAINS NEXT INS LOCATION 
 TST BFLAG IS IT A BRANCH? 
 BEQ NOTBB NO 
 CLRA YES, COMPUTE TARGET LOCATION 
 LDAB PB2 
 BGE DPOS TEST FOR BRANCH BACK 
 LDAA #$FF FF FOR BACKWARD BRANCH 
DPOS ADDB XLOW ADD OPERAND TO LOWER 
 ADCA XHI 8 BITS OF PROGRAM COUNTER 
 STAA BPOINT SAVE TARGET ADDRESS 
 STAB BPOINT+1 
 LDX #BPOINT DISPLAY TARGET ADDRESS 
 BSR OUT4 
NOTBB JSR CRLF 
 JSR INEEE GET COMMAND 
 TAB SAVE IN B REGISTER 
 JSR OUTS 
 CMPB #$20 IF SPACE EXECUTE THE 
 BEQ DOT INSTRUCTION. IF NOT A 
CKCBA LDX SP SPACE, TEST FOR A CHANGE 
 INX REGISTER COMMAND. NOTE, THIS 
 CMPB #'C' PART OF MEMORY IS SHARED 
 BEQ RDC WITH THE CHANGE REGISTER 
 INX COMMANDS WHEN NOT IN TRACE 
 CMPB #'B' MODE. IF IT IS A CHANGE 
 BEQ RDC REGISTER COMMAND WHILE IN 
 INX TRACE MODE, RETURN TO 
 CMPB #'A' NOTBB FOR NEXT COMMAND. 
 BNE CHKX 
RDC JSR OUT2HS DISPLAY REGISTER CONTENTS 
 DEX SAVED IN STACK 
 BSR BYT GET NEW CONTENTS 
 STAA 0,X AND STORE IN STACK 
 BRA RETDID 
CHKX CMPB #'X' 
 BNE C4 
 INX 
 BSR OUT4 DISPLAY INDEX CONTENTS 
 BSR BYT GET HIGH 8 BITS 
 LDX SP 
 STAA 4,X STORE IN STACK 
 BSR BYT GET LOWER 8 BITS 
 STAA 5,X STORE 
RETDID TST TFLAG IN TRACE? 
 BNE NOTBB YES, GET NEXT TRACE CMD 
RETNOT BRA C4 RETURN TO CONTROL 
DOT LDAB #$3F SWI CODE TO B-REG 
 LDAA PB1 GET INSTRUCTION 
 CMPA #$8D IS IT A BSR? 
 BNE TSTB IF YES, NEXT INSTRUCTION 
 LDX BPOINT WILL BE AT ADDRESS STORED 
 STX XHI IN BPOINT. 
 CLR BFLAG ONLY ONE SWI NEED BE SET 
 BRA EXEC SET BKPOINT AND EXECUTE INST 
TSTB TST BFLAG IS IT CONDITIONAL BRANCH? 
 BEQ TSTJ YES, SET BREAKPOINT AT 
 LDX BPOINT TARGET ADDRESS IN CASE 
 LDAA 0,X PROGRAM GOES THERE. 
 STAA BPOINT+2 SAVE INSTRUCTION 
 STAB 0,X SET SW! AT TARGET ADDRESS 
 BRA EXEC 
TSTJ CMPA #$6E INDEXED JUMP INSTRUCTION? 
 BEQ ISX 
 CMPA #$AD INDEXED JSR? 
 BEQ ISX 
 CMPA #$7E STRAIGHT JUMP? 
 BEQ ISJ
 CMPA #$BD STRAIGHT JSR? 
 BNE NOTJ 
ISJ LDX PB2 PUT NEXT INSTRUCTION 
 STX XHI ADDRESS IN XHI & XLOW 
 BRA EXEC 
ISX LDX SP COMPUTE NEXT INST ADDRESS 
 LDAA 5,X FOR INDEXED JUMPS 
 ADDA PB2 
 STAA XLOW 
 LDAA 4,X 
 ADCA #0 
 STAA XHI 
 BRA EXEC 
NOTJ LDX SP 
 CMPA #$39 IS INSTRUCTION AN RTS? 
 BNE NOTRTS NO 
 LDX 8,X YES, PULL RETURN ADDRESS 
 BRA EXR FROM STACK AND STORE IN 
NOTRTS CMPA #$38 NEXT INSTRUCTION POINTER. 
 BNE NOTRTI 
 LDX 13,X 
EXR STX XHI 
NOTRTI CMPA #$3F SWI? 
 BEQ RETNOT YES, RETURN TO CONTROL 
 CMPA #$3E WAI? 
 BEQ RETNOT YES, RETURN TO CONTROL 
EXEC LDX XHI SET BREAKPOINT AT NEXT 
 LDAA 0,X INSTRUCTION LOCATION AND SAVE 
 STAA OPSAVE OP CODE. 
 STAB 0,X STORE SWI AT BREAKPOINT & 
 CMPB 0,X VERIFY THAT IT'S WITHIN RAM 
 BNE RETNOT IF ROM, G0 TO CONTROL 
* EXECUTE INSTRUCTION 
 JMP CONTG RTI TO EXECUTE INSTRUCTION 
*RETURN HERE ON SWI IF TRACE FLAG ON 
SWTURN LDX XHI 
 LDAA OPSAVE 
 STAA 0,X REPLACE SWI'S WITH PREVIOUS 
 TST BFLAG CONTENTS. IF BFLAG IS CLEAR, 
 BEQ DISPLY THEN ONLY ONE BREAKPOINT 
 LDX BPOINT WAS SET. 
 LDAA BPOINT+2 
 STAA 0,X 
DISPLY JMP RETURN DISPLAY REGISTER STATUS 

CRLFAS FCB $D,$A,0,0,0,4,'S,'1,4 

TDEX CMPA #'U' IF IT'S A "U" 
 BEQ CHA71 GET PREVIOUS ADDRESS 
 JSR INHEX+2 IF NOT HEX, JMP CONTROL 
 JSR BYTE+2 ELSE, GET NEW DATA 
 DEX 
 JMP CHA61 STORE NEW DATA 
CHA71 DEX GET PREVIOUS ADDRESS 
 DEX 
 STX XHI 
 JMP CHA51 PRINT PREVIOUS ADDRESS 

FUTABL EQU * COMMAND LOOKUP TABLE 
 FCC /M/ 
 FDB CHANGE MEMORY EXAMINE 
 FCC /G/ 
 FDB CONTG GO TO $A048 
 FCC /R/ 
 FDB PRINT PRINT REGISTERS 
 FCC /T/ 
 FDB TRACE TRACE ROUTINE 
 FCC /I/ 
 FDB IFILL MEMORY FILL 
 FCC /K/ 
 FDB BKPNT SET BREAKPOINT 
 FCC /4/ 
 FDB $E400 GO TO $E400 
 FCC /J/ 
 FDB JUMP JUMP TO ADDRESS ENTERED 
 FCC /Q/ 
 FDB $8020 QUICKSTART - BOOT DISC 
 FCC /D/ 
 FDB $7283 DISC WARMSTART
 FCC /H/ 
 FDB PRNTON SET HARDCOPY FLAG 
 FCC /L/ 
 FDB LOAD LOAD ASCII FORMATTED TAPE 
 FCC /P/ 
 FDB PUNCH PUNCH ASCII FORMATTED TAPE 
 FCC /E/ 
 FDB ECHON TURN INPUT ECHO ON 
 FCC /N/ 
 FDB ECHOFF TURN INPUT ECHO OFF 
TBLEND EQU * 
MCLOFF FCB $13 
MCL FCB $0D,$0A,$14,0,0,'*,4 

 ORG $FFF8
 FDB IO IRQ VECTOR 
 FDB SFE SWI VECTOR 
 FDB POWDWN NMI VECTOR 
 FDB START RESET VECTOR 

* RAM STORAGE LOCATIONS 

 ORG $A000
IOV RMB 2 I/O INTERRUPT POINTER 
BEGA RMB 2 BEGINNING ADDRESS 
ENDA RMB 2 ENDING ADDRESS 
NIO RMB 2 NMI INTERRUPT POINTER 
SP RMB 2 TARGET STACK POINTER 
ACIAT RMB 1 ACIA STATUS WORD 
ECHO RMB 1 ECHO FLAG 
XHI RMB 1 INDEX REG HI 
XLOW RMB 1 INDEX REG LOW 
TEMP RMB 1 TEMP 
TW RMB 2 TEMP 
TFLAG RMB 1 TRACE FLAG 
XTEMP RMB 2 X-REG TEMP STORAGE 
BKFLG RMB 1 BREAKPOINT FLAG 
 RMB 45 SMARTBUG STACK 
STACK RMB 1 STACK POINTER 
 RMB 29 
TSTACK RMB 1 TRACE MODE STACK 
BPOINT RMB 3 BRANCH POINT ADDR & CODE 
MCONT RMB 1 TEMP 
BFLAG RMB 1 BRANCH FLAG (TRACE) 
OPSAVE RMB 1 OPERAND (TRACE) 
PB1 RMB 1 TRACE TEMP 
PB2 RMB 1 TRACE TEMP 
PB3 RMB 1 TRACE TEMP 
CKSM RMB 1 CHECKSUM 
BYTECT RMB 1 BYTE COUNT 
PRINTR EQU $A04A USER PRINT ROUTINE 
 END
