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