Premier IT Outsourcing and Support Services within the UK

User Tools

Site Tools

Problem, Formatting or Query -  Send Feedback

Was this page helpful?-10+1

  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. ——- —-

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?

  1. ——————————————

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

Memory Management

  1. —————-

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?

  1. —————————————————-

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?

  1. ————————————————

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

  1. ———————————————-

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

Mode 1: Break Point and No Output

  1. ——————————–

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

  1. ——————————–

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

  1. ——————

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

  1. ——————-

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
   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.


   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
  1. ————————————————————————-

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.
  1. ————————————————————————

Time=000000.000042 million cycles

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.
  1. ———————————————————————-

NOP Cruise $F005-$F009

F009 EA       NOP  (10)           00 FF 00 FF F009=>F00A 10100000 0080=#$????

Option 'i'

  1. ———

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'

  1. ———

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

  1. ———————

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

  1. —————————-

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'

  1. ———

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'

  1. ———

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:


    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'

  1. ———

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'

  1. ———

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,

$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'

  1. ———

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'

  1. ———

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

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

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):


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
   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
   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
   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

   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.


  1. ——

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

  1. ——————————————————–

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,


2) The Transactor, Volume 4, Issue 05, pp52-53 (Reprinted in your


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
    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!

/data/webs/external/dokuwiki/data/pages/archive/programming/dr6502.txt · Last modified: 2000/12/16 02:37 (external edit)