; 68EC000 MONITOR Version 3.00, modified 1/5/2006. ; ; Version 3.00 modification makes the SBC capable of ; ececuting the EASy68K TRAP #15 tasks 0-2, 4-7, 9 ; and 12-14. This enables the user to switch to the ; windows oriented, public domain, EASy68K ; assembler-emulator package. ; ; Based on Antonakos's monitor with substantial changes ; since the original version lacked many features. ; Register display, register modify, tracing and ; break-pointing were added by Sol Rosenstark (SR). ; Disassembly was added by Dave Harrison (DH). ; ; Serial port assignments DREG EQU $10000 ;serial data port CSREG EQU $10001 ;control/status port DAVBIT EQU $2 ;data available bit BFEBIT EQU $1 ;buffer empty bit ; Ram storage assignments. RAM EQU $8000 ;Change for other decoding RAMLEN EQU $8000 ;$8000 for 62256 ENDRAM EQU RAM+RAMLEN USTCK EQU ENDRAM-$150 ;user stack pointer STACK EQU ENDRAM-$CA ;system stack pointer OLD_PC EQU ENDRAM-$CA ;preceding PC UNADR EQU ENDRAM-$C6 ;unasm start address UASMCMD EQU ENDRAM-$C2 ;unasm cmd buf. 32 char UASMOPR EQU ENDRAM-$BA ;****** SPARE EQU ENDRAM-$B9 ;spare byte for future ;use REGTYP EQU ENDRAM-$B8 ;information for return ;from regmod cmd PRTBUF EQU ENDRAM-$A0 ;16 char print buffer INPBUF EQU ENDRAM-$90 ;32 char input buffer SAVREGS EQU ENDRAM-$70 ;D0-D7/A0-A6 storage SAV_A7 EQU ENDRAM-$34 ;A7 storage SAV_PC EQU ENDRAM-$30 ;PC storage SAV_SR EQU ENDRAM-$2C ;SR storage DUMPADR EQU ENDRAM-$2A ;dump start address ; The 2 permanent breakpoint addresses go below BP_AD3 EQU ENDRAM-$26 BP_AD4 EQU ENDRAM-$22 ; Temporary breakpoint addresses go below BP_ADS1 EQU ENDRAM-$1E BP_ADS2 EQU ENDRAM-$1A BP_ADS3 EQU ENDRAM-$16 BP_ADS4 EQU ENDRAM-$12 ; Saved breakpoint opcodes go below OPCOD1 EQU ENDRAM-$E OPCOD2 EQU ENDRAM-$C OPCOD3 EQU ENDRAM-$A OPCOD4 EQU ENDRAM-$8 ; FP_FLG EQU ENDRAM-$6 ;TRACE 1st pass flag SKIPFLG EQU ENDRAM-$5 ;Go skip 1 instruction flag S2_FLG EQU ENDRAM-$4 ;LOAD S2 line flag ECHOFLG EQU ENDRAM-$3 ;Flag for task 12 of EASy68K ; miscellaneous equates TRPTEN EQU $4E4A TRPELF EQU $4E4B NUMCMD EQU 13 ;# commands checked DUMPBYT EQU $8F ;# of chars in dump CR EQU $D LF EQU $A BS EQU 8 ; equates for RAM testing of exceptions TRP_11 EQU RAM ;TRAP #11 TRP_12 EQU RAM+4 ;TRAP #12 TRP_13 EQU RAM+8 ;TRAP #13 TRP_14 EQU RAM+12 ;TRAP #14 FUTURE EQU RAM+16 ; ORG 0 ; The code below goes into the ROM vector table DC.L STACK ;RESET: initial SSP DC.L START ;RESET: initial PC DC.L BUSERR DC.L ADDERR DC.L ILEGAL DC.L DIVZERO DC.L START ;CHK not implemented DC.L TRAP_V DC.L PRIVIOL ;Privilege violation DC.L TRACE DC.L LINE_A DC.L LINE_F ;As a precaution, skip reserved vectors ORG $7C DC.L LEVEL_7 DC.L TO_CHARIN ;TRAP #0 DC.L TO_CHAROUT ;TRAP #1 DC.L TO_CRLF ;TRAP #2 DC.L TO_PRTMSG ;TRAP #3 DC.L TO_PRT_BYT ;TRAP #4 DC.L TO_PRT_WRD ;TRAP #5 DC.L TO_PRT_LON ;TRAP #6 DC.L TO_GET_BYT ;TRAP #7 DC.L TO_GETADR ;TRAP #8 DC.L TRP_9 ;TRAP #9 DC.L TRP_10 ;TRAP #10 DC.L TRP_11 ;TRAP #11 DC.L TRP_12 ;TRAP #12 DC.L TRP_13 ;TRAP #13 DC.L TRP_14 ;TRAP #14 DC.L TRP_15 ;TRAP #15 ; ; The address below can be much lower if ; few interrupts are used. ORG $400 ;start of monitor ; START BSR NULLREG ;init user regs BSR SERINI ;init ser. chip BSR SIGN_ON ;greet user ; ; This point is reentered after each command ; is executed, so various things are reset. It ; then sends the prompt and calls GETLIN to ; obtain a line of KBD input terminated by ; a CR. The typed line is in the INPBUF. GET_CMD ANDI.W #$7FFF,SR ;disable tracing ANDI.W #$7FFF,SAV_SR ;fix the USR MOVEA.L #STACK,A7 ;init stack BSR CRLF MOVE.B #'%',D1 ;output prompt BSR CHAROUT BSR GETLIN ;fill INPBUF from KBD MOVEA.L #INPBUF,A6 ;repoint to buffer BSR SKIPSP ;skip leading SPs ; ; A6 now points to the first non SP char. ; This is put in D1, changed to UC. It will ; put the last character preceding a CR or ; SP into D2 and go on to SEARCH. Thus ; typing command ABCD is the same as D. ; This routine leaves A6 pointing one beyond ; the CR or SP which follows the principal ; command character where it stays until the ; command service routine is executed. INCOM MOVE.B (A6)+,D1 BSR UP_CASE CMPI.B #CR,D1 ;test for CR BEQ.S SEARCH CMPI.B #' ',D1 ;test for SP BEQ.S SEARCH MOVE.B D1,D2 ;insert it into D2 BRA.S INCOM ;get next char ; ; Put the # of commands in D5, the command ; addresses in A1 and the command character ; addresses in A2. If the command letter is ; legit then jump to the command routine, ; else signal by typing "Bad Command." SEARCH MOVE.B #NUMCMD,D5 ;# of cmds MOVEA.L #CMD_ADR,A1 ;A1 -> cmd addrs MOVEA.L #COMANDS,A2 ;A2 -> cmd chars TSTNEXT CMP.B (A2)+,D2 ;test again BEQ.S DO_JUMP ADDQ.L #4,A1 ;point to next cmd SUBQ.B #1,D5 ;all cmds checked? BNE.S TSTNEXT BRA CMDERR ;illegal command DO_JUMP MOVEA.L (A1),A1 ;get command addr JMP (A1) ;and go execute it ; ; Fill memory between 2 addresses with a ; HEX value. FILL BSR GETADR ;get start addr MOVEA.L D2,A1 BSR GETADR ;get end addr ADDQ.L #1,D2 ;Needed because using (A1)+ MOVEA.L D2,A2 BSR GETADR ;get HEX byte FILLEM CMPA.L A1,A2 ;at end yet? BEQ GET_CMD MOVE.B D2,(A1)+ ;move'em BRA.S FILLEM ; ; Dumps memory. The starting address is ; fixed to end in 00. Displays in rows of ; 16 bytes. Displays ASCII equivalents too. DUMP CMPI.B #CR,-1(A6) ;is previous CR? BNE.S DUMP0 ;no, so proceed MOVE.L DUMPADR,D2 ;get old starting address MOVEA.L D2,A4 ADDI.L #DUMPBYT,D2 ;get standard # of lines MOVEA.L D2,A5 BRA.S ADR_OUT ;all done, so dump DUMP0 CMPI.B #',',(A6) ;is char a comma? BNE.S DUMP0A ;no, then get new start addr MOVE.L DUMPADR,D2 ;get old dump addr MOVEA.L D2,A5 ;into A5 ADDQ.L #1,A6 ;point past comma BRA.S DUMP1 ;get count DUMP0A BSR GETADR ;get start address ANDI.B #$F0,D2 ;zero lower nibble MOVEA.L D2,A4 CMPI.B #CR,-1(A6) ;is previous CR? BNE.S DUMP1 ;no, so proceed ADDI.L #DUMPBYT,D2 MOVEA.L D2,A5 BRA.S ADR_OUT DUMP1 BSR GETADR ;get # of lines to display SUBQ.L #1,D2 ;reduce by 1 LSL.L #4,D2 ;x16 bytes per line MOVEA.L D2,A5 ADDA.L A4,A5 ;add the start address ADR_OUT BSR CRLF ;new line please MOVE.L A4,D2 ;print address BSR PRT_SIX BSR TWO_SP ;and some spaces BYTEOUT MOVE.B (A4)+,D2 ;get a byte BSR PRT_BYT ;print the byte BSR SPACE MOVE.L A4,D1 ;done 16 yet? ANDI.L #$F,D1 BNE.S BYTEOUT SUBA.L #16,A4 ;back up 16 bytes BSR SPACE ASC_OUT MOVE.B (A4)+,D1 ;get a byte CMPI.B #' ',D1 ;is it printable? BMI.S UN_PRT CMPI.B #$7D,D1 BMI.S SEND_IT UN_PRT MOVE.B #'.',D1 ;unprintables -> . SEND_IT BSR CHAROUT ;print ASCII equiv MOVE.L A4,D2 ;done 16 yet? ANDI.L #$F,D2 BNE.S ASC_OUT MOVE.L A4,DUMPADR BSR INSTAT ;key pressed? BEQ.S SEND1 ;no, go on BSR CHARIN ;yes, get the char CMPI.B #3,D1 ;Is it ^C? BEQ GET_CMD ;If yes then quit SEND1 CMPA.L A4,A5 ;Is A4 > A5? BMI GET_CMD ;Yes, then quit BRA.S ADR_OUT ; ; Set breakpoints and transfer execution ; to the user program. ; G starts execution at current address ; G is obvious ; G , continues from current ; program counter. GO CMPI.B #CR,-1(A6) ;is previous CR? BEQ.S GO3 ;yes, so start CMPI.B #',',(A6) ;is char a comma? BNE.S GO1 ;no, then go on ADDQ.L #1,A6 ;point past comma BRA.S GO2 ;get breakpoints ; get execution address GO1 BSR GETADR MOVE.L D2,SAV_PC ;save it CMPI.B #CR,-1(A6) ;is previous CR? BEQ.S GO3 ;yes, so start ; get first breakpoint address GO2 BSR GETADR MOVE.L D2,BP_ADS1 ;save it CMPI.B #CR,-1(A6) ;is previous CR? BEQ.S GO3 ;yes, so start ; get second breakpoint address BSR GETADR MOVE.L D2,BP_ADS2 ;save it ; Now move-in the 2 permanent addresses GO3 MOVE.L BP_AD3,BP_ADS3 MOVE.L BP_AD4,BP_ADS4 ; Duplicate breakpoints wreak havoc when set. To avoid ; these problems RID_EQ nulls duplicate entries. BSR RID_EQ ; Now all breakpoints are in place. If a breakpoint ; address is 0 then it's not set. If not 0 then ; proceed to see if the address is the same as that ; at SAV_PC. If yes then execute 1 instruction and ; now proceed to set the breakpoint by saving its ; opcode and replacing it with TRAP #10. This is to ; be done but once. MOVEA.L #BP_ADS1,A0 ;A0 -> BP_ADS1 MOVEA.L #OPCOD1,A1 ;A1 -> OPCOD1 SF D1 ;succcesive instructions flag MOVE.W #3,D0 ;loop counter in D0.W GO4 TST.L (A0) BEQ.S GO6 ;if bkpt addr is 0 then ignore MOVE.L SAV_PC,D2 ;Not 0, so compare bkpt CMP.L (A0),D2 ;addr. with user PC BNE.S GO5 ;Go and set if not same TST.B D1 ;Is this the 1st occurrence? BNE.S GO5 ;No, the go set it. MOVEM.L D0/A0-A1,-(A7) ;If bkpt = (SAV_PC) BSR.S GOSKIP ;then skip one instruction MOVEM.L (A7)+,D0/A0-A1 ST D1 ;Make sure this happens but once ; Okay, now finally set the breakpoints. GO5 MOVEA.L (A0),A2 ;get bkpt addr MOVE.W (A2),(A1) ;save and replace MOVE.W #TRPTEN,(A2) ;its opcode ; Bump pointers to the next breakpoint GO6 LEA 4(A0),A0 ;bump A0 LEA 2(A1),A1 ;bump A1 DBRA D0,GO4 BSR REGREST ;restore user regs RTE ;and go to user program ; ; This is the routine for doing a hidden ; trace tracing of a single line of code. GOSKIP ST SKIPFLG ;set the flag SF FP_FLG ;clear flag BSR REGREST ;restore user regs ORI.W #$8000,SR ;enable tracing RTE ; ; This routine nulls duplicate entries. RID_EQ MOVE.W #3,D1 MOVEA.L #BP_ADS1,A0 ;point to 1st num RID1 MOVE.W D1,D4 LEA 4(A0),A1 ;point to 2nd num RID2 MOVE.L (A0),D2 ;put it in D2 CMP.L (A1),D2 BNE.S RID3 ;skip if not equal CLR.L (A1) RID3 ADDQ.L #4,A1 ;point to next enty SUBQ.W #1,D4 ;decrement inner loop counter BNE.S RID2 ADDQ.L #4,A0 ;point to next enty SUBQ.W #1,D1 BNE.S RID1 RTS ; ; This routine saves the user registers ; after a TRAP #9 program termination, ; prints the address at which the TRAP #9 ; instruction was found and puts back the ; original opcodes at all breakpoints. TRP_9 BSR REG_SAV MOVEA.L #MSG_NIN,A3 ;point to message BSR PRTMSG MOVE.L SAV_PC,D2 ;get user PC value SUBQ.L #2,D2 ;adjust address BSR PRT_SIX BSR CRLF BSR CLR_BK ;clear the bkpts BRA GET_CMD ;all done ; ; This TRAP #10 routine is executed when a ; breakpoint is encountered. It saves the ; registers and prints MSG_TEN. It then ; puts back the original opcodes at all ; breakpoints. TRP_10 BSR REG_SAV MOVEA.L #MSG_TEN,A3 ;point to message BSR PRTMSG MOVE.L SAV_PC,D2 ;get user PC value SUBQ.L #2,D2 ;adjust address MOVE.L D2,SAV_PC ;store adjusted PC BSR PRT_SIX BSR CRLF BSR.S CLR_BK ;clear the bkpts BRA GET_CMD ;all done ; ; Removes any breakpoints that existed and ; puts back the appropriate opcodes. ; First remove bkpts set by GO command. CLR_BK MOVEA.L #BP_ADS1,A0 ;A0 -> BP_AD1 MOVEA.L #OPCOD1,A1 ;A1 -> OPCOD1 MOVEQ #3,D0 ;loop 4 times CLR_BK1 TST.L (A0) BEQ.S CLR_BK2 ;if 0 then ignore MOVEA.L (A0),A2 ;get breakpoint addr MOVE.W (A1),(A2) ;restore opcode CLR.L (A0) CLR_BK2 LEA 4(A0),A0 ;bump A0 LEA 2(A1),A1 ;bump A1 DBRA D0,CLR_BK1 RTS ; VERIFY BSR GETADR ;get start addr MOVEA.L D2,A1 ;start addr in A1 BSR GETADR ;get end addr MOVEA.L D2,A2 ;end addr in A2 ADDQ.L #1,A2 ;Needed because using (A1)+ BSR GETADR ;get dest addr MOVEA.L D2,A3 ;dest addr in A3 VERIF1 CMPM.B (A1)+,(A3)+ ;compare bytes BNE.S FAIL CMPA.L A1,A2 ;at end addr yet? BNE.S VERIF1 LEA PASSMSG,A3 ;POINT TO MESSAGE BRA.S QUIT FAIL LEA FAILMSG,A3 ;POINT TO MESSAGE QUIT BSR PRTMSG BRA GET_CMD ; MOOV BSR GETADR ;get start addr MOVEA.L D2,A1 BSR GETADR ;get end addr MOVEA.L D2,A2 ADDQ.L #1,A2 ;Needed because using (A1)+ BSR GETADR ;get dest addr MOVEA.L D2,A3 MOOV1 MOVE.B (A1)+,(A3)+ ;move bytes CMPA.L A1,A2 ;at end addr yet? BNE.S MOOV1 BRA GET_CMD ; ; Edit data on the screen EDIT BSR GETADR ;get start address MOVEA.L D2,A2 ;point A2 to memory BSR CRLF ;new line please NEW_DAT MOVE.L A2,D2 ;print data address BSR PRT_SIX BSR SPACE MOVE.B (A2),D2 ;get the data stored BSR PRT_BYT ;and show it MOVE.B #'?',D1 ;Print change prompt BSR CHAROUT BSR GET_BYT ;get new data TST.B D2 ;no change desired? BEQ.S ENTR_IT ;jump if new data MOVE.B (A2),D1 ;reget old data ENTR_IT MOVE.B D1,(A2)+ ;save data and bump BSR.S NEW_DAT ;pointer ; ; Display or modify register data as ; required. SEARCH left A6 pointing one ; beyond the CR or SP which follows the ; principal command character. ; Next line added in mon209 to set where to return REGMOD MOVE.B #$00,REGTYP CMPI.B #CR,-1(A6) ;is previous CR? BNE.S REGMOD0 ;no, so skip BSR REGPRT1 BRA GET_CMD REGMOD0 BSR SKIPSP ;skip leading SPs MOVE.B (A6)+,D1 ;get the next char BSR UP_CASE MOVEA.L #SAVREGS+32,A3 ;temporary CMPI.B #'A',D1 BEQ.S REGMOD1 ;A reg so jump MOVEA.L #SAVREGS,A3 ;temporary CMPI.B #'D',D1 BEQ.S REGMOD1 ;D reg so jump MOVEA.L #SAV_PC,A3 ;temporary CMPI.B #'P',D1 BNE REGME ; No command errors, so we modify the PC. MOVE.B D1,D4 ;will need 'P' later MOVE.B (A6)+,D1 ;get next char BSR UP_CASE CMPI.B #'C',D1 ;is it 'C'? BNE REGME ;no,so quit MOVE.B D1,D3 ;will need 'C' later MOVE.B (A6)+,D1 ;get last char CMPI.B #CR,D1 ;is it CR? BNE REGME ;no,so quit BSR CRLF ;passed all tests MOVE.B D4,D1 ;display the 'P' BSR CHAROUT MOVE.B D3,D1 ;display the 'C' BSR CHAROUT MOVE.B #':',D1 ;also a ':' BSR CHAROUT BSR SPACE ;a ' ' looks good MOVE.L (A3)+,D2 ;get the data in D2 BSR PRT_LON ;display it BSR SPACE ;another ' ' MOVE.B #'?',D1 ;now a '?' BSR CHAROUT BSR SPACE ;one more ' ' BSR GETADRT ;get new data in D2 TST.B D6 ;check flag for CR BNE REGMQ ;was FF so quit it MOVE.L D2,-(A3) ;save it BRA REGMQ ;done ;This portion modifies the A and D registers REGMOD1 MOVE.B D1,D4 ;save the A or D MOVE.B (A6)+,D1 ;get register # CMPI.B #'0',D1 ;within bounds? BMI.S REGME ;< than, no good CMPI.B #'7',D1 BGT.S REGME ;> than, no good MOVE.B D1,D3 ;will need # later MOVE.B (A6)+,D1 ;get last char CMPI.B #CR,D1 ;is it CR? BNE.S REGME ;no, so quit MOVE.B D3,D1 ;find displacement ANDI.L #$F,D1 ;remove ASCII bias ASL.L #2,D1 ;multiply by 4 ADDA.L D1,A3 ;A3 points correctly MOVE.B D4,D1 ;display 'A' or 'D' BSR CHAROUT MOVE.B D3,D1 ;display the # BSR CHAROUT MOVE.B #':',D1 ;also a ':' BSR.S CHAROUT BSR SPACE ;a ' ' looks good MOVE.L (A3)+,D2 ;get the data in D2 BSR PRT_LON ;display it BSR SPACE ;another ' ' MOVE.B #'?',D1 ;now a '?' BSR.S CHAROUT BSR SPACE ;one more ' ' BSR GETADRT ;get new data in D2 TST.B D6 ;check flag for CR BNE.S REGMQ ;was FF so quit it MOVE.L D2,-(A3) ;save it ; ; Added in mon209 to exit from different regmod types REGMQ CMPI.B #$FF,REGTYP BNE GET_CMD RTS ; REGME CMPI.B #$FF,REGTYP BNE CMDERR RTS ; SERINI MOVEA.L #CSREG,A0 MOVE.B #$AA,(A0) MOVE.B #$40,(A0) MOVE.B #$4E,(A0) ;$CE for 2 stops MOVE.B #$27,(A0) RTS ; ; Returns Z-flag = 0 if no char. INSTAT MOVEM.L D0,-(A7) MOVE.B CSREG,D0 ;get status ANDI.B #DAVBIT,D0 ;mask MOVEM.L (A7)+,D0 ;Movem affects no flags RTS ; ; Returns 7-bit char in D1.B CHARIN BSR.S INSTAT ;get status BEQ.S CHARIN ;no char so loop MOVE.B DREG,D1 ;get char ANDI.B #$7F,D1 ;reset bit 7 RTS ; ; Sends out char in D1.B CHAROUT MOVEM.L D0,-(A7) MOVE.B CSREG,D0 ;get status ANDI.B #BFEBIT,D0 ;is buffer empty? MOVEM.L (A7)+,D0 ;Movem affects no flags BEQ.S CHAROUT ;no, so loop MOVE.B D1,DREG ;buffer's empty, send RTS ; ; This routine prints a message pointed to ; by A3. The message must end in a NULL. PRTMSG MOVE.B (A3)+,D1 ;get a char BEQ.S PRTMEX ;quit on 0 BSR.S CHAROUT ;display the char BRA.S PRTMSG ;do it again PRTMEX RTS ; ; Inputs and echoes a character CHARIO BSR.S CHARIN BSR.S CHAROUT RTS ; ; Send out CR and LF CRLF MOVE.B #CR,D1 ;send ASCII CR BSR.S CHAROUT MOVE.B #LF,D1 ;send ASCII LF BSR.S CHAROUT RTS ; ; Send out a SP SPACE MOVE.B #' ',D1 ;send ASCII SP BSR.S CHAROUT RTS ; ; Send two spaces to the screen TWO_SP BSR.S SPACE BSR.S SPACE RTS ; *************************************** ; The TRAP #15 routines below were added ; to make the SBC capable of ececuting ; the EASy68K tasks 0-2, 4-7, 9 and ; 12-14. ; *************************************** ;Implementation of the EASy68K trap #15 tasks. trp_15 ; Task #0. Displays string at (A1), D1.W long, with CR, LF. tst.b d0 beq.s task0 ; Task #1. Displays string at (A1), D1.W long, without CR, LF. cmpi.b #1,d0 beq.s task1 ; Task #2. Read, and echo, string from KBD and store at (A1). ; Length returned in D1.W (max 80). cmpi.b #2,d0 beq.s task2 ; Task #4. It converts a typed decimal string into a HEX ; number in D1.L. Max DEC number is 655,359. Input is ; terminated with . cmpi.b #4,d0 beq task4 ; Task #5. Get a KBD char into D1.B. If ECHOFLG is ; set then echo char to screen. cmpi.b #5,d0 beq task5 ; Task #6. Send the char in D1.B to the screen. cmpi.b #6,d0 beq task6 ; Task #7. Get KBD status in D1.B. 1 if key was pressed, 0 if not. cmpi.b #7,d0 beq task7 ; Task #9. Make a graceful exit using the old TRAP #9 feature. cmpi.b #9,d0 beq trp_9 ; Task #12. If D1.B is zero then clear the ECHOFLG, else set it. cmpi.b #12,d0 beq task12 ; Task #13. Print on screen the NULL terminated string pointed ; to by A1, followed by CR, LF. cmpi.b #13,d0 beq task13 ; Task #14. Print on screen the NULL terminated string pointed ; to by A1 without CR, LF. cmpi.b #14,d0 beq task14 ; If none of the above then send message and terminate the program. lea uimpmsg,a3 trap #3 bra trp_9 ; Implementation of the task #0. Displays string at (A1), D1.W long, ; with CR, LF. task0 bsr.s prtstr bsr.s crlf rte ; ; Implementation of the task #1. Displays string at (A1), D1.W long, ; without CR, LF. task1 bsr.s prtstr rte ; prtstr move.w d1,d7 ;D7.W is the loop counter prtstr1 move.b (a1)+,d1 bsr charout ;print it subq.w #1,d7 bne.s prtstr1 rts ; ; Implementation of the task #2. Read, and echo, string from KBD and ; store at (A1). Length returned in D1.W (max $FFFF). BS is implemented. ; Process teminated with . Screen gets a CR, LF at end of input. task2 clr.w d7 ;temporary char counter task2a bsr charin ;get a char cmpi.b #cr,d1 ;if CR then done beq.s task2ex cmpi.b #bs,d1 beq.s task2bs bsr charout ;echo it move.b d1,(a1)+ ;store it addq.w #1,d7 ;add to count bra.s task2a ;go back for more task2bs subq.b #1,d7 ;adjust count subq.l #1,a1 ;adjust pointer movea.l #bsspbs,a3 ;fix up screen bsr prtmsg bra.s task2a task2ex bsr crlf move.w d7,d1 rte ; ; Implementation of the task #4. It converts a typed decimal ; string into a HEX ; number in D1.L. Max DEC number is 655,359. ; Input is terminated with . If a non-decimal char is typed ; then it is discarded and cleared off the screen. task4 clr.l d7 task4a bsr charin cmpi.b #cr,d1 beq.s task4ex cmpi.b #'9',d1 bhi.s task4a ;If >9 then get another cmpi.b #'0',d1 blt.s task4a ;If <0 then get another bsr charout ;It's good so echo it andi.l #$f,d1 ;strip ASCII bias and clear upper part mulu #10,d7 add.l d1,d7 bra task4a task4ex move.l d7,d1 rte ; ; Implementation of the task #5 feature. It gets a KBD char ; into D1.B. If ECHOFLG is set then it echos char to screen. task5 bsr charin ;get KBD char into D1.B. tst.b echoflg beq.s task5ex bsr charout task5ex rte ; ; Implementation of the task #6 feature. Sends a char in D1.B ; to the screen. task6 bsr charout rte ; ; Task #7 implementation. Get KBD status in D1.B. ; 1 if key was pressed, 0 if not. task7 clr.b d1 bsr instat beq.s task7ex move.b #1,d1 task7ex rte ; Task #12 implementation. If D1.B is zero then clear the ; ECHOFLG, else set it. task12 clr.b echoflg tst.b d1 beq.s tsk12ex st.b echoflg tsk12ex rte ; ; Task #13 implementation. Print on screen the NULL terminated ; string pointed to by A1, followed by a CR, LF task13 movea.l a1,a3 bsr prtmsg bsr crlf rte ; ; Task #14 implementation. Print on screen the NULL terminated ; string pointed to by A1 without a CR, LF. task14 movea.l a1,a3 bsr prtmsg rte ; *************************************** ; Prints sign-on message SIGN_ON MOVEA.L #HELLO,A3 ;point to 'HELLO' BSR PRTMSG ;send it out RTS ; ; Takes a byte in D2.B, converts to 2 ; ASCII characters and puts them on screen. PRT_BYT MOVE.L D2,D1 ;init conversion reg ROL.B #4,D1 ;do upper nibble first BSR NUM_ASC ;convert to ASCII BSR CHAROUT MOVE.L D2,D1 ;now do lower nibble BSR.S NUM_ASC BSR CHAROUT ;send character RTS ; ; Takes a word in D2.W, converts to 4 ; ASCII characters and puts them on screen. PRT_WRD ROL.W #8,D2 ;swap bytes in word BSR.S PRT_BYT ;output MSB ROL.W #8,D2 ;reswap bytes BSR.S PRT_BYT ;output LSB RTS ; ; Takes a long word in D2.L, converts to 8 ; ASCII characters and puts them on screen. PRT_LON SWAP D2 ;get upper 16 bits BSR.S PRT_WRD ;convert 4 chars SWAP D2 ;get lower 16 bits BSR.S PRT_WRD RTS ; ; Takes a long word in D2.L, and prints the ; least significand 6 ASCII on the screen. PRT_SIX SWAP D2 ;get upper 16 bits BSR.S PRT_BYT ;convert 4 chars SWAP D2 ;get lower 16 bits BSR.S PRT_WRD RTS ; ; Checks to see if D1.B contains a valid HEX ; digit. VALDIG CMPI.B #'F',D1 ;char > 'F' ? BGT.S DATAERR ;yes, so alert CMPI.B #'0',D1 ;char < '0' ? BLT.S DATAERR ;yes, so alert CMPI.B #'9',D1 ;char < = '9'? BLE.S VALDIGE ;'0' < char < '9' CMPI.B #'A',D1 ;char < 'A'? BLT.S DATAERR ;yes, so alert VALDIGE RTS ;'A' < char < 'F' ; ; Prints out the message "Bad Command" ; then looks for another command. CMDERR MOVEA.L #BADCMD,A3 ;point to message BRA REPORT ;restart monitor ; ; Prints out the message "Invalid address ; or hex data." Then it restarts monitor. DATAERR MOVEA.L #INVDATA,A3 ;point to message BRA REPORT ;restart monitor ; ; Converts legit ASCII #s to BCD. ASC_BCD SUBI.B #$30,D1 ;remove ASCII bias CMPI.B #10,D1 ;0-9? BMI.S ASC_BX ;Yes, so job's done SUBQ.B #7,D1 ;remove alpha bias ASC_BX RTS ; ; Convert HEX digit in D1.B to ASCII NUM_ASC ANDI.B #$F,D1 ;reset upper nibble ADDI.B #$30,D1 ;add ASCII bias CMPI.B #$3A,D1 ;test if > '9' BMI.S NUM_EX ;< '9' so done ADDQ.B #7,D1 ;> '9', so add 7 NUM_EX RTS ; ; It first fills INPBUF with chars until a ; CR occurs. The chars are then examined. ; If 1st char is CR then it sets D2.B and ; quits. Else it resets D2.B and proceeds to ; change valid hex digits to ASCII numbers. ; This routine is only used by EDIT. GET_BYT BSR GETLIN ;get chars from kbd MOVEA.L #INPBUF,A6 ;reset A6 GETB1 BSR SKIPSP ;get rid if spaces MOVE.B (A6)+,D1 ;get first char ST D2 ;set D2.B for now BSR.S UP_CASE ;convert to UC CMPI.B #CR,D1 ;test for CR BEQ.S GETBX ;if CR, no change BSR.S VALDIG ;valid digit? BSR.S ASC_BCD ;convert into hex MOVE.B D1,D2 ;save 1st digit MOVE.B (A6)+,D1 ;get second digit BSR.S UP_CASE CMPI.B #CR,D1 ;test for CR BNE.S GETB2 ;not CR, so process MOVE.B D2,D1 ;reget 1st digit BRA.S GETB3 ;and get out GETB2 BSR.S VALDIG ;valid digit? BSR.S ASC_BCD ;convert into hex ROL.B #4,D2 ;move first digit ADD.B D2,D1 ;form final result GETB3 SF D2 ;signal change GETBX RTS ; ; Gets keyboard input and transforms it into ; a longword into D2. If only a CR was typed ; then D6.B contains $FF, else it's 0. GETADRT BSR GETLIN ;fill buffer MOVEA.L #INPBUF,A6 ;repoint A6 ST D6 ;set flag in D6.B CMPI.B #CR,(A6) ;check 1st char BEQ.S EX_ADR ;if it's CR then exit SF D6 ;not CR, so reset D6.B GETADR BSR SKIPSP ;skip over SPs CLR.L D1 ;init temp register CLR.L D2 ;init result register NEXTCHR MOVE.B (A6)+,D1 ;get a char BSR.S UP_CASE CMPI.B #CR,D1 ;exit if CR BEQ.S EX_ADR CMPI.B #' ',D1 ;exit if SP BEQ.S EX_ADR BSR VALDIG ;valid digit? BSR ASC_BCD ;convert it to hex ROL.L #4,D2 ;next digit in D2 ANDI.B #$F0,D2 ADD.B D1,D2 ;insert new digit BRA.S NEXTCHR ;and continue EX_ADR RTS ; ; Changes chars in the range 'a'=buffer ADDQ.B #1,D6 ;update char count BSR CHAROUT ;echo the char BRA.S GETCHAR ;get another char GETCHX MOVE.B D1,(A6) ;Place CR in buffer ADDQ.B #1,D6 ;and count it BSR CRLF ;send a CR & LF RTS ; ; If not SP do nothing. If SP increment ; pointer A6 by one. SKIPSP CMPI.B #' ',(A6) BNE.S SKIPSPE ADDQ.L #1,A6 BRA.S SKIPSP SKIPSPE RTS ; ; Initializes the user registers to zeros. NULLREG MOVEA.L #SAVREGS,A1 MOVEA.L #ENDRAM,A2 NULLR1 CLR.B (A1)+ ;clear them CMPA.L A1,A2 ;done yet? BNE.S NULLR1 MOVE.L #USTCK,SAV_A7 CLR.L UNADR ST.B ECHOFLG RTS ; ; This routine saves the registers of the ; executed program for future display and ; future restoration. REG_SAV MOVEM.L D0-D7/A0-A6,SAVREGS ;d0-a6 MOVE.L (A7)+,D0 ;pop ret address MOVE.W (A7)+,SAV_SR ;pop SR MOVE.L SAV_PC,OLD_PC MOVE.L (A7)+,SAV_PC ;pop PC MOVE.L D0,-(A7) ;repush ret addr MOVE.L USP,A5 ;get user's A7 MOVE.L A5,SAV_A7 ;save it RTS ; ; This routine restores the registers of a ; program whose execution terminates with ; either a trap #9 or some other trap put ; in place to breakpoint a program. Transfer ; to the user program is then accomplished ; with an RTE instruction. REGREST MOVE.L (A7)+,D0 ;pop ret address MOVEA.L SAV_A7,A5 ;get user's A7 MOVE.L A5,USP ;restore it MOVE.L SAV_PC,-(A7) ;push PC MOVE.W SAV_SR,-(A7) ;push SR MOVE.L D0,-(A7) ;repush ret addr MOVEM.L SAVREGS,D0-D7/A0-A6 ;d0-a6 RTS ; ; This routine will diplay the register ; information saved by REG_SAV. REG_PRT BSR PRTOLD ;Old PC with disassembly REGPRT1 MOVEA.L #SAVREGS,A0 ;A0 -> reg. data MOVE.B #'D',D7 ;print the D regs BSR REGDISP MOVE.B #'A',D7 ;print the A regs BSR REGDISP BSR.S PRTNEW BSR PRTSR RTS ; ; Disassebly and display of the OPCODE at OLD_PC. PRTOLD MOVEA.L OLD_PC,A5 ;Disassem address in A5 BSR UNASMB ;call unasm core routine MOVE.L A5,D2 ;move instruction address BSR PRT_SIX BSR TWO_SP CLR.L D3 ;blank spaces counter (BSC) PRTOLD1 MOVE.W (A5)+,D2 ;get word BSR PRT_WRD ;print word of hex code BSR SPACE ;space ADDQ.B #2,D3 ;add 2 bytes to BSC SUBQ.B #2,D6 ;reduce length counter by 2 BNE.S PRTOLD1 ;if more bytes print again PRTOLD2 CMPI.B #10,D3 ;is the string 10 bytes BGE.S PRTOLD3 BSR TWO_SP BSR TWO_SP BSR SPACE ADDQ.B #2,D3 BRA.S PRTOLD2 PRTOLD3 BSR SPACE MOVEA.L #UASMCMD,A3 ;point A3 to unasm cmd buff BSR PRTMSG ;display commant text BSR CRLF RTS ; ; Next PC is printed and disassembled. PRTNEW MOVEA.L #PC_MSG,A3 BSR PRTMSG MOVE.L SAV_PC,D2 ;get the register BSR PRT_SIX MOVEA.L #SP24MSG,A3 BSR PRTMSG MOVEA.L SAV_PC,A5 BSR UNASMB MOVEA.L #UASMCMD,A3 ;A3 -> to unasm cmd buffer BSR PRTMSG ;display command text BSR CRLF RTS ; REGDISP MOVE.B #'0',D5 ;register # in here REGD1 MOVE.B D7,D1 ;print reg letter BSR CHAROUT MOVE.B D5,D1 ;print reg number BSR CHAROUT BSR COL_SP ;print :, space MOVE.L (A0)+,D2 ;print the register BSR PRT_LON BSR TWO_SP ;print 2 spaces BSR SPACE ADDQ.B #1,D5 CMPI.B #'8',D5 ; D5 = '8' yet? BEQ.S REGDFIN ; if yes then exit CMPI.B #'4',D5 ; D5 = '4' yet? BNE.S REGD1 ; no, then next reg BSR CRLF ; D5 = '4' send CRLF BRA.S REGD1 ; and do next reg REGDFIN BSR CRLF RTS ; ; Print the USR PRTSR MOVEA.L #SR_MSG,A3 BSR PRTMSG MOVE.W SAV_SR,D2 MOVE.W D2,D4 ;copy SR to D4 BSR PRT_WRD ;print the register BSR TWO_SP ;print 2 spaces ; Print "Flags: X = " and X flag MOVEA.L #MESGFLG,A3 BSR PRTMSG MOVE.B #'1',D1 BTST #4,D4 BNE.S REGETC1 MOVE.B #'0',D1 REGETC1 BSR CHAROUT ;Print ", N = " and N flag MOVEA.L #MESGN,A3 BSR PRTMSG MOVE.B #'1',D1 BTST #3,D4 BNE.S REGETC2 MOVE.B #'0',D1 REGETC2 BSR CHAROUT ;Print ", Z = " and Z flag MOVEA.L #MESGZ,A3 BSR PRTMSG MOVE.B #'1',D1 BTST #2,D4 BNE.S REGETC3 MOVE.B #'0',D1 REGETC3 BSR CHAROUT ;Print ", V = " and V flag MOVEA.L #MESGV,A3 BSR PRTMSG MOVE.B #'1',D1 BTST #1,D4 BNE.S REGETC4 MOVE.B #'0',D1 REGETC4 BSR CHAROUT ;Print " C = " and C flag MOVEA.L #MESGC,A3 BSR PRTMSG MOVE.B #'1',D1 BTST #0,D4 BNE.S REGETC5 MOVE.B #'0',D1 REGETC5 BSR CHAROUT BSR CRLF RTS ; ; Send : and space to the screen COL_SP MOVE.B #':',D1 BSR CHAROUT MOVE.B #' ',D1 BSR CHAROUT RTS ; ; Download a .HEX file in ASCII S-format. ; A .HEX file consists of pure ASCII chars. ; (See MacKenzie p.50.) The explanation ; below with typical file lines is perfectly ; general and applies to all files. ; ; The 1st line S00700007465737438 signifies: ; S0 = header line ; 07 = $7 bytes to load ; 0000 = address, in this case meaningless ; 74 65 73 74 = ASCII filename "TEST." ; 38 = hex check byte used as follows: 16 ; bit check sum = 07+00+00+74+65+73+74+38=FF ; ; The following lines contain code and data. ; A typical line S10780003200428183 means: ; S1 = code line with 16 bit load address ; 07 = $7 bytes to load ; 8000 = start loading at this HEX address ; 32 00 42 81 = code or data to load ; 83 = hex check sum as above ; ; Another typical line S208AF800032004281D3 ; signifies: ; S2 = code line with 24 bit load address ; 08 = $8 bytes to load ; AF8000 = start loading at this HEX address ; 32 00 42 81 = execution code to load ; D3 = hex check sum as always ; ; There are two kinds of footer line: ; The line S90380007C signifies: ; S9 = This line contains a 16-bit entry ; address, in this case 8000. The byte ; count is 03 and 7C is the check sum. ; ; The second kind of footer line is, e.g. ; S804AF8000CC signifies: ; S8 = This line contains a 24-bit entry ; address, in this case AF8000. The byte ; count is 04 and CC is the check sum. ; ; S5 lines exist too. They inform you of ; the number of lines of code in the file. ; Nothing will happen if we simply ignore ; these lines. ; ; The code directly below steers the ; loading. LD_FILE MOVEA.L #0,A5 ;A5 holds offset address CMPI.B #CR,-1(A6) ;Is previous CHAR a CR? BEQ.S LD_FIL0 ;Yes so skip BSR GETADR ;get offset address MOVEA.L D2,A5 ;save for later LD_FIL0 MOVEA.L #LS_MSG,A3 ;Tell'em to start BSR PRTMSG ;sending the file LD_FIL1 BSR CHARIN ;Get first char CMPI.B #3,D1 ;Is it ^C? BEQ GET_CMD ;Yes, so abandon CMPI.B #'S',D1 ;Is it 'S'? BEQ.S IS_S ;Yes, get next char ; The end of line CR and LF are handled here. If ; it's a CR then send a CRLF else get another char CMPI.B #CR,D1 ;Is it CR? BNE.S LD_FIL1 ;No, so dump LFs BSR CRLF ;If CR, then do CRLF BNE.S LD_FIL1 ;get another char IS_S BSR CHAROUT ;Print the 'S' BSR CHARIO ;get next char CMPI.B #'0',D1 ;Is it '0'? BEQ.S S0 ;if so branch SF S2_FLG ;Reset flag CMPI.B #'1',D1 ;Is it '1'? BEQ.S S12 ;It's '1' so process ST S2_FLG ;Set flag CMPI.B #'2',D1 ;Is it '2'? BEQ.S S12 ;It's '2' so process CMPI.B #'5',D1 ;Is it '5'? BEQ.S S5 ;Yes, go dump line ST S2_FLG ;Set flag CMPI.B #'8',D1 ;Is it '8'? BEQ.S S89 ;if so branch SF S2_FLG ;Reset flag CMPI.B #'9',D1 ;Is it '9'? BEQ.S S89 ;if so branch BRA LD_ERR ;None of above, err ; ; A line that begins with S0 is the header ; containing the name S0 CLR.B D4 ;Null hex check sum BSR LD_NUM ;line length in D2.B BSR LD_ADR ;discard 0000 MOVEA.L #PRTBUF,A0 CMPI.B #1,D2 ;hex check byte yet? BEQ.S S0B ;jump if there's no name S0A MOVE.L D2,-(A7) ;push line length BSR LD_NUM ;get a name char MOVE.B D2,D1 MOVE.L (A7)+,D2 ;pop line length BSR UP_CASE ;change to UC MOVE.B D1,(A0)+ ;store it SUBQ.B #1,D2 ;length counter = 1? CMPI.B #1,D2 ;hex check byte yet? BNE.S S0A ;if not then loop S0B CLR.B (A0) ;end name with NULL BSR LD_CHK ;branch chk BRA LD_FIL1 ;Go to next line ; ; Loads an S1 or S2 line S12 CLR.B D4 ;Null hex check sum BSR.S LD_NUM ;line length in D2.B BSR LD_ADR ;line address in A4 ADDA.L A5,A4 ;Add offset to address BSR LD_DATA ;load data BRA LD_FIL1 ;Go to next line ; ; Discard all chars in the S5 line S5 BSR LD_NUM ;line length in D2.B ADD.B D2,D2 ;double it and add 2 ADDQ.B #2,D2 ;to discard the CRLF S5A BSR CHARIO ;Input and echo char SUBQ.B #1,d2 BNE.S S5A BRA LD_FIL1 ;Go to next line ; ; End of file line. Its data is used to ; change the value of the user PC. Works ; with S8 and S9 lines. S89 CLR.B D4 ;Null hex check sum BSR.S LD_NUM ;line length in D2.B BSR.s LD_ADR ;load address in A4 MOVE.L A4,SAV_PC ;save it CMPA.L #0,A4 BEQ.S S89A MOVE.L A4,UNADR MOVE.L A4,DUMPADR S89A BSR LD_CHK BSR CHARIO ;read the final CR BSR CHARIO ;and LF BSR CRLF MOVEA.L #PRTBUF,A3 ;print file name BSR PRTMSG MOVEA.L #LG_MSG,A3 ;print BSR PRTMSG ;successful load BRA GET_CMD ;go to prompt ; ; Reads and echos the two ASCII bytes repre- ; senting a number and converts them to a HEX ; number in D2.B. Thus a '2' & 'E' is conver- ; ted to $2E. Also updates checksum in D4.B LD_NUM BSR CHARIO ;get first char BSR ASC_BCD ;convert it to BCD ROL.B #4,D1 ;move it to MSB MOVE.B D1,D2 ;copy to reg D2 BSR CHARIO ;get second char BSR ASC_BCD ;convert it to hex ADD.B D1,D2 ;add them ADD.B D2,D4 ;update check sum RTS ; ; Routine to extract 16 or 24 bit address ; from S-file into A4. The line count in D2.B ; represents the # of words in the S-line. ; The address info takes 2 or 3 words so the ; line count is reduced by 2 or 3 at routine's ; end. Also updates checksum in D4.B LD_ADR CLR.L D3 ;D3.L = 0 MOVE.W #3,D5 ;Get set for 4 times TST.B S2_FLG ;See if set BEQ.S LD_AD1 ;Not set, so skip ADDQ.W #2,D5 ;Change to 6 times LD_AD1 ROL.L #4,D3 ;move it up a nibble BSR CHARIO ;Get char & convert BSR ASC_BCD ;to hex in D1.B ADD.B D1,D3 ;Add it to D3.B and DBRA D5,LD_AD1 ;Loop 4 or 6 times MOVEA.L D3,A4 ;Put address in A4 ADD.B D3,D4 ;Update check sum ROL.W #8,D3 ;for both bytes in ADD.B D3,D4 ;D3.W SWAP D3 ;Update 3rd byte too ADD.B D3,D4 ;Checksum now in D4.B SUBQ.B #2,D2 ;line counter-2 TST.B S2_FLG ;If not set, skip BEQ.S LD_AD2 ;Set, so do one more SUBQ.B #1,D2 ;subtraction LD_AD2 RTS ; ; Loads, into RAM, data in a HEX file whose ; line begins with S1 or S2. D2 holds the ; byte count and A4 the loading address. Also ; updates checksum which is finally checked ; by the routine that follows. LD_DATA CMPI.B #1,D2 ;At check byte? BEQ.S LD_CHK ;Yes, jump BSR CHARIO ;get char BSR ASC_BCD ;convert to hex ROL.B #4,D1 ;move it to MSB MOVE.B D1,D3 ;copy to reg D3 BSR CHARIO ;get second char BSR ASC_BCD ;convert it to hex ADD.B D1,D3 ;add them MOVE.B D3,(A4)+ ;move to load addr ADD.B D3,D4 ;update check sum SUBQ.B #1,D2 ;decr. line counter BRA.S LD_DATA ;Go for more ; Gets the last byte in an S line. If check ; sum is not 0FFH it flags an error. LD_CHK BSR CHARIO ;get char BSR ASC_BCD ;convert it to hex ROL.B #4,D1 ;move it to MSB MOVE.B D1,D3 ;copy to reg D3 BSR CHARIO ;get second char BSR ASC_BCD ;convert it to hex ADD.B D1,D3 ;add them ADD.B D3,D4 ;should = 0FFH ADDQ.B #1,D4 ;Should be 0 BNE.S LD_ERR ;Not 0, so flag it RTS ; ; Flags loading error and goes to GET_CMD LD_ERR MOVEA.L #LE_MSG,A3 ;get message ptr BRA REPORT ;restart monitor ; ; Routine that initializes the tracing BEG_TRC CMPI.B #CR,-1(A6) ;is previous CR? BEQ.S BEG1 ;yes, so start BSR GETADR ;get execution addr MOVE.L D2,SAV_PC ;save it BEG1 BSR REGREST ;restore user regs ORI.W #$8000,SR ;enable tracing RTE ; ; If the SKIPFLG is set then jump to TRACE5, else ; proceed normally. In the regular trace no tracing ; is done on the 1st pass. If a TRAP instruction is ; next then tracing is terminated. Tracing continues ; when a CR is typed. Any other chararacter causes ; termination of tracing. The FP_FLG is 0 in entry. TRACE BSR REG_SAV ;save USER registers TST.B FP_FLG ;is flag = 0? BNE.S TRACE0 ;no, so continue ST FP_FLG ;it was 0, so set it BRA.S TRACE4 ;do nothing this time TRACE0 TST.B SKIPFLG ;If not 0 BNE.S TRACE5 ;then jump BSR REG_PRT ;display them ; Check if TRAP is the next instruction. MOVEA.L SAV_PC,A0 CMPI.W #$4E4F,(A0) ;> TRAP #15? BGT.S TRACE1 ;you're okay CMPI.W #$4E40,(A0) ;< TRAP #0? BLT.S TRACE1 ;okay again MOVEA.L #TRC_MSG,A3 BSR PRTMSG BRA.S TRACE2 ; Check for CHARIN. If CR then keep tracing. TRACE1 MOVE.B #'>',D1 BSR CHAROUT BSR CHARIN CMPI.B #CR,D1 BEQ.S TRACE3 BSR CHAROUT ; If R modify register BSR UP_CASE ; <<<< Added in mon209 >>>> CMPI.B #'R',D1 ; <<<< Added in mon209 >>>> BEQ.S TRACE6 ; <<<< Added in mon209 >>>> ; Turn off all tracing and put out prompt. TRACE2 ANDI.W #$7FFF,SR ;disable tracing ORI.W #$2000,SR ;enable supervisor ANDI.W #$7FFF,SAV_SR ;fix the USR SF FP_FLG ;clear flag BRA GET_CMD ; Continue tracing TRACE3 BSR CRLF TRACE4 ANDI.W #$0FFF,SAV_SR ;enable user ORI.W #$8000,SAV_SR ;enable tracing BSR REGREST RTE ; ; TRACE saved the USER registers. This means ; that the return address of the routine ; that called GOSKIP is next on the stack. TRACE5 ANDI.W #$7FFF,SR ;disable tracing ORI.W #$2000,SR ;enable supervisor ANDI.W #$7FFF,SAV_SR ;fix the USR SF SKIPFLG ;clear flag SF FP_FLG ;clear flag RTS ;pick up where you left off ; ; <<<< Added in mon209 >>>> ; Get register to be modified then ; set register value TRACE6 BSR GETLIN MOVEA.L #INPBUF,A6 ;point to buffer MOVE.B #$0FF,REGTYP BSR REGMOD0 BRA TRACE1 ; ; Set (at most two) permanent breakpoints. ; B displays the current breakpoints. ; B 1
sets breakpoint 1. ; B 1 clears breakpoint 1. BREAK CMPI.B #CR,-1(A6) ;is previous CR? BEQ.S DSPBRK ; get breakpoint number in D2.L MOVEA.L #BP_AD3,A0 CMPI.B #'1',(A6) ;is char a '1'? BEQ.S BREAK1 ;no, then go on MOVEA.L #BP_AD4,A0 BREAK1 ADDQ.L #1,A6 ;point past # CMPI.B #CR,(A6) ;is it a CR? BNE.S BREAK2 CLR.L (A0) BRA.S BREAK3 BREAK2 BSR GETADR MOVE.L D2,(A0) ;save it BREAK3 BRA GET_CMD ; ;Deal with 1st breakpoint first. DSPBRK MOVEA.L #MSG_8,A3 ;breakpoint 1: BSR PRTMSG MOVEA.L #BP_AD3,A0 ;A0 -> #BP_AD3 TST.L (A0) BNE.S DSPBRK1 MOVEA.L #MSG_10,A3 BSR PRTMSG BRA.S DSPBRK2 DSPBRK1 MOVE.L (A0),D2 BSR PRT_SIX ;Deal with 2nd breakpoint next. DSPBRK2 MOVEA.L #MSG_9,A3 ;breakpoint 1: BSR PRTMSG MOVEA.L #BP_AD4,A0 ;A0 -> #BP_AD3 TST.L (A0) BNE.S DSPBRK3 MOVEA.L #MSG_10,A3 BSR PRTMSG BRA.S DSPBRK4 DSPBRK3 MOVE.L (A0),D2 BSR PRT_SIX DSPBRK4 BRA GET_CMD ; ; Finds and prints the sum and difference ; of 2 HEX numbers HEXCALC BSR GETADR ;get first number MOVE.L D2,D3 ;move it to D3 BSR GETADR ;get second number MOVE.L D2,D4 ;make a spare in D4 ADD.L D3,D2 ;add them MOVEA.L #HS_MSG,A3 BSR PRTMSG ;print sum msg BSR PRT_LON ;print sum MOVE.L D4,D2 ;reload original D2 SUB.L D2,D3 ;subtract them MOVE.L D3,D2 ;move to D2 to print MOVEA.L #HD_MSG,A3 BSR PRTMSG ;print diff msg BSR PRT_LON ;print difference BRA GET_CMD ;put out prompt ; ;**************************************************** ;Begin Unassemble Routines ;**************************************************** ; ;First get the disassembly start address and # of lines UNASM MOVE.B #10,D7 ;Prepare to do 10 lines CMPI.B #CR,-1(A6) ;is previous CR? BNE.S UNASMS1 ;no, so proceed MOVE.L UNADR,D2 ;get old disassebly addr MOVEA.L D2,A5 ;into A5 BRA.S UNASMS3 ;stick with 10 lines & go on UNASMS1 CMPI.B #',',(A6) ;is char a comma? BNE.S USM1 ;no, then get start address MOVE.L UNADR,D2 ;get old disassebly addr MOVEA.L D2,A5 ;into A5 ADDQ.L #1,A6 ;point past comma BRA.S UNASMS2 ;get count USM1 BSR GETADR ;get start address into D2 MOVEA.L D2,A5 ;and put into A5 CMPI.B #CR,-1(A6) ;is previous CR? BNE.S UNASMS2 ;no, so proceed BRA.S UNASMS3 UNASMS2 BSR GETADR ;get # of lines to display MOVE.B D2,D7 ;Command line is totally parsed, so do the disassembly UNASMS3 BSR UNASMB ;call unasm core routine MOVE.L A5,D2 ;move instruction address BSR PRT_SIX ;into D2 and print it BSR TWO_SP ;two space CLR.L D3 ;blank spaces counter (BSC) UNASMS4 MOVE.W (A5)+,D2 ;get word BSR PRT_WRD ;print word of hex code BSR SPACE ;space ADDQ.B #2,D3 ;add 2 bytes to BSC SUBQ.B #2,D6 ;reduce length counter by 2 BNE.S UNASMS4 ;if more bytes print again UNASMS5 CMPI.B #10,D3 ;is the string 10 bytes BGE.S UNASMS6 BSR TWO_SP BSR TWO_SP BSR SPACE ADDQ.B #2,D3 BRA.S UNASMS5 UNASMS6 BSR SPACE ;space MOVEA.L #UASMCMD,A3 ;point A3 to unasm cmd buff BSR PRTMSG ;display commant text BSR CRLF SUBQ.B #1,D7 BNE.S UNASMS3 MOVE.L A5,UNADR BRA GET_CMD ; ; 32 bytes of ram are reserved above the stacks ; for the text of the disassembled command. ; UNASMCMD points to the beginning and ; UNASMOPR points 9 characters in, so the operands ; are always evenly spaced. The text is ternminated ; with a zero and can be displayed with a call to ; PRTMSG. ; ;example ;12345678901234567890123456789012 ;MOVE.B #$01,D0 ;^ ^ ;| |---UNASMOPR ;| ;|------UNASMCMD ; ; Disasemble routine. When called, A5 points to code. ; Use of Registers ; D0-Varies A0-Varies ; D1-Varies A1-Varies ; D2-Varies A2-Varies ; D3-Varies A3-Varies ; D4-cmd size (B,W,L) A4-Instruction text buffer ; D5-instruction hex (W) A5-Ptr. to 1st byte of code ; D6-instr lngth (bytes) A6-Varies ; D7-loop count A7-stack ; UNASMB MOVE.W (A5),D5 ;D5 gets 1st byte of code MOVE.L #2,D6 ;D6 will have # of bytes in code MOVEA.L #UASMCMD,A4 ;A4 -> to unasm cmd buff ; MOVE.B #32,D1 ;Prefill UASMCMD with 32 ' 's UNASML MOVE.B #' ',(A4)+ SUBQ.B #1,D1 BNE.S UNASML ; MOVEA.L #UASMCMD,A4 ;Repoint A4 BSR.S UNSEAR ;Returns with A3 -> matching cmd MOVEA.L 10(A3),A1 ;put sub-routine addr in A1 ADDQ.L #4,A3 ;point A3 to inst txt UNASM1 MOVE.B (A3)+,D1 ;get a char BEQ.S UNASM2 ;stop on 0 MOVE.B D1,(A4)+ ;move to cmd buff BRA.S UNASM1 ;do it again UNASM2 JSR (A1) ;run sub-routine CLR.B (A4)+ ;end cmd text with zero RTS ; ; This routine searches through the list of commands ; UNINSTR, comparing to the code. When a match is ; found, the routine returns with A3 pointing to it. UNSEAR MOVEA.L #UNINSTR,A3 ;point A3 to first cmd UNSEAR0 MOVE.W D5,D0 ;Get opcode into D0 AND.W 2(A3),D0 ;AND opcode word with mask CMP.W (A3),D0 ;CMP result with stored word BEQ.S UNSEARE ;Same, so done ADDA.L #14,A3 ;Test failed, so try next one BRA.S UNSEAR0 UNSEARE RTS ; ; The following subroutines are for the specific ; commands. They all follow a similar format. ; First, if need be, move the length info to the end ; of the instruction, i.e. (.B, .L, .W). Next shift A4 ; to UNASMOPR, then find the operands. ; ;for commands with no operands U00 RTS ; ; ILLEGAL adds AL to end of instruction U01 MOVE.B #'A',(A4)+ MOVE.B #'L',(A4)+ RTS ; ; ADD, SUB, AND, EOR, OR, CMP U02 CLR.L D0 MOVE.B #7,D0 BSR USZ MOVEA.L #UASMOPR,A4 MOVE.B #8,D0 BTST D0,D5 BEQ.S U02_01 MOVE.B #'D',(A4)+ MOVE.B #11,D0 BSR UREG MOVE.B #',',(A4)+ BSR UEA BRA.S U02_02 U02_01 BSR UEA MOVE.B #',',(A4)+ MOVE.B #'D',(A4)+ MOVE.B #11,D0 BSR UREG U02_02 RTS ; ; ADDA, SUBA, CMPA U03 CLR.L D0 MOVE.B #8,D0 BTST D0,D5 BEQ.S U03_01 MOVE.B #'.',(A4)+ MOVE.B #'L',(A4)+ MOVE.B #' ',(A4)+ MOVE.B #'L',D4 BRA.S U03_02 U03_01 MOVE.B #'.',(A4)+ MOVE.B #'W',(A4)+ MOVE.B #' ',(A4)+ MOVE.B #'W',D4 U03_02 MOVEA.L #UASMOPR,A4 BSR UEA MOVE.B #',',(A4)+ MOVE.B #'A',(A4)+ MOVE.B #11,D0 BSR UREG RTS ; ; ADDX, SUBX U04 CLR.L D0 MOVE.B #7,D0 BSR USZ MOVEA.L #UASMOPR,A4 MOVE.B #3,D0 BTST D0,D5 BEQ.S U04_01 MOVE.B #'-',(A4)+ MOVE.B #'(',(A4)+ MOVE.B #'A',(A4)+ MOVE.B #2,D0 BSR UREG MOVE.B #')',(A4)+ MOVE.B #',',(A4)+ MOVE.B #'-',(A4)+ MOVE.B #'(',(A4)+ MOVE.B #'A',(A4)+ MOVE.B #11,D0 BSR UREG MOVE.B #')',(A4)+ BRA.S U04_02 U04_01 MOVE.B #'D',(A4)+ MOVE.B #2,D0 BSR UREG MOVE.B #',',(A4)+ MOVE.B #'D',(A4)+ MOVE.B #11,D0 BSR UREG U04_02 RTS ; ; CMPM U05 CLR.L D0 MOVE.B #7,D0 BSR USZ MOVEA.L #UASMOPR,A4 MOVE.B #'(',(A4)+ MOVE.B #'A',(A4)+ MOVE.B #02,D0 BSR UREG MOVE.B #')',(A4)+ MOVE.B #'+',(A4)+ MOVE.B #',',(A4)+ MOVE.B #'(',(A4)+ MOVE.B #'A',(A4)+ MOVE.B #11,D0 BSR UREG MOVE.B #')',(A4)+ MOVE.B #'+',(A4)+ RTS ; ; DIVU, DIVS, MULU, MULS U06 CLR.L D0 MOVE.B #'W',D4 MOVEA.L #UASMOPR,A4 BSR UEA MOVE.B #',',(A4)+ MOVE.B #'D',(A4)+ MOVE.B #11,D0 BSR UREG RTS ; ; ASL, ASR, LSL, LSR, ROXL, ROXR, ROL, ROR ; memory shifts U07 CLR.L D0 MOVE.B #8,D0 ;check direction BTST D0,D5 BEQ.S U07_01 MOVE.B #'L',(A4)+ BRA.S U07_02 U07_01 MOVE.B #'R',(A4)+ U07_02 MOVE.B #'.',(A4)+ MOVE.B #'W',(A4)+ MOVE.B #'W',D4 MOVEA.L #UASMOPR,A4 BSR UEA RTS ; ; ASL, ASR, LSL, LSR, ROXL, ROXR, ROL, ROR ; register shifts U08 CLR.L D0 MOVE.B #8,D0 ;check direction BTST D0,D5 BEQ.S U08_01 MOVE.B #'L',(A4)+ BRA.S U08_02 U08_01 MOVE.B #'R',(A4)+ U08_02 MOVE.B #7,D0 BSR USZ MOVEA.L #UASMOPR,A4 MOVE.B #5,D0 BTST D0,D5 ;i/r = 0 then count is within BEQ.S U08_03 ;bits 9,10,11 so jump MOVE.B #'D',(A4)+ ;i/r = 1 so count is in Dn MOVE.B #11,D0 BSR UREG BRA.S U08_08 U08_03 MOVE.B #'#',(A4)+ ;Store a # symbol MOVE.W D5,D1 ;Don't trash D5 MOVE.L #9,D0 ;Put shift size in D0 LSR.W D0,D1 ;Move shift-count bits down 9 ANDI.B #7,D1 ;Mask out unwanted stuff BNE.S U08_06 ;If not 0 then it's ready MOVE.B #8,D1 ;If 0 replace with 8 U08_06 ADDI.B #'0',D1 ;Add the 30H to D1 MOVE.B D1,(A4)+ ;Store it U08_08 MOVE.B #',',(A4)+ ;Add a ',' MOVE.B #'D',(A4)+ ;Now add a 'D' MOVE.L #2,D0 ;Point to register bits BSR UREG RTS ; ; ANDI, ORI, EORI to CCR U09 CLR.L D0 MOVE.B #'.',(A4)+ MOVE.B #'B',(A4)+ MOVEA.L #UASMOPR,A4 MOVE.B #'#',(A4)+ MOVE.B #'$',(A4)+ MOVE.W 0(A5,D6.L),D1 BSR UGBYT ADDQ.B #2,D6 MOVE.B #',',(A4)+ MOVE.B #'C',(A4)+ MOVE.B #'C',(A4)+ MOVE.B #'R',(A4)+ RTS ; ; ANDI, ORI, EORI to SR U10 CLR.L D0 MOVE.B #'.',(A4)+ MOVE.B #'W',(A4)+ MOVE.B #'L',D4 MOVEA.L #UASMOPR,A4 MOVE.B #'#',(A4)+ MOVE.B #'$',(A4)+ MOVE.W 0(A5,D6.L),D1 ROL.W #8,D1 BSR UGBYT MOVE.W 0(A5,D6.L),D1 BSR UGBYT ADDQ.B #2,D6 MOVE.B #',',(A4)+ MOVE.B #'S',(A4)+ MOVE.B #'R',(A4)+ RTS ; ; ADDI, ANDI, ORI, EORI, SUBI, CMPI U11 CLR.L D0 MOVE.B #7,D0 BSR USZ MOVEA.L #UASMOPR,A4 MOVE.B #'#',(A4)+ MOVE.B #'$',(A4)+ CMPI.B #'B',D4 BNE.S U11_01 MOVE.W 0(A5,D6.L),D1 BSR UGBYT ADDQ.B #2,D6 BRA.S U11_03 U11_01 CMPI.B #'W',D4 BNE.S U11_02 MOVE.W 0(A5,D6.L),D1 ROL.W #8,D1 BSR UGBYT MOVE.W 0(A5,D6.L),D1 BSR UGBYT ADDQ.B #2,D6 BRA.S U11_03 U11_02 MOVE.W 0(A5,D6.L),D1 ROL.W #8,D1 BSR UGBYT MOVE.W 0(A5,D6.L),D1 BSR UGBYT MOVE.W 2(A5,D6.L),D1 ROL.W #8,D1 BSR UGBYT MOVE.W 2(A5,D6.L),D1 BSR UGBYT ADDQ.B #4,D6 U11_03 MOVE.B #',',(A4)+ BSR UEA RTS ; ; BRA, BSR U12 CLR.L D0 CMPI.B #0,D5 BEQ.S U12_00 MOVE.B #'.',(A4)+ MOVE.B #'S',(A4)+ U12_00 MOVEA.L #UASMOPR,A4 MOVE.B #'$',(A4)+ MOVE.L A5,D1 ADDQ.L #2,D1 CMPI.B #0,D5 BEQ.S U12_01 CMPI.B #$FF,D5 BEQ.S U12_02 MOVE.B D5,D0 ADD.B D0,D1 BRA.S U12_03 U12_01 MOVE.W 0(A5,D6.L),D0 ADD.W D0,D1 ADDQ.B #2,D6 BRA.S U12_03 U12_02 MOVE.L 0(A5,D6.L),D0 ADD.L D0,D1 ADDQ.B #4,D6 U12_03 MOVE.B #4,D0 U12_04 ROL.L #8,D1 BSR UGBYT SUBQ.B #1,D0 BNE.S U12_04 RTS ; ; JMP, JSR U13 MOVEA.L #UASMOPR,A4 BSR UEA RTS ; ; BTST, BCHG, BCLR, BSET immediate data. These don't ; need .B or .L. If the destination is a data register ; then it's automatically .L, otherwise it's always .B U14 MOVE.B #'B',D4 MOVEA.L #UASMOPR,A4 MOVE.B #'#',(A4)+ MOVE.B #'$',(A4)+ MOVE.W 0(A5,D6.L),D1 BSR UGBYT ;Change imm data to ASCII & store ADDQ.B #2,D6 MOVE.B #',',(A4)+ BSR UEA RTS ; ; BTST, BCHG, BCLR, BSET ; register data U15 CLR.L D0 MOVE.B #'L',D4 MOVEA.L #UASMOPR,A4 MOVE.B #'D',(A4)+ MOVE.B #11,D0 BSR UREG MOVE.B #',',(A4)+ BSR UEA RTS ; ; MOVE U16 CLR.L D0 MOVE.B #13,D0 BSR USZM MOVEA.L #UASMOPR,A4 BSR UEA MOVE.B #',',(A4)+ MOVE.L D5,-(A7) ;<<< these lines MOVE.W D5,D0 ;flip destination addr. ROL.W #7,D5 ;RRRMMM to MMMRRR format AND.W #7,D5 ;in EA location ROR.W #3,D0 ANDI.W #$38,D0 ADD.W D0,D5 BSR UEA ;<<<< end flip MOVE.L (A7)+,D5 ;get back D5 RTS ; ; MOVEA U17 CLR.L D0 MOVE.B #13,D0 BSR USZM MOVEA.L #UASMOPR,A4 BSR UEA MOVE.B #',',(A4)+ MOVE.B #'A',(A4)+ MOVE.B #11,D0 BSR UREG RTS ; ; Bcc U18 MOVE.L #8,D0 BSR UCC BSR U12 ;bsr routine RTS ; ; DBcc U19 MOVE.L #8,D0 BSR UCC MOVEA.L #UASMOPR,A4 MOVE.B #'D',(A4)+ MOVE.B #2,D0 BSR UREG MOVE.B #',',(A4)+ MOVE.B #'$',(A4)+ MOVE.L A5,D1 ADDQ.L #2,D1 MOVE.W 0(A5,D6.L),D0 ADD.W D0,D1 ADDQ.B #2,D6 MOVE.B #4,D0 U19_01 ROL.L #8,D1 BSR UGBYT SUBQ.B #1,D0 BNE.S U19_01 RTS ; ; Scc U20 MOVE.L #8,D0 BSR UCC MOVE.B #'B',D4 MOVEA.L #UASMOPR,A4 MOVE.B #'B',D4 BSR UEA RTS ; ; NEGX, CLR, NEG, NOT, TST U21 CLR.L D0 MOVE.B #7,D0 BSR USZ MOVEA.L #UASMOPR,A4 BSR UEA RTS ; ; TAS U22 CLR.L D0 MOVE.B #'B',D4 MOVEA.L #UASMOPR,A4 BSR UEA RTS ; ; SWAP U23 CLR.L D0 MOVEA.L #UASMOPR,A4 MOVE.B #'D',(A4)+ MOVE.B #2,D0 BSR UREG RTS ; ; UNLK U24 CLR.L D0 MOVEA.L #UASMOPR,A4 MOVE.B #'A',(A4)+ MOVE.B #2,D0 BSR UREG RTS ; ; LINK U25 MOVEA.L #UASMOPR,A4 MOVE.B #'A',(A4)+ MOVE.B #11,D0 BSR UREG MOVE.B #',',(A4)+ MOVE.B #'#',(A4)+ MOVE.B #'$',(A4)+ MOVE.W 0(A5,D6.L),D1 ADDQ.B #2,D6 MOVE.B #2,D0 U25_01 ROL.W #8,D1 BSR UGBYT SUBQ.B #1,D0 BNE.S U25_01 RTS ; ; ABCD, SBCD U26 CLR.L D0 ;Mnemonic is already in buffer MOVEA.L #UASMOPR,A4 ;A4 -> to argument storage BTST #3,D5 ;D5 contains the hex opcode BNE.S U26_01 MOVEA.L #UASMOPR,A4 MOVE.B #'D',(A4)+ MOVE.B #2,D0 BSR UREG MOVE.B #',',(A4)+ MOVE.B #'D',(A4)+ MOVE.B #11,D0 BSR UREG BRA.S U26_02 U26_01 MOVE.B #'-',(A4)+ MOVE.B #'(',(A4)+ MOVE.B #'A',(A4)+ MOVE.B #02,D0 BSR UREG MOVE.B #')',(A4)+ MOVE.B #',',(A4)+ MOVE.B #'-',(A4)+ MOVE.B #'(',(A4)+ MOVE.B #'A',(A4)+ MOVE.B #11,D0 BSR UREG MOVE.B #')',(A4)+ U26_02 RTS ; ; ADDQ, SUBQ U27 CLR.L D0 MOVE.B #7,D0 BSR USZ MOVEA.L #UASMOPR,A4 MOVE.B #'#',(A4)+ MOVE.B #'$',(A4)+ MOVE.L D5,-(A7) ;get back D5 ROL.W #7,D5 AND.W #7,D5 ADDI.B #$30,D5 MOVE.B D5,(A4)+ MOVE.L (A7)+,D5 ;get back D5 MOVE.B #',',(A4)+ BSR UEA RTS ; ; CHK U28 CLR.L D0 MOVE.B #'W',D4 MOVEA.L #UASMOPR,A4 BSR UEA MOVE.B #',',(A4)+ MOVE.B #'D',(A4)+ MOVE.B #11,D0 BSR UREG RTS ; ; EXG Dn,Dm. It's always long. U29DD CLR.L D0 MOVEA.L #UASMOPR,A4 MOVE.B #'D',(A4)+ MOVE.B #11,D0 BSR UREG MOVE.B #',',(A4)+ MOVE.B #'D',(A4)+ MOVE.B #2,D0 BSR UREG RTS ; ; EXG An,Am. It's always long. U29AA CLR.L D0 MOVEA.L #UASMOPR,A4 MOVE.B #'A',(A4)+ MOVE.B #11,D0 BSR UREG MOVE.B #',',(A4)+ MOVE.B #'A',(A4)+ MOVE.B #2,D0 BSR UREG RTS ; ; EXG. It's always long. U29DA CLR.L D0 MOVEA.L #UASMOPR,A4 MOVE.B #'D',(A4)+ MOVE.B #11,D0 BSR UREG MOVE.B #',',(A4)+ MOVE.B #'A',(A4)+ MOVE.B #2,D0 BSR UREG RTS ; ; EXT U30 CLR.L D0 MOVE.B #'.',(A4)+ BTST #6,D5 BEQ.S U30_01 MOVE.B #'L',(A4)+ BRA.S U30_02 U30_01 MOVE.B #'W',(A4)+ U30_02 MOVEA.L #UASMOPR,A4 MOVE.B #'D',(A4)+ MOVE.B #2,D0 BSR UREG RTS ; ; LEA U31 CLR.L D0 MOVE.B #'.',(A4)+ ; D5 contains the instruction word BTST #0,D5 BNE.S U31A MOVE.B #'W',(A4)+ MOVE.B #'W',D4 BRA.S U31B U31A MOVE.B #'L',(A4)+ MOVE.B #'L',D4 U31B MOVEA.L #UASMOPR,A4 BSR UEA MOVE.B #',',(A4)+ MOVE.B #'A',(A4)+ MOVE.B #11,D0 BSR UREG RTS ; ; NBCD U32 MOVE.B #'B',D4 MOVEA.L #UASMOPR,A4 BSR UEA RTS ; ; PEA U33 MOVE.B #'L',D4 MOVEA.L #UASMOPR,A4 BSR UEA RTS ; ; STOP U34 MOVEA.L #UASMOPR,A4 MOVE.B #'#',(A4)+ MOVE.B #'$',(A4)+ MOVE.W $00(A5,D6.L),D1 ROL.W #8,D1 BSR UGBYT MOVE.W 0(A5,D6.L),D1 BSR UGBYT ADDQ.B #2,D6 RTS ; ; TRAP U35 MOVEA.L #UASMOPR,A4 MOVE.B #'#',(A4)+ MOVE.B #'$',(A4)+ MOVE.B D5,D1 BSR NUM_ASC MOVE.B D1,(A4)+ RTS ; ; MOVE TO CCR U36 MOVE.B #'.',(A4)+ MOVE.B #'W',(A4)+ MOVE.B #'W',D4 MOVEA.L #UASMOPR,A4 BSR UEA MOVE.B #',',(A4)+ MOVE.B #'C',(A4)+ MOVE.B #'C',(A4)+ MOVE.B #'R',(A4)+ RTS ; ; MOVE from SR U37 MOVE.B #'.',(A4)+ MOVE.B #'W',(A4)+ MOVE.B #'W',D4 MOVEA.L #UASMOPR,A4 MOVE.B #'S',(A4)+ MOVE.B #'R',(A4)+ MOVE.B #',',(A4)+ BSR UEA RTS ; ; MOVE to SR U38 MOVE.B #'.',(A4)+ MOVE.B #'W',(A4)+ MOVE.B #'W',D4 MOVEA.L #UASMOPR,A4 BSR UEA MOVE.B #',',(A4)+ MOVE.B #'S',(A4)+ MOVE.B #'R',(A4)+ RTS ; ; MOVE An <-> USP U39 MOVE.B #'.',(A4)+ MOVE.B #'L',(A4)+ MOVEA.L #UASMOPR,A4 BTST #3,D5 BEQ.S U39_01 MOVE.B #'U',(A4)+ MOVE.B #'S',(A4)+ MOVE.B #'P',(A4)+ MOVE.B #',',(A4)+ MOVE.B #'A',(A4)+ MOVE.B #2,D0 BSR UREG BRA.S U39_02 U39_01 MOVE.B #'A',(A4)+ MOVE.B #2,D0 BSR UREG MOVE.B #',',(A4)+ MOVE.B #'U',(A4)+ MOVE.B #'S',(A4)+ MOVE.B #'P',(A4)+ U39_02 RTS ; ; MOVEQ U40 MOVE.B #'.',(A4)+ MOVE.B #'L',(A4)+ MOVEA.L #UASMOPR,A4 MOVE.B #'#',(A4)+ MOVE.B #'$',(A4)+ MOVE.B D5,D1 BSR UGBYT MOVE.B #',',(A4)+ MOVE.B #'D',(A4)+ MOVE.B #11,D0 BSR UREG RTS ; ; MOVEP U41 BTST #6,D5 BEQ.S U41_01 MOVE.B #'.',(A4)+ MOVE.B #'L',(A4)+ BRA.S U41_02 U41_01 MOVE.B #'.',(A4)+ MOVE.B #'W',(A4)+ U41_02 MOVEA.L #UASMOPR,A4 BTST #7,D5 BEQ.S U41_03 ;If 0 then it's d(Ay),Dx MOVE.B #'D',(A4)+ ;It's 1 so do Dx,d(Ay) MOVE.B #11,D0 ;point to bit 11 and put in BSR UREG ;place the data register # MOVE.B #',',(A4)+ BSR DOIT BRA.S U41_04 U41_03 BSR DOIT MOVE.B #',',(A4)+ MOVE.B #'D',(A4)+ MOVE.B #11,D0 BSR UREG U41_04 RTS ; DOIT MOVE.B #'$',(A4)+ MOVE.W $00(A5,D6.L),D1 ROL.W #8,D1 BSR UGBYT MOVE.W 0(A5,D6.L),D1 BSR UGBYT ADDQ.B #2,D6 MOVE.B #'(',(A4)+ MOVE.B #'A',(A4)+ MOVEQ #2,D0 BSR UREG MOVE.B #')',(A4)+ RTS ; ; MOVEM U42 BTST #6,D5 BEQ.S U42_01 MOVE.B #'.',(A4)+ MOVE.B #'L',(A4)+ BRA.S U42_02 U42_01 MOVE.B #'.',(A4)+ MOVE.B #'W',(A4)+ U42_02 MOVEA.L #UASMOPR,A4 MOVE.W 2(A5),D3 U42_03 BTST #5,D5 BEQ.S U42_04 BTST #4,D5 BNE.S U42_04 BTST #3,D5 BNE.S U42_04 CLR.L D0 CLR.L D2 MOVE.W #$F,D1 U42_06 BTST D1,D3 BEQ.S U42_05 BSET D0,D2 U42_05 ADDQ.B #1,D0 SUBQ.B #1,D1 CMPI.B #$F,D0 BLE.S U42_06 MOVE.W D2,D3 U42_04 MOVE.B #10,D0 BTST D0,D5 BEQ.S U42_07 BSR UEA MOVE.B #',',(A4)+ MOVE.B #'D',D2 ADDQ.B #2,D6 BSR UM MOVE.W D3,D1 ROL.W #8,D3 CMPI.W #$100,D1 BLT.S U42_10 AND.W #$FF,D1 CMPI.W #1,D1 BLT.S U42_10 MOVE.B #'/',(A4)+ U42_10 MOVE.B #'A',D2 BSR UM BRA.S U42_08 U42_07 MOVE.B #'D',D2 ADDQ.B #2,D6 BSR UM MOVE.W D3,D1 ROL.W #8,D3 CMPI.W #$100,D1 BLT.S U42_09 AND.W #$FF,D1 CMPI.W #1,D1 BLT.S U42_09 MOVE.B #'/',(A4)+ U42_09 MOVE.B #'A',D2 BSR UM MOVE.B #',',(A4)+ BSR UEA U42_08 RTS ; ; Tests effective address field ; D0 points to first bit of ; D4.B is length of cmd 'B','W','L' ; moves result to cmd line (A4) ; format MMMRRR UEA CLR.L D0 MOVE.B #05,D0 BTST D0,D5 ;check first bit XMM BEQ UEA0 ;is 0MM, jmp SUBQ.B #1,D0 BTST D0,D5 ;check second bit 1XM BEQ UEA1 ;is 10M, jmp SUBQ.B #1,D0 BTST D0,D5 ;check third bit 11X BEQ UEA2 ;is 110, jmp SUBQ.B #1,D0 ;<<<<<<<< 111-RRR BTST D0,D5 ;test register bits BEQ.S UEA7 ;is 0RR, jmp MOVE.B #'#',(A4)+ ;<<<<<<<< 111-100 # MOVE.B #'$',(A4)+ CMPI.B #'B',D4 BNE.S UEA11 MOVE.W 2(A5),D1 BSR UGBYT ADDQ.B #2,D6 BRA UEAD ;go to RTS ; UEA11 CMPI.B #'W',D4 BNE.S UEA12 MOVE.W 0(A5,D6.L),D1 ROL.W #8,D1 BSR UGBYT MOVE.W 0(A5,D6.L),D1 BSR UGBYT ADDQ.B #2,D6 BRA UEAD UEA12 MOVE.W $00(A5,D6.L),D1 ROL.W #8,D1 BSR UGBYT MOVE.W 0(A5,D6.L),D1 BSR UGBYT MOVE.W 2(A5,D6.L),D1 ROL.W #8,D1 BSR UGBYT MOVE.W 2(A5,D6.L),D1 BSR UGBYT ADDQ.B #4,D6 BRA UEAD ; UEA7 SUBQ.B #1,D0 BTST D0,D5 ;test register bits BEQ UEA8 ;is 00R, jmp SUBQ.B #1,D0 BTST D0,D5 BEQ.S UEA9 ;is 010, jmp MOVE.B #'$',(A4)+ ;<<<<<<<< 111-011 (d8,PC,Xn) MOVE.W 2(A5),D1 BSR UGBYT ADDQ.B #2,D6 MOVE.B #'(',(A4)+ MOVE.B #'P',(A4)+ MOVE.B #'C',(A4)+ MOVE.B #',',(A4)+ MOVE.W 2(A5),D1 MOVE.B #15,D0 BTST D0,D1 BEQ.S UEA17 MOVE.B #'A',(A4)+ BRA.S UEA18 UEA17 MOVE.B #'D',(A4)+ UEA18 SUBQ.B #1,D0 MOVE.L D5,D3 MOVE.W 2(A5),D5 BSR UREG MOVE.L D3,D5 MOVE.B #'.',(A4)+ MOVE.B #11,D0 BTST D0,D1 BEQ.S UEA19 MOVE.B #'L',(A4)+ BRA.S UEA20 UEA19 MOVE.B #'W',(A4)+ UEA20 MOVE.B #')',(A4)+ BRA UEAD ;go to RTS ; UEA9 MOVE.B #'$',(A4)+ ;<<<<<<<< 111-010 (d16,PC) MOVE.W 0(A5,D6.L),D1 ROL.W #8,D1 BSR UGBYT MOVE.W 0(A5,D6.L),D1 BSR UGBYT ADDQ.B #2,D6 MOVE.B #'(',(A4)+ MOVE.B #'P',(A4)+ MOVE.B #'C',(A4)+ MOVE.B #')',(A4)+ BRA UEAD ;go to RTS ; UEA8 SUBQ.B #1,D0 BTST D0,D5 BEQ.S UEA10 ;is 000, jmp MOVE.B #'$',(A4)+ ;<<<<<<<< 111-001 (xxx).L MOVE.W $00(A5,D6.L),D1 ROL.W #8,D1 BSR UGBYT MOVE.W 0(A5,D6.L),D1 BSR UGBYT MOVE.W 2(A5,D6.L),D1 ROL.W #8,D1 BSR UGBYT MOVE.W 2(A5,D6.L),D1 BSR UGBYT ADDQ.B #4,D6 BRA UEAD ; UEA10 MOVE.B #'$',(A4)+ ;<<<<<<<< 111-000 (xxx).W MOVE.W 0(A5,D6.L),D1 ROL.W #8,D1 BSR UGBYT MOVE.W 0(A5,D6.L),D1 BSR UGBYT ADDQ.B #2,D6 BRA UEAD UEA2 MOVE.B #'$',(A4)+ ;<<<<<<<< 110 (d8,An,Xn) MOVE.W 2(A5),D1 BSR UGBYT ADDQ.B #2,D6 MOVE.B #'(',(A4)+ MOVE.B #'A',(A4)+ SUBQ.B #1,D0 BSR UREG MOVE.B #',',(A4)+ MOVE.W 2(A5),D1 MOVE.B #15,D0 BTST D0,D1 BEQ.S UEA13 MOVE.B #'A',(A4)+ BRA.S UEA14 UEA13 MOVE.B #'D',(A4)+ UEA14 SUBQ.B #1,D0 MOVE.L D5,D3 MOVE.W 2(A5),D5 BSR UREG MOVE.L D3,D5 MOVE.B #'.',(A4)+ MOVE.B #11,D0 BTST D0,D1 BEQ.S UEA15 MOVE.B #'L',(A4)+ BRA.S UEA16 UEA15 MOVE.B #'W',(A4)+ UEA16 MOVE.B #')',(A4)+ BRA UEAD ; UEA1 SUBQ.B #1,D0 BTST D0,D5 ;check third bit 10X BEQ.S UEA3 ;is 100, jmp UEA1A MOVE.B #'$',(A4)+ ;<<<<<<<< 101 (d16,An) MOVE.W $00(A5,D6.L),D1 ROL.W #8,D1 BSR UGBYT MOVE.W 0(A5,D6.L),D1 BSR UGBYT ADDQ.B #2,D6 MOVE.B #'(',(A4)+ MOVE.B #'A',(A4)+ SUBQ.B #1,D0 BSR UREG MOVE.B #')',(A4)+ BRA.S UEAD ; UEA3 MOVE.B #'-',(A4)+ ;<<<<<<<< 100 -(An) MOVE.B #'(',(A4)+ MOVE.B #'A',(A4)+ SUBQ.B #1,D0 BSR UREG MOVE.B #')',(A4)+ BRA.S UEAD ; UEA0 SUBQ.B #1,D0 BTST D0,D5 ;check second bit 0XM BEQ.S UEA4 ;is 00M, jmp SUBQ.B #1,D0 BTST D0,D5 ;check third bit 01X BEQ.S UEA5 ;is 010, jmp MOVE.B #'(',(A4)+ ;<<<<<<<< 011 (An)+ MOVE.B #'A',(A4)+ SUBQ.B #1,D0 BSR UREG MOVE.B #')',(A4)+ MOVE.B #'+',(A4)+ BRA.S UEAD ; UEA5 MOVE.B #'(',(A4)+ ;<<<<<<<< 010 (An) MOVE.B #'A',(A4)+ SUBQ.B #1,D0 BSR UREG MOVE.B #')',(A4)+ BRA.S UEAD ; UEA4 SUBQ.B #1,D0 BTST D0,D5 ;check third bit 00X BEQ.S UEA6 ;is 000, jmp MOVE.B #'A',(A4)+ ;<<<<<<<< 001 An SUBQ.B #1,D0 BSR UREG BRA.S UEAD ; UEA6 MOVE.B #'D',(A4)+ ;<<<<<<<< 000 Dn SUBQ.B #1,D0 BSR UREG BRA UEAD UEAD RTS ; ; Gets the register number and adds it to printout ; buffer. D0.B points to MSB of register in OPCODE. ; A4 points to next place in printout buffer. UREG MOVE.W D5,D1 ;Don't trash D5 SUBI.B #2,D0 ;Point D0 to lowest bit ANDI.L #$FF,D0 ;Reset the upper 3 bytes in D0 BEQ.S UREG1 ;If shift size is 0 then skip LSR.W D0,D1 ;Shift down the register num UREG1 ANDI.B #7,D1 ;Mask out irrelevant bits ADDI.B #'0',D1 ;Add 30H to convert to ASCII MOVE.B D1,(A4)+ ;Store it RTS ; ; Converts byte in D1.B to ASCII and moves it to ; cmd line UGBYT MOVE.L D1,D2 ;init conversion reg ROL.B #4,D1 ;do upper nibble first BSR NUM_ASC ;convert to ASCII MOVE.B D1,(A4)+ MOVE.L D2,D1 ;now do lower nibble BSR NUM_ASC MOVE.B D1,(A4)+ MOVE.L D2,D1 RTS ; ; cmd size. 00=byte 01=word 10=long ; moves .B, .W or .L to cmd line ; D0 points to first size bit ; also moves L or W or B to D4 USZ BTST D0,D5 BEQ.S USZ1 MOVE.B #'.',(A4)+ MOVE.B #'L',(A4)+ MOVE.B #'L',D4 BRA.S USZE USZ1 SUBQ.B #1,D0 BTST D0,D5 BEQ.S USZ2 MOVE.B #'.',(A4)+ MOVE.B #'W',(A4)+ MOVE.B #'W',D4 BRA.S USZE USZ2 MOVE.B #'.',(A4)+ MOVE.B #'B',(A4)+ MOVE.B #'B',D4 USZE RTS ; ; cmd size for move 01=byte 11=word 10=long ; moves .B, .W or .L to cmd line ; D0 points to first size bit ; also moves L or W or B to D4 USZM BTST D0,D5 BNE.S USZM1 MOVE.B #'.',(A4)+ MOVE.B #'B',(A4)+ MOVE.B #'B',D4 BRA.S USZME USZM1 SUBQ.B #1,D0 BTST D0,D5 BEQ.S USZM2 MOVE.B #'.',(A4)+ MOVE.B #'W',(A4)+ MOVE.B #'W',D4 BRA.S USZME USZM2 MOVE.B #'.',(A4)+ MOVE.B #'L',(A4)+ MOVE.B #'L',D4 USZME RTS ; ; Condition codes routine ; D0 contains nubmber of bits to roll UCC MOVE.W D5,D1 ROR.W D0,D1 AND.L #$F,D1 MULU.W #2,D1 MOVEA.L #UCCLST,A0 MOVE.B 0(A0,D1.L),(A4)+ MOVE.B 1(A0,D1.L),(A4)+ RTS ; ; <<<<<< Fixed in mon209 >>>>>> ; Routine for move multiple. ; D3 contains byte in X7-X0 format ; D2 contains letter (ie A,D) UM CLR.L D0 MOVE.B #$FF,D1 UM00 BTST.L D0,D3 BNE UM01 ADDI.B #$01,D0 CMPI.B #$08,D0 BEQ UME BRA UM00 UM01 MOVE.B D0,D1 BSR UMP ADDI.B #$01,D0 CMPI.B #$08,D0 BEQ UME BTST.L D0,D3 BNE UM02 ADDI.B #$01,D0 CMPI.B #$08,D0 BEQ UME BRA UM03 UM02 MOVE.B D0,D1 ADDI.B #$01,D0 CMPI.B #$08,D0 BEQ UME BTST.L D0,D3 BNE UM02 MOVE.B #'-',(A4)+ BSR UMP ADDI.B #$01,D0 CMPI.B #$08,D0 BEQ UME UM03 BTST.L D0,D3 BNE UM04 ADDI.B #$01,D0 CMPI.B #$08,D0 BEQ UME BRA UM03 UM04 MOVE.B #'/',(A4)+ BRA UM01 UME CMPI.B #$FF,D1 BEQ UME0 BSR UMP UME0 RTS UMP MOVE.B D2,(A4)+ ADDI.B #$30,D1 MOVE.B D1,(A4)+ MOVE.B #$FF,D1 RTS ; ;**************************************************** ;End Unassemble Routines ;**************************************************** ; HELP MOVEA.L #H_MSG1,A3 ;help menu BSR PRTMSG ;now the help menu BRA GET_CMD ; BUSERR BSR CLR_BK ;clear the bkpts MOVEA.L #MSG_1,A3 BRA REPORT ; ; The address error exception stores more infomation ; than other exceptions. 8 additonal bytes are pushed ; to the stack before the SR and PC so a modified ; version of REG_SAV is used. ADDERR MOVEM.L D0-D7/A0-A6,SAVREGS ;d0-a6 ADDA.L #$08,A7 MOVE.W (A7)+,SAV_SR ;pop SR MOVE.L (A7)+,SAV_PC ;pop PC (It points to ;next instruction) MOVE.L USP,A5 ;get user's A7 MOVE.L A5,SAV_A7 ;save it MOVEA.L #MSG_2,A3 ;point to message BSR PRTMSG MOVE.L SAV_PC,D2 ;get user PC value BSR PRT_SIX BSR CRLF BSR CLR_BK ;clear the bkpts BRA GET_CMD ;all done ; ILEGAL BSR REG_SAV MOVEA.L #MSG_3,A3 ;point to message BSR PRTMSG MOVE.L SAV_PC,D2 ;get user PC value (illegal instruction) BSR PRT_SIX ADDQ.L #2,D2 ;skip a longword in SAV_PC MOVE.L D2,SAV_PC SF FP_FLG ;clear flag BSR CRLF BSR CLR_BK ;clear the bkpts BRA GET_CMD ;all done ; DIVZERO BSR REG_SAV MOVEA.L #MSG_4,A3 ;point to message BSR PRTMSG MOVE.L SAV_PC,D2 ;get user PC value (next instruction) BSR PRT_SIX BSR CRLF BSR CLR_BK ;clear the bkpts BRA GET_CMD ;all done ; LINE_A BSR REG_SAV MOVEA.L #MSG_A,A3 ;point to message BSR PRTMSG MOVE.L SAV_PC,D2 ;get user PC value (illegal instruction) BSR PRT_SIX ADDQ.L #2,D2 ;skip a longword in SAV_PC MOVE.L D2,SAV_PC SF FP_FLG ;clear flag BSR CRLF BSR CLR_BK ;clear the bkpts BRA GET_CMD ;all done ; LINE_F BSR REG_SAV MOVEA.L #MSG_F,A3 ;point to message BSR PRTMSG MOVE.L SAV_PC,D2 ;get user PC value (illegal instruction) BSR PRT_SIX ADDQ.L #2,D2 ;skip a longword in SAV_PC MOVE.L D2,SAV_PC BSR CRLF SF FP_FLG ;clear flag BSR CLR_BK ;clear the bkpts BRA GET_CMD ;all done ; TRAP_V BSR CLR_BK ;clear the bkpts MOVEA.L #MSG_5,A3 BRA.S REPORT ; PRIVIOL BSR CLR_BK ;clear the bkpts MOVEA.L #MSG_6,A3 BRA.S REPORT ; LEVEL_7 BSR CLR_BK ;clear the bkpts MOVEA.L #MSG_7,A3 REPORT BSR CRLF BSR PRTMSG ;now the help menu BSR CRLF BRA GET_CMD ; TO_CHARIN BSR CHARIN RTE ; TO_CHAROUT BSR CHAROUT RTE ; TO_CRLF BSR CRLF RTE ; TO_PRTMSG BSR PRTMSG RTE ; TO_PRT_BYT BSR PRT_BYT RTE ; TO_PRT_WRD BSR PRT_WRD RTE ; TO_PRT_LON BSR PRT_LON RTE ; TO_GET_BYT BSR GET_BYT RTE ; TO_GETADR BSR GETADRT RTE ; ;****************************************************** ; Begin Unassemble of Instructions. Each entry is in ; the following format: The 1st word is the opcode ; with all variable bits made 0. The 2nd word is ; the mask consisting of all 1's in the bit positions ; in which the instruction is fully defined and 0's ; in the positions in which the bits can change. Next ; are 6 ASCII bytes of null-padded instruction text. ; Next is one long word pointing to the subroutine ; that handles the disassembly of the opcode. ; The order of the commands is extremely important. ; The most specific commands, those that have more ; ones bits in their mask, must come first. With each ; instruction you'll find the bit count of its mask. ; ; HEX opcode examples ;----------------------------------------------------- ; NOP This instruction is fully defined ; BITS (X's for variable bits) 0100111001110001 ; 1st word (X bits converted to 0) 0100111001110001 ; 2nd word (The mask, see CMPA below) 1111111111111111 ; Mask bit count of ones = 16 ; ; CMPA ; BITS (X's for variable bits) 1011XXXX11XXXXXX ; 1st word (X bits converted to 0) 1011000011000000 ; 2nd word (Defined bits = 1, X = 0) 1111000011000000 ; Mask bit count of ones = 6 ; ;****************************************************** UNINSTR ; Instructions with 1st nibble = 0000. ; ORI to CCR. Number of bits in mask = (16) DC.W $3C,$FFFF DC.B 'ORI',0,0,0 DC.L U09 ; ORI to SR (16) DC.W $7C,$FFFF DC.B 'ORI',0,0,0 DC.L U10 ; ANDI to CCR (16) DC.W $23C,$FFFF DC.B 'ANDI',0,0 DC.L U09 ; ANDI to SR (16) DC.W $27C,$FFFF DC.B 'ANDI',0,0 DC.L U10 ; EORI to CCR (16) DC.W $A3C,$FFFF DC.B 'EORI',0,0 DC.L U09 ; EORI to SR (16) DC.W $A7C,$FFFF DC.B 'EORI',0,0 DC.L U10 ; BTST (10) DC.W $800,$FFC0 DC.B 'BTST',0,0 DC.L U14 ; BCHG (10) DC.W $840,$FFC0 DC.B 'BCHG',0,0 DC.L U14 ; BCLR (10) DC.W $880,$FFC0 DC.B 'BCLR',0,0 DC.L U14 ; BSET (10) DC.W $8C0,$FFC0 DC.B 'BSET',0,0 DC.L U14 ; Ordinary ORI (8) DC.W $0,$FF00 DC.B 'ORI',0,0,0 DC.L U11 ; Ordinary ANDI (8) DC.W $200,$FF00 DC.B 'ANDI',0,0 DC.L U11 ; SUBI (8) DC.W $400,$FF00 DC.B 'SUBI',0,0 DC.L U11 ; ADDI (8) DC.W $600,$FF00 DC.B 'ADDI',0,0 DC.L U11 ; Ordinary EORI (8) DC.W $A00,$FF00 DC.B 'EORI',0,0 DC.L U11 ; CMPI (8) DC.W $C00,$FF00 DC.B 'CMPI',0,0 DC.L U11 ; MOVEP (8) DC.W $108,$F138 DC.B 'MOVEP',0 DC.L U41 ; BTST (7) DC.W $100,$F1C0 DC.B 'BTST',0,0 DC.L U15 ; BCHG (7) DC.W $140,$F1C0 DC.B 'BCHG',0,0 DC.L U15 ; BCLR (7) DC.W $180,$F1C0 DC.B 'BCLR',0,0 DC.L U15 ; BSET (7) DC.W $1C0,$F1C0 DC.B 'BSET',0,0 DC.L U15 ; MOVEA (5) DC.W $40,$C1C0 DC.B 'MOVEA',0 DC.L U17 ; MOVE (2) DC.W $0,$C000 DC.B 'MOVE',0,0 DC.L U16 ; Instructions with 1st nibble = 0100 ; ILLEGAL (16) DC.W $4AFC,$FFFF DC.B 'ILLEG',0 DC.L U01 ; RESET (16) DC.W $4E70,$FFFF DC.B 'RESET',0 DC.L U00 ; NOP (16) DC.W $4E71,$FFFF DC.B 'NOP',0,0,0 DC.L U00 ; STOP (16) DC.W $4E72,$FFFF DC.B 'STOP',0,0 DC.L U34 ; RTE (16) DC.W $4E73,$FFFF DC.B 'RTE',0,0,0 DC.L U00 ; RTS (16) DC.W $4E75,$FFFF DC.B 'RTS',0,0,0 DC.L U00 ; TRAPV (16) DC.W $4E76,$FFFF DC.B 'TRAPV',0 DC.L U00 ; RTR (16) DC.W $4E77,$FFFF DC.B 'RTR',0,0,0 DC.L U00 ; SWAP (13) DC.W $4840,$FFF8 DC.B 'SWAP',0,0 DC.L U23 ; LINK (13) DC.W $4E50,$FFF8 DC.B 'LINK',0,0 DC.L U25 ; UNLK (13) DC.W $4E58,$FFF8 DC.B 'UNLK',0,0 DC.L U24 ; MOVE An <-> USP (12) DC.W $4E60,$FFF0 DC.B 'MOVE',0,0 DC.L U39 ; TRAP (12) DC.W $4E40,$FFF0 DC.B 'TRAP',0,0 DC.L U35 ; JSR (12) DC.W $4E80,$FFC0 DC.B 'JSR',0,0,0 DC.L U13 ; JMP (12) DC.W $4EC0,$FFC0 DC.B 'JMP',0,0,0 DC.L U13 ; EXT (11) DC.W $4880,$FEB8 DC.B 'EXT',0,0,0 DC.L U30 ; MOVE from SR (10) DC.W $40C0,$FFC0 DC.B 'MOVE',0,0 DC.L U37 ; MOVE to CCR (10) DC.W $44C0,$FFC0 DC.B 'MOVE',0,0 DC.L U36 ; MOVE to SR (10) DC.W $46C0,$FFC0 DC.B 'MOVE',0,0 DC.L U38 ; NBCD (10) DC.W $4800,$FFC0 DC.B 'NBCD',0,0 DC.L U32 ; PEA (10) DC.W $4840,$FFC0 DC.B 'PEA',0,0,0 DC.L U33 ; TAS (10) DC.W $4AC0,$FFC0 DC.B 'TAS',0,0,0 DC.L U22 ; NEGX (8) DC.W $4000,$FF00 DC.B 'NEGX',0,0 DC.L U21 ; CLR (8) DC.W $4200,$FF00 DC.B 'CLR',0,0,0 DC.L U21 ; NEG (8) DC.W $4400,$FF00 DC.B 'NEG',0,0,0 DC.L U21 ; NOT (8) DC.W $4600,$FF00 DC.B 'NOT',0,0,0 DC.L U21 ; TST (8) DC.W $4A00,$FF00 DC.B 'TST',0,0,0 DC.L U21 ; MOVEM (8) DC.W $4880,$FB80 DC.B 'MOVEM',0 DC.L U42 ; LEA (7) DC.W $41C0,$F1C0 DC.B 'LEA',0,0,0 DC.L U31 ; CHK (5) DC.W $4000,$F040 DC.B 'CHK',0,0,0 DC.L U28 ; Instructions with 1st nibble = 0101 ; DBcc (9) DC.W $50C8,$F0F8 DC.B 'DB',0,0,0,0 DC.L U19 ; Scc (6) DC.W $50C0,$F0C0 DC.B 'S',0,0,0,0,0 DC.L U20 ; ADDQ (5) DC.W $5000,$F100 DC.B 'ADDQ',0,0 DC.L U27 ; SUBQ (5) DC.W $5100,$F100 DC.B 'SUBQ',0,0 DC.L U27 ; Instructions with 1st nibble = 0110 ; BRA (8) DC.W $6000,$FF00 DC.B 'BRA',0,0,0 DC.L U12 ; BSR (8) DC.W $6100,$FF00 DC.B 'BSR',0,0,0 DC.L U12 ; Bcc (4) DC.W $6000,$F000 DC.B 'B',0,0,0,0,0 DC.L U18 ; Instructions with 1st nibble = 0111 ; MOVEQ (5) DC.W $7000,$F100 DC.B 'MOVEQ',0 DC.L U40 ; Instructions with 1st nibble = 1000 ; SBCD (9) DC.W $8100,$F1F0 DC.B 'SBCD',0,0 DC.L U26 ; DIVU (7) DC.W $80C0,$F1C0 DC.B 'DIVU',0,0 DC.L U06 ; DIVS (7) DC.W $81C0,$F1C0 DC.B 'DIVS',0,0 DC.L U06 ; OR (4) DC.W $8000,$F000 DC.B 'OR',0,0,0,0 DC.L U02 ; Instructions with 1st nibble = 1001 ; SUBX (7) DC.W $9100,$F130 DC.B 'SUBX',0,0 DC.L U04 ; SUBA (6) DC.W $90C0,$F0C0 DC.B 'SUBA',0,0 DC.L U03 ; SUB (4) DC.W $9000,$F000 DC.B 'SUB',0,0,0 DC.L U02 ; Instructions with 1st nibble = 1011 ; CMPM (8) DC.W $B108,$F138 DC.B 'CMPM',0,0 DC.L U05 ; CMPA (6) DC.W $B0C0,$F0C0 DC.B 'CMPA',0,0 DC.L U03 ; EOR (5) DC.W $B100,$F100 DC.B 'EOR',0,0,0 DC.L U02 ; CMP (4) DC.W $B000,$F000 DC.B 'CMP',0,0,0 DC.L U02 ; Instructions with 1st nibble = 1100 ; EXG Dn,Dm. (10) DC.W $C140,$F1F8 DC.B 'EXG',0,0,0 DC.L U29DD ; EXG An,Am. (10) DC.W $C148,$F1F8 DC.B 'EXG',0,0,0 DC.L U29AA ; EXG Dn,An. (10) DC.W $C188,$F1F8 DC.B 'EXG',0,0,0 DC.L U29DA ; ABCD (9) DC.W $C100,$F1F0 DC.B 'ABCD',0,0 DC.L U26 ; MULS (7) DC.W $C1C0,$F1C0 DC.B 'MULS',0,0 DC.L U06 ; MULU (7) DC.W $C0C0,$F1C0 DC.B 'MULU',0,0 DC.L U06 ; AND (4) DC.W $C000,$F000 DC.B 'AND',0,0,0 DC.L U02 ; Instructions with 1st nibble = 1101 ; ADDX (7) DC.W $D100,$F130 DC.B 'ADDX',0,0 DC.L U04 ; ADDA (6) DC.W $D0C0,$F0C0 DC.B 'ADDA',0,0 DC.L U03 ; ADD (4) DC.W $D000,$F000 DC.B 'ADD',0,0,0 DC.L U02 ; Instructions with 1st nibble = 1110 ; ASL and ASR mem shifts (9) DC.W $E0C0,$FEC0 DC.B 'AS',0,0,0,0 DC.L U07 ; LSL and LSR mem shifts (9) DC.W $E2C0,$FEC0 DC.B 'LS',0,0,0,0 DC.L U07 ; ROXL and ROXR mem shifts (9) DC.W $E4C0,$FEC0 DC.B 'ROX',0,0,0 DC.L U07 ; ROL and ROR mem shifts (9) DC.W $E6C0,$FEC0 DC.B 'RO',0,0,0,0 DC.L U07 ; ASL and ASR reg shifts (6) DC.W $E000,$F018 DC.B 'AS',0,0,0,0 DC.L U08 ; LSL and LSR reg shifts (6) DC.W $E008,$F018 DC.B 'LS',0,0,0,0 DC.L U08 ; ROXL and ROXR reg shifts (6) DC.W $E010,$F018 DC.B 'ROX',0,0,0 DC.L U08 ; ROL and ROR reg shifts (6) DC.W $E018,$F018 DC.B 'RO',0,0,0,0 DC.L U08 ; This is the 'I have no idea' entry. DC.W 0,0 DC.B '?????',0 DC.L U00 ; UCCLST DC.B 'T ' DC.B 'F ' DC.B 'HI' DC.B 'LS' DC.B 'CC' DC.B 'CS' DC.B 'NE' DC.B 'EQ' DC.B 'VC' DC.B 'VS' DC.B 'PL' DC.B 'MI' DC.B 'GE' DC.B 'LT' DC.B 'GT' DC.B 'LE' ; ;*************************************************** ;End Unassemble Instructions ;*************************************************** ; ; Vectors to the command line routines CMD_ADR DC.L DUMP ;DUMP execution address DC.L GO DC.L EDIT DC.L MOOV DC.L HELP DC.L LD_FILE DC.L FILL DC.L HEXCALC DC.L REGMOD DC.L BEG_TRC ;tracing DC.L BREAK DC.L UNASM DC.L VERIFY ; The next command is for future command ; development in the RAM of the SBC ; DC.L FUTURE ; COMANDS DC.B 'D' DC.B 'G' DC.B 'E' DC.B 'M' DC.B '?' DC.B 'L' DC.B 'F' DC.B 'H' DC.B 'R' DC.B 'T' DC.B 'B' DC.B 'U' DC.B 'C' ; The next command is for future command ; development in the RAM of the SBC ; DC.B 'X' ; ; Messages go at end so that code word ; alignment won't get derailed mesgflg dc.b ' Flags: X = ',0 mesgn dc.b ', N = ',0 mesgz dc.b ', Z = ',0 mesgv dc.b ', V = ',0 mesgc dc.b ', C = ',0 ; MSG_1 DC.B 'Bus Error',0 MSG_2 DC.B 'Address Error before ',0 MSG_3 DC.B 'Illegal Instruction Error at ' DC.B 0 MSG_4 DC.B 'Divide by Zero Error before ',0 MSG_5 DC.B 'TRAPV Overflow',0 MSG_6 DC.B 'Privilege Violation',0 MSG_7 DC.B 'Level-7 Interrupt',0 MSG_8 DC.B CR,LF,'Breakpoint 1: ',0 MSG_9 DC.B CR,LF,'Breakpoint 2: ',0 MSG_10 DC.B 'Inactive',0 MSG_A DC.B 'Line 1010 emulator instruction encountered at ',0 MSG_F DC.B 'Line 1111 emulator instruction encountered at ',0 ; ; Help menu in response to typing a ? H_MSG1 DC.B CR,LF DC.B '*** 68EC000 CPU-based ' DC.B 'Single Board Computer ' DC.B '*** Monitor Version 3.00',CR,LF DC.B '====================================' DC.B '================================' DC.B CR,LF DC.B 'B <1 or 2> ' DC.B 'Set permanent breakpoint ' DC.B '1 or 2.',CR,LF DC.B 'B <1 or 2> ' DC.B 'Clear breakpoint 1 or 2.',CR,LF DC.B 'B ' DC.B 'Display permanent breakpoints.',CR,LF DC.B 'C ' DC.B 'Compare Memory',CR,LF DC.B 'D <#$ of lines> ' DC.B 'Dump Memory with optional ' DC.B 'parameters. ^C to quit.',CR,LF DC.B 'D , <#$ of lines> As ' DC.B 'above, but start at current address.' DC.B CR,LF DC.B 'E
' DC.B 'Edit Memory',CR,LF DC.B 'F ' DC.B 'Fill Memory',CR,LF DC.B 'G ' DC.B 'Go to USER program with op' DC.B 'tional breakpoints.',CR,LF DC.B 'G , ' DC.B 'As above but start at ' DC.B 'current program counter.' DC.B CR,LF DC.B 'G ' DC.B 'Start at current program ' DC.B 'counter, no breakpoints.' DC.B CR,LF DC.B 'H ' DC.B 'Hex sum & difference',CR,LF DC.B 'L ' DC.B 'Load S-FILE Program. ^C to abandon.' DC.B CR,LF DC.B 'M ' DC.B 'Move Memory',CR,LF DC.B 'R ' DC.B 'Register Dump',CR,LF DC.B 'R D7 ' DC.B 'Register Modify D7',CR,LF DC.B 'T ' DC.B 'Trace. >R Dn to modify any ' DC.B 'register while ',CR,LF DC.B ' ' DC.B 'tracing. Type to continue ' DC.B 'tracing.',CR,LF DC.B 'U <#$ of lines> ' DC.B 'Unassemble memory with optional ' DC.B 'parameters.',CR,LF DC.B 'U , <#$ of lines> As ' DC.B 'above, but start at current address.' DC.B CR,LF DC.B '? ' DC.B 'This Screen',0 ; BADCMD DC.B 'Bad Command.',0 INVDATA DC.B 'Invalid address or hex ' DC.B 'data.',0 HELLO DC.B CR,LF,'68EC000 Monitor, ' DC.B 'version 3.00',CR,LF,LF DC.B 'Type ? for help menu.' DC.B CR,LF,0 ; Load file error message LE_MSG DC.B 'There was an error ' DC.B 'loading the file.',0 LG_MSG DC.B ' HEX file loaded successfully.' DC.B CR,LF,0 LS_MSG DC.B CR,LF DC.B 'Start sending the file, ' DC.B '^C to abandon.' DC.B CR,LF,0 LF_MSG DC.B 'Loading file named ',0 HS_MSG DC.B CR,LF,'Sum = ',0 HD_MSG DC.B CR,LF,'Diff = ',0 BSSPBS dc.b 8,' ',8,0 REDOMSG DC.B CR,LF,'%',0 MSG_NIN DC.B CR,LF DC.B 'Program terminated at ' DC.B 'address ',0 MSG_TEN DC.B CR,LF DC.B 'Breakpoint encountered at ' DC.B 'address ',0 TRC_MSG DC.B 'TRAP instruction is next. ' DC.B 'Trace terminated.',0 PASSMSG DC.B CR,LF,'Comparison successful.',CR,LF,0 FAILMSG DC.B CR,LF,'Comparison failed.',CR,LF,0 SP24MSG DC.B ' ',0 PC_MSG DC.B 'PC: ',0 SR_MSG DC.B 'SR: ',0 UIMPMSG DC.B CR,LF,'This TRAP #15 task is not ' DC.B 'implemented!',0 ; ZEND DC.B 0 ; END START