thomasw@vlsi1.CS.Concordia.CA (Thomas Wieland 1728423) (10/18/89)
As promised several days ago, here is the source code for the 68000 monitor I wrote some time ago. Sorry that it took so long, but I had to upload it to my university account and then make it a bit more presentable. Thanks to George Kyriazis (kyriazis@rdrc.rpi.edu), druks!jamesc@att.att.com, and to Jeff Turner (jeff@uf.msc.umn.edu) who each provided me with a shar script or program and to Daniel Berglund (FOPERATOR@tekno.chalmers.se) who told me where I could get one. And yes, I had it installed on our systems. If you have any comments, feel free to drop me a line. Enjoy, Thomas Thomas Wieland Email: thomasw@jupiter.cs.concordia.ca Dept. of Computer Science or: thomasw@concour.cs.concordia.ca Concordia University Montreal, PQ Canada Phone: (514) 848-3039 ---------------------------------- clip here ---------------------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # README # MANIFEST # mon68.main.s # mon68.cmds.s # This archive created: Tue Oct 17 19:46:49 1989 export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'README'" '(10093 characters)' if test -f 'README' then echo shar: "will not over-write existing file 'README'" else cat << \SHAR_EOF > 'README' MON68K - A monitor for Motorola M68000-based systems ==================================================== Written by Thomas Wieland, 1984 Donated to the public domain, 17th October 1989 This file is is intended as a quick introduction to MON68K: what it is, how it came into being, some notes on the files etc. History ------- In 1983, I purchased a 68000 processor board for my Apple II; this board was called a DTACK (Grounded) board and was manufactured by a small company named Digital Acoustics in Santa Ana, CA. The board was designed as a single-board computer which was attached to the Apple through a simple parallel port; the board was simple, but fast: just the processor and some static memory running at 12.5 MHz (DTACK was grounded, therefore no waitstates). With the board came some sample programs, a couple of floating point libraries, and little else. Eventually, some programs were written by other owners, such as a Apple-based monitor and a BASIC compiler, and distributed through a software exchange. Probably the two most successful products used with the board were a 68000 crossassembler running on a basic Apple II (ie. without using the DTACK board, see below) and a very nice adaption of the Apple/UCSD p-system which ran completely on the 68000 side and used the Apple merely as an I/O processor. A few years later, with the advent of the Atari ST, Digital Acoustics stopped producing hardware, went into developping an incremental BASIC compiler for the ST, and that was the last I ever heard of them. The DTACK board was a bare-bones design, and provided only a boot PROM which supported commands to upload and download blocks of memory and to transfer control from the boot PROM to an address in 68K memory. Any program that was to run on the board therefore had to include a part which was to run on the Apple II which would upload and start the 68000 part and that had to support (as a minimum) commands for reading from the Apple keyboard and writing to the Apple screen as the DTACK board did not have any I/O connectors. I started developing MON68K to get a 68K-based monitor going on the DTACK board, and to familiarize myself with 68K assembly language. As there was no operating system on the 68K side of things, my design included two parts, one which was running on the Apple and provided a file system interface, and the other which was running on the DTACK board and was the monitor proper. I am only posting the code for the 68K monitor here, as it is pretty much self-contained and I don't think the Apple part is useful to anyone on this net. I finished writing the monitor in the middle of 1984 and released it through the software exchange, but after that I got too busy with moving to Canada and then going to school, that I never went back to doing much more with the DTACK board. That is also part of the reason it took me as long as it did to get the sources posted; not only did I first have to find them, I also had to then tranfer them between different Apple operating systems, and upload them to my account at university. Some Notes on the Assembler --------------------------- The assembler I was using to develop MON68K was called ASSEM68K from a company called Phase0 in (I believe) Arizona, no doubt long since gone. ASSEM68K was a floppy disk-based assembler which uses Apple II DOS 3.3; it produced a binary load image which could be transferred to the DTACK board by a utility program. I believe the assembler syntax is pretty much standard; I noticed, however, that the Sun-OS assembler (I don't know about other UNIX assemblers) combines the opcode and the operand size into one word (eg. movel, addw etc) whereas ASSEM68K separates the opcode and its size by a period (eg. MOVE.L, ADD.W); this latter is also the format used by the disassembler. In addition, ASSEM68K makes no distinction between upper- and lowercase as early Apple II's didn't have lowercase characters. By default, ASSEM68K assumes that the operand size is word, so the operand size for a word operand does not have to (but may be) specified; eg, ADD D0,D1 will be treated like ADD.W D0,D1. ASSEM68K also uses default settings for forward references when assembling code; these can be changed using the three pseudo-ops listed below. Backward references always assemble in the shortest possible address format. BRANCH S|W assemble forward branches with a byte (B) or word (W) offset FWRD W|L assemble forward operand references using a word (W) or longword (L) address. SHORT 7|F use short addressing up to $7FFF (7) or up to $FFFF (F) (*) Some of the assembler pseudo-ops provided by ASSEM68K are listed below to avoid any interpretation problems that might arise from other assemblers' syntax. ORG <expr>,<file> assemble object at address <expr> and save to <file> <lbl> EQU <expr> equate label <lbl> to the address given by <expr> DC.s <expr> define constant storage; reserves space for the constant and intializes it to <expr> DS.s <expr> define storage; reserve <expr> bytes, words, or longwords of unintialized storage CHAIN <file> chain to sourcefile <file> ASC <string> reserve string storage and initialize it to <string> ACZ <string> like ASC, but add a zero byte at the end of <string> LIST generate assembler listing and symbol table NOLIST suppress assembler listing and symbol table where: s=B|W|L a size specification: byte (B), word (W), longword (L) <lbl> a label name <expr> an expression <file> a file name <string> an ASCII string enclosed in single or double quotes (*) Note: the DTACK board includes some special address decoding hardware to fix the 68000's "zero page bug" (or feature), which results from sign-extending word-length addresses and which splits the 64K of memory which can be addressed using short (word) addresses into a low (0..$7FFF) and a high part ($FF8000..$FFFFFF). This hardware maps the high part back down into the address range $8000..$FFFF, reducing the total addressable space by 32K but resulting in a contiguous 64K zero page. The SHORT pseudo-op tells the assembler which zero page mapping is in effect; even though MON68K has been assembled with SHORT=F (64K zero page), it should not make a difference to the code as it doesn't extend past $3A00. MON68K Files ------------ As mentioned above, I had not looked at the source files for MON68K for more than five years at the time I offered posting them. As I don't have the time for it now, I have not edited them significantly and have not tried to improve or change the code at all. I would have done a few things differently now that I have done them once, especially in the disassembler, but for the time being I'm not going to change anything; at least I know for a fact that this version works and is reasonably bug-free. I did, however, split the source files up into more manageable parts and added some comments in places I felt it was necessary (ie. where I had trouble figuring out what was going on). I also commented out a selftest routine which was used by the Apple part of the code to determine if the monitor code had been corrupted and moved some routines into the hardware-specific file. There are also some chapters of the original disk-based manual included with this post (chapters dealing with the Apple part of the code were not included). I have not edited these at all, except for deleting some of the Apple-specific parts that I felt were not appropriate, so please excuse any spelling or grammatical mistakes in them. The following files were posted to the net: File name Contents -------------------------------------------------------------------------------- README this file MANIFEST list of files and file lengths mon68.main.s equates; cold/warm start, main command loop mon68.cmds.s subroutines implementing monitor commands mon68.csub.s aux. subroutines used by monitor command subroutines mon68.exce.s exception handlers mon68.dasm.s disassembler & disasm support routines mon68.spec.s hardware-specific subroutines; these rely on/are used by support routines on the host (6502) side mon68.io.s line editor & I/O subroutines mon68.tbl.s data area: vector/jump tables, text/mask tables for disassembler, monitor texts, monitor data area mon68.ch3.doc documents the available monitor commands mon68.ch5.doc documents some of the internals of the monitor routines mon68.qref quick reference to monitor commands and line editor control keys Last Words ---------- I hope the code will be of help to those of you who are doing a 68K-based project; I realize it will take some work to transfer it to other systems, but I think it is a reasonable starting point. I would appreciate any comments you may have about the monitor and would like to hear about any bugs you find and any uses that you put the code to. Of course, I would also be interested in seeing how others have solved the same problem. If you wish to contact me, you can write to me at the address below or send me e-mail (the account will be valid at least until April 90) at: thomasw@jupiter.cs.concordia.ca or: thomasw@concour.cs.concordia.ca Home Address: Thomas Wieland 4615 Walkley #21 Montreal, PQ H4B 2K7 Canada =============================================================================== Thomas Wieland Email: thomasw@jupiter.cs.concordia.ca Dept. of Computer Science or: thomasw@concour.cs.concordia.ca Concordia University Montreal, PQ Canada Phone: (514) 848-3039 SHAR_EOF if test 10093 -ne "`wc -c < 'README'`" then echo shar: "error transmitting 'README'" '(should have been 10093 characters)' fi fi echo shar: "extracting 'MANIFEST'" '(228 characters)' if test -f 'MANIFEST' then echo shar: "will not over-write existing file 'MANIFEST'" else cat << \SHAR_EOF > 'MANIFEST' README 10093 MANIFEST 228 mon68.main.s 7708 mon68.cmds.s 20768 mon68.csub.s 11276 mon68.exce.s 8040 mon68.dasm.s 17308 mon68.spec.s 3606 mon68.io.s 16417 mon68.tbl.s 7821 mon68.ch3.doc 39010 mon68.ch5.doc 30933 mon68.qref 5665 SHAR_EOF if test 228 -ne "`wc -c < 'MANIFEST'`" then echo shar: "error transmitting 'MANIFEST'" '(should have been 228 characters)' fi fi echo shar: "extracting 'mon68.main.s'" '(7708 characters)' if test -f 'mon68.main.s' then echo shar: "will not over-write existing file 'mon68.main.s'" else cat << \SHAR_EOF > 'mon68.main.s' **************************** * * * MON68K * * * * A 68000 Monitor Program * * * * VERSION 2.2 15-JUL-84 * * * **************************** * * * mon68.main.s: equates; cold/warm start, main command loop * * * Source code donated to the public domain, 17 Oct 1989 * * You may use this code in any way you see fit, including * incorporating some or all of it into a project of your own, * commercial or otherwise. I would appreciate receiving some * credit if you decide to use some of my code, but as this is * quite unenforceable it remains a wish, not a condition. * * Naturally, I can make no guarantees as to the code's correctness * or suitability for any purpose, although I would hope that it is * both reasonably correct and suitable for something, and I know * that it works on my equipment. * * If you wish to contact me, you can write to me at the address * below or send me e-mail (until April 90) at: * * thomasw@jupiter.cs.concordia.ca * or: thomasw@concour.cs.concordia.ca * * Written by: Thomas Wieland * 4615 Walkley #21 * Montreal, PQ * H4B 2K7 * Canada * * * * * SET ASSEMBLER SWITCHES * BRANCH S FWRD W SHORT F * * ORG $10F4,MON68K * * * ASCII CONSTANTS * NUL EQU $00 ;ASCII NUL BEL EQU $07 BS EQU $08 ;BACKSPACE CR EQU $0D ;CARRIAGE RETURN SPC EQU $20 ;BLANK DQT EQU $22 ;DOUBLE QUOTE SQT EQU $27 ;SINGLE QUOTE * * FLAG DEFINITIONS FOR FLAGREGISTER (D7) * CURSOR EQU 0 ;CURSOR CHAR. VALID INSMOD EQU 1 ;INSERT MODE DELIM EQU 0 ;BLANKS ARE DELIMITERS ASCTYP EQU 1 ;0/1=LOW/HIGH ASCII ASCLST EQU 2 ;INSIDE OF ASCII LIST NUMFND EQU 3 ;GETNUM FOUND NUMBER SADR EQU 4 ;STARTADR. SPECIFIED EADR EQU 5 ;ENDADR. SPECIFIED TBLERR EQU 6 ;ERROR COND IN TABLE S/R EXTTBL EQU 7 ;EXTENDED TABLE * * DTACK BOARD EQUATES * IDLE EQU $122 ;BOOT PROM IDLE ROUTINE * DATIN EQU $FF8 ;DATA INPUT PORT * NOTE: R/W DECODES TO DIFFERENT PORTS DATOUT EQU $FFA ;DATA OUTPUT PORT (W) STATUS EQU $FFA ;I/O STATUS PORT (R) * VECTOR EQU $1000 ;EXCEPTION VECTOR TABLE PRIVVI EQU $1024 ;PRIV. VIOLATION VECTOR DISASMSP EQU $10AE ;TEMP. SP FOR DISASSEMBLER SYSREG EQU $10B2 ;SAVE AREA FOR PROC.REGS SYSSP EQU SYSREG+60 ;STACK POINTER SYSSTAT EQU SYSREG+64 ;SAVE AREA FOR STAT.REG * * MONITOR EQUATES * NTBL EQU 8 ;Number of ENTRIES IN monitor TABLES (1..NTBL) * * Note: $37E0 is no "magic number", it's just an address that * leaves a reasonable amount of stack space after the * end of the code as determined by assembling the code * and looking at where it ends. This could be done more * elegantly using symbols, but the assembler I was using * at the time couldn't handle all the forward references. * INBUF EQU $37E0 ;also top of monitor stack area LSTBUF EQU INBUF+$100 ;for byte lists * PROGRAM FLAGS (LAST THREE BYTES OF LSTBUF ARE NEVER USED) TRCFLAG EQU LSTBUF+$FE ;GO/TRACE/SINGLE STEP FLAG PROMPT EQU LSTBUF+$FF ;CURRENT PROMPT CHARACTER BITBUF EQU LSTBUF+$100 ;flags wildcards in byte list BUFTOP EQU BITBUF+$20 ;last byte+1 of buffers * * * ********************************* * BOOT PROM COMMAND VECTORTABLE * ********************************* * CMD10 DC.W CLDSTRT ;COLDSTART ENTRY POINT CMD11 DC.W WRMSTRT ;WARMSTART ENTRY POINT CMD12 DC.W STEST68 ;TEST 68000 CODE (FROM 6502) CMD13 DC.W MEMSIZE ;DETERMINE MEMORY SIZE CMD14 DC.W MONENTP ;GET MONITOR ENTRY POINTS * * UNUSED VECTORS GO BACK TO IDLE * CMD15 DC.W IDLE CMD16 DC.W IDLE CMD17 DC.W IDLE CMD18 DC.W IDLE CMD19 DC.W IDLE CMD1A DC.W IDLE CMD1B DC.W IDLE CMD1C DC.W IDLE CMD1D DC.W IDLE CMD1E DC.W IDLE CMD1F DC.W IDLE CMD20 DC.W IDLE * * ********************************* * MONITOR COLDSTART ENTRY POINT * ********************************* * * CLDSTRT MOVEA #INBUF,SP ;SET SSP JSR MEMSIZE ;DETERMINE MEMORY SIZE MOVE.L A0,RAMHIGH ;SAVE HIGHEST RAM ADDRESS MOVE.L A0,CMDHIGH ;SET UPPER LIMIT FOR COMMANDS MOVE.L A0,HILIM ;SET UPPER LIMIT FOR EXECUTION JSR PRTCLSC ;CLEAR SCREEN MOVE #HEADTXT,A0 JSR PRTTEXT ;SEND HEADER MOVE.L RAMLOW,D2 JSR PRTLHEX ;DISPLAY LOW RAM ADDRESS JSR PRTTEXT ;SECOND PART OF TEXT MOVE.L RAMHIGH,D2 JSR PRTLHEX ;DISPLAY HIGH RAM ADDRESS JSR PRTTEXT ;THIRD PART OF TEXT * * ********************************* * MONITOR WARMSTART ENTRY POINT * ********************************* * * WRMSTRT MOVEA #INBUF,SP ;SET SSP TO BOTTOM OF BUFFERS MOVEA #EVECTBL,A0 MOVEA #VECTOR+4,A1 MOVEQ #26-1,D0 ;26 EXCEPTION VECTORS SETEVECT MOVE (A0)+,(A1)+ ;SET JUMPS TO EXCEPTION HANDLERS ADDQ #4,A1 DBF D0,SETEVECT WRMSTRT1 MOVE.B #'M',PROMPT ;SET MONITOR PROMPT JSR GETLIN ;GET LINE OF INPUT * ************************** * MAIN COMMAND PROCESSOR * ************************** * CMDPROC MOVEQ #0,D7 ;CLEAR FLAGS MOVE A5,-(SP) ;SAVE TXTPTR JSR GETCHRNS BVC CMDPROC1 ADDQ #2,SP ;DROP TXTPTR BRA WRMSTRT1 ;INPUT LINE WAS EMPTY OR ALL BLANKS CMDPROC1 CMPI.B #'A',D0 BCS CMDPROC3 ;CHAR < 'A' CMPI.B #'B',D0 BHI CMDPROC3 ;CHAR > 'B' JSR GETCHRNS ;GET SECOND CHAR. BVS CMDPROC2 ;'A' OR 'B' SUBMODE CMPI.B #';',D0 BNE CMDPROC3 ;CAN'T BE 'A' OR 'B' SUBMODE CMDPROC2 MOVEA (SP)+,A5 JSR GETCHRNS ;GET COMMAND LETTER SUBQ #1,A5 ;POINT A5 TO CMD CHAR. BRA CMDPROC7 ;EXECUTE COMMAND CMDPROC3 MOVE (SP)+,A5 ;RESTORE TXTPTR JSR GETNUM ;GET FIRST ADDRESS BTST #NUMFND,D7 BEQ CMDPROC4 ;NO NUMBER WAS FOUND BSET #SADR,D7 ;SIGNAL & MOVEA.L D1,A1 ;SAVE START ADDRESS (CCR UNAFFECTED) CMDPROC4 BVS CMDPROC6 ;SINGLE ADDRESS => EXAMINE CMPI.B #'.',D0 BNE CMDPROC7 ;D0 MUST BE CMDLETTER NOW ADDQ #1,A5 ;ADVANCE TO NEXT CHAR. JSR GETNUM ;GET SECOND ADDRESS BTST #NUMFND,D7 BNE CMDPROC5 BSR ERROR2 ;'.' MUST BE FOLLOWED BY ADDRESS BRA CMDPROC CMDPROC5 BSET #EADR,D7 ;SIGNAL & MOVEA.L D1,A2 ;SAVE END ADDRESS (CCR UNAFFECTED) BVC CMDPROC7 ;TWO ADDRESSES MUST BE FOLLOWED BY A CMD LETTER CMDPROC6 MOVEQ #'X',D0 ;SET X(AMINE AS DEFAULT CMDPROC7 MOVE #CMDTEND-CMDTBL,D1 ;COUNT= NO. OF CMDLETTERS-1 MOVEA #CMDTEND+1,A0 ;+1 FOR PREDECR. CMDPROC8 CMP.B -(A0),D0 BEQ CMDPROC9 ;COMMAND LETTER FOUND DBF D1,CMDPROC8 ;LOOP THROUGH ALL CMD LETTERS BSR ERROR1 ;NO COMMAND LETTER FOUND BRA CMDPROC CMDPROC9 ADD D1,D1 ;DOUBLE TO USE AS INDEX MOVEA D1,A0 MOVE JMPTBL(A0),A0 ;GET SUBROUTINE ADDRESS JSR (A0) ;EXECUTE COMMAND SUBROUTINE BRA CMDPROC ;GET NEXT COMMAND * * ERROR #n * ERROR1 MOVEQ #1,D0 BRA ERRHDL ERROR2 MOVEQ #2,D0 BRA ERRHDL ERROR3 MOVEQ #3,D0 BRA ERRHDL ERROR4 MOVEQ #4,D0 BRA ERRHDL ERROR5 MOVEQ #5,D0 * * ERROR HANDLER * D0.B : ERROR CODE * (SP) : RETURN ADDRESS FOR CONT'D EXECUTION * ERRHDL CMPA A5,A6 ;AT END OF BUFFER ? BNE ERRHDL1 SUBQ #1,A5 ;DON'T PRINT CR ERRHDL1 ADDQ #1,A5 ;CHAR. AFTER ERROR MOVE.B (A5),D1 ;SAVE BUFFER CONTENTS MOVE D1,-(SP) MOVE D0,-(SP) ;SAVE ERROR CODE CLR.B (A5) ;MARK END OF TEXT MOVEA #INBUF,A0 ;SET TO START OF BUFFER JSR PRTCR JSR PRTTEXT ;PRINT CONTENTS OF BUFFER JSR PRTEOP ;CLEAR TO EOP JSR PRTLF JSR PRTBS MOVEQ #'^',D0 JSR SENDBYTE ;MARK ERROR POSITION JSR PRTCR JSR PRTBEL MOVE #ERRTXT,A0 ;SET TO START OF ERROR TABLE MOVE (SP)+,D0 ;GET ERROR CODE BACK BRA ERRHDL3 ERRHDL2 MOVE.B (A0)+,D1 ;SET A0 TO START BNE ERRHDL2 ;OF ERROR MESSAGE ERRHDL3 DBF D0,ERRHDL2 JSR PRTTEXT ;PRINT ERROR MESSAGE MOVE #ERRTXT1,A0 JSR PRTTEXT MOVE (SP)+,D0 ;RESTORE BUFFER MOVE.B D0,(A5) SUBQ #1,A5 MOVEQ #6,D0 JSR PRTSFCT ;6=GET 'Y' OR 'N' JSR GETBYTE ;GET ANSWER MOVE D0,D1 ;SAVE ANSWER JSR PRTCR CMPI.B #'Y',D1 BEQ ERRHDL5 ;YES, CONTINUE ERRHDL4 ADDQ #4,SP ;DROP RETURN ADDRESS BRA WRMSTRT1 ;GET NEW LINE * ERRHDL5 JSR SKIPNXT ;SKIP UNTIL ';' BVS ERRHDL4 RTS ;CONTINUE WITH NEXT CMD * * CHAIN MON68.CMDS.S SHAR_EOF if test 7708 -ne "`wc -c < 'mon68.main.s'`" then echo shar: "error transmitting 'mon68.main.s'" '(should have been 7708 characters)' fi fi echo shar: "extracting 'mon68.cmds.s'" '(20768 characters)' if test -f 'mon68.cmds.s' then echo shar: "will not over-write existing file 'mon68.cmds.s'" else cat << \SHAR_EOF > 'mon68.cmds.s' **************************** * * * MON68K * * * * A 68000 Monitor Program * * * * VERSION 2.2 15-JUL-84 * * * **************************** * * * mon68.cmds.s: subroutines implementing monitor commands * * * Source code donated to the public domain, 17 Oct 1989 * * You may use this code in any way you see fit, including * incorporating some or all of it into a project of your own, * commercial or otherwise. I would appreciate receiving some * credit if you decide to use some of my code, but as this is * quite unenforceable it remains a wish, not a condition. * * Naturally, I can make no guarantees as to the code's correctness * or suitability for any purpose, although I would hope that it is * both reasonably correct and suitable for something, and I know * that it works on my equipment. * * If you wish to contact me, you can write to me at the address * below or send me e-mail (until April 90) at: * * thomasw@jupiter.cs.concordia.ca * or: thomasw@concour.cs.concordia.ca * * Written by: Thomas Wieland * 4615 Walkley #21 * Montreal, PQ * H4B 2K7 * Canada * * * * * ';' SEPARATES COMMANDS * COLON ADDQ #1,A5 ;ADVANCE TO NEXT CHAR. RTS * * TEST FOR FIRST, GET SECOND OPERAND * TSTOP BTST #SADR,D7 BNE TSTOP1 ;1.OPERAND GIVEN MOVEA.L LASTRES,A1 ;DEFAULT: LAST RESULT TSTOP1 BTST #EADR,D7 BNE TSTOP3 ;2.OPERAND NOT ALLOWED ADDQ #1,A5 ;ADVANCE TO CHAR. AFTER OPERATOR JSR GETNUM ;2.OPERAND IN D1.L BTST #NUMFND,D7 BEQ TSTOP2 ;2.OPERAND NOT GIVEN MOVE.L A1,D2 ;1.OPERAND IN D2.L RTS TSTOP2 ADDQ #4,SP ;DROP RETURN ADR. BRA ERROR3 ;RETURNS TO CMDPROC TSTOP3 ADDQ #4,SP BRA ERROR4 * * SIGNAL ARITHMETIC OVERFLOW * OVL MOVEQ #'C',D0 OVL0 JSR SENDBYTE MOVEQ #'=',D0 JSR SENDBYTE MOVEQ #'1',D0 JSR SENDBYTE ;SEND 'C=1' OR 'V=1' JSR PRTBEL JMP PRTCR ;EXIT * * ADD TWO OPERANDS * PLUS BSR TSTOP ADD.L D1,D2 BCC.L SAVERES BCS MINUS1 ;SIGNAL CARRY * * SUBTRACT TWO OPERANDS * MINUS BSR TSTOP SUB.L D1,D2 BCC SAVERES MINUS1 BSR OVL ;SIGNAL BORROW BRA SAVERES * * MULTIPLY TWO 16 BIT OPERANDS * MULT BSR TSTOP TST D1 BEQ MULT0 ;2.OP=0 TST D2 BEQ MULT0 ;1.OP=0 MULU D1,D2 BRA SAVERES MULT0 MOVEQ #0,D2 ;RESULT=0 BRA SAVERES * * DIVIDE A 32 BIT BY A 16 BIT OPERAND * DIVID BSR TSTOP TST D1 BEQ ERROR5 ;DIVIDE BY 0 TST.L D2 BEQ MULT0 ;1.OPERAND=0 DIVU D1,D2 ;HIGH/LOW WORD=D2 MOD D1/D2 DIV D1 BVC DIVID1 MOVEQ #'V',D0 BSR OVL0 ;OPERAND OR RESULT OVERFLOW SWAP D2 CLR.W D2 ;CLEAR 'MODULO' SWAP D2 DIVID1 SWAP D2 MOVE D2,-(SP) ;SAVE D2 MOD D1 CLR.W D2 SWAP D2 BSR SAVERES ;DISPLAY & SAVE D2 DIV D1 MOVEQ #0,D2 MOVE (SP)+,D2 BRA CONVERT0 ;DISPLAY D2 MOD D1 & EXIT * * SHIFT OPERAND LEFT BY COUNT * SHFTL BSR TSTOP LSL.L D1,D2 BRA SAVERES * * SHIFT OPERAND RIGHT BY COUNT * SHFTR BSR TSTOP LSR.L D1,D2 BRA SAVERES * * ROTATE OPERAND LEFT BY COUNT * ROL BSR TSTOP ROL.L D1,D2 BRA SAVERES * * ROTATE OPERAND RIGHT BY COUNT * ROR BSR TSTOP ROR.L D1,D2 BRA SAVERES * * LOGICAL AND TWO OPERANDS * AND BSR TSTOP AND.L D1,D2 BRA SAVERES * * LOGICAL OR TWO OPERANDS * OR BSR TSTOP OR.L D1,D2 BRA SAVERES * * LOGICAL EOR TWO OPERANDS * EOR BSR TSTOP EOR.L D1,D2 * * SAVE RESULT OF OPERATION & PRINT IT * SAVERES MOVE.L D2,LASTRES BRA CONVERT0 * * CONVERT 32-BIT DATA * CONVERT BTST #SADR,D7 BEQ ERROR3 ;NO DATA BTST #EADR,D7 BNE ERROR4 ;2.OPERAND NOT ALLOWED ADDQ #1,A5 ;ADVANCE TO CHAR. AFTER "=" MOVE.L A1,D2 ;GET DATA CONVERT0 JSR PRTEOL ;CLEAR LINE JSR PRTDOL JSR PRTLHEX ;DISPLAY AS HEX MOVEQ #16,D0 BSR HTABN ;POS. FOR DECIMAL JSR PRTPND JSR PRTLDEC ;DISPLAY AS DECIMAL MOVEQ #32,D0 BSR HTABN ;POS. FOR ASCII JSR PRTLASC ;DISPLAY AS ASCII JSR PRTCR JSR PRTEOL JSR PRTPCT JSR PRTLBIN ;DISPLAY AS BINARY JMP PRTCR ;NEW LINE & RETURN * HTABN MOVE D0,-(SP) ;SAVE HTAB MOVEQ #3,D0 JSR PRTSFCT ;3=HTAB n MOVE (SP)+,D0 ;GET HTAB JMP SENDBYTE ;SEND COUNT & RETURN * * ASSEMBLER SUBMODE * ASMSUB MOVE.B #'A',PROMPT ADDQ #1,A5 MOVEQ #0,D0 BRA ERRHDL ;NOT IMPLEMENTED * * BREAKPOINT SUBMODE * BRKSUB MOVE.B #'B',PROMPT ADDQ #1,A5 BRKSUB1 JSR GETCHRNS ;GET FIRST CHAR BVC BRKSUB2 JSR GETLIN BRA BRKSUB1 BRKSUB2 CMPI.B #';',D0 BEQ BRKSUB1 ;SKIP COLONS CMPI.B #'Q',D0 BEQ.L BRKSUB8 ;EXIT BREAKPOINT SUBMODE CMPI.B #'K',D0 BEQ.L CLRBRK ;KILL BREAKPOINT TABLES CMPI.B #'P',D0 BEQ.L DSPBRK ;SHOW ALL BREAKPOINTS CMPI.B #'L',D0 BEQ.L SETLLIM ;SET LOW LIMIT CMPI.B #'H',D0 BEQ.L SETHLIM ;SET HIGH LIMIT CMPI.B #'M',D0 BEQ.L SETMBRK ;SET MEMORY BREAKPOINT CMPI.B #'X',D0 BEQ.L DELBRK ;DELETE (MEM) BREAKPOINT BRKSUB3 SUBQ #1,A5 BSR GETBRK ;GET ADDRESS OF BREAKPOINT CMPI.B #',',D0 ;GETNUM RETURNS NEXT CHAR. <> ' ' BNE BRKSUB4 ;NO COUNT GIVEN MOVE.L D1,D3 ;SAVE ADDRESS ADDQ #1,A5 BSR GETBRK ;COUNT MUST FOLLOW NOW MOVE D1,D2 ;SET COUNT MOVE.L D3,D1 ;RESTORE ADDRESS BRA BRKSUB5 BRKSUB4 MOVEQ #0,D2 ;SET COUNT=0 BRKSUB5 BSR MAKEEVEN MOVEA #BRKTBL,A3 ;SET TABLE ADDRESS BCLR #EXTTBL,D7 JSR ADDTBL ;ADD BREAKPOINT MOVEA #BTBLTXT,A0 BRKSUB6 BTST #TBLERR,D7 BEQ BRKSUB7 JSR PRTTEXT ;ERROR: TABLE FULL ADDQ #6,A0 JSR PRTTEXT BRKSUB7 JSR SKIPNXT BRA BRKSUB1 BRKSUB8 RTS BRKERR JSR PRTBEL ;ERROR IN COMMAND BRA BRKSUB7 * CLEAR BREAKPOINT TABLES CLRBRK MOVEA #LWLIM,A3 MOVEA #MBRKXTBL,A4 MOVE.L #BUFTOP,(A3)+ ;RESET LOW LIMIT MOVE.L RAMHIGH,(A3)+ ;RESET HIGH LIMIT BCLR #EXTTBL,D7 JSR CLRTBL ;CLEAR BRK TABLE BSET #EXTTBL,D7 JSR CLRTBL ;CLEAR MEMBRK & EXTENDED TABLES BRA BRKSUB7 * GETBRK JSR GETNUM ;GET ADDRESS BRA GETBRKS1 * GETBRKS JSR GETADRS ;GET ADDRESS + SIZE GETBRKS1 BTST #NUMFND,D7 BEQ GETBRKS2 ;NO ADDRESS GIVEN RTS GETBRKS2 ADDQ #4,SP ;DROP RETURN ADDRESS BRA BRKERR ;ERROR & NEXT COMMAND * SET LOW LIMIT SETLLIM BSR GETBRK BSR MAKEEVEN MOVE.L D1,LWLIM ;SET LOW LIMIT FOR EXECUTION BRA BRKSUB7 * SET HIGH LIMIT SETHLIM BSR GETBRK BSR MAKEEVEN MOVE.L D1,HILIM ;SET HIGH LIMIT FOR EXECUTION BRA BRKSUB7 * MAKE ADDRESS IN D1 EVEN MAKEEVEN BCLR #0,D1 RTS * SET MEMORY BREAKPOINT SETMBRK BSR GETBRKS ;GET ADR & SIZE JSR GETCHRNS CMPI.B #',',D0 BNE BRKERR ;',' MUST FOLLOW MOVE.L D1,-(SP) ;SAVE ADR FIELD MOVE D2,-(SP) ;SAVE TAG FIELD JSR GETNUM ;GET CONTENTS FIELD MOVE.L D1,D3 MOVE (SP)+,D2 ;RESTORE TAG FIELD MOVE.L (SP)+,D1 ;RESTORE ADR FIELD BTST #NUMFND,D7 BEQ BRKERR ;CONTENTS FIELD MUST FOLLOW CMPI.B #2,D2 BHI SETMBRK2 ;SIZE = LONG BEQ SETMBRK1 ;SIZE = WORD ANDI.W #$00FF,D3 ;SIZE = BYTE SETMBRK1 SWAP D3 CLR.W D3 ;CLEAR UPPER WORD SWAP D3 SETMBRK2 CMPI.B #1,D2 BEQ SETMBRK3 BSR MAKEEVEN SETMBRK3 MOVEA #MBRKTBL,A3 ;SET TABLE ADDRESSES MOVEA #MBRKXTBL,A4 BSET #EXTTBL,D7 JSR ADDTBL ;ADD MEM BRKPNT TO TABLES MOVEA #MBTBLTXT,A0 ;SET ERROR MESSAGE BRA BRKSUB6 ;TEST FOR ERROR & CONTINUE * DELETE A BREAKPOINT DELBRK BSR GETBRK ;GET ADDRESS TO DELETE MOVEA #BRKTBL,A3 BCLR #EXTTBL,D7 JSR DELTBL ;TRY TO DELETE IN BRK TABLE BTST #TBLERR,D7 BEQ BRKSUB7 ;ENTRY FOUND MOVEA #MBRKXTBL,A4 BSET #EXTTBL,D7 JSR DELTBL ;TRY TO DELETE IN MEMBRK TABLE BRA BRKSUB7 * DISPLAY ALL TABLES DSPBRK JSR PRTCR MOVEA #BRKTXT,A0 JSR PRTTEXT MOVEA #BRKTBL,A3 BSR.L DBRKTST ;TEST FOR ENTRIES MOVEQ #NTBL-1,D5 DSPBRK1 MOVE.L (A3)+,D2 ;GET TABLE ENTRY MOVE.W (A3)+,D4 BMI DSPBRK2 ;EMPTY ENTRY, FINISHED BSR.L DBRKADR MOVEQ #SPC,D0 MOVEQ #4,D3 JSR PRTNCHR ;PRINT 4 SPACES MOVE.B D4,D1 JSR PRTDOL ;PRINT COUNT JSR PRTHEX ;IN HEX JSR PRT2SPC JSR PRTPND JSR PRTDEC ;AND DECIMAL JSR PRTCR DBF D5,DSPBRK1 DSPBRK2 JSR PRTCR MOVEA #MBRKTXT,A0 JSR PRTTEXT MOVEA #MBRKTBL,A3 MOVEA #MBRKXTBL,A4 BSR DBRKTST MOVEQ #NTBL-1,D5 DSPBRK3 MOVE.L (A3)+,D2 ;GET ADDRESS MOVE.W (A3)+,D3 ;GET SIZE BMI DSPBRK7 ;EMPTY ENTRY, FINISHED MOVE.L (A4)+,D4 ;GET CONTENTS BSR DBRKADR MOVEQ #'.',D0 JSR SENDBYTE MOVE.L D4,D2 ;GET CONTENTS SUBQ.B #2,D3 ;TEST SIZE BHI DSPBRK5 ;SIZE = LONG BEQ DSPBRK4 ;SIZE = WORD MOVEQ #'B',D0 BSR DBRKSIZE MOVE.B D2,D1 ;GET BYTE TO DISPLAY JSR PRTHEX ;PRINT DATA BYTE BRA DSPBRK6 DSPBRK4 MOVEQ #'W',D0 BSR DBRKSIZE JSR PRTWHEX ;PRINT DATA WORD BRA DSPBRK6 DSPBRK5 MOVEQ #'L',D0 BSR DBRKSIZE JSR PRTLHEX ;PRINT DATA LONGWORD DSPBRK6 JSR PRTCR DBF D5,DSPBRK3 DSPBRK7 JSR PRTCR MOVEA #LADRTXT,A0 JSR PRTTEXT ADDQ #4,A0 MOVE.L LWLIM,D2 BSR DBRKLIM ;PRINT LOW LIMIT MOVEA #HADRTXT,A0 MOVE.L HILIM,D2 BSR DBRKLIM ;PRINT HIGH LIMIT BRA BRKSUB7 * TEST IF >=1 ENTRY IN TABLE DBRKTST TST.B 4(A3) BMI DBRKTST1 ;NO ENTRY JMP PRTCR DBRKTST1 JMP PRTTEXT * DISPLAY ENTRY NUMBER & ADDRESS DBRKADR MOVEQ #NTBL,D1 SUB.B D5,D1 ;CALC. ENTRY NO., 1..NTBL JSR PRTPND JSR PRTDEC ;ENTRY # (3 CHAR.S) JSR PRTSPC JSR PRTDOL JMP PRTLHEX ;ADDRESS * DISPLAY SIZE DBRKSIZE JSR SENDBYTE JSR PRT2SPC JMP PRTDOL * DISPLAY TEXT & LOW/HIGH ADDRESS DBRKLIM JSR PRTTEXT JSR PRTLHEX JMP PRTCR * * CHANGE MEMORY FROM SADR TO BYTES IN LIST * CHANGE JSR SADRNXT ADDQ #1,A5 ;ADVANCE TO START OF LIST JSR GETLIST TST.B D2 BEQ CHANGE5 ;EMPTY LIST, EXIT CHANGE0 SUBQ #1,D2 ;ADJUST INDEX CHANGE1 CMPA A3,A4 BHI CHANGE2 MOVEA D3,A3 ;RESET TO START OF LSTBUF CHANGE2 MOVE.B (A3)+,D1 ;GET BYTE BNE CHANGE3 JSR TSTWCD ;IS IT ZERO OR WILDCARD ? BNE CHANGE6 CHANGE3 MOVE.B D1,(A1)+ ;CHANGE MEMORY CHANGE4 DBF D2,CHANGE1 MOVE.L A1,NXTADR ;SAVE DEFAULT ADDRESS CHANGE5 RTS CHANGE6 ADDQ #1,A1 ;WILDCARD, LEAVE MEMORY ALONE BRA CHANGE4 * * EXECUTE USER PROGRAM * GOUSER JSR SADRPC ;GET SADR ADDQ #1,A5 ;ADVANCE TO NEXT CHAR JSR GETCHRNS BVS GOUSER2 ;ONLY ONE 'G' CMPI.B #'G',D0 BNE GOUSER1 BSET #5,USRSTAT ;SET SUPERVISOR MODE BCLR #7,USRSTAT ;NO TRACE BSR GETSP MOVE.L #RTNSUP,-(A0) ;SET SUPERVISOR RETURN ADDRESS SUBQ.L #4,A0 ;SET TO DUMMY RETURN ADR MOVE.L A0,SP ;SET SSP BRA GOUSER4 GOUSER1 SUBQ #1,A5 ;ADJUST TXTPTR GOUSER2 CLR.B TRCFLAG ;0 <=> GO GOUSER3 BCLR #5,USRSTAT ;SET USER MODE BSET #7,USRSTAT ;INVISIBLE TRACE BSR GETSP MOVE.L #RTNUSR,-(A0) ;SET USER RETURN ADDRESS SUBQ.L #4,A0 ;SET TO DUMMY RETURN ADR MOVE A0,USP GOUSER4 MOVE.L A1,(A0) ;SET START ADDRESS MOVEM.L USRREG,D0-A6 ;SET UP USRREGS MOVE USRSTAT,SR RTS ;START TRACE AT (A1) * SAVE PROCESSOR REGISTERS, * GET & CHECK USER STACKPOINTER GETSP MOVEM.L D0-A6,SYSREG ;SAVE SYSTEM REGS MOVE SR,SYSSTAT MOVE.L SP,A0 ADDQ.L #4,A0 ;ADJUST FOR RETURN ADDRESS MOVE.L A0,SYSSP MOVE.L USRSP,D0 ;GET USER STACKPOINTER MOVE.L RAMHIGH,D1 ADDQ.L #1,D1 ;SET TO HIGHEST POSSIBLE SP CMPI.L #BITBUF,D0 BCS GETSP1 ;USP < BITBUF CMP.L D1,D0 BLS GETSP2 ;USP <= RAMHIGH+1 GETSP1 MOVE.L D1,D0 ;SET USP TO TOP OF RAM GETSP2 BCLR #0,D0 ;WORD-ALIGN USP MOVE.L D0,A0 RTS * * HELP FACILITY * HELP MOVEQ #8,D0 JSR PRTSFCT ;8=HELP ADDQ #1,A5 JSR GETCHRNS BVS HELPALL CMPI.B #';',D0 BEQ HELPALL HELP1 JMP SENDBYTE ;SEND (OPTIONAL) PARAMETER HELPALL MOVEQ #SPC,D0 ;ALL COMMANDS BRA HELP1 * * INSERT BYTELIST AT START ADDRESS, MOVE MEMORY * INSERT JSR EADRLST EXT.L D2 ;CLEAR HIGH WORD MOVE.L A1,-(SP) ;SAVE SADR (DESTROYED BY MOVE) MOVE.L A1,A3 ADDA.L D2,A3 ;DADR=SADR+NO. OF BYTES CMPA A3,A2 BCS INSERT1 ;DON'T MOVE IF DADR>EADR SUBA.L D2,A2 ;EADR=EADR-NO. OF BYTES JSR MOVE0 ;MOVE RANGE UP INSERT1 MOVE.L (SP)+,A1 MOVE D3,A3 ;RESTORE POINTER TO LSTBUF BRA CHANGE0 ;NOW INSERT BYTELIST * * FILL MEMORY FROM SADR THROUGH EADR WITH PATTERN IN LIST * FILL JSR EADRLST SUBQ.B #1,D2 BEQ FILLB ;ONLY ONE BYTE IN LIST FILL1 CMPA.L A1,A2 BCS FILL5 ;END OF RANGE CMPA A3,A4 BHI FILL2 MOVE D3,A3 ;RESET LIST POINTER TO START FILL2 MOVE.B (A3)+,D1 ;GET BYTE FROM LIST BNE FILL3 ;CAN'T BE WILDCARD JSR TSTWCD BNE FILL4 ;CHAR. IS WILDCARD FILL3 MOVE.B D1,(A1)+ ;FILL MEMORY BRA FILL1 FILL4 ADDQ.L #1,A1 ;ADVANCE TO NEXT BYTE BRA FILL1 FILL5 MOVE.L A1,NXTADR ;SAVE DEFAULT ADDRESS FILL6 RTS * LIST IS ONLY ONE BYTE FILLB MOVEA D4,A4 ;SET TO BITBUF BTST D2,(A4) ;D2=0, TEST BIT 0 FOR ONLY BYTE BNE FILL6 ;THE ONLY BYTE IS A WILDCARD MOVE.B (A3)+,D1 ;GET BYTE FILLB1 CMPA.L A1,A2 BCS FILL5 ;END OF RANGE MOVE.B D1,(A1)+ ;FILL MEMORY BRA FILLB1 * * DISASSEMBLE RANGE OF INSTRUCTIONS * LIST JSR SADRPC ;GET START ADDRESS JSR EADRCNT ;GET END ADDRESS BTST #EADR,D7 BEQ LIST2 ;NO EADR => COUNT=# INSTRUCTIONS LIST1 JSR DISASM ;DISPLAY, DISASSEMBLE & ADVANCE A1 CMPA.L A1,A2 BCC LIST1 BRA LIST3 LIST2 JSR DISASM DBF D1,LIST2 LIST3 MOVE.L A1,PCADR ;SAVE NEXT PC RTS * * MOVE MEMORY FROM STARTADR THROUGH ENDADR TO DESTADR * MOVE JSR DESTADR MOVE0 CMPA.L A1,A3 BEQ MOVE3 ;IGNORE IF SADR=DADR BCS MOVE2 ;DADR<SADR CMPA.L A2,A3 BHI MOVE2 ;SADR<DADR & EADR<DADR * RANGES OVERLAP (SADR<DADR<=EADR), MOVE FROM END ADDA.L A2,A3 SUBA.L A1,A3 ;DADR=DADR+(EADR-SADR) ADDQ.L #1,A3 ;ADJUST FOR PREDECR ADDQ.L #1,A2 ;ADJUST FOR PREDECR MOVE1 CMPA.L A2,A1 BCC MOVE3 ;ALL DONE IF EADR<=SADR MOVE.B -(A2),-(A3) BRA MOVE1 ;NEXT BYTE * RANGES DON'T OVERLAP, MOVE FORWARD MOVE2 CMPA.L A1,A2 BCS MOVE3 ;ALL DONE IF SADR>EADR MOVE.B (A1)+,(A3)+ BRA MOVE2 MOVE3 RTS * * OUTPUT CONTROL SUBMODE * OUTSUB MOVE.B #'O',PROMPT BCLR #EXTTBL,D7 ;ONLY REGULAR TABLES ADDQ #1,A5 OUTSUB1 JSR GETCHRNS ;GET FIRST CHAR BVC OUTSUB2 JSR GETLIN BRA OUTSUB1 OUTSUB2 CMPI.B #';',D0 BEQ OUTSUB1 ;SKIP COLONS CMPI.B #'Q',D0 BEQ OUTSUB4 ;EXIT OUTPUT SUBMODE CMPI.B #'K',D0 BEQ CLROUT ;KILL OUTPUT TABLE CMPI.B #'P',D0 BEQ DSPOUT ;GIVE SAMPLE OUTPUT CMPI.B #'H',D0 BEQ.L SETCMDH ;SET HIGHEST MEM.ADR FOR COMMANDS CMPI.B #'M',D0 BEQ SETMOUT ;SET MEMORY ADDRESS CMPI.B #'X',D0 BEQ DELOUT ;CLEAR MEM ADR OR REGS SUBQ #1,A5 ;RESET TO FIRST CHAR. JSR GETRLST ;SET REGISTERS TST.L D6 BEQ OUTSUB3 ;INVALID LIST OR.L D6,REGMASK ;SET REGISTER MASK OUTSUB3 JSR SKIPNXT BRA OUTSUB1 OUTSUB4 RTS OUTERR JSR PRTBEL ;SIGNAL ERROR BRA OUTSUB3 * CLEAR OUTPUT TABLE CLROUT MOVEA #REGMASK,A3 CLR.L (A3)+ ;CLEAR REGISTER MASK JSR CLRTBL ;CLEAR OUTPUT TABLE MOVE.L RAMHIGH,CMDHIGH ;RESET HIGHEST MEM. ADDRESS BRA OUTSUB3 * SHOW SAMPLE OUTPUT DSPOUT MOVEA #REGMASK,A3 MOVEA #USRREG,A4 JSR PRTMREG ;DISPLAY REG & MEM BRA OUTSUB3 * SET MEMORY ADDRESS TO DISPLAY SETMOUT JSR GETADRS ;GET ADDRESS & SIZE BTST #NUMFND,D7 BEQ OUTERR ;NO ADDRESS GIVEN CMPI.B #1,D2 BEQ SETMOUT1 JSR MAKEEVEN ;DISPLAY W/L ONLY AT EVEN ADDRESS SETMOUT1 MOVEA #OUTTBL,A3 JSR ADDTBL BTST #TBLERR,D7 BEQ OUTSUB3 MOVEA #OTBLTXT,A0 JSR PRTTEXT ;ERROR: TABLE FULL BRA OUTSUB3 * DELETE REGISTERS OR ADDRESS DELOUT JSR GETRLST ;GET REG LIST TST.L D6 BEQ DELOUT1 ;NO REGISTER LIST AND.L REGMASK,D6 ;CLEAR REGS NOT YET SET EOR.L D6,REGMASK ;CLEAR REGISTERS BRA OUTSUB3 DELOUT1 JSR GETNUM ;TRY FOR ADDRESS BTST #NUMFND,D7 BEQ OUTERR ;ADDRESS OR REGLIST MUST FOLLOW MOVEA #OUTTBL,A3 JSR DELTBL ;DELETE ENTRY BRA OUTSUB3 * SET HIGHEST DEFAULT MEMORY ADDRESS SETCMDH JSR GETNUM ;TRY TO GET ADDRESS BTST #NUMFND,D7 BEQ SETCMDH1 MOVE.L D1,CMDHIGH SETCMDH1 MOVEA #CMDHTXT,A0 JSR PRTTEXT MOVE.L CMDHIGH,D2 JSR PRTLHEX JSR PRTCR BRA OUTSUB3 * * PRINTER CONTROL * PRINTER ADDQ #1,A5 ;ADVANCE TO NEXT CHAR. MOVEQ #7,D0 JMP PRTSFCT ;TOGGLE 6502 PRTFLAG & RETURN * * QUIT : RETURN TO EXEC MODE * QUIT MOVEQ #0,D0 JSR PRTSFCT ;0=RETURN TO E-MODE JMP IDLE ;BACK TO DTACK MONITOR * * REGISTER SUBMODE: DISPLAY & SET REGISTERS * REGSUB MOVE.B #'R',PROMPT ADDQ #1,A5 ;ADVANCE TO FIRST CHAR REGSUB1 MOVEA #USRREG,A4 ;DISPLAY USER REGS REGSUB2 MOVEQ #$FF,D6 ;DISPLAY ALL REGS JSR PRTREG REGSUB3 JSR GETCHRNS ;GET FIRST CHAR. BVC REGSUB4 JSR GETLIN ;GET NEW INPUT LINE BRA REGSUB3 REGSUB4 CMPI.B #';',D0 BEQ REGSUB3 ;SKIP ';' CMPI.B #'Q',D0 BEQ REGSUB8 ;EXIT SUBMODE CMPI.B #'K',D0 BEQ CLRREG ;CLEAR USER REGS CMPI.B #'P',D0 BEQ PROCREG ;DISPLAY PROCESSOR REGS CMPI.B #'I',D0 BEQ SETINT SUBQ #1,A5 ;RESET TO FIRST CHAR. JSR GETRLST ;TRY FOR REGISTER LIST OR 'SR' TST.L D6 BMI SETSTAT ;SET STATUS REG BNE SETREG ;SET REGISTERS MOVEA #FLGLST,A0 MOVEQ #7-1,D1 ;7 FLAGS LEFT REGSUB5 CMP.B (A0)+,D0 BEQ.L SETFLAG ;SET A SINGLE FLAG DBF D1,REGSUB5 REGSUB6 JSR PRTBEL ;SIGNAL ERROR JSR SKIPNXT ;SKIP TO NEXT COMMAND BRA REGSUB3 REGSUB7 JSR SKIPNXT ;SKIP TO NEXT COMMAND (NO ERROR) BRA REGSUB1 REGSUB8 RTS * CLEAR USER REGISTERS CLRREG MOVEQ #0,D0 MOVEQ #33-1,D1 ;33 WORDS= D0-SR MOVEA #USRREG,A0 CLRREG1 MOVE D0,(A0)+ DBF D1,CLRREG1 MOVE.L RAMHIGH,D0 ADDQ.L #1,D0 MOVE.L D0,USRSP ;SET SP = TOP OF RAM +1 BRA REGSUB7 * DISPLAY PROCESSOR REGISTERS PROCREG MOVEM.L D0-D7/A0-A7,SYSREG MOVE SR,SYSSTAT ;SAVE PROCESSOR REGS MOVEA #SYSREG,A4 ;DISPLAY PROCESSOR REGS JSR SKIPNXT BRA REGSUB2 ;DISPLAY REGISTERS * SET INTERRUPT MASK SETINT JSR GETNUM07 ;GET I-MASK BTST #NUMFND,D7 BEQ REGSUB6 MOVE.B USRSTAT,D1 ;GET SYSTEM BYTE ANDI.B #%11111000,D1 ;CLEAR I-MASK OR.B D0,D1 ;SET I-MASK MOVE.B D1,USRSTAT ;SAVE SYSTEM BYTE BRA REGSUB7 * SET STATUS REGISTER SETSTAT JSR GETNUM ;GET DATA FOR SR BTST #NUMFND,D7 BEQ REGSUB6 ;NO DATA GIVEN MOVE D1,USRSTAT ;SET STATUS REGISTER BRA REGSUB7 * SET USER REGISTERS SETREG JSR GETNUM ;GET DATA FOR REGS BTST #NUMFND,D7 BEQ REGSUB6 ;NO DATA GIVEN MOVEA #USRREG,A0 MOVEQ #16-1,D0 SETREG1 LSR #1,D6 BCC SETREG3 ;REG NOT SPECIFIED MOVE.L D1,(A0)+ ;SET REGISTER SETREG2 DBF D0,SETREG1 BRA REGSUB7 SETREG3 ADDQ #4,A0 ;SKIP REGISTER BRA SETREG2 * SET A STATUS FLAG SETFLAG CMPI.B #'T',D0 BNE SETFLAG1 MOVEQ #15,D1 ;SET FOR TRACE FLAG BRA SETFLAG2 SETFLAG1 CMPI.B #'S',D0 BNE SETFLAG2 MOVEQ #13,D1 ;SET FOR SUPERVISOR FLAG SETFLAG2 ADDQ #1,A5 ;ADVANCE TO CHAR AFTER FLAGNAME JSR GETNUM01 ;GET STATE OF FLAG IN D0 BTST #NUMFND,D7 BEQ REGSUB6 MOVE USRSTAT,D2 ;GET STATUS REGISTER LSR #1,D0 BCS SETFLAG3 BCLR D1,D2 ;CLEAR FLAG BRA SETFLAG4 SETFLAG3 BSET D1,D2 ;SET FLAG SETFLAG4 MOVE D2,USRSTAT ;SAVE STATUS REGISTER BRA REGSUB7 * * SEARCH RANGE FROM SADR THROUGH EADR FOR BYTELIST * SEARCH JSR EADRLST SUBQ.B #1,D2 BEQ SEARCHB ;ONLY ONE BYTE TO LOOK FOR SEARCH1 CMPA.L A1,A2 BCS SEARCH10 ;END OF RANGE MOVE.B (A1)+,D2 ;GET MEM. BYTE MOVE.B (A3)+,D1 ;LIST BYTE BNE SEARCH2 ;NO WILDCARD JSR TSTWCD BNE SEARCH3 ;WCD SEARCH2 CMP.B D1,D2 BEQ SEARCH5 ;FIRST BYTES MATCH MOVEA D3,A3 ;RESET TO START OF LSTBUF BRA SEARCH1 ;TRY NEXT BYTE SEARCH3 CMPA A3,A4 BHI SEARCH1 ;STILL MORE CHAR. IN LIST SEARCH4 RTS ;EXIT, LIST IS ALL WILDCARDS SEARCH5 MOVE.L A1,-(SP) ;SAVE ADR. OF NEXT BYTE SEARCH6 CMPA.L A1,A2 BCS SEARCH9 ;NO MATCH POSSIBLE CMPA A3,A4 BLS SEARCH8 ;END OF LIST, MATCH FOUND MOVE.B (A1)+,D2 ;MEM. BYTE MOVE.B (A3)+,D1 ;LIST BYTE BNE SEARCH7 ;NO WILDCARD JSR TSTWCD BNE SEARCH6 ;WCD, MEM. BYTE IRRELEVANT SEARCH7 CMP.B D1,D2 BEQ SEARCH6 ;MATCH STILL POSSIBLE MOVEA D3,A3 ;RESET LIST POINTER MOVEA.L (SP)+,A1 ;SET MEM. PTR TO NEXT BYTE BRA SEARCH1 ;START OVER SEARCH8 MOVEA.L (SP)+,A1 ;GET ADDRESS OF MATCH MOVE.L A1,D2 BSR VFYPRT1 ;PRINT MATCH ADDRESS BRA SEARCH1 SEARCH9 ADDQ #4,SP ;DROP MEM.PTR SEARCH10 MOVE.L A1,NXTADR ;SAVE DEFAULT ADDRESS JMP PRTCR * LIST IS ONLY ONE BYTE SEARCHB MOVEA D4,A4 ;SET TO BITBUF BTST D2,(A4) ;D2=0, TEST BIT 0 FOR ONLY BYTE BNE SEARCH4 ;THE ONLY BYTE IS WILDCARD MOVE.B (A3)+,D3 ;GET SEARCH BYTE SEARCHB1 CMPA.L A1,A2 BCS SEARCH10 ;END OF RANGE CMP.B (A1)+,D3 BNE SEARCHB1 ;NO MATCH MOVE.L A1,D2 BSR VFYPRT1 ;PRINT MATCH ADDRESS BRA SEARCHB1 * * TRACE USER PROGRAM * TRACE JSR SADRPC ;GET SADR JSR EADRCNT ;GET EADR CMPA.L A2,A1 BHI TRACE1 ;NOTHING TO TRACE ST TRCFLAG ;$FF <=> SINGLE STEP BRA GOUSER3 TRACE1 JMP PRTBEL * * COMPARE TWO MEMORY RANGES * Output FORMAT: AAAAAA: HH C - AAAAAA: HH C * AAAAAA - 3-byte address (hex); HH - hex, C - ASCII * VERIFY JSR DESTADR VERIFY1 CMPA.L A1,A2 BCS VERIFY2 ;END OF RANGE MOVE.B (A1)+,D3 ;GET ORIGINAL BYTE CMP.B (A3)+,D3 ;COMPARE WITH BYTE AT DEST ADR BEQ VERIFY1 ;NEXT BYTE MOVE.L A1,D2 BSR VFYPRT1 ;PRINT ORIG ADR MOVE.B D3,D1 JSR VFYPRT2 ;PRINT ORIG BYTE JSR PRT2SPC JSR PRTMIN JSR PRT2SPC MOVE.L A3,D2 BSR VFYPRT1 ;PRINT COMP ADR MOVE.B -1(A3),D1 JSR VFYPRT2 ;PRINT COMP BYTE JSR PRTCR ;NEW LINE BRA VERIFY1 VERIFY2 RTS * VFYPRT1 SUBQ.L #1,D2 ;ADJUST POSTINCR JSR PRTADR JMP PRTSPC * VFYPRT2 JSR PRTHEX JSR PRTSPC JMP PRTASC * * EXAMINE MEMORY * Output FORMAT: AAAAAA:HH HH HH HH HH HH HH HH CCCCCCCC * AAAAAA - 3-byte address (hex); HH - hex, C - ASCII * XAMINE JSR SADRNXT ;GET START ADDRESS JSR EADRCNT ;GET END ADDRESS XAMINE1 MOVE.L A1,D2 JSR PRTADR ;SEND ADDRESS & ':' MOVEQ #7,D3 ;HTAB HEX AREA MOVEQ #31,D4 ;HTAB ASCII AREA XAMINE2 MOVE.B (A1)+,D1 ;GET BYTE JSR PRTHEX MOVE.B D4,D0 JSR HTABN ;HTAB TO ASCII AREA JSR PRTASC ;PRINT AS ASCII CMPA.L A1,A2 BCS XAMINE4 ;A1>A2, END OF RANGE MOVE.L A1,D2 ANDI #%00000111,D2 BEQ XAMINE3 ;END OF LINE ADDQ #3,D3 ;UPDATE HTABS ADDQ #1,D4 MOVE.B D3,D0 JSR HTABN ;HTAB TO HEX AREA BRA XAMINE2 ;NEXT BYTE XAMINE3 JSR PRTCR BRA XAMINE1 ;NEXT LINE XAMINE4 MOVE.L A1,NXTADR ;SAVE NEXT MEMORY ADDRESS JMP PRTCR ;NEW LINE & EXIT * * CHAIN MON68.CSUB.S SHAR_EOF if test 20768 -ne "`wc -c < 'mon68.cmds.s'`" then echo shar: "error transmitting 'mon68.cmds.s'" '(should have been 20768 characters)' fi fi exit 0 # End of shell archive