I since have received copies of some quite excellent 68k monitor codes.
I notice there are some news members out there that such a beast.
However since I am not the original owner of the codes I can only post
reference to whom you could direct your request to.
1/ rbr...@svax.cs.cornell.edu Russell Brown,CORNELL UNIV
CS Dept. ITHACA. NY.
2/ tho...@jupiter.cs.concordia.ca Thomas Wieland,CONCORDIA UNIV
CS Dept.MONTREAL.PQ. CANADA
3/ ke...@latcs1.oz
I will seek permission from the owner to post the codes.
Please keep watch on this news group.
Thanks a million,
H.Thongvilu ( My friend call me Pan, it's much easier!).
Computer Centre.
Monash University. Wellington Rd CLAYTON 3168. AUSTRALIA
-----------------------------------------------------------------------
Thanks to George Kyriazis (kyri...@rdrc.rpi.edu), druks!jam...@att.att.com,
and to Jeff Turner (je...@uf.msc.umn.edu) who each provided me with a shar
script or program and to Daniel Berglund (FOPE...@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: tho...@jupiter.cs.concordia.ca
Dept. of Computer Science or: tho...@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:
tho...@jupiter.cs.concordia.ca
or: tho...@concour.cs.concordia.ca
Home Address: Thomas Wieland
4615 Walkley #21
Montreal, PQ
H4B 2K7
Canada
===============================================================================
Thomas Wieland Email: tho...@jupiter.cs.concordia.ca
Dept. of Computer Science or: tho...@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:
*
* tho...@jupiter.cs.concordia.ca
* or: tho...@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:
*
* tho...@jupiter.cs.concordia.ca
* or: tho...@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
3. The monitor mode
===================
This chapter will describe the various commands available to you
in monitor mode.
! Please remember that all the commands described in !
! this chapter deal with memory on the DTACK board !
! only, Apple memory will not be affected by them. !
As this chapter is a fairly lengthy one, it has been divided
into several sub-chapters, each focussing on some particular
subset of commands:
3.1. Prompts, line editor and control characters
3.2. Syntax, number formats, bytelists, command line
3.3. Arithmetic commands
3.4. Memory commands
3.5. Debugging commands
3.6. Miscellaneous commands
For a complete, alphabetically sorted summary of all commands
available in monitor mode, please refer to chapter six.
A special word about "modes":
I know some of you will not particularly like the idea of having
different "modes" in this program. However, one of my goals
writing the monitor has been to keep the commands as short as
possible and the only way to achieve this goal, considering the
number of commands available, has been to group certain commands
into submodes with, as I hope, closely resembling syntax.
The alternative, using multi-character commands, seemed much
less appealing to me, so I hope no one will be scared away by
my use of different modes (or command levels).
3.1. Prompts, line editor and control characters
------------------------------------------------
3.1.1. Prompts
--------------
Switching from EXEC mode into monitor mode, you will notice that
the prompt characters have changed from "E>" (for EXEC mode)
to "M>" (for monitor mode).
Throughout MON68K, the CP/M-type prompt is used to indicate
which mode (or submode, see discussion of B,O and R commands)
you are presently in. Some characters (commands) typed by you
have different effects depending on the mode you are in, so
whenever you feel unsure which mode you are in, the prompt will
be there to tell you.
3.1.2. Line editor and control characters
-----------------------------------------
Entering the 68000 monitor, you will also notice that the cursor
marker has changed from a blinking square (or checkerboard in
case of the Apple//e) to a solid inverse square. This is to show
you that the 68000 line editor is active.
When in monitor mode, all input from the keyboard (with three
exceptions) is passed on to the 68000 which in turn is to
decide what to do with the input. The Apple is in essence
reduced to a terminal, its function is mostly to react to
control characters received by the 68000.
The three exceptions mentioned above are:
ESC Typing ESC will abort the current command executed by
the 68000 and force it back into the input receiving
routine. No monitor variables or 68000 memory will be
changed by typing ESC. This is especially useful to
regain control of the 68000 when a user program has
gone astray.
CTRL-Z This is an "emergency exit" out of monitor mode. Should
the 68000 code be seriously damaged or the communi-
cation between the processors be fouled up, typing
CTRL-Z will let you return to EXEC mode. Thus it should
not be necessary to resort to the RESET key except for
the most extreme cases.
CTRL-S This is used to temporarily suspend output from the
68000. Output is enabled again by typing any key.
All other characters typed on the keyboard are stored in a 256
byte buffer in the Apple and sent on to the 68000 as soon as it
is ready to receive data. The line you are entering is kept in a
separate buffer on the DTACK board and may be edited using the
following control-character commands:
Cursor movement commands:
CTRL-B : move cursor to the beginning of the line.
CTRL-H : move cursor one character to the left (left arrow, <-).
CTRL-I : move cursor one line up. (*)
CTRL-J : move cursor one character to the left.
CTRL-K : move cursor one line down. (*)
CTRL-L : move cursor one character to the right.
CTRL-N : move cursor to the end of the line.
CTRL-O : move cursor to the top of the screen. (*)
CTRL-P : move cursor to the top of the screen and clear the screen. (*)
CTRL-U : move cursor one character to the right (right arrow,->)
(*) CTRL-I,K,O,P commands may only be typed in as the first
characters on a line, later they will not have any effect.
Line editing commands:
CTRL-A : add (insert) characters at cursor position. Insertion
is cancelled by any other control character.
CTRL-D : delete one character at cursor position.
CTRL-M : accept the current input line as it is (<RETURN>).
CTRL-Q : truncate input line at cursor position and accept line.
CTRL-R : recover and retype last input line. Tries to restore a
valid input line from the contents of the line input
buffer. Should this be impossible, the bell will ring.
CTRL-X : cancel the current input line and flush the buffer.
Miscellaneous commands:
CTRL-C : convert the letter under the cursor to opposite case.
CTRL-E : clear the screen to the end of the line and truncate
the current input line to the right of the cursor.
CTRL-F : clear the screen to the end of the page and truncate
the current input line to the right of the cursor.
CTRL-G : ring bell.
CTRL-V : enter a character not available on the regular Apple ][
keyboard. The character typed after CTRL-V is converted
if it is one of the three special characters, otherwise
CTRL-V is ignored. The special characters are:
"]" : is converted to : "["
"/" : is converted to : "\"
"." : is converted to : "_"
After hitting <RETURN> or CTRL-Q, the input line will be con-
verted to uppercase, except for items enclosed in apostrophes
or quotation marks (" and ' respectively).
3.2. Syntax, number formats, bytelists, command line
----------------------------------------------------
3.2.1. Syntax used to describe commands
---------------------------------------
When describing the monitor commands, I will use a sort of
formal language to specify the format of commands. In it,
CAPITAL letters are used for the command letter while variable
parts of the command like addresses or data are represented by
lowercase variables. The name of the variable indicates what
kind of input is expected in its place.
The variables used are:
"adr" (or "data") stands for any 32-bit number denoting an
address (or data) element.
"cnt" stands for count, a number used for example to specify
the number of bytes an instruction is to process.
"size" is for a size suffix after an address, this may be "B"
for byte, "W" for word or "L" for longword values.
"blst" stands for a list of byte values (see 3.2.3.)
"reglst" is a list of 68000 register names in standard Motorola
notation, that is, items of the list are separated by "/"
and a range of registers is indicated by "-". "SP" may be
used instead of A7 and "SR" is used to denote the status
register.
Optional parts of the command are enclosed in curly brackets,
"{" and "}". If optional items are not specified, the
appropriate default values will be used instead.
3.2.2. Number formats
---------------------
Whenever a monitor command expects an address or a data item, it
tries to parse the input line into a number, starting at the
current position in the buffer. With the exception of byte lists
(see paragraph 3.2.3.), spaces are ignored during number
conversion. The result of the conversion is a right-justified
32-bit number. Conversion will be stopped by any command letter,
base prefix or the special characters "." and ";".
You may specify any number in several ways, as a binary,
decimal or hexadecimal number (base 2,10 or 16, respectively) or
as an ASCII string (MSB clear or set), whichever seems appro-
priate or convenient to you. The result will always be treated
as a 32-bit number, no matter how you specified it.
You may select the base for number conversion by using a base
prefix in front of your number. Base prefices are "%" for
binary, "#" for decimal and "$" for hexadecimal numbers.
Using the "$" prefix is optional as the default base used during
conversion is hexadecimal.
Strings are delimited using apostrophes "'" or quotation marks
'"'. A string delimited by apostrophes will be evaluated as low
ASCII (bit7=0), one delimited by quotation marks will evaluate
as high ASCII (bit7=1).
Some examples of numbers and strings you may input are:
37AF89 = $37AF89 = #3649417
%0110111001 = $1B9 = #441
'Atom' = $41746F6D = #1098149741
"HI THERE" = $C8C9A0D4 (remember, 32-bits maximum !)
3.2.3. Byte lists
-----------------
Even though the 68000 is a word (16 bits) rather than a byte
oriented processor, its smallest directly addressable memory
cell is still a byte (8 bits). Therefore, and as I felt that it
is more natural doing it this way, when it comes to handling
data which is to be put into memory, searched or displayed,
MON68K is a byte-oriented monitor.
As a result, several commands which need a list of data items to
process, will be looking for a "bytelist". The items of this
list must be separated by blanks unless the beginning of the
following data byte can be determined out of the context of the
list. Each item in the list represents one 8-bit byte and may
consist of either a number, an ASCII character or the special
wildcard character "*".
Numbers may be given in any base using the prefices described
above. Characters may be given as single characters or strings,
delimited by "'" or '"'. In the case of a string, each character
of the string represents one byte of the list. The wildcard
character "*" does not represent any value, instead it specifies
that the byte at its position is not to be changed or is to be
treated as a "don't care" byte, depending on the command.
A possible example of a list would be:
31'ABC'#1234 5F$EC C9*%10010111"XYZ"
Its equivalent hexadecimal value would be:
31 41 42 43 D2 5F EC C9 ?? 97 D8 D9 DA
^ ^
^ will be treated as wildcard
#1234 = $4D2, however, only byte values will be used
3.2.4. The command line
-----------------------
When you have typed in and edited your commands, you tell the
monitor that you are finished with the current input line (max.
256 bytes) by typing either a <RETURN> or a CTRL-Q. Typing
<RETURN> will accept the contents of the line buffer as it is,
the line will not be truncated at the current cursor position.
Typing CTRL-Q will truncate the input line from the current
cursor position to the right.
After you have accepted the input line, the line editor will
process it, converting all lowercase characters to uppercase
(except for those enclosed in apostrophes or quotes) and setting
up some pointers to the input buffer.
The monitor command processor will then process the contents of
the input buffer sequentially from left to right. The command
processor has the ability to detect some syntactic errors (like
a missing address) and will tell you accordingly. It will retype
the input buffer from the start up to the character where the
error was detected, place a carat "^" below that character and
will print the appropriate error message.
Following this, you will be asked whether you want to continue
with the execution of the command line. Answering with a "N"o
will return you to the line editor and you may then input the
next command(s). If you answered "Y"es, the command interpreter
will skip all characters up to the next semicolon and will then
continue to interpret the command line as before. If no semi-
colon is found, you will be returned to the line editor.
The semicolon thus acts as a delimiter between several commands
on the command line, making it possible to have multiple
commands on the same line.
3.3. Arithmetic Commands
------------------------
Using these commands, you may perform basic arithmetic and
logical operations on 32-bit operands. The result of an
operation will be displayed in all three number bases (hex,
decimal and binary) and as an ASCII string.
The result of the last operation performed is saved in a special
location by the monitor and may be used as the first operand for
the next arithmetic operation.
================================================================
data = : convert and display data
================================================================
This command displays the 32-bit number "data" in all number
bases and as a string.
The output format is:
$HHHHHHHH #DDDDDDDDDD AAAA
%BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB
with "H..H" being the hexadecimal, "D..D" the decimal,
"A..A" the ASCII and "B..B" the binary representation of the
input data. Control characters will be displayed in inverse.
================================================================
{data1} <o> data2 : perform operation <o> and display the result
================================================================
<o> stands for one of the symbols in the following list.
If "data1" is not given, the result of the last performed
operation will be used as a default. The result of the operation
is displayed using the same format as the data conversion
command "=".
Symbol | Operation performed
----------------------------------------------------------------
+ | 32-bit addition. (Note 1)
- | 32-bit subtraction. (Note 1)
* | 16-bit by 16-bit multiplication. (Note 2)
/ | 32-bit by 16-bit division. (Note 3)
< | shift data1 left, data2 times.
> | shift data1 right, data2 times.
( | rotate data1 left, data2 times. (Note 4)
) | rotate data1 right, data2 times. (Note 4)
& | AND data1 with data2.
! | OR data1 with data2.
^ | EOR data1 with data2.
Note 1 : A resulting carry or borrow will be flagged.
Note 2 : This is a straightforward implementation of the 68000's
MULU command. Only the low-order 16 bits of the two
operands are used to calculate the 32-bit result.
Note 3 : A simple implementation of the DIVU command. The result
will be displayed as two numbers, the first number
being the result of the integer division (data1 DIV
data2), the second the remainder (data1 MOD data2).
Should the result of the division be too large to be
expressed in 16 bits, an overflow will be flagged, the
bell will ring, the first operand ("data1") will be
unchanged and the remainder will be cleared.
Note 4 : This is equivalent to a ROL or ROR instruction, that
is, the rotate will not be through the carry.
To calculate the ones-complement of data1 use data1^$FFFFFFFF,
to calculate the twos-complement of data2 use 0-data2.
To get a quick $FFFFFFFF, use 0-1.
3.4. Memory commands
--------------------
All of the commands discussed in this section allow you to
handle data in memory on the DTACK board.
The monitor keeps two special locations in conjunction with
memory commands:
- For all commands with an optional start address, the last
opened (accessed) address+1 will be used as the default
address if a start address is omitted. The last opened address
is initialized to the lowest user RAM address ($3A00 in the
current version) and will be updated by any memory command.
- For the I,J and S commands, the default end address is kept in
a special location. Initially, this location is set to the
highest RAM address, but it may be set to a different address
using the H option in the O submode (see chapter 3.5).
================================================================
{adr1} : blst : change memory
================================================================
This command changes memory starting at address "adr1" to the
byte data given in the bytelist "blst" following the colon.
================================================================
{adr1}{.adr2} I blst : insert data
================================================================
This command inserts the data in the bytelist "blst" into memory
starting at address "adr1". First, the contents of memory from
address "adr1" through address "adr2" are being moved up by the
number of bytes in the bytelist. Next, memory starting at
address "adr1" is changed to the data given in the bytelist
until the list is exhausted. Memory above "adr2" will not be
affected by this command.
================================================================
{adr1}{.adr2} J blst : fill memory with pattern
================================================================
This command fills the memory from "adr1" through "adr2" with
the byte pattern contained in the bytelist "blst". If the data
in the list is exhausted before the memory range has been
filled, the pattern in the list will be repeated from the start.
================================================================
adr1.adr2 M adr3 : move memory
================================================================
This command will move the contents of the block of memory from
address "adr1" through address "adr2" to the block starting at
address "adr3".
Contrary to the Apple ][ monitor move command, this is a
non-destructive memory move, that is, no care has to be
exercised whether the source and destination block overlap.
The trick you may be used to from the Apple monitor for filling
a memory range with a pattern by using overlapping source and
destination ranges will not work here. To do this, use the J
command instead.
Please note that all three addresses have to be specified for
this command. A move command will not have any effect on the
setting of the last opened address.
================================================================
{adr1}{.adr2} S blst : search memory for pattern
================================================================
Using this command, you may search the memory range from "adr1"
through "adr2" for the pattern given in the bytelist "blst". For
every occurence of the pattern, the address of its first byte is
displayed on the screen.
================================================================
adr1.adr2 V adr3 : compare two memory ranges
================================================================
The memory range from address "adr1" through "adr2" will be
compared to the block of memory starting at address "adr3". For
every byte in which the two ranges differ, the addresses of the
bytes as well as their hex and ASCII interpretations will be
given.
As with the M command, note that all three addresses have to be
specified for this command. A compare command will not have any
effect on the setting of the last opened address.
================================================================
{adr1}{.adr2} X / {adr} X {cnt} : display (examine) memory
================================================================
You may view the contents of the specified memory range using
this command. The data is displayed bytewise in its hex and
ASCII interpretation. Printable characters are displayed in
normal, control characters in inverse, no difference is made
between high and low "flavours" of ASCII.
The memory range for this command may be specified either by
giving a start- and endaddress or by giving a startaddress and a
count for the number of bytes you want to be displayed. If no
endaddress or count is given, a count of eight bytes is used.
================================================================
adr1{.adr2} : display memory
================================================================
This alternate form of the X command was included for your
convenience to provide a notation similar to the Apple ][
monitor. The display format is the same as in the X command.
Leaving out the endaddress "adr2" of the command will display
eight bytes as a default. Naturally, there is no way to specify
a count for the number of bytes to be displayed.
3.5 Debugging commands
----------------------
This section will discuss the commands used in debugging of
programs and related commands, like setting processor registers.
The monitor remembers the last address of a disassembly or
program execution in a special location, this address will be
used as the default address whenever the start address for a
debugging command is not specified.
Furthermore, the monitor program provides the user with a
separate register set, including stackpointer and status
register. This user register set is kept in memory and will only
be loaded into the processor registers at the start of execution
of a user program. When the user program ends, the register
contents will be saved again in memory. This way, you are
completely free as to which registers to use in your program.
================================================================
B : breakpoint submode
================================================================
With MON68K, you may set several breakpoints to interrupt your
program at strategic locations during debugging. All breakpoints
can be set, displayed and deleted using the breakpoint submode.
When a break condition arises during the execution of your
program, the monitor will display the user registers and stop
the execution of your program. A break condition can be caused by
hitting a breakpoint or exceeding the PC address limits, which
can be set separately (see H and L subcommands).
MON68K knows two differrent kinds of breakpoints, code (regular)
breakpoints and memory breakpoints:
- Code breakpoints are the ones you are likely to be accustomed
to if you have been using any debugger at all. Setting a code
breakpoint at an address means that a break condition arises
whenever your program reaches the address where the code
breakpoint has been set.
In MON68K, this concept has been taken one step further,
allowing you to specify a count together with the address of
the breakpoint. If the count is omitted, a count of zero will
be assumed, meaning your program will stop the first time that
address is reached. Otherwise, the count associated with the
breakpoint will be decremented each time the breakpoint's
address is reached and program execution continues as long as
the count is not zero. This is useful, for example, for the
debugging of loops.
- Memory breakpoints can be set to stop the execution of a
program at the moment the memory location where the memory
breakpoint has been set reaches a certain value.
When setting a memory breakpoint, you have to specify the
address of the data you want to be checked and the contents of
this address at which a breakcondition should occur.
Optionally, a size suffix may be appended to the address,
which will specify the length of the data to be tested for.
As currently configured, there is a maximum of eight code and
memory breakpoints each.
The following commands are available in the breakpoint submode:
----------------------------------------------------------------
adr{,cnt} : set code breakpoint
----------------------------------------------------------------
Typing an address "adr", optionally followed by a count "cnt",
sets a code breakpoint.
Example:
Typing "4100,10" will set a code breakpoint at address $4100
with a count of $10. This results in a break condition arising
when your program passes location $4100 for the 16th time.
----------------------------------------------------------------
M adr{.size},cont : set memory breakpoint
----------------------------------------------------------------
This command allows setting a memory breakpoint at address "adr"
with the associated contents "cont". Both the address and the
contents to test for must be given. The size suffix "size" is
optional, if it is not specified, a size of word (W) will be
assumed. The size suffix may be either byte (B), word (W) or
longword (L). Odd addresses for sizes W or L will result in the
address being rounded off to an even address.
Examples of memory breakpoints :
Typing.. | ..will result in a breakcondition when..
----------------------------------------------------------------
|
M6000,1234 | locations $6000 and $6001 contain $1234.
M6005.B,FF | location $6005 contains $FF.
M6011.L,F0001234 | locations $6010 through $6013 contain
| $F0001234 (odd addresses rounded off).
----------------------------------------------------------------
H adr : set high address for program execution
----------------------------------------------------------------
This command allows you to specify the highest value of the
program counter which is allowed during the execution of your
program. Whenever the processor's PC surpasses the limit set by
you, a break will occur. The highest address is initially set to
the top of RAM. Odd addresses will be truncated to even ones.
----------------------------------------------------------------
L adr : set low address for program execution
----------------------------------------------------------------
This command allows you to specify the lowest value of the
program counter which is allowed during the execution of your
program. Whenever the processor's PC is below the limit set by
you, a break will occur. The lowest address is initially set to
the start of the user RAM space (currently $3A00). Odd addresses
will be truncated to even ones.
----------------------------------------------------------------
X adr : delete breakpoint at adr
----------------------------------------------------------------
With this command, you may delete single breakpoints you have
set. First, the list of code breakpoints will be searched, then,
if no corresponding entry is found there, the list of memory
breakpoints will be searched and the entry with the corres-
ponding address will be deleted if it is found.
----------------------------------------------------------------
K : delete ("kill") all breakpoints
----------------------------------------------------------------
This command will delete all breakpoints previously set and will
also initialize the low and high limits for the PC. It is
recommended to use this command when entering MON68K for the
first time to clear all breakpoints.
----------------------------------------------------------------
P : display (print) all breakpoints
----------------------------------------------------------------
This will display a list of all code and memory breakpoints set
as well as show the current low and high PC limits.
----------------------------------------------------------------
Q : quit breakpoint submode
----------------------------------------------------------------
Using this command, finally, you may leave the breakpoint
submode to return to the main command level.
================================================================
{adr} G : execute user program
================================================================
Using the G(o) command, you may execute one of your programs
under monitor control. With the G command, all the breakpoints
and register contents you have set are in effect, however,
there will be no diagnostic output as with the T(race command.
Your program will run either until it is finished or until a
break condition arises.
As this command works by single-stepping your program using the
68000's built-in trace facility, execution of your program will
need a lot more time than running it directly without inter-
vention from the monitor. Also, if your program uses any of the
68000's privileged instructions, a "privilege violation"
exception will occur.
To return to MON68K, your program should have a RTS instruction
at its end.
================================================================
{adr} GG : execute user program w/o monitor control
================================================================
To enable you to execute your program at full speed and without
any intervention by the monitor, this second version of the G
command has been included. The "GG" command will load your
preset register contents as did the "G" command, after that,
however, the monitor will jump directly to your program and
execute it, so no breakpoints will be in effect and your program
is solely responsible for returning to MON68K.
To return to MON68K, your program should have a RTS instruction
at its end and should be careful not to manipulate the stack in
a way as to destroy the return address saved on it when jumping
(actually, JSRing) to its start.
================================================================
{adr1}{.adr2} L / {adr} L {cnt} : disassemble instructions
================================================================
To disassemble 68000 programs, use this command. The output from
this command will list the start address of each instruction,
the words making up this instruction and the mnemnonic repre-
sentation of this instruction.
If you do not specify address "adr1", the address+1 of the last
disassembled byte will be used instead. If no endaddress "adr2"
or count "cnt" is given, a count of eight will be assumed. The
count, in this command only, counts the number of instructions
to disassemble, not the number of bytes as in other commands.
================================================================
O : output control submode
================================================================
This submode is to control the output produced by your tracing
of a program. It allows you to select either all or a subset of
the 68000's registers as well as to select up to eight different
memory locations to be displayed during a trace operation.
----------------------------------------------------------------
reglist : select registers for display
----------------------------------------------------------------
Each register given in the register list "reglist" will be
selected for display during a trace. Naming the same register
several times has no effect on the display.
----------------------------------------------------------------
M adr{.size} : select memory location for display
----------------------------------------------------------------
The data stored at memory address "adr" will be selected for
display during a trace. To specify the size of the data, you may
append a size suffix "size" to the address. The size may be any
of byte (B), word (W) or longword (L). If the size suffix is
omitted, a size of word will be assumed. For word and longword
sized data, the address will be rounded down to an even address.
----------------------------------------------------------------
X reglist : delete registers from display
----------------------------------------------------------------
Each register in the register list will be deleted from the
display, deleting the same register several times has no effect.
----------------------------------------------------------------
X adr : delete memory location from display
----------------------------------------------------------------
The list of memory locations to be displayed will be searched
for the given address and, if found, this address will be
deleted.
----------------------------------------------------------------
K : delete all registers and memory locations from display
----------------------------------------------------------------
This will delete all registers and memory locations from the
display, leaving you with an "output" of three blank lines
during a trace. It is recommended to use this command when
entering MON68K for the first time to clear all memory locations
from the display.
----------------------------------------------------------------
P : display (print) a sample output
----------------------------------------------------------------
Using this command, you get a sample output with all the
registers and memory locations you have selected up to now. This
is the same output that you would get at any step when tracing
or single-stepping a program.
----------------------------------------------------------------
Q : quit output control submode
----------------------------------------------------------------
To leave the output control submode and get back to the main
monitor command level, type "Q".
----------------------------------------------------------------
H {adr} : display/set highest address for I,J,S commands
----------------------------------------------------------------
Using this command you may display without altering (when not
giving an address) or set the highest address used by the
I (insert), J (fill) and S (search) commands. Initially, this
address is set to the top of RAM, meaning that these three
commands will use the top of RAM as their default endaddress.
This may be inconvenient to you if you have large amounts of RAM
available, so you are able to specify a different address using
this command.
================================================================
R : register submode
================================================================
Using the commands in register submode, you may set selected
processor registers and/or flags to the value needed by your
program. All the commands in this submode (except for the "P"
command) work on the user register set kept in memory. This
register set will be loaded into the processor registers prior
to the execution of any user program. After each change to the
registers, all registers will be displayed again with their
current contents.
The setting of the flags in the status register is indicated by
their display mode. Flagnames displayed in normal mode indicate
reset (zero) flags, flagnames displayed in reverse mode indicate
set (one) flags. The interrupt level is displayed as a number
from zero to seven which is derived from the setting of the
interrupt mask bits in the processor status register.
----------------------------------------------------------------
reglist data : set registers to data
----------------------------------------------------------------
All the registers contained in the registerlist "reglist" will
be set to the 32-bit number "data". In the case of the status-
register, the number will be truncated to 16 bits.
----------------------------------------------------------------
T|S|X|N|Z|V|C data01 : set/reset flags
----------------------------------------------------------------
Using the flagname and either a "0" or "1", you may set any one
of the flags in the status register to the desired state. Data
larger than one will result in an error. Please note, that you
may set the T(race) and S(upervisor) flags to any state, but
that they will be set to the appropriate values by the G,GG and
T commands.
----------------------------------------------------------------
I data07 : set interrupt mask
----------------------------------------------------------------
This command sets the interrupt mask bits to the interrupt level
indicated by "data07". "Data07" means that any number between
zero and seven is allowed with this command, higher numbers will
result in an error.
----------------------------------------------------------------
K : clear all registers
----------------------------------------------------------------
Using this command, you may clear all registers simultaneously.
Registers D0 through D7, A0 through A6 and the status register
will be cleared to zero and the stackpointer A7 will be set to
the highest RAM address+1, that is, your program stack will be
located at the top of memory unless you change this.
----------------------------------------------------------------
P : display processor registers
----------------------------------------------------------------
Unlike all the other commands in the register submode, this
command allows you to take a look at the current contents of the
68000's registers. This command does not have any effect on the
user registers in memory and is used for debugging.
----------------------------------------------------------------
Q : quit register submode
----------------------------------------------------------------
Allows you to return to the main monitor command level.
================================================================
{adr1}{.adr2} T / {adr} T {cnt}
================================================================
When you select this command, the user register set will be
moved into the processor registers and execution will be begun
at address "adr1", or the last disassembled or executed address
plus one. Following this, the program will be executed step by
step using the 68000's trace facility, up to address "adr2" or
"cnt" bytes. If no endaddress or count is given, a count of
eight bytes is assumed.
During a trace, the instruction which is to be executed next is
displayed together with the registers and memory locations you
selected in the output control mode. After each step, the
monitor checks for your input and continues with the next step
according to your input.
To select single-stepping through a program, press the spacebar.
To select tracing through a program, press any key other than
the spacebar or a control-key.
To abort the trace or single-step, input any control-character.
3.6. Miscellaneous commands
---------------------------
================================================================
H {cmdletter} : display help information
================================================================
This command provides a short overview of the commands available
and the associated command syntax, much like the command summary
in chapter six.
Typing a command letter after the "H" will show only the
descripton for this one command.
The help facility may be disabled using the CONFIGURE program as
the helpfile takes up around 3500 bytes in Apple memory. If the
help command is disabled, you will get the message "System not
configured for HELP" when requesting help information.
================================================================
P : toggle printer on/off
================================================================
This command selects whether screen output will be echoed on the
printer. The system is set up to use a printer in slot #1 with
an Epson interface card. Should you need a different setup, the
system can be reconfigured using the CONFIGURE program. For more
information on printer drivers refer to chapter five.
================================================================
Q : quit monitor
================================================================
This returns you to EXEC mode. None of the system variables and
no memory is affected by this, so if you return to the monitor
you can continue exactly in the same environment that you left
off (provided, of course, that you did not destroy the monitor
code somehow).
SHAR_EOF
if test 39010 -ne "`wc -c < 'mon68.ch3.doc'`"
then
echo shar: "error transmitting 'mon68.ch3.doc'" '(should have been 39010 characters)'
5. Technical Information
This chapter will give you information about the inner workings
of MON68K. The information in this chapter is not needed to work
with the monitor but it is intended for those who want to know
more about how the program works and who may be interested using
some of the built-in subroutines of the monitor.
On your MON68K distribution disk, you will find, among others,
the files MON68K, MON68K/1, MON68K/2AB and MON68K/2CD. These
files make up the heart of the monitor.
MON68K contains a short machine language program which will
initialize the language card and some page three vectors and
which will then load the codefiles containing the monitor
program. Information on how to customize the loader program of
MON68K for your system (i.e. if you need to accomodate RAM disk
drivers or similar programs) will be presented in section 5.2.
MON68K/1 contains all the 6502 code for the monitor, this is the
EXEC mode and the I/O package for communication with the 68000.
This part will be discussed further in section 5.1.
MON68K/2AB and MON68K/2CD hold the code for monitor mode. This
is the 68000 part of the monitor and will be loaded to the DTACK
board during the operation of MON68K. For further details, see
section 5.2.
5.1. The 6502 part of MON68K
----------------------------
This section will describe the part of the monitor code which
resides in Apple memory at all times and which makes it possible
for the 68000 to use the Apple as a terminal.
5.1.1. The boot process
-----------------------
When you BRUN MON68K, this program will in turn load the 6502
and 68000 code files. As a first step, the Apple monitor will
will be copied onto the language card from $F800 through $FFFF.
Following this, the language card is enabled and the three code
files are loaded into the language card.
The two parts of the 68000 code are kept in RAM starting at
$D000 on bank one and two on the language card. The 6502 code is
loaded starting at $EC00 and extends up to $F7FF. As all code is
kept on the language card, it is possible to reload the 68000
monitor program to the DTACK board if it has been destroyed.
If your system is configured for it, the helpfile MON68K/HLP
will be loaded at $8800 into Apple RAM.
As it has to be possible to switch from the language card to
Applesoft and back, some code is needed to do the bankswitching.
This code is moved to $9C00 by the boot program and then the DOS
buffers are moved down one page to protect this code. This is
the same method that is used by some programs like PLE and, as I
understand, by some RAMcard drivers, so there may be problems if
you want to use any of these with MON68K. For this reason, the
source of the boot program has been provided to enable you to
modify it for your system (see chapter 5.2).
Finally, the boot program will read-enable the language card and
will jump to the monitor coldstart entry point at $EC00.
5.1.2. Coldstart and EXEC mode
------------------------------
The 6502 part of MON68K consists of two code parts and one
parameter block. The first part of code contains the coldstart
routines, the EXEC mode and all subroutines which belong to EXEC
mode. This code starts at $EC00 with a jump to the coldstart
routine. At $EC03 there is a jump to the warmstart entry point.
At coldstart, a checksum of the 6502 code is done, the 68000 is
reset, the 68000 part of the monitor code is loaded to the DTACK
board and a checksum of the 68000 code is done. If any of these
tests fails, the appropriate error message is given and the
program run will be aborted.
At warmstart, the 68000 is reset, a checksum of the 68000 code
is performed, the DOS error handler is redirected to a error
handler within MON68K and finally the EXEC mode menu is entered.
When leaving monitor mode a warmstart cycle is run, this way it
is ensured that the 68000 is ready to listen to commands given
to it by the 6502 host.
I will not comment on any of the other routines making up EXEC
mode as these are of no further use for the users of MON68K. All
these routines are used for is to make the EXEC mode work, they
are therefore rather specialized and quite uninteresting.
5.1.3. The 6502/68000 communication routines
--------------------------------------------
The second part of 6502 code contains all the routines used to
interface to the 68000. For one, these are routines to reset the
68000, to send a command byte and to transfer a block of memory
from the 6502 to the 68000 and back. These routines are similar
to the routines RES68K, SENDCMD, CMD7 and CMD8 used in the DTACK
utility package. All these routines use full handshake, so there
is no problem using MON68K with a dynamic RAM board.
When entering monitor mode from the EXEC mode menu, the Apple
enters the I/O routines contained in this second part of the
6502 code. These will coldstart the 68000 monitor code through
the DTACK board's boot ROM command #16, will initialize the
keyboard buffer and will then cycle in an I/O loop until this is
exited through either the 68000, CTRL-Z or RESET.
The I/O loop consists of the following steps:
- get user input from keyboard; process special characters (ESC,
CTRL-S, CTRL-Z) and store all others in the input buffer.
- get input from the 68000; process special function calls and
control-characters, display all others on the CRT. If the
printer is selected, also send character to printer through
printer interface routine.
- send data to the 68000; if the input buffer is not empty and
the 68000 is ready, get the next element and send it on.
- start loop over.
All character I/O between the Apple and the DTACK board is done
in low ASCII (bit7=0).
The input buffer is a circular buffer of 256 bytes located in
page two of Apple memory. Using the Apple to buffer keyboard
input makes it possible to enter the next command while the
68000 is still processing the last.
The following control-characters are recognized when received
from the 68000:
CTRL-E : clear to end of line.
CTRL-F : clear to end of page.
CTRL-G : ring the Apple's bell.
CTRL-H : move cursor one character to the left.
CTRL-I : move cursor one line up.
CTRL-K : move cursor one line down.
CTRL-M : move cursor one line down and to the start of the line.
CTRL-O : move cursor to the top left position of the screen.
CTRL-P : move cursor to the top left and clear the screen.
CTRL-U : get the character at the current cursor position,
convert it to low ASCII and send it to the 68000.
CTRL-X : flush input buffer and restart I/O loop.
All other control characters are ignored.
Special function calls:
-----------------------
To make it possible for the 68000 to have the 6502 execute
different tasks which cannot easily be handled by the above
protocol, a "special function call" routine has been
incorporated into the I/O protocol. The special function call
starts by the 68000 sending a $FF byte to the 6502, followed by
the number of the function it wants executed (0..21), followed
by any other data which may be required by the called routine.
Whenever the 6502 receives a databyte $FF from the 68000, it
leaves the I/O protocol described above and jumps to a special
routine, called the special function handler.
The special function handler in turn gets the number of the
called routine from the 68000, looks up the appropriate address
in the table of special functions and transfers control there.
From then on, the called routine is responsible for interpreting
the input from the 68000 correctly, executing the desired
function and returning to the I/O loop. The I/O loop is
restarted by executing a JMP ($F7FC).
The table of special functions starts at $F7D0, extends through
$F7FB and has a maximum of (decimal) 22 entries. Each entry
holds the start address-1 of the special function routine, high
byte first.
So far, special functions #0 through #9 have been defined,
functions #10 through #21 are left for extensions.
The special functions defined are:
# | Function
----------------------------------------------------------------
0 | leave monitor mode, warmstart EXEC mode
1 | set normal video
2 | set inverse video
3 | HTAB to column N (N=0..39, from 68000)
4 | VTAB to line N (N=0..23, from 68000)
5 | get keypress, convert to low ASCII and send char. to 68000
6 | get a "Y" or "N" from keyboard and send it to 68000
7 | toggle printer on/off, if turned on then initialize printer
8 | print help information
9 | HIRES graphics support, depending on the data byte N
| received from the 68000, do the following:
| N=0: display text, page 1
| N=1: display hires, page 1
| N=2: display hires, page 2
| N=16 ($10): get hires page 1 from 68000
| N=32 ($20): get hires page 2 from 68000
| All other values of N are ignored.
5.1.4. The parameter block
--------------------------
[ ..deleted, too Apple specific.. ]
5.2. Changing the Boot Program
------------------------------
[ ..deleted, too Apple specific.. ]
5.3. The 68000 part of MON68K
-----------------------------
The part of MON68K written in 68000 assembly language holds all
the routines and data which make up the monitor mode. It is this
part of MON68K that is in control whenever you enter the monitor
mode from the EXEC mode menu.
The memory area occupied by the monitor extends from $1000, the
start of RAM on the DTACK board, up to $39FF. Space from $1000
to $1117 is taken up by the 68000's exception vectors and the
ROM monitor command vector table. Following that, the monitor's
code and data areas reach up to about $3750, with the rest up to
$39FF taken up by the monitor's stack area and input buffers.
5.3.1. Exception vectors and ROM command table
----------------------------------------------
The ROM on the DTACK board points the 68000's exception vectors
out to RAM starting at $1000, assigning six bytes to each
exception vector. Initially, these vectors are set to point back
to the boot ROM's "IDLE" routine. These RAM exception vectors
and some scratch memory space used by the boot ROM take up
memory up to $10F3, followed by the ROM monitor command vector
table for user commands $10 and up.
As there is almost no upper limit for the number of user
commands possible, I decided that 17 user commands, from $10
through $20, would be enough for the desired application.
Of these, commands $10 through $14 are used by the monitor as
described below:
Cmd | Address | Action
------------------------------------------------------------ ----
$10 | $10F4 | Jump to coldstart entrypoint of monitor mode
$11 | $10F6 | Jump to warmstart entrypoint of monitor mode
$12 | $10F8 | Jump to monitor code selftest routine
$13 | $10FA | Address of routine determining RAM size
$14 | $10FC | Address of routine determining the entrypoints
| | of the main routines of MON68K and other system
| | variables
Of these commands, commands $10, $11 and $12 may be executed
directly from the Apple by sending the appropriate command byte.
Commands $10 and $11 do not return to the caller and command $12
will send back the result of the selftest and then jump to IDLE.
Commands $13 and $14 may only be called by another 68000
assembly language program, as they return using a RTS
instruction rather than a JMP IDLE.
At $1118 a routine is located which will handle I/O calls from
user programs as described in section 5.3.2.
A coldstart using command $10 will determine the system memory
size and initialize some monitor variables. Following this, a
header text will be printed and the coldstart routine falls
through into the warmstart routine.
The warmstart routine (command $11) will set the RAM exception
vectors to the appropriate exception handling routines inside
MON68K, will reset the system stack pointer and will then fall
through into the main monitor command loop. When using ESC to
stop execution of a monitor command, the 68000 will be reset
(this being the only way to stop it from the Apple) and a
warmstart command will be issued to the 68000.
The selftest routine will calculate a checksum of the monitor
code and compare it to the one stored in the monitor data area.
If the two sums match, $FF will be sent back to the Apple three
times to indicate that everything is o.k. If the selftest fails,
three times $00 will be sent back to the Apple. Afterwards, a
JMP back to IDLE is performed.
The routine at ($10FA) will determine the address of the highest
RAM cell and return this address in addressregister A0.
Registers D0, D1 and D2 will be destroyed, all other registers
and memory will be unaffected.
The routine at ($10FC) will load 68000 data and address
registers with data as follows:
Reg. | Contents
----------------------------------------------------------------
D0.W | Monitor version (current one is $0784 - July 84)
D1.L | Lowest RAM address available to user
D2.L | Highest RAM address available to user
|
A0.L | Address of coldstart routine
A1.L | Address of warmstart routine
A2.L | Address of address table for I/O routines (see 5.3.2.)
A3.L | Address of address table for monitor commands (see 5.3.3)
A4.L | Address of entrypoint for move routine (see 5.3.3.)
A5.L | Address of entrypoint for disassembler (see 5.3.3.)
All other boot ROM commands from $15 to $20 may be used without
restrictions in the current version of the monitor.
5.3.2. MON68K I/O routines
--------------------------
A number of the monitor's I/O routines may be used by a user
program. To make these routines usable without problems in all
versions of MON68K, their entrypoints will not be given as
absolute addresses within the code, but rather through an
address table of I/O routines. The baseaddress of this table may
be obtained through a subroutine call to the address located at
$10FC (command $14). It will return the base address in address
register A2. Using this base address and the number of the I/O
routine as an offset into the table, you may then call any of
the I/O subroutines provided. (For an example on how to
calculate the offset and call the I/O routines, take a look at
the code of the I/O handler described below.)
Alternatively, you may also use the I/O handler at address $1118
with the appropriate call parameters. This routine expects the
number of the subroutine you want to use in data register D4. In
the present version, 26 I/O routines are provided, numbered from
0 to 25.
The following table lists the I/O subroutines available:
No.| Name | Function
----------------------------------------------------------------
00 | GETLIN0 | Get a line of text, entrypoint to line editor
01 | GETRLST | Parse a registerlist from the input buffer
02 | GETBYTE | Get a data byte from the Apple
03 | SENDBYTE | Send a data byte to the Apple
04 | GETNUM | Parse a number from the input buffer (all bases)
05 | HEXNUM | Parse a hex number from the input buffer
06 | DECNUM | Parse a decimal number from the input buffer
07 | BINNUM | Parse a binary number from the input buffer
08 | PRTTEXT | Print text delimited by a null byte
09 | PRTNCHR | Print one character N times
10 | PRTREG | Print register dump
11 | PRTSFCT | Send special function number to the Apple
12 | PRTLHEX | Print a 32-bit number as hex
13 | PRTWHEX | Print a 16-bit number as hex
14 | PRTHEX | Print an 8-bit number as hex
15 | PRTADR | Print a 3-byte address
16 | PRTLDEC | Print a 32-bit number as decimal
17 | PRTWDEC | Print a 16-bit number as decimal
18 | PRTDEC | Print an 8-bit number as decimal
19 | BINDEC | Convert binary to decimal
20 | PRTLBIN | Print a 32-bit number as binary
21 | PRTWBIN | Print a 16-bit number as binary
22 | PRTBIN | Print an 8-bit number as binary
23 | PRTLASC | Print a 32-bit number as ASCII
24 | PRTWASC | Print a 16-bit number as ASCII
25 | PRTASC | Print an 8-bit number as ASCII
Before discussing each of the above I/O routines in further
detail, we first have to take a look at how MON68K handles its
input and output.
As already mentioned above in the 6502 section, keyboard input
is buffered in a circular buffer of 256 bytes in the Apple and
from there sent on to the DTACK board. The 68000 in turn, when
waiting for input from the 6502, puts the characters it receives
into another 256-byte buffer (INBUF) on the DTACK board, until
it receives a return character (CR, $0D) or a CTRL-Q ($11). When
processing the input line, two additional buffers are needed
for processing a bytelist. One buffer (LSTBUF, 254 bytes) is
used to hold the converted values of each byte, therefore making
it unnecessary to interpret the input line anew for longer
patterns; the other (BITBUF, 32 bytes = 256 bits) is used to
flag any wildcard characters in the bytelist. These three
buffers are situated immediately below the bottom of the freely
usable RAM, in the current version this is from $37E0 through
$39FF.
Output from the 68000 to the Apple is not buffered, the 68000
will wait until the Apple is ready to receive data.
Address registers A5 and A6 are used as pointers to the start and
the end of the input buffer (INBUF) in all routines dealing with
the input buffer. Furthermore, register D7 is used as a
flagregister, some bits of it flag certain states for some
routines. Some of these flags and their meaning are:
DELIM (B0) : 1/0: Blanks are/aren't treated as delimiters by
GETNUM during number conversion.
ASCLST (B2) : 1/0: GETNUM is currently inside/outside of an ASCII string.
ASCTYP (B1) : 1/0: If ASCLST=1, then the string is high/low
ASCII (for string constants).
NUMFND (B3) : 1/0: When called, GETNUM did/didn't find a number
at the current position in the input buffer.
SADR (B4) : 1/0: Start address was/wasn't given (for command
subroutines).
EADR (B5) : 1/0: End address was/wasn't given (for command
subroutines).
These flags have to be set correctly for the I/O subroutines to
function properly.
I will now discuss the I/O routines in greater detail:
#00 - GETLIN0: Get a line of text
---------------------------------
The task of this routine is to receive input from the Apple and
put it into the input buffer until a CR or CTRL-Q is received.
This routine incorporates all the line-editing features
described in chapter 3.1.
Input : None
Output: D2.B : number of characters in INBUF (w/o CR)
A5 : pointer to start of INBUF
A6 : pointer to last char. in INBUF (= CR)
Characters of input line are stored in INBUF, the last
character stored is a RETURN.
D0,D1,D3,D7,A3,A4 : scrambled
#01 - GETRLST: Parse a registerlist from the input buffer
---------------------------------------------------------
This routine will try to parse a registerlist from the input
buffer and will return a register mask in D6. In this register
mask, each set (one) bit indicates a register selected, each
cleared (zero) bit means that the register has not been
selected.
The bits in the register mask are assigned as follows:
D0..D7 <=> Bit 0..Bit 7
A0..A7 <=> Bit 8..Bit 15
SR <=> Bit 16
Input : None
Output: If reg.list found : D6.L : register list
A5 : points to next character in
input buffer after reg.list
If reg.list not found : D6.L : 0
A5 : unchanged
D0,D1,D2 : scrambled
#02 - GETBYTE: Get a data byte from the Apple
---------------------------------------------
This is the standard routine to receive a data byte from the
Apple. This routine will wait until data from the Apple is
received and therefore will "hang up" if none is coming !
Input : None
Output: D0.B : Data byte received from the Apple.
#03 - SENDBYTE: Send a data byte to the Apple
----------------------------------------------
This is the standard routine to send a data byte to the Apple.
This routine will wait until the data is accepted by the Apple
and therefore "hang up" if the data is not read by the Apple !
Input : D0.B : Data byte to send to the Apple.
Output: No registers destroyed.
Byte in D0.B sent to Apple.
#04 - GETNUM: Parse a number from the input buffer
--------------------------------------------------
This routine tries to parse a number from the input buffer and
returns its hexadecimal equivalent. This routine recognizes the
base prefices and branches to the appropriate conversion
routine. It will also convert an ASCII (text) constant into a
number. Conversion is stopped by any non-numeric character
(according to the current number base).
Input : DELIM : if DELIM=1, conversion stops at the first
<space> character encountered. In case of a text
constant, the text will be converted one
character at a time.
Output: A5.L : points to first character which could not be
converted into the current number (= D0.B).
D0.B : next character in input buffer.
D1.L : if NUMFND=1, a number has been parsed.
D2.L : scrambled.
#05 - HEXNUM: Parse a hex number from the input buffer
------------------------------------------------------
This routine will parse a hex number from the input buffer.
Input to and output from the routine are the same as for GETNUM,
except that A5 must already point to the first character of the
number (or <space>) and must not point to the base prefix
character '$'.
#06 - DECNUM: Parse a decimal number from the input buffer
----------------------------------------------------------
This routine will parse a decimal number from the input buffer.
Input to and output from the routine are the same as for GETNUM,
except that A5 must already point to the first character of the
number (or <space>) and must not point to the base prefix
character '#'.
#07 - BINNUM: Parse a binary number from the input buffer
---------------------------------------------------------
This routine will parse a binary number from the input buffer.
Input to and output from the routine are the same as for GETNUM,
except that A5 must already point to the first character of the
number (or <space>) and must not point to the base prefix
character '%'.
#08 - PRTTEXT: Print text delimited by a null byte
--------------------------------------------------
Prints text delimited (= ended) by a zero ($00) byte.
Input : A0 : points to the first character of the string.
Output: D0.B : 00
A0 : points to the next byte after the zero byte.
The string has been printed on the screen.
#09 - PRTNCHR: Print one character N times
------------------------------------------
Prints the same character N times.
Input : D0.B : ASCII character (or byte) to send.
D3.W : N (count)
Output: D0.B : unchanged
D3.W : $FFFF
Character in D0.B is sent N times.
#10 - PRTREG: Print register dump
---------------------------------
Print a register dump of the selected registers.
Input : D6 : register select mask (bitvalues as in GETRLST).
A4 : points to start of register save area.
Output: D0-D6,A0,A1,A4: scrambled.
The selected registers are printed.
#11 - PRTSFCT: Send special function number to the Apple
--------------------------------------------------------
Input : D0.B : number of special function
Output: No registers destroyed.
$FF and special function number sent to Apple.
#12 - PRTLHEX: Print a 32-bit number as hex
-------------------------------------------
Input : D2.L : Number to print
Output: D2.L : unchanged.
D0,D1: scrambled.
Number in D2.L printed as eight hex digits.
#13 - PRTWHEX: Print a 16-bit number as hex
-------------------------------------------
Input : D2.W : Number to print
Output: D2.W : unchanged.
D0,D1: scrambled.
Number in D2.W printed as four hex digits.
#14 - PRTHEX: Print an 8-bit number as hex
------------------------------------------
Input : D1.B : Number to print
Output: D1.B : unchanged.
D0 : scrambled.
Number in D1.B printed as two hex digits.
#15 - PRTADR: Print a 3-byte address
------------------------------------
Input : D2.L : Number to print
Output: D2.L : unchanged.
D0,D1: scrambled.
Number in D2.L printed as six hex digits followed by a colon.
#16 - PRTLDEC: Print a 32-bit number as decimal
-----------------------------------------------
Input : D2.L : Binary number to print.
Output: D2.L : unchanged.
D0 : scrambled.
Number in D2.L printed as ten decimal digits.
#17 - PRTWDEC: Print a 16-bit number as decimal
-----------------------------------------------
Input : D2.W : Binary number to print.
Output: D2.W : unchanged.
D0 : scrambled.
Number in D2.W printed as five decimal digits.
#18 - PRTDEC: Print an 8-bit number as decimal
----------------------------------------------
Input : D1.B : Binary number to print.
Output: D1.B : unchanged.
D0 : scrambled.
Number in D1.B printed as three decimal digits.
#19 - BINDEC: Convert binary to decimal
---------------------------------------
Input : D2.L : Binary number to convert.
Output: D2.L : Unchanged.
D0,D1,D3 : scrambled.
D6.W&D5.L&D4.L : Ten character ASCII text for decimal
number (high/mid/low characters).
#20 - PRTLBIN: Print a 32-bit number as binary
----------------------------------------------
Input : D2.L : Binary number to print.
Output: D2.L : unchanged.
D0,D1,D3: scrambled.
Number in D2.L printed as 32 binary digits.
#21 - PRTWBIN: Print a 16-bit number as binary
----------------------------------------------
Input : D2.W : Binary number to print.
Output: D2.W : unchanged.
D0,D1,D3: scrambled.
Number in D2.W printed as 16 binary digits.
#22 - PRTBIN: Print an 8-bit number as binary
---------------------------------------------
Input : D1.B : Binary number to print.
Output: D1.B : unchanged.
D0,D3: scrambled.
Number in D1.B printed as eight binary digits.
#23 - PRTLASC: Print a 32-bit number as ASCII
---------------------------------------------
Input : D2.L : Number to print as character value.
Output: D2.L : unchanged.
D0,D1: scrambled.
Number in D2.L printed as four ASCII characters.
#24 - PRTWASC: Print a 16-bit number as ASCII
---------------------------------------------
Input : D2.W : Number to print as character value.
Output: D2.W : unchanged.
D0,D1: scrambled.
Number in D2.W printed as two ASCII characters.
#25 - PRTASC: Print an 8-bit number as ASCII
--------------------------------------------
Input : D1.B : Number to print as character value.
Output: D1.B : unchanged.
D0,D1: scrambled.
Number in D1.B printed as two ASCII characters.
5.3.3. MON68K command routines
------------------------------
The entry points for MON68K's command routines are listed in a
table whose starting address can be obtained in address register
A3.L through ROM monitor command $14. The entry for each command
consists of a word address pointing to the start of the routine
handling that command. As it would lead to far to dig into the
specifics of each routine, it is enough to point out that
entries are ordered alphabetically from A to Z, followed by the
arithmetic commands in the same order as they are listed in
chapter three.
At the entry to every command routine, addresses or data of the
form <adr1>.<adr2> or <data1>.<data2> preceding the command
character have already been parsed by the command interpreter.
The argument values are passed in registers A1.L (1st argument)
and A2.L (2nd argument) and their presence (or absence) is
indicated by the SADR and EADR flags. Furthermore, A5 points to
the command character and D0.B holds the command character.
Two routines, the MOVE and DISASM routines, may be especially
useful and that is why their entrypoints are provided by ROM
command $14 in address registers A4.L and A5.L.
MOVE0 - move a block of memory
------------------------------
This routine will perform a nondestructive memory move as
described for the monitor M(ove command in section 3.4.
Input : A1.L : start address of sourceblock
A2.L : end address of sourceblock
A3.L : start address of destinationblock
Output: the memoryblock from (A1) through (A2) has been moved
to the destinationblock starting at (A3). No move will
be done if A1=A3.
A1,A2,A3 : scrambled.
DISASM - disassemble instruction
--------------------------------
This routine will disassemble one instruction starting at (A1).
Input : A1.L : points to the first (or only) word of the
instruction (address must be even).
Output: two lines will be displayed on the screen in the same
format as in the monitor L(ist command, the first line
showing the address and the hexadecimal opcode for the
instruction, the second its mnemnonic representation.
A1.L : points to the word after the last word of the
previous instruction.
All other data and address registers remain unchanged.
5.3.4. DTACK Memory Map
-----------------------
$000000 ------------------------------------------------
| ROM exception vectors (four bytes each) |
$000100 |----------------------------------------------|
| DTACK boot PROM ($122: IDLE) |
$000400 |----------------------------------------------|
| reserved for memory mapped I/O |
| ($FF8: data input, $FFA: data output/status) |
$001000 |----------------------------------------------|
| RAM exception vectors (six bytes each) and |
| temporary storage area for PROM monitor |
$0010F4 |----------------------------------------------|
| PROM command vector table (two bytes each) |
$001118 |----------------------------------------------|
| |
| I/O handler for user programs and start of |
| MON68K monitor mode code and data area |
| |
$0037E0 |----------------------------------------------|
| monitor input buffer INBUF (256 bytes) |
$0038E0 |----------------------------------------------|
| temporary buffer for bytelists (256 bytes) |
$0039E0 |----------------------------------------------|
| flag area for wildcards (32 bytes) |
$003A00 |----------------------------------------------|
| start of free RAM (to top of RAM) |
. .
. .
Note: Memory assignments from $1118 and up are shown for monitor
version 2.2 only, these may change later on.
SHAR_EOF
if test 30933 -ne "`wc -c < 'mon68.ch5.doc'`"
then
echo shar: "error transmitting 'mon68.ch5.doc'" '(should have been 30933 characters)'
fi
fi
echo shar: "extracting 'mon68.qref'" '(5665 characters)'
if test -f 'mon68.qref'
then
echo shar: "will not over-write existing file 'mon68.qref'"
else
cat << \SHAR_EOF > 'mon68.qref'
MON68K Command Reference
========================
1. Line editor control characters
---------------------------------
Cursor movement:
CTRL-B : move cursor to the beginning of the line.
CTRL-H : move cursor one character to the left (left arrow)
CTRL-I : move cursor one line up. (*)
CTRL-J : move cursor one character to the left.
CTRL-K : move cursor one line down. (*)
CTRL-L : move cursor one character to the right.
CTRL-N : move cursor to the end of the line.
CTRL-O : move cursor to the top of the screen. (*)
CTRL-P : move cursor to the top of the screen and clear screen. (*)
CTRL-U : move cursor one character to the right (right arrow)
(*) CTRL-I,K,O,P commands may only be typed in as the first characters
on a line, later they will not have any effect.
Line editing:
CTRL-A : add (insert) characters at cursor position. Insertion is
cancelled by any other control character.
CTRL-D : delete one character at cursor position.
CTRL-M : accept the current input line as it is (<RETURN>).
CTRL-Q : truncate input line at cursor position and accept line.
CTRL-R : recover and retype last input line. Tries to restore a valid
input line from the contents of the line input buffer. Should
this be impossible, the bell will ring.
CTRL-X : cancel the current input line and flush the buffer.
Miscellaneous:
CTRL-C : convert the letter under the cursor to opposite case.
CTRL-E : clear the screen to the end of the line and truncate the
current input line to the right of the cursor.
CTRL-F : clear the screen to the end of the page and truncate the
current input line to the right of the cursor.
CTRL-G : ring bell.
CTRL-V : enter a character not available on the regular Apple ][
keyboard. The character typed after CTRL-V is converted if it
is one of the three special characters, otherwise CTRL-V is
ignored. The special characters are:
"]" : is converted to : "["
"/" : is converted to : "\"
"." : is converted to : "_"
Characters handled directly by the Apple keyboard input routine:
ESC : Abort the command currently executed by the 68000.
CTRL-S : Temporarily suspend output from the 68000.
CTRL-Z : "Emergency exit" out of monitor mode.
2. Monitor mode command summary
-------------------------------
B : breakpoint submode;
adr{,cnt} : set code breakpoint
M adr{.size},data : set memory breakpoint
H adr : set high address for program execution
L adr : set low address for program execution
X adr : delete breakpoint at adr
K : delete ("kill") all breakpoints
P : display (print) all breakpoints
Q : quit breakpoint submode
{adr} G : execute user program
{adr} GG : execute user program w/o monitor control
H {cmdletter} : display help information
{adr1}{.adr2} I blst : insert data
{adr1}{.adr2} J blst : fill memory with pattern
{adr1}{.adr2} L /
{adr} L {cnt} : disassemble instructions
adr1.adr2 M adr3 : move memory
O : output control submode;
reglist : select registers for display
M adr{.size} : select memory location for display
X reglist : delete registers from display
X adr : delete memory location from display
K : delete registers and memory from display
P : display (print) a sample output
Q : quit output control submode
H {adr} : display/set highest address for I,J,S commands
P : toggle printer on/off
Q : quit monitor (back to EXEC mode)
R : register submode;
reglist data : set registers to data
T|S|X|N|Z|V|C data01 : set/reset flags
I data07 : set interrupt mask
K : clear all registers
P : display processor registers
Q : quit register submode
{adr1}{.adr2} S blst : search memory for pattern
{adr1}{.adr2} T /
{adr} T {cnt} : trace/single-step program
adr1.adr2 V adr3 : compare two memory ranges
{adr1}{.adr2} X /
{adr} X {cnt} : display (examine) memory
adr1{.adr2} : display memory
{adr1} : blst : directly change memory
data = : convert and display data
{data1} <o> data2 : perform operation <o> and display the result
<o> | Operation performed
--------------------------------------------
+ | 32-bit addition.
- | 32-bit subtraction.
* | 16-bit by 16-bit multiplication.
/ | 32-bit by 16-bit division.
< | shift data1 left, data2 times.
> | shift data1 right, data2 times.
( | rotate data1 left, data2 times.
) | rotate data1 right, data2 times.
& | AND data1 with data2.
! | OR data1 with data2.
^ | EOR data1 with data2.
where:
adr : address
cnt : count
blst : byte list; list of byte values
data : 32-bit data
data01 : 1-bit data (ie. 0 or 1)
data07 : 3-bit data (ie. 0 .. 7)
size : operand size: B(yte), W(ord), L(ongword)
reglist : register list (eg. D1/D3-D5/A5/A2-A4)
Arguments in curly brackets {..} are optional
SHAR_EOF
if test 5665 -ne "`wc -c < 'mon68.qref'`"
then
echo shar: "error transmitting 'mon68.qref'" '(should have been 5665 characters)'