2075 lines
75 KiB
Plaintext
2075 lines
75 KiB
Plaintext
|
|
|
|
|
|
|
|
|
|
|
|
DR6502
|
|
======
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A 6502 Software and Hardware Execution Simulator System
|
|
=======================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
with Code Debugging
|
|
===================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Using a Symbolic Assembler/Disassembler
|
|
=======================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
By: M.J.Malone
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
====================================================================
|
|
DR 6502 AER 201S Engineering Design 6502 Execution Simulator
|
|
====================================================================
|
|
|
|
Simulator Manual By: M.J.Malone
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Contents Page
|
|
-------- ----
|
|
|
|
1) Introduction 1
|
|
|
|
2) Simulator Modes of Operations 4
|
|
|
|
3) Stopped Mode Simulator Command Options 6
|
|
|
|
4) After The CRASH: Simulator Command Options 8
|
|
|
|
5) DRSYM and Debugging with the Symbolic Assembler/Disassembler 10
|
|
|
|
6) Explanation of Commands 12
|
|
|
|
7) Extended Instruction Set for the 65C02 and Rockwell R65C02 22
|
|
|
|
8) Differences Between DR6502 and the R6502, 65C02 and R65C02 23
|
|
|
|
9) DR 6502 Support Files 25
|
|
|
|
10) References 26
|
|
|
|
Appendix A: OpCode Alignment 27
|
|
|
|
Appendix B: Merging with EDIT/Blackbeard 30
|
|
|
|
Appendix C: Hardware Simulator Diagrams 31
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DR6502 - A 6502 Software and Hardware Execution Simulator System
|
|
==================================================================
|
|
|
|
with Code Debugging Using a Symbolic Assembler/Disassembler
|
|
===========================================================
|
|
|
|
|
|
|
|
|
|
1) Introduction
|
|
===============
|
|
|
|
|
|
What is the Simulator and how does it work?
|
|
-------------------------------------------
|
|
The 6502 is a digital circuit. Its reactions to logic levels
|
|
in interior registers and external memory locations are fixed. If
|
|
the logic levels are all known in advance then the operations of the
|
|
6502 are determined. The simulator, using the same information as
|
|
in a project target computer, traces the execution the 6502 would
|
|
take. The simulator is a piece of software that runs on an IBM
|
|
compatible computer. The simulator is programmed with the
|
|
instruction set of the 6502. The task of tracing the movements a
|
|
6502 would make through a piece of code is tackled in the same way
|
|
as any other computational problem. The fact that the IBM does not
|
|
use the 6502 as its central processor is not relevant.
|
|
|
|
The hardware simulator is an interface card and cable that
|
|
plugs into the 6502 socket on an aerospace project board. The
|
|
simulator software, if informed about the presence of the hardware
|
|
card, uses it to perform reads and writes on the target computer's
|
|
memory. This causes data to actually be read from and written to
|
|
I/O ports allowing software debugging while the project hardware is
|
|
present.
|
|
|
|
|
|
Memory Management
|
|
-----------------
|
|
The simulator is a compiled BASIC program. It uses BASIC
|
|
variables to keep track of the processor registers and flags. The
|
|
program 'grabs' a 160K chunk of a 512K IBM computer's high memory.
|
|
Note that the operating system of the IBM is not consulted about the
|
|
allocation of this memory and problems can occur. If you have only
|
|
256K the area of memory used simply does not exist. If you have a
|
|
large number of memory resident programs that push the simulator
|
|
code up into this area then the code will corrupt itself and will
|
|
once again not work. 64K of that memory is used to record all of
|
|
the data in the 64K address space of the 6502 if the hardware
|
|
simulator card is not present. Another 64K is used to hold a status
|
|
number for each memory location that indicates whether the memory is
|
|
allocated, whether it is EPROM or RAM if it is RAM, whether a value
|
|
has been written to it or not. This status number will also
|
|
indicate if the corresponding memory location is to be found in the
|
|
IBM's simulated 6502 address space or found via the hardware card on
|
|
the target computer. This makes partial hardware simulation easy
|
|
where some of the memory elements are accessed by the hardware board
|
|
and others are assumed to be in the simulated address space. One
|
|
example of this is EPROM emulation where the simulator accesses the
|
|
real RAM and VIA on the target but looks to the IBM memory for the
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 2
|
|
|
|
program. The last 32K is used for internal variables and data. As
|
|
a result, to run the simulator a system must have at least 373K of
|
|
the lower 640K free:
|
|
|
|
DR 6502 Code 85K
|
|
Extra Data 160K
|
|
512-640K Unused 128K
|
|
-------------------------
|
|
Total Required: 373K
|
|
|
|
Included among the files on the DR6502 disk is a program 'MM.COM'
|
|
which will tell the user how a system's memory is allocated. To run
|
|
DR6502 it must respond with more than 373K free. If not, the
|
|
AUTOEXEC.BAT and CONFIG.SYS files must be altered to remove some of
|
|
the memory resident utilities or a RAM drive. Also included are two
|
|
handy memory management utilities, 'MARK.COM' and 'RELEASE.COM' to
|
|
mark a spot in memory and then later to release any memory resident
|
|
utilities added after the mark.
|
|
|
|
|
|
The Procedure: What do you have to do to make it run?
|
|
-----------------------------------------------------
|
|
|
|
As explained in the 'QIKSTART.DOC' file, the command line to
|
|
use in assembling 'myfile.asm' with TASM is as follows.
|
|
|
|
tasm -65 -b -l -fff myfile.asm myfile.bin myfile.lst <enter>
|
|
|
|
Note on Options: -65 : Assemble for the 6502
|
|
-b : Binary file output
|
|
-l : List the symbol table
|
|
-fff: Fill unassigned spaces of the EPROM with $FF
|
|
|
|
After the program is assembled, to produce a symbol file for
|
|
DR6502, the user must run DRSYM.EXE as follows:
|
|
|
|
drsym <enter>
|
|
|
|
The user must next provide the name of the listing file, in this
|
|
case 'myfile'. DRSYM produces a file 'myfile.sym' that can be read
|
|
by DR6502. The user would next execute the DR6502 CONFIG program
|
|
(if a different memory configuration is to be used):
|
|
|
|
config <enter>
|
|
|
|
The user then provides a description of the memory elements in the
|
|
system. When the EPROM is input, the CONFIG program will as for the
|
|
name of the binary file, in this case 'myfile'. After the
|
|
configuration is complete, the CONFIG program will automatically
|
|
execute the DR6502 program. To run DR6502 with the same
|
|
configuration as before and with a binary file of the same name and
|
|
with a current or no symbol file then type:
|
|
|
|
dr6502 <enter>
|
|
|
|
The simulation begins.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 3
|
|
|
|
The Simulation: What does DR6502 do when it runs?
|
|
-------------------------------------------------
|
|
|
|
The simulator constructs an exact memory map of your target
|
|
system with RAM, EPROM and VIA. The simulator then reads your .BIN
|
|
program file produced by TASM into the spaces allocated as EPROM.
|
|
(Note that the .BIN file is the form of your software that is ready
|
|
to be burned on an EPROM and installed on your target system so the
|
|
simulation will be exact.) The program then simulates the start up
|
|
and running of the processor. Several run time error conditions are
|
|
checked such as reads or writes to unallocated memory (not occupied
|
|
by a chip), attempted writes to ROM space, reads from RAM spaces
|
|
that were never set etc. Regular CPU crashes are recognized by the
|
|
occurrence of undefined opcodes.
|
|
|
|
When using the hardware simulator option, the RST, NMI, IRQ, SO
|
|
and RDY signals are monitored in the hardware and are obeyed by the
|
|
simulator. When used entirely in software, a simulated IRQ
|
|
frequency is available (Search /Option 'i'/).
|
|
|
|
The simulator is called a symbolic code simulator because it
|
|
will read a ??.SYM file for each EPROM present in your simulated
|
|
computer and will create a reverse symbol table. This table is then
|
|
used in the 'P' program option and 'D' assembly code to allow the
|
|
user to operate with the symbols that were used in the source code.
|
|
This makes viewing and editing the code (Option 'P') much easier.
|
|
With symbol information present, program outputs produced under
|
|
Option 'D' could be combined back into the original assembly code to
|
|
incorporate changes made during simulation sessions.
|
|
|
|
|
|
Other Benefits of the Hardware Simulator System
|
|
-----------------------------------------------
|
|
|
|
Once again, the hardware simulator is made up of two
|
|
components, an interface card and cable that plugs into an IBM
|
|
mother board slot and the DR6502 program. The copy of DR6502 given
|
|
out to all students is capable of operating in either hardware or
|
|
software mode. If a student wishes to construct a hardware
|
|
simulator card to use on their MS-DOS machine at home, the
|
|
schematics are given in the notes. In addition to simulating the
|
|
operation of the 6502 on the target board with DR6502, the interface
|
|
card can be used to run diagnostics.
|
|
The programs 'RAMTEST' and 'EPRMTEST' are used to test the RAM
|
|
and EPROM chips respectively. The program 'EEPROM' can be used with
|
|
the interface card to program electrically erasable, programmable
|
|
read only memories or EEPROMs of the XL2864A type or equivalent. By
|
|
installing the chip on your target computer board, plugging in the
|
|
interface cable to your 6502 processor socket and running one of the
|
|
above mentioned programs, all of these services are available
|
|
through the interface card.
|
|
Because students sometimes wish to test chips outside their
|
|
board or would like to test their VIA chips, an auxiliary board is
|
|
provided with ZIF (zero insertion force) sockets that uses a project
|
|
computer board as its base. The board has been specially wired to
|
|
allow testing of RAM, EPROM, and VIA or programming of EEPROMs.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 4
|
|
|
|
2) Simulator Modes of Operations
|
|
================================
|
|
|
|
The program can run in one of four modes given by the
|
|
combinations of user output/no output and break point set/no break
|
|
point set. Each of the four modes gives a different amount of user
|
|
feedback and executes instructions at a different speed.
|
|
|
|
Screen Output:
|
|
When the simulator reports to the screen after every program
|
|
step, the execution is quite slow in comparison to the speed of a
|
|
6502. To speed up the execution of the program, the user has the
|
|
option to suppress screen printing thereby saving a great deal of
|
|
time. Note that any time screen output is selected, the history
|
|
file (DR_6502.HST) is updated as per its user selected output
|
|
option. When the screen output is suppressed, the history file is
|
|
not written to either. (Search /Option 'H'/)
|
|
|
|
Trace Controlled Screen Output:
|
|
The simulator has a control option (Search /Option 't'/) where
|
|
the screen output is enabled and disabled based on the position of
|
|
execution in the subroutine calling tree. This option is called the
|
|
trace option because it can be used to trace the execution of a
|
|
particular routine, performing all of the calculations in
|
|
subroutines without displaying them. The speed of execution of the
|
|
simulator is not effected whether operating under the trace mode or
|
|
not however as the trace option changes execution modes, the speed
|
|
changes accordingly.
|
|
|
|
Break Point Set:
|
|
If the 'processor' encounters the one user selected break point
|
|
address during any memory access (OpCode fetch, read, write etc) the
|
|
simulation will stop and await user prompting. If there is no break
|
|
point set then no check of addresses will be done. (Search /Option
|
|
'b'/)
|
|
|
|
|
|
Mode 1: Break Point and No Output
|
|
---------------------------------
|
|
The fastest execution occurs when a break point has been set
|
|
and no output is selected. In this mode the 'processor' blasts
|
|
along at maximum speed scanning for the ` key which indicates
|
|
switching back to full user output. Without user input the program
|
|
will run 'silently' until the breakpoint address is reached. At
|
|
maximum, the program is currently capable of simulating about 166
|
|
MCPS (machine cycles per second) or one second of 6502 CPU time in
|
|
about 1.67hr of XT (8Mhz) execution time which is 1/6000th real
|
|
speed. With delay loops disabled, this mode can move very rapidly
|
|
though the program, executing about one page of assembly source code
|
|
per second. Since most every computer owned by students is many
|
|
times faster than an XT, the simulation will be that much faster on
|
|
their machine at home. If the break point address is reached, the
|
|
program will switch to Mode 4: Stopped Mode.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 5
|
|
|
|
Mode 2: No Output, No Break Point
|
|
---------------------------------
|
|
The program still scans for the ` key because with no break
|
|
point this is the only means of returning the program to full output
|
|
mode. Since the program will run indefinitely in this mode, the
|
|
user needs to know at what stage the program is so that it may be
|
|
stopped near points of interest. The program prints the current
|
|
program counter value to the screen after each program step to let
|
|
the user know where the program is. This mode runs at about 118
|
|
MCPS, that is 70% of the speed of mode 1.
|
|
|
|
|
|
Mode 3: Full Output
|
|
-------------------
|
|
In this mode the program prints the values of all registers
|
|
after every program step. If there is a break point set then the
|
|
current fetch and program addresses will be compared to the break
|
|
point address at each program step. If the program reaches the
|
|
break point address it will go into Mode 4: Stopped Mode. Running
|
|
with full output with or without a breakpoint is very slow but still
|
|
faster than the average human is able to absorb the information
|
|
flipping past on the screen. For this reason the program builds a
|
|
DR_6502.HST history file on disk that records any program steps that
|
|
are displayed on the screen. In this mode the simulator executes
|
|
about 16 MCPS or about 1/10th the speed of mode 1 including all disk
|
|
and screen output. In this mode the program is scanning for user
|
|
input. To transfer to modes 1 or 2 press the ` key. To stop the
|
|
execution (go to Mode 4: Stopped Mode) press the 's' key (stands
|
|
for 'STOP').
|
|
|
|
|
|
Mode 4: Stopped Mode
|
|
--------------------
|
|
|
|
In this mode the program does not execute program steps but
|
|
waits for user input. To go back to each of the other modes from
|
|
mode 4, the user must input:
|
|
|
|
Mode 1: Enter a [new] break point address. Press the ` key.
|
|
Mode 2: Press the ` key.
|
|
Mode 3: Press the 'g' key (stands for GO)
|
|
|
|
To remain in stopped mode but advance by one program step, the
|
|
user can press the 's' key (stands for STEP). The other command
|
|
options available are explained in the next section.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 6
|
|
|
|
3) Stopped Mode Simulator Command Options
|
|
=========================================
|
|
|
|
Since there are several avenues open to the user under the
|
|
stopped mode, no command prompt is displayed but the program will
|
|
react to keystrokes. The following is a list of the keystrokes and
|
|
the commands they initiate. The more complete description of what
|
|
each of the commands does is given in below. The reader can use a
|
|
word search or find option searching for /Option 'x'/ where x is the
|
|
keystroke to be searched.
|
|
|
|
|
|
Key | Function
|
|
====================================================================
|
|
|
|
|
b | Set the break point address
|
|
|
|
|
t | Trace on, Full screen output for this level subroutine
|
|
| only. Screen output is disabled upon JSR and is
|
|
| re-enabled after the matching RTS is executed.
|
|
|
|
|
T | Trace off
|
|
|
|
|
d | Dump memory data to a disk file in hex, TASM or block
|
|
| format
|
|
|
|
|
R | Read a disk data file in block format into memory
|
|
|
|
|
* D | Dump Disassembled Program to a Disk file in TASM format
|
|
|
|
|
p | Poke values into memory (good for simulating I/O, sensors)
|
|
|
|
|
* P | (Re)Program: Disassembles a Page of Program Memory and
|
|
| Offers the following sub-menu
|
|
|
|
|
| Key Function
|
|
| ==========================================================
|
|
| u move Up a line in the program
|
|
| d move Down a line in the program
|
|
| c Change the code - begin reprogramming in assembly
|
|
| code
|
|
| s Save current page
|
|
| r Reread current page discarding any changes
|
|
| + read and disassemble the next memory page of the
|
|
| program
|
|
| p read and disassemble a different Page
|
|
| m Make space for new assembly code to be inserted
|
|
| i Symbol information
|
|
| a Assign a Symbol
|
|
| l Label current line with a symbol
|
|
| b toggle display of Branch line labels
|
|
| n modify Notepad
|
|
| q Quit Program module - do not save the current page
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 7
|
|
|
|
m | Monitor an address (variable)
|
|
|
|
|
r | Change the contents of the processor Registers including
|
|
| the flags
|
|
|
|
|
v | View memory in hex dump format to the screen
|
|
|
|
|
n | Display and edit the notepad
|
|
|
|
|
l | List a text file to the screen - copy to notepad
|
|
| f - find text
|
|
| ESC - quit
|
|
|
|
|
h | History, display the short history that is maintained in
|
|
| memory
|
|
|
|
|
H | Change the history file and short history format
|
|
|
|
|
! | RESET the processor - all memory remains
|
|
|
|
|
i | Set interrupt frequency (Available only in software
|
|
| simulation mode)
|
|
|
|
|
e | End the simulation - Check DR_6502.HST for a log of that
|
|
| run
|
|
|
|
|
? | HELP - List the Keystrokes available to the user
|
|
|
|
|
====================================================================
|
|
* Segments contained in the second overlay. Upon initiating the
|
|
command the simulator will stop for a few moments to transfer in
|
|
'OVERLAY1.EXE'. These segments of the program utilize the symbol
|
|
information if present to enhance their operation. Please see
|
|
section 5) DRSYM and the Symbolic Debugging.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 8
|
|
|
|
4) After The CRASH: Simulator Command Options
|
|
=============================================
|
|
|
|
After the simulator has flagged some condition that would lead
|
|
to a malfunction of a real 6502 system, the mode of operations
|
|
changes to the post crash analysis. The user has many option
|
|
available to analyze memory and processor status to discover where
|
|
things went wrong. The user also has the option to direct the
|
|
simulator to return to normal operations after some adjustments to
|
|
registers or data has been made. The following is a list of
|
|
commands available in the post crash analysis.
|
|
|
|
|
|
Key | Function
|
|
====================================================================
|
|
|
|
|
d | Dump memory data to a disk file in hex, TASM or block
|
|
| format
|
|
|
|
|
* D | Dump Disassembled Program to a Disk file in TASM format
|
|
|
|
|
p | Poke values into memory (good for simulating I/O, sensors)
|
|
|
|
|
* P | (Re)Program: Disassembles a Page of Program Memory and
|
|
| Offers the following sub-menu
|
|
|
|
|
| Key Function
|
|
| ==========================================================
|
|
| u move Up a line in the program
|
|
| d move Down a line in the program
|
|
| c Change the code - begin reprogramming in assembly
|
|
| code
|
|
| s Save current page
|
|
| r Reread current page discarding any changes
|
|
| + read and disassemble the next memory page of the
|
|
| program
|
|
| p read and disassemble a different Page
|
|
| m Make space for new assembly code to be inserted
|
|
| i Symbol information
|
|
| a Assign a Symbol
|
|
| l Label current line with a symbol
|
|
| b toggle display of Branch line labels
|
|
| n modify Notepad
|
|
| q Quit Program module - do not save the current page
|
|
|
|
|
|
|
|
r | Change the contents of the processor Registers including
|
|
| the flags
|
|
|
|
|
v | View memory in hex dump format to the screen
|
|
|
|
|
n | Display and edit the notepad
|
|
|
|
|
h | History, display the short history that is maintained in
|
|
| memory
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 9
|
|
|
|
H | Change the history file and short history format
|
|
|
|
|
! | RESET the processor - all memory remains
|
|
|
|
|
e | End the simulation - Check DR_6502.HST for a log of that
|
|
| run
|
|
|
|
|
? | HELP - List the Keystrokes available to the user
|
|
|
|
|
j | Jump Start the simulation - Direct the simulator to resume
|
|
|
|
|
====================================================================
|
|
* Segments contained in the second overlay. Upon initiating the
|
|
command the simulator will stop for a few moments to transfer in
|
|
'OVERLAY1.EXE'. These segments of the program utilize the symbol
|
|
information if present to enhance their operation. Please see
|
|
section 5) DRSYM and the Symbolic Debugging.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 10
|
|
|
|
5) DRSYM and Debugging with the Symbolic Assembler/Disassembler
|
|
================================================================
|
|
|
|
DRSYM is a very short program that reads the symbol table
|
|
printed in ASC II at the end of the TASM list file and turns it into
|
|
a packed binary file for input into DR6502. DRSYM also excludes
|
|
from the list of symbols it produces, any symbols that appear
|
|
anywhere in the assembly code as constant arguments in the format
|
|
'#symbol'. The reasons for this will be explained later. If
|
|
another assembler is used other than TASM, a different DRSYM program
|
|
will need to be programmed. For this reason both the BASIC source
|
|
code and compiled code for DRSYM have been provided so that the user
|
|
may alter the program to read the list file from their favorite
|
|
assembler.
|
|
With the symbol information and the machine code the simulator
|
|
is able to recreate your assembly code fairly closely. The two
|
|
program modules that use this ability are the 'D' dump assembly code
|
|
to disk file and the 'P' (re)program assembly code modules.
|
|
|
|
|
|
'D' Dump Assembly Code Option
|
|
-----------------------------
|
|
|
|
The 'D' dump code option is quite straight forward. The
|
|
simulator looks at the section of memory to be disassembled and
|
|
dumped to the disk and inserts labels whenever it finds a match
|
|
between an address reference and a label value.
|
|
|
|
Constants
|
|
Labels are not substituted in the case of constant references
|
|
since there may be times when #$01 is used as the 'number 1', 'bit
|
|
zero set' or 'true' each with a different label. It would be
|
|
impossible for the simulator to determine which usage of the #$01
|
|
was intended in a particular piece of code. Since constants are
|
|
never substituted for, there is no need for constant labels to
|
|
appear in the symbol table. For this reason, DRSYM does not record
|
|
constants labels in the symbol table in the .SYM file.
|
|
|
|
Address with No Symbol
|
|
References to addresses that do not have a corresponding label
|
|
but are only a few bytes offset from a label will be recorded as
|
|
'label+offset' assuming a multibyte storage data structure. For
|
|
example, if 'Register_0' where assigned the value of $00 in the
|
|
source assembly code and no label were assigned to the address
|
|
$01, it is very likely that references to the address $01 would
|
|
actually be written in the code as 'Register_0 + 1' where
|
|
Register_0 is in this case a multibyte piece of data. If
|
|
contents of address $01 had absolutely nothing to do with the
|
|
contents of address $00 then, as dictated by good programming
|
|
style, $01 should have been assigned a label that explained its
|
|
purpose such as 'Register_1' or 'Temp'.
|
|
|
|
Though these rules may not seem to make sense when stated,
|
|
experimentation has found, on average, this set of rules produces
|
|
code that is closest to the original assembly source code. It is
|
|
very possible that the code reproduced by DR6502 will be identical
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 11
|
|
|
|
to the original source code with the omission of the comments. The
|
|
dump module is not interactive, the output of the symbolic
|
|
disassembly goes directly to the user specified disk filename. The
|
|
output of the dump option is easily incorporated into the original
|
|
source code to reflect reprogramming done in the 'P' (re)program
|
|
code option.
|
|
|
|
|
|
'P' (re)Program Code Option
|
|
---------------------------
|
|
|
|
The 'P' (re)program code option is an interactive symbolic
|
|
assembler/disassembler based on a machine language page of assembly
|
|
code. As with the 'D' dump option the 'P' option disassembles
|
|
starting at a user specified memory address inserting address labels
|
|
in the same manner as described above. The disassembled code is
|
|
displayed on the screen and the user can move up and down through
|
|
the page. The user can inquire about label information, assign a
|
|
new label or label the current memory address indicated by the line
|
|
the cursor is currently on. The user can modify the code and use
|
|
labels to specify any arguments including constant arguments (like
|
|
#True for #$01).
|
|
|
|
**** In fact the user need not start with any real code at all! ****
|
|
|
|
By assembling a file with one instruction, and the reset vector, the
|
|
user can start the simulator with no actual program present. The
|
|
'P' option could be used as an interactive, line by line assembler,
|
|
inputting labels as necessary developing code on the fly. Though
|
|
this is definitely not a good programming practice, it is very
|
|
useful if the user just wants to try something out, preferably that
|
|
will code out to less than 256 bytes of machine code or about 100
|
|
lines of assembly code. After the code has been programmed or
|
|
reprogrammed in the case of repairing a bug, the page must be saved
|
|
back to the memory of the simulated 6502.
|
|
Using the 'P' option, it is possible to work on your code in
|
|
the simulator at a near source code level provided symbol
|
|
information is provided. It is convenient and wise to use the 'D'
|
|
option to record to disk, for later reference, any changes made to a
|
|
section of the assembly code. Search /Option 'D'/ or /Option 'P'/
|
|
for specific information on how each option is used.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 12
|
|
|
|
6) Explanation of Commands
|
|
===========================
|
|
|
|
Option 'b'
|
|
----------
|
|
Often the user would like the code to run to a certain point
|
|
and then stop. DR6502 allows the user to set a break point address
|
|
and whenever that address is used in a memory fetch of any sort,
|
|
including data, the simulator will stop and display the current
|
|
status of the simulated processor. This can be used to make the
|
|
program execute to a certain address by specifying the code address
|
|
you wish the program to stop at. The user can monitor the data
|
|
traffic to a VIA port by setting the break point to be the address
|
|
of the VIA port. In this case whenever a read or a write is done to
|
|
the port the simulator would stop and display the status.
|
|
|
|
|
|
Option 't' and Option 'T'
|
|
-------------------------
|
|
The 't' trace option modifies the screen output of the
|
|
simulator. The 'b' option allows the user to execute until a
|
|
certain address. Often, the user wants to execute a routine that
|
|
calls a number of subroutines. In this case the user may only be
|
|
interested in monitoring the execution of the program when it is in
|
|
the high level routine and not when it jumps into the lower level
|
|
subroutines. When the trace option is initialed at a particular
|
|
point in the subroutine call tree, DR6502 automatically switches to
|
|
no output mode (as initiated by the ' option) when executing
|
|
subroutines at nesting levels lower and switches back to full output
|
|
mode for subroutines of a equal or higher nesting level. This
|
|
allows the user to view only the higher level logic. The 'T' cancel
|
|
trace option, cancels the current trace mode.
|
|
|
|
|
|
Option 'm'
|
|
----------
|
|
The 'm' monitor a variable option allows the user to constantly
|
|
monitor the contents of a memory location. The value is displayed
|
|
in the status area next to the 6502 register values. This option
|
|
can be used to monitor a memory location that is used by the code as
|
|
a variable or it can be used to monitor in a memory location
|
|
corresponding to a VIA port. The user is given the option of
|
|
selecting a two byte display where the memory location specified and
|
|
the one following are interpreted as a 16 bit variable.
|
|
|
|
|
|
Option 'r'
|
|
----------
|
|
The 'r' modify registers option allows the user to modify the
|
|
processor .A, .X, .Y, .SP, .PC and .R registers. This option can be
|
|
used to correct for data or stack errors recognized in the program.
|
|
As the user is testing their individual subroutines, they may wish
|
|
to place the break point at the RTS, set data register initial
|
|
values and then set the program counter to begin the routine.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 13
|
|
|
|
Option 'j'
|
|
----------
|
|
Presumably if the crash was not too bad and a little adjustment
|
|
of the registers will fix it (including possibly the program
|
|
counter) then the program will allow you to attempt to jump-start
|
|
the simulation again. This may be attempted as many times as the
|
|
user wishes.
|
|
|
|
***** WARNING ***** An infinite loop is NOT a crash if it is
|
|
composed of valid 6502 instructions, so be careful.
|
|
|
|
Option '!'
|
|
----------
|
|
The '!' reset option performs the same function on the
|
|
simulator as the reset button on the target microprocessor board.
|
|
The user is given the option of changing the type of 6502 processor
|
|
simulated.
|
|
|
|
|
|
Option 'h'
|
|
----------
|
|
The 'h' history option displays a short history of the last 9
|
|
instructions that the processor has executed. The user will
|
|
probably find this most helpful after the simulation has stopped at
|
|
a break point to discover by what manner it came to arrive at the
|
|
break point.
|
|
|
|
|
|
Option 'H' and the History File
|
|
-------------------------------
|
|
As stated earlier, the simulator writes to a history file
|
|
whenever full screen output is selected. The format of the file can
|
|
be controlled by the 'H' history file mode option. The first choice
|
|
is full output including disassembled code, all registers, program
|
|
counter before and after and the monitored variable address and
|
|
value (if selected) at every program step. The second choice is
|
|
every line output with the disassembled code only. The last option
|
|
is nesting output that writes to the history file only on the
|
|
occurrence of JSR, RTS, BRK, RTI and the hardware interrupt.
|
|
The first choice is most useful if extensive checking of the
|
|
flow of data through the registers is desired. The disadvantage of
|
|
full output mode is that it requires a lot of disk storage space for
|
|
the DR_6502.HST file. The second mode is best for simple tracing of
|
|
the program execution. This mode requires less disk space yet still
|
|
provides enough information to help debug the program. The third
|
|
option allows the user to check that subroutines are nested properly
|
|
and called when expected. This mode saves a great deal on disk
|
|
space (and runs faster too) by cutting out a lot of the unnecessary
|
|
information not required for high level debugging.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 14
|
|
|
|
Sample output from mode 1:
|
|
|
|
Addr Op Args Mn Addr Mode A X Y SP PC PC NV BDIZC Variable
|
|
-----------------------------------------------------------------------------
|
|
F001 A2 FF LDX #const (2) 00 FF 00 00 F001=>F003 10100100 0080=#$????
|
|
F003 9A TXS (2) 00 FF 00 FF F003=>F004 10100100 0080=#$????
|
|
F004 58 CLI (2) 00 FF 00 FF F004=>F005 10100000 0080=#$????
|
|
NOP Cruise $F005-$F009
|
|
F009 EA NOP (10) 00 FF 00 FF F009=>F00A 10100000 0080=#$????
|
|
F00A A9 FF LDA #const (2) FF FF 00 FF F00A=>F00C 10100000 0080=#$????
|
|
F00C 8D 00 02 STA addr (4) FF FF 00 FF F00C=>F00F 10100000 0080=#$????
|
|
F00F A9 02 LDA #const (2) 02 FF 00 FF F00F=>F011 00100000 0080=#$????
|
|
F011 85 81 STA zpage (3) 02 FF 00 FF F011=>F013 00100000 0080=#$????
|
|
F013 A9 00 LDA #const (2) 00 FF 00 FF F013=>F015 00100010 0080=#$????
|
|
F015 85 80 STA zpage (3) 00 FF 00 FF F015=>F017 00100010 0080=#$0200
|
|
F017 A9 55 LDA #const (2) 55 FF 00 FF F017=>F019 00100000 0080=#$0200
|
|
F019 8D 01 02 STA addr (4) 55 FF 00 FF F019=>F01C 00100000 0080=#$0200
|
|
F01C A9 01 LDA #const (2) 01 FF 00 FF F01C=>F01E 00100000 0080=#$0200
|
|
-----------------------------------------------------------------------------
|
|
|
|
Sample output from mode 2: (Note: this is the default mode on start up)
|
|
|
|
Addr Op Args Mn Addr Mode
|
|
---------------------------------------------------------------------------
|
|
F001 A2 FF LDX #const (2)
|
|
F003 9A TXS (2)
|
|
F004 58 CLI (2)
|
|
NOP Cruise $F005-$F009
|
|
F009 EA NOP (10)
|
|
F00A A9 FF LDA #const (2)
|
|
---------------------------------------------------------------------------
|
|
|
|
Sample output from mode 3:
|
|
|
|
Addr Op Args Mn
|
|
---------------------------------------------------------------------------
|
|
F020 20 00 F8 JSR dest (6)
|
|
F812 60 RTS (6)
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|
Other History File Entries
|
|
--------------------------
|
|
|
|
Certain conditions including errors and warnings produce
|
|
notations in the history file. The following are several such
|
|
example entries.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 15
|
|
|
|
Sample RESET Entry:
|
|
|
|
Each time the simulator is RESET the following appears in the
|
|
history file:
|
|
|
|
--------------------------------------------------------------------------
|
|
RESET ====> $FFFC
|
|
Reset Vector = $F000
|
|
F000 78 SEI (2) **** Note this depends on your first instruction
|
|
--------------------------------------------------------------------------
|
|
|
|
|
|
Sample Stopped Mode Entry
|
|
|
|
Each time the user presses the 's' key whether to stop
|
|
execution or to step execution by one step the value of all
|
|
registers is written to the history file.
|
|
|
|
-------------------------------------------------------------------------
|
|
Time=000000.000042 million cycles
|
|
Registers:
|
|
Acc=$01
|
|
Xreg=$FF
|
|
Yreg=$00
|
|
SP=$00
|
|
PC=$F01E
|
|
N V 1 B D I Z C
|
|
0 0 1 0 0 0 0 0
|
|
------------------------------------------------------------------------
|
|
|
|
|
|
Sample NOP Special Execution Entry
|
|
Often a program will contain large areas that contain nothing
|
|
but NOP no operation instructions. Since these instructions do not
|
|
modify memory, registers or program flow, they are given a special
|
|
notation in the history file to save space.
|
|
|
|
-----------------------------------------------------------------------
|
|
NOP Cruise $F005-$F009
|
|
F009 EA NOP (10) 00 FF 00 FF F009=>F00A 10100000 0080=#$????
|
|
-----------------------------------------------------------------------
|
|
|
|
|
|
Option 'i'
|
|
----------
|
|
In software simulation mode, there is no target computer to
|
|
provide NMI or IRQ signals. The simulator provides an option where
|
|
one interrupt signal can be simulated at a user defined frequency
|
|
(period given in clock cycles). This 'signal' can be blocked by the
|
|
interrupt flag in the processor status register. This 'signal' can
|
|
be blocked by the interrupt flag in the processor status register
|
|
and uses the IRQ jump vector so it is a close simulation of the IRQ
|
|
function of the processor.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 16
|
|
|
|
Option 'e'
|
|
----------
|
|
The 'e' end option allows the user to end the simulation
|
|
session. The history file maintained on the disk is closed and the
|
|
simulator returns the use stopped or crashed mode.
|
|
|
|
|
|
The 'n' Notepad Option
|
|
----------------------
|
|
A minor deficiency in the DR6502 program was the necessity for
|
|
the user to constantly be making note of addresses so that they may
|
|
be correctly input to another option of the program etc. Such minor
|
|
note taking has been taken care of by the 'n' option where the user
|
|
is given four lines at the top of the screen (used for errors and
|
|
warnings only) to make notes of any kind. This area of the screen
|
|
is not erased after the user exits the notepad option and may stay
|
|
for quite a while. The contents of the note pad can always be
|
|
called up again if they are erased.
|
|
|
|
|
|
The 'l' List Text File Option
|
|
-----------------------------
|
|
Sometimes the user would like to check a text file for
|
|
information necessary to the debugging of the code under testing.
|
|
Commonly the user would like check the source or listing files from
|
|
the assembly code but this option allows any text file to be
|
|
examined including this documentation file for DR6502.
|
|
The reading of the text file is one way, forward only, with one
|
|
line read for each keystroke. The 'f' key in this mode invokes a
|
|
find or search function. The <ESC> ends this option. On exiting
|
|
this option the user is allowed the option to copy the portion of
|
|
the file displayed into the notepad so that it may be edited and
|
|
redisplayed. Note: there is no facility to copy the contents of the
|
|
notepad back to the file or to a different file so this cannot be
|
|
used for file editing.
|
|
|
|
|
|
Option 'v'
|
|
----------
|
|
The 'v' view memory option allows the user to display portions
|
|
of the 6502 virtual memory to the screen. With this option the user
|
|
can check the data values at any point in the execution of the
|
|
program code. The memory is listed beginning at a user supplied
|
|
address and then the user has the option of paging up and down
|
|
through the memory using the 'u' and 'd' keys.
|
|
|
|
|
|
Option 'd'
|
|
----------
|
|
The 'd' dump data option is conceptually equivalent to the 'v'
|
|
view option. The dump option allows the user to dump the contents
|
|
the 6502 virtual memory to a disk file in hex format for later
|
|
inspection or merging into a TASM source file. This allows the user
|
|
to take data generated by 6502 commands and incorporate it into the
|
|
source code. The 'd' option dumps a section of memory to a disk
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 17
|
|
|
|
file in one of two formats, either in hex format:
|
|
|
|
F000 A9 00 8D 00 02 CD ........
|
|
|
|
for easy (?) interpretation later or in 'TASM' format:
|
|
|
|
.ORG $F000
|
|
.BYTE $A9,$00,$8D,$00,$02,$CD,....
|
|
|
|
for easy merging with the program source code to make it a data
|
|
table. (see Appendix A)
|
|
|
|
The user may also record the data in a 'block' format in the
|
|
data file. The block format is useful for recording memory values
|
|
to be read back into memory later using the 'R' option. The format
|
|
of a 'block' file is as follows:
|
|
|
|
4096
|
|
0, 1, 2, 3, 4, 5, 6, 7
|
|
8, 9, 10, 11, 12, 13, 14, 15
|
|
-1, 0, 0, 0, 0, 0, 0, 0
|
|
|
|
The first number '4096' corresponds to the address in memory,
|
|
in this case $1000 at the beginning of the data block. The numbers
|
|
that follow, in rows of 8, are the values of the memory locations
|
|
sequentially following the beginning address of the data block. The
|
|
last line must begin with a -1 followed by 7 other numbers. All
|
|
numbers (except the -1) must be in the range 0-255.
|
|
|
|
|
|
Option 'R'
|
|
----------
|
|
The 'R' read data option inputs data from disk files into the
|
|
6502 ram memory in a block format (see Option 'd', 'block' output as
|
|
described above). The data file may be produced by DR6502 by the
|
|
'd' option or may be created by a user with a text editor. See the
|
|
'd' option above for details on the format.
|
|
|
|
|
|
Option 'p'
|
|
----------
|
|
The 'p' poke option allows the user to directly write to RAM
|
|
spaces within the 6502 virtual memory map. The user supplies a
|
|
start address and fills in the values in that and successive
|
|
locations by separating the figures with spaces. The user can
|
|
prefix the data with '$' or '%' to indicate hexidecimal format or
|
|
binary format respectively. If no prefix is included, the data is
|
|
assumed to be decimal. Once a prefix is attached to the first
|
|
figure, all other figures input on that line are assumed to be in
|
|
the same format and no further prefixes are required. For example,
|
|
typing:
|
|
|
|
$7f 6a f2 00 37
|
|
|
|
would place $7F in the specified memory location and $F2, $00 and
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 18
|
|
|
|
$37 int and no further prefixes are required. For example, typing:
|
|
|
|
$7f 6a f2 00 37
|
|
|
|
would place $7F in the specified memory location and $F2, $00 and
|
|
$37 in the next 3 memory locations.
|
|
|
|
|
|
Option 'D'
|
|
----------
|
|
The 'D' dump program option is used to dump a disassembled copy
|
|
of the program in a user specified memory range to disk. If symbol
|
|
information is read into DR6502 then the disassembled listing will
|
|
contain symbolic representations for any address references in
|
|
arguments. This allows the user to make changes in the code
|
|
permanent. (See Appendix B: Merging with EDIT/Blackbeard to
|
|
recognize the possibilities here)
|
|
|
|
|
|
Option 'P'
|
|
----------
|
|
|
|
The 'P' (re)program option reads, disassembles and displays 256
|
|
bytes or one page of program code starting at a user selected
|
|
address. The user may then move a cursor '=>' up and down ('u' and
|
|
'd') line by line through the disassembled page. The user may quit
|
|
the 'P' (re)program option with the 'q' key. The '+' key causes the
|
|
simulator to read the Next page of assembly code. If the user would
|
|
like to look at a different part of the code, the 'p' causes the
|
|
simulator to read a new page of code starting at a user specified
|
|
address. Using these commands and the 'u' and 'd' commands this is
|
|
similar to a 'view code' mode however there are other subcommand
|
|
options that allow the user to alter the program at the assembly
|
|
language level.
|
|
|
|
The 'c' change suboption allows the user to input lines of
|
|
assembly code as opcodes and operands. Note that labels and macros
|
|
are not allowed since this is a line by line assembly process. Be
|
|
warned that the change suboption overwrites the bytes of code that
|
|
were in the locations prior to changing. If the change requires
|
|
more than a simple substitution or if the user is not certain that
|
|
the opcode alignment will be preserved after the change then the
|
|
make space option (described below) should be used first.
|
|
|
|
All editing of the code is done in a buffer so that if
|
|
mistakes are made in changes to the code, the actual 6502 memory map
|
|
can be read again to retrieve the original program. The 's' save
|
|
subcommand saves the current page of assembly code back into the
|
|
6502 virtual memory. This does not make the change permanent (to
|
|
the binary file) but will remain for the rest of the session with
|
|
the simulator. If the user would like to make program changes made
|
|
in the simulator permanent then consult the 'D' option of the
|
|
Stopped Mode commands.
|
|
|
|
If the user has made changes to the program in the buffer and
|
|
would like to discard them and reread the program from the 6502
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 19
|
|
|
|
virtual memory then the 'r' reread option is available. This will
|
|
discard any changes that may have been made in 'c' change operations
|
|
but will not discard changes that have been saved with the 's' save
|
|
option. If a virgin copy of the program is required then the user
|
|
must exit the simulator and start over so that the .BIN file can be
|
|
reread.
|
|
|
|
The simulator is capable of reading a file of symbol
|
|
information if one is produced using DRSYM. Whether a file has been
|
|
input or not the user can 'a' assign values to new symbols or 'l'
|
|
label the current memory address with a symbol (as with branch
|
|
labels). The user can search the list of symbols for 'i'
|
|
information, either the symbol assigned to an address or the address
|
|
represented by an symbol. Users may prefer to see or not to see the
|
|
branch line labels in the assembly code and these can be toggled on
|
|
and off by the 'b' option.
|
|
|
|
The user is able to make notes in the notepad with the 'n'
|
|
suboption of the 'P' option. This is the same notepad as is
|
|
accessed from the stopped status screen and is very useful for
|
|
making note of address, labels or diagnostic states.
|
|
|
|
When the user has found that an error has been made and some
|
|
code has been omitted, the 'c' change suboption is not sufficient.
|
|
The user must first open up a space in the program for the omitted
|
|
code to be inserted. The 'm' make space option does just this.
|
|
Here is a graphical representation of the 'make space' process
|
|
|
|
|
|
Program Start Addr > ============= =============
|
|
| | | |
|
|
| | | |
|
|
| A | | A |
|
|
| | | |
|
|
Cut ____|___________| |___________|
|
|
Here | | | |
|
|
| | | NOP Filler|
|
|
| B | Slide down ____|___________|
|
|
| | to here | |
|
|
| | | |
|
|
Program End Addr > ============= | B |
|
|
| | | |
|
|
| | | |
|
|
=============
|
|
|
|
|
|
............. End of Eprom .............
|
|
|
|
Process in Brief:
|
|
|
|
1) Program sections (A+B) are searched for address references to the
|
|
B section (JMPs, JSRs, Branches, Data access like LDA, STA etc).
|
|
The references are adjusted to reflect the relocation of the B
|
|
section of the program.
|
|
Two possible error conditions can arise during this
|
|
adjustment. Relative branches have a maximum length of 128
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 20
|
|
|
|
bytes. If a relative branch forward or backward crosses the cut
|
|
line and the added length of the branch due to the inserted
|
|
section exceeds the maximum length of a branch then an error is
|
|
counted and the branch is recorded as Bxx $FE. This will result
|
|
in an endless loop if the branch is taken but will also be easier
|
|
to find if you have to change it. Absolute addresses must fall
|
|
into the range of $0000-$FFFF. If the user has miscalculated and
|
|
tries to make so much space that the end of the B section of the
|
|
code is pushed off the end of the EPROM space (past $FFFF) then
|
|
another error will occur. If an absolute address plus the offset
|
|
of the move exceeds $FFFF then these are counted as errors and the
|
|
address is recorded as $0000. This would happen for references to
|
|
the part of B that is pushed off the end of the EPROM.
|
|
If any symbol information has been input into DR6502, either
|
|
with a .SYM file at the beginning of the session of during the
|
|
session with the 'a' assign symbol or 'l' label current address
|
|
commands, then these symbols are adjusted as well. The code will
|
|
automatically adjust all address labels that fall into the range
|
|
of code being moved.
|
|
Since labels used to represent constants (as opposed to those
|
|
used to represent addresses) are not present in the symbol table
|
|
as created by DRSYM, the DR6502 system attempts to shield the user
|
|
from the following problem. In the rare instance that the user
|
|
has used the 'a' assign symbol to assign a symbol used as a
|
|
constant AND has assembly code on the zero page AND uses the 'm'
|
|
make space option to move it, the following can be a problem.
|
|
There is the possibility that constant symbols may be confused for
|
|
address labels. If for instance the code being moved was in the
|
|
range $0060-$0090 and a constant label like 'Bit_7_set = $80' is
|
|
assigned by the user during the simulator session, then DR6502
|
|
will mistakenly adjust this label's value interpreting it as an
|
|
address. This has NO EFFECT on the actual code since in the
|
|
memory of the 6502, TASM has already removed the symbols from the
|
|
machine code. This also has NO EFFECT on the disassembled outputs
|
|
produced by DR6502 in the 'D' or 'P' options since constant
|
|
arguments are never substituted for. In the 'D' option however,
|
|
at the beginning of the file produced, DR6502 writes out the
|
|
values of all the symbols in the form of assembly language
|
|
assignment statements. (This allows the 'D' dumped code to be
|
|
reassembled directly if the user desires.) In the list of
|
|
assignments the label 'Bit_7_set = ...' will have an adjusted
|
|
address.
|
|
|
|
2) The slide is performed, regardless of any errors that were
|
|
encountered. The simulator was programmed assuming the user knows
|
|
what they are doing, allowing users who know what they are doing
|
|
to do some very unusual things. If one of the errors mentioned
|
|
above occurs and you were not anticipating it then it may be best
|
|
to end the session and start again with a virgin copy of the
|
|
binary code.
|
|
|
|
3) The space opened up is then filled with NOP instructions. Since
|
|
NOP instructions are one byte long, they can be replaced in the
|
|
'c' change option in reprogramming the code without worrying about
|
|
the opcode alignment. The simulator is optimized to execute a
|
|
memory space filled with NOP instructions very quickly so the user
|
|
need not worry about opening up a little more space than is
|
|
required by the code to be inserted.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 21
|
|
|
|
The 'm' make space subcommand requires the user to input the
|
|
first and last program space addresses to define the space A+B. The
|
|
address of the first opcode of section B is input to define the
|
|
position of the cut. The new address of the first opcode of section
|
|
B is input to define the offset of the relocation. Spaces can only
|
|
be created by this method. If a data table is present then care
|
|
must be taken that it has been handled in one of the ways as
|
|
described below.
|
|
|
|
Address references are CORRECTED for the new location of the
|
|
relocated part of the code but ONLY within a user specified
|
|
'program' area. Herein lies another problem. A program is a thin
|
|
line of opcode alignment; shift by one byte and a program starts
|
|
looking like a random stream of bytes. (See Appendix A for an
|
|
explanation/definition of opcode alignment) Given a valid program
|
|
opcode address as a starting point, a program can be traced and
|
|
address references to the area of relocated code can be adjusted.
|
|
If the program encounters a 'data' space half way through the
|
|
'program' space it is not trivial for the program to determine where
|
|
the data space ends and the program space resumes since op-code
|
|
misalignment can make programs look like data and coincidental data
|
|
may appear to be a program. As a result, if this relocate option of
|
|
DR6502 is to be used one of three arrangements must be used. NOTE:
|
|
the described options are only necessary if DATA (.BYTE or .WORD)
|
|
directives have been included in the eprom.
|
|
|
|
One option is to put user data tables that are to be burned
|
|
into the eprom at the beginning of the eprom before the program
|
|
code. In this case, the user specified 'program' space defined for
|
|
the purposes of address reference adjustments would be specified
|
|
from after the data table to the end of the program. (Note NOT the
|
|
end of the eprom! If the user hopes to create a blank space in the
|
|
program space then the end of the program cannot be specified as the
|
|
last address of the eprom or the memory shift will result in
|
|
'spillage' off the high end of the eprom.)
|
|
|
|
A second option is to put the data directly after the program.
|
|
In this case two things are necessary. First the data must be
|
|
defined as part of the program space so that it is relocated along
|
|
with the code instead of being overwritten. This will also make
|
|
sure that address references to the data table will be corrected.
|
|
At least one non-opcode byte must appear between the program and the
|
|
data table so that when DR6502 encounters this byte it will know a
|
|
data table has started and it will not attempt to interpret any
|
|
bytes that follow as opcodes or operands. Any non-opcode byte would
|
|
do just fine.
|
|
|
|
A third option is to put the data table at the very highest
|
|
address of the eprom, leaving a space between the end of the program
|
|
and the beginning of the data. In this case when defining the
|
|
'program' section, do not include the data. The relocated program
|
|
will move closer to the data when slid toward higher memory to make
|
|
room for more program lines.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 22
|
|
|
|
7) Extended Instruction Set for the 65C02 and Rockwell R65C02
|
|
=============================================================
|
|
|
|
With the development of the AER 201S computer board, which uses
|
|
the 65C02, it became more necessary for DR6502 to handle the
|
|
extended CMOS instruction set. Since the R65C02 is commonly
|
|
available, the specialty Rockwell instructions may also be
|
|
required. The following instructions were therefore added:
|
|
|
|
Branch Bit Reset (R65C02):
|
|
BBR0 zpage,rel ; BBR1, BBR2, BBR3, BBR4, BBR5, BBR6, BBR7
|
|
|
|
Branch Bit Set (R65C02):
|
|
BBS0 zpage,rel ; BBS1, BBS2, BBS3, BBS4, BBS5, BBS6, BBS7
|
|
|
|
BRanch Always (65C02):
|
|
BRA rel
|
|
|
|
PusH/PulL X and Y (65C02):
|
|
PHX, PHY, PLX, PLY
|
|
|
|
Reset memory bit (R65C02):
|
|
RMB0 zpage ; RMB1, RMB2, RMB3, RMB4, RMB5, RMB6, RMB7
|
|
|
|
Set Memory Bit (R65C02):
|
|
SMB0 zpage ; SMB1, SMB2, SMB3, SMB4, SMB5, SMB6, SMB7
|
|
|
|
STore #$00 Zero into a memory location (65C02):
|
|
STZ address mode
|
|
|
|
Test and Reset Bits (65C02):
|
|
TRB address mode
|
|
|
|
Test and Set Bits (65C02):
|
|
TSB address mode
|
|
|
|
Note that no accurate number of clock cycles durations were
|
|
available for the R65C02 instructions so estimates were used based
|
|
on other 6502 instructions.
|
|
|
|
The simple indirect (zpage) address mode was also added for memory
|
|
fetches as per the 65C02 standard. The special address/argument
|
|
structure of the BBSx and BBRx of zpage,rel is also supported.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 23
|
|
|
|
8) Differences Between DR6502 and the R6502, 65C02 and R65C02
|
|
=============================================================
|
|
|
|
Reference 3, Hendrix, details some anomalies in the operation
|
|
of the 6502 in Chapter 6 'Quirks, Bugs and Other Oddities of the
|
|
6502' which will be mentioned shortly. The simulator was not
|
|
programmed intentionally to imitate any of these problems in the
|
|
6502.
|
|
When using the add or subtract instructions in decimal mode on
|
|
the NMOS 6502, the Negative flag, Overflow flag and Zero flags are
|
|
not valid. On the 65C02 they are valid however the instructions
|
|
require one more clock cycle. In the simulator they are valid,
|
|
regardless of 6502 version simulated and the execution clock cycles
|
|
used are correct for the type of processor selected. If the
|
|
simulator is used to simulate an NMOS 6502 using the add and
|
|
subtract in decimal mode and makes use of the N, V or Z flags, the
|
|
simulation will not match the real (errant) execution of the NMOS
|
|
6502.
|
|
When using the indirect jump with a the address of a page (ie:
|
|
ending with $FF), an NMOS 6502 does not fetch the high byte of the
|
|
jump vector from the first byte of the next page but incorrectly
|
|
from the first byte of the current page. In NMOS 6502 mode, the
|
|
simulator flags JMP ($xxFF) as an error because on a 6502 it leads
|
|
to an incorrect jump. It is assumed that no program is designed to
|
|
exploit this error. The 65C02 does the jump correctly requiring an
|
|
addition clock cycle as does the simulator in 65C02 and R65C02 mode.
|
|
The unimplemented opcodes on the NMOS 6502 do unpredictable
|
|
things, sometimes crashing the CPU. The unimplemented opcodes on
|
|
the 65C02 and R65C02 are taken as NOP instructions. All
|
|
unimplemented NMOS 6502, 65C02 and R65C02 instructions are
|
|
interpreted as crash codes by the simulator since it is assumed a
|
|
user will never use an invalid code in the intended program.
|
|
The 6502 has no such thing as an idle bus cycle. In all cycles
|
|
there must be either a read from or a write to memory. The NMOS
|
|
6502, 65C02 and R65C02 all perform an extraneous read when executing
|
|
a absolute indexed addressing mode. The NMOS 6502 reads the next
|
|
byte after the instruction's argument, sometimes causing an error
|
|
with I/O devices that are sensitive to having their port memory
|
|
location read. The 65C02 and R65C02 both read the last byte of the
|
|
present instruction with less chance of such an error. The
|
|
simulator does not perform any extraneous reads.
|
|
The NMOS 6502 does not modify the decimal mode flag in the
|
|
processor status register in a reset operation or an interrupt. The
|
|
65C02 and R65C02 does clear the decimal mode flag in these two
|
|
cases. The simulator clears the decimal flag for all resets
|
|
regardless of the processor chosen. The simulator clears the
|
|
decimal flag on interrupts only in the case of 65C02 and R65C02
|
|
processors.
|
|
The NMOS 6502 requires 7 machine cycles to perform an absolute
|
|
indexed read/modify/write operator type instruction such as INC, ASL
|
|
or ROR. The 65C02 and R65C02 requires only 6 cycles to do the same
|
|
instructions in that particular addressing mode. The simulator uses
|
|
the correct number of cycles in each case.
|
|
The NMOS 6502 does not save any information on receiving a
|
|
reset signal. The 65C02 and R65C02 saves information on reset
|
|
consistent with an interrupt signal. The simulator does not save
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 24
|
|
|
|
any information on reset regardless of which processor it is
|
|
emulating.
|
|
In read/modify/write operator instructions such as DEC, LSR or
|
|
ROL there is an 'idle' bus cycle during the modify operation. As
|
|
mentioned above there is no such thing as an idle cycle for the
|
|
6502, either a read or a write must be performed. In the case of
|
|
these type of instructions, either a read or a write is performed in
|
|
the modify cycle to the address that will be written to on the
|
|
following cycle. Once again, unnecessary reads or writes can cause
|
|
problems with peripheral ports. The simulator does not do the
|
|
extraneous read or write.
|
|
|
|
Summary
|
|
-------
|
|
All of the above cases where the simulator deviates from the
|
|
processors, the instances are rare or the true behaviour is
|
|
undesirable. Any other deviations from the simulation of the actual
|
|
behaviour of the processor chosen is an error in the simulator.
|
|
Though not many such errors are likely to exist in the program,
|
|
there are undoubtedly a few left. Such errors will be fixed as soon
|
|
as they are identified by a user or a user supplies a minimum length
|
|
program (5-10 lines) and the simulator commands that will cause the
|
|
error every time.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 25
|
|
|
|
9) DR 6502 Support Files
|
|
========================
|
|
|
|
List of Files Necessary to the Operation of the Simulator
|
|
---------------------------------------------------------
|
|
DR6502.EXE - Main executable code of the simulator
|
|
OVERLAY1.EXE - Second module of the simulator program
|
|
CONFIG.EXE - Creates Memory Map 'CONFIG' files for your target
|
|
BLANK.BAS - A file used to initialize the 6502 virtual memory
|
|
CINST.SET - 6502, 65C02 and R65C02 Instruction sets
|
|
DRSYM.EXE - Symbol table preparation program
|
|
DRSYM.BAS - The BASIC source code for DRSYM.EXE
|
|
MM.COM - Utility to display memory allocation
|
|
MARK.COM - A memory resident utility whose purpose is to
|
|
mark a point in memory
|
|
RELEASE.COM - A memory utility used to release all memory
|
|
resident programs added after the last mark
|
|
in memory
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 26
|
|
|
|
10) References
|
|
==============
|
|
|
|
1) Commodore 64 Reference Manual, Chapter 5: Machine Language,
|
|
pp209-259
|
|
|
|
2) The Transactor, Volume 4, Issue 05, pp52-53 (Reprinted in your
|
|
handouts)
|
|
|
|
3) Steven P. Hendrix, The 6502, 65C02 and 65816 Handbook, Weber
|
|
Systems Inc., Cleveland, Ohio, 1986, pp221-227
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 27
|
|
|
|
Appendix A: OpCode Alignment
|
|
============================
|
|
|
|
Note that the 65C02 will not necessarily have the same problems
|
|
as a 6502 with opcode alignment, it will have worse problems
|
|
actually. Please read on and the differences will be explained.
|
|
So you aren't quite clear on what exactly I mean by opcode
|
|
alignment. Consider this question: How many groves are there in the
|
|
average phonograph record? The answer is one (or maybe two - one on
|
|
each side). This is a very unique condition if you think about it:
|
|
Put the needle down anywhere and the record will always play the
|
|
same series of songs. A few years back there was at least one
|
|
novelty record made where there were two groves, two possible series
|
|
of songs depending on the original placement of the needle on the
|
|
record. This record is conceptually similar to an assembly program,
|
|
where the songs represent the instructions in the program. The
|
|
series of songs played depends on the starting point on the record,
|
|
whether grove one or two is chosen. There are only two possible
|
|
'programs' available to the listener. Only the radial starting
|
|
point in the record determines what portion of two 'programs' are
|
|
played. An assembly language program however is more closely
|
|
comparable to a Snakes and Ladders game with rich interconnections
|
|
than to the sequential nature of a recording.
|
|
I know, you are saying hold on now, I have only one program, I
|
|
used the assembler, where is this other program you are talking
|
|
about? Well you are absolutely right, you have only one program: in
|
|
assembly. In machine code it is just numbers in an EPROM. Try
|
|
looking at machine code even when you know what is supposed to be
|
|
there: the program is not obvious. The key point is recognizing
|
|
what bytes represent opcodes and what bytes represent operands. To
|
|
the human eye opcodes, 'pop' out from inspection. A9 - LDA; 8D -
|
|
STA; 20 - JSR Your brain sees these and recognizes the pattern. The
|
|
6502 is not blessed with this ability to 'see' what are opcodes and
|
|
what are not. All it knows is the next byte it fetches will be an
|
|
opcode, then the operands, then another opcode. Where you start
|
|
determines what the 6502 interprets as the first instruction and the
|
|
course of the program from then on. Using an assembler assures that
|
|
opcodes will be in the right spot at the right time and things will
|
|
go just fine, provided no .BYTE directives are placed in the middle
|
|
of a piece of code. The problem arises when the user starts hacking
|
|
around with a piece of software with a tool like DR6502. If the
|
|
code has an error or if the user messes up the program, an operand
|
|
may be fetched instead of an opcode and all of a sudden the 6502 is
|
|
executing a very different program.
|
|
So just how many of these alternate universe programs are there
|
|
in a given piece of machine code? Well, if you have 4k of code, if
|
|
we take 35-50% of those bytes to be opcodes and the rest operands
|
|
then there are a good 2000 possible alternate universes that your
|
|
6502 could fall into. There is some good news and some bad news.
|
|
These alternate programs are very unstable (and erratic) and they
|
|
usually do one of two things after a few opcode fetches. They
|
|
either crash (that's the good news, because you know you have a
|
|
problem) after fetching an bad opcode or they fall back in line with
|
|
the proper opcode alignment and things go back to normal. This is
|
|
very bad since you may have a 'mysterious' error that you have no
|
|
idea what is going on with. Now what are the probabilities for all
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 28
|
|
|
|
of this? Of all the 256 opcodes, about 151 correspond to valid
|
|
opcodes, about 35 crash the CPU outright and the other 70 or so are
|
|
weird combinations of incrementing and adding with strange flag
|
|
results. In a real 6502 system, the CPU has a (151+70)/256 chance
|
|
of continuing to execute. Upon the completion of each opcode there
|
|
is the chance that the proper opcode stream may be rejoined. The
|
|
chance therefore of an outright crash is low. The bottom line: this
|
|
is bad news.
|
|
Someone, in a stroke of genius, said lets make the 65C02
|
|
better. Lets make all of the undefined opcodes behave as NOP's.
|
|
The 65C02 can NEVER crash. After hopping into the wrong opcode
|
|
alignment, the 65C02 will execute a maximum of two undefined opcodes
|
|
in a row before rejoining the proper opcode alignment. The
|
|
difficulty is that the 65C02 has a great number more defined opcodes
|
|
so a 'strange' program will execute for a long time before hitting
|
|
an undefined opcode, executing a NOP and rejoining the proper opcode
|
|
stream (possibly). If you are operating DR6502 and have used only
|
|
regular 6502 instructions then you should use DR6502 in 6502 mode.
|
|
This will cause the simulator to object to a wider array of mistakes
|
|
and more quickly.
|
|
The overall landscape of a section of machine code if compared
|
|
to a record would have a great many possible paths threading near
|
|
the intended opcode path. The alternate paths would be short lived
|
|
in general and would most frequently rejoin the main path but would
|
|
occasionally dead end in a crash. The Snakes and Ladders
|
|
interpretation necessary when considering loops in the real code and
|
|
accidental branches, JMPs, RTS, JSR statements in the parallel codes
|
|
would not look very different since a quick count gives only
|
|
(8+1+2+2)=13 program counter modifying opcodes out of the 151 legal
|
|
codes. If the proportion is the same for the illegal 70 or so codes
|
|
then the chances of an accidental jump is only about 1 in 10. These
|
|
instances are catastrophes since the destination (by Murphy's Law)
|
|
is nearly always a pure data space where there is no opcode line to
|
|
be rejoined and the results can be very erratic.
|
|
|
|
In summary: How do you get off track and how to avoid it? The
|
|
easiest way is to push data into the stack in a subroutine and
|
|
forget to pull it off again before executing an RTS (frightfully
|
|
common error). Mishandling interrupts, etc could be a real problem
|
|
usually in the misbalance of the stack and return addresses. Doing
|
|
little tricks like using the address pushed on the stack after a JSR
|
|
in a calculation and returning the wrong number to the stack or
|
|
using calculated JMPs using a push and RTS method and messing up the
|
|
address etc would do it too. If you use DR6502 you could do it in
|
|
one careless p-poke command or not watching what you are doing while
|
|
using the P-program command. The best way to avoid the alignment
|
|
problem is knowing it exists and being very careful of the stack and
|
|
changes to the program.
|
|
|
|
An exercise: If you want to see what an alternate universe
|
|
program looks like, invoke the P-program function on DR6052 with a
|
|
program loaded. If your code starts at $E000 try giving DR6502 the
|
|
page start address of $E000+a random number that does not correspond
|
|
to an opcode address and observe the results. 105/256 opcodes will
|
|
show up as .BYTE directives which means you have no idea what a real
|
|
6502 would do. 70% of the time it will do something, with some
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 29
|
|
|
|
operands and lead to another opcode fetch. 30% of the time
|
|
(anything $x2 or $xF is usually a crash) it will lead to a crash.
|
|
DR6502 traps all undefined opcodes as errors and halts execution.
|
|
|
|
The 65C02 was improved to define all undefined opcopes to be
|
|
NOPs so that alternate program streams will never crash the system.
|
|
As pointed out before, the alternate program lines that rejoin the
|
|
main program line are more mysterious and dangerous than ones that
|
|
crash the computer outright. DR6502 still considers all
|
|
non-allocated 65C02 opcodes as crashes and halts the 'processor'.
|
|
This is done because in the actual program such codes should never
|
|
occur and when they do it is a sure sign that something is wrong.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page 30
|
|
|
|
Appendix B: Merging with EDIT/Blackbeard
|
|
========================================
|
|
|
|
You have probably found yourself reading this because you have
|
|
a section of 'invented' assembly that you made up to patch a bug
|
|
found while using DR6502 in one file and your original code in
|
|
another file. The merging process is a simple one:
|
|
|
|
|
|
1) edit the original file
|
|
2) ctrl-F2 to switch to window #2 (see Windows-Switch-window#2 in
|
|
ESC help menus)
|
|
3) ctrl-n to select a new file for window #2 (see Files-Newfile in
|
|
help) and enter the filename of the 'invented' section of code.
|
|
4) 'Copy' the desired section of the code from the 'invented' file
|
|
using f1 to mark the top of the range, f2 to mark the line after
|
|
the end of the range, f3 to copy this range into the paste
|
|
buffer. (transfer smaller blocks if the whole block is too large
|
|
for the paste buffer - shift f9 clears the paste buffer)
|
|
5) ctrl-f1 to switch back to window#1 where the original source code
|
|
is.
|
|
6) Cursor to the line that the range is to be inserted before and
|
|
press f7.
|
|
7) Make what ever other changes are necessary and
|
|
8) ctrl-z to save!
|
|
|