  sim68xx Users Guide
  Arne Riiber, riiber@systek.no <mailto:riiber@systek.no>
  August 1999

  The main purpose of this document is to describe how to use and cus
  tomize the sim68xx simulator family. Sim68xx programs can simulate
  microcontrollers like HD6301V0, MC68HC05C8, and MC68HC11A0.  It can
  also be used for other CPUs in the same family (6800 for example).
  ______________________________________________________________________

  Table of Contents:

  .       Introduction

  1.      Features

  2.      Future

  2.1.    Graphical window user interface

  2.2.    Character window user interface

  2.3.    Symbolic C debugging

  2.4.    Dynamic Linking for simulating on-chip and external IO

  3.      Revision history

  3.      Installing the simulator

  4.      Getting the simulator

  5.      Installing on unix

  5.1.    Extracting the archive

  5.2.    Compiling the source code

  5.3.    Installing the binaries

  6.      Installing on DOS/Windows

  6.1.    Extracting the archive

  6.2.    Compiling the source code

  6.3.    Installing the binaries

  6.3.    Running the simulator

  7.      Starting up

  8.      Getting on-line help

  9.      Displaying the source

  10.     Stepping through an instruction

  11.     Setting break point

  12.     Running until breakpoint

  13.     Displaying the call stack

  14.     Entering IO port data

  14.     Adding code that simulates your hardware

  15.     Simulator API for installing an IO port function

  16.     Simulator API for storage of IO port data

  17.     Simulator API for memory access

  18.     Example

  18.1.   Hardware circuit

  18.2.   Polled IO

  18.2.1. Target CPU (68xx) code

  18.2.2. Simulator code

  18.3.   Interrupt IO

  18.3.1. Target CPU (68xx) code

  18.3.2. Simulator code

  18.3.2. FAQ - Frequently Asked Questions

  19.     Why did you write this simulator?

  20.     What is the difference between a simulator and an emulator?

  21.     When can I benefit from using a simulator like this?

  22.     What are the design ideas behind the simulator?

  23.     Why is there no DOS version?

  24.     How can I compile under DOS?

  25.     Why are there so many directories?

  26.     How does the simulator simulate interrupt?

  27.     What other simulators exist?

  27.1.   BSVC

  27.2.   UMPS

  27.3.   NOICE

  27.4.   tgdb

  28.     How to simulate interrupt when using the simulator?

  29.     How to simulate interrupt that happens when the simulator is
  running?

  30.     How to get IO data into the simulator?

  31.     How to get IO data out from the simulator?

  32.     What is the difference between the 6800, 6301, 6805 and 6811?

  32.1.   6800 family

  32.2.   6301 family

  32.3.   6805 family

  32.4.   6811 family

  33.     Are there any design notes?

  33.1.   Design note 1

  33.2.   Design note 2

  33.3.   Design note 3

  33.4.   Design note 4 - results of inlining

  33.5.   Design note 5 - character user interface

  33.6.   Design note 6 - how the SPI is simulated

  33.7.   Design note 7 - I2C
  ______________________________________________________________________

  11..  IInnttrroodduuccttiioonn

  11..11..  FFeeaattuurreess

    Simulation of 6801/6301, 6805, and 6811 series processors

    ROM like monitor with one/two character commands (Motorola style)

    Breakpoints in code and data

    Disassembler

    Global symbol table (formats generated by ASLINK and FASM)

    On chip I/O partially simulated (SCI, SPI, single timer output
     compare)

    64K memory model

    Easy for user to add  code simulating IO peripherals. A couple of
     examples included (including an I2C like device, Xicor X9241).

    Runs many example test programs, including monitors. A rather
     comprehensive 6800 test program from the 6800 user group archive on
     Motorolas FTP site (http://www.mot.com/sps/mcu/usrgroup) has been
     successfully run on the simulator.

    Performance. When compiled with gcc and inlining, the simulator
     runs at

    486DX33 w/64kb cache

    0.15 the speed of an 8Mhz 6811 (2Mhz internal clock)

    0.4 the speed of an 2.4576 Mhz 6301 (0.6144 Mhz internal clock)

    Pentium 133

    0.5 the speed of an 8Mhz 6811 (2Mhz internal clock)

    1.0 the speed of an 2.4576 Mhz 6301 (0.6144 Mhz internal clock)

  11..22..  FFuuttuurree

  The following is a list of features that may be added to sim68xx in
  the future.

  11..22..11..  GGrraapphhiiccaall wwiinnddooww uusseerr iinntteerrffaaccee

  Candidates to concider:

    Tcl/Tk (tksim68xx). Will run under Unix, MS Windows and Mac.
     Windows and commands have already been designed using the vtcl GUI
     builder (vtcl).

    Java AWT (jsim68xx). Standalone or applet. Will run on Unix, MS
     Windows, OS/2 and Mac.

    WxWindows. Will run under Unix, MS Windows and Mac.

    V. Will run under Unix, MS Windows (later OS/2 and Mac)

    YACL. Will run under Unix, MS Windows, OS/2 and Mac.

  11..22..22..  CChhaarraacctteerr wwiinnddooww uusseerr iinntteerrffaaccee

  Candidates to concider:

    Xview (sim68xxtool). Will run under Unix variants supporting Open
     Windows, for example Sun, Linux, AT&T.

    Turbo Vision (tvsim68xx). Will run under MSDOS, OS/2 and Unix (at
     least Linux), but not native MS Windows.

  11..22..33..  SSyymmbboolliicc CC ddeebbuuggggiinngg

  This requires that symbol and line number information is available,
  either in the executable file or in a separate file. Which symbol
  format that will be supported, has to be defined. The ASLINK and FASM
  assemblers that are support global symbols only.

  Remote debugging, where the simulator communicates with a symbolic
  debugger over a serial line (simulated or real line), is another
  possible solution. It is quite attractive in the way that the debugger
  is completely independent of the simulator. The GNU debugger, GDB, for
  example, has defined a protocol to debug using a serial line. GDB can
  use this protocol to read from and write to memory adresses.

  11..22..44..  DDyynnaammiicc LLiinnkkiinngg ffoorr ssiimmuullaattiinngg oonn--cchhiipp aanndd eexxtteerrnnaall IIOO

  The current design requires that code for simulating IO is separately
  compiled, and statically linked into the executable, even though the
  simulator calls the IO through a function pointer.

  11..33..  RReevviissiioonn hhiissttoorryy

    1996-08-03/AR. Created document skeleton.

    1996-08-03/AR. Wrote IO chapters with unfinished example.

    1999-08-20/AR. Completed. Collected info from many small files.

  22..  IInnssttaalllliinngg tthhee ssiimmuullaattoorr

  This chapter is incomplete.

  22..11..  GGeettttiinngg tthhee ssiimmuullaattoorr

  The home page for the simulator is located at:
  http://www.geocities.com/TheTropics/Harbor/8707/simulator/sim68xx
  <http://www.geocities.com/TheTropics/Harbor/8707/simulator/sim68xx>

  From this homepage, you can download executable programs and source
  code.

  In this document, the source code package is named sim68xx.tar.gz or
  sim68xx.zip.

  The following are examples of installing the simulator.

  22..22..  IInnssttaalllliinngg oonn uunniixx

  If you downloaded a binary version, you can skip the compiling.

  22..22..11..  EExxttrraaccttiinngg tthhee aarrcchhiivvee

   unix$ tar xfz sim68xx.tar.gz

   unix$ unzip sim68xx.zip

  22..22..22..  CCoommppiilliinngg tthhee ssoouurrccee ccooddee

  Perform this step if downloaded the source. You need GNU make v.3.70
  or greater.

   unix$ cd src

   unix$ make

  22..22..33..  IInnssttaalllliinngg tthhee bbiinnaarriieess

  The binaries are located in src/boards.  Copy the binaries to a
  directory in the search path.  The simulator can be run without
  copying the binaries, though.

  22..33..  IInnssttaalllliinngg oonn DDOOSS//WWiinnddoowwss

  Please note that the MSDOS version does not exist, use the Win95/NT
  version instead. If you downloaded a binary version, you can skip the
  compiling.

  22..33..11..  EExxttrraaccttiinngg tthhee aarrcchhiivvee

   MSDOS> unzip -a sim68xx.zip

   MSDOS> pkunzip -d sim68xx.zip

  WinZip.

  22..33..22..  CCoommppiilliinngg tthhee ssoouurrccee ccooddee

  Perform this step if downloaded the source. You need the GCC compiler
  for Win32 and GNU make v.3.70 or greater.

   MSDOS> cd src

   MSDOS> gnumake -f makefile.w32

  22..33..33..  IInnssttaalllliinngg tthhee bbiinnaarriieessa
                                 r
  The binaries are located in srcd Copy the binaries to a directory in
  the search path.  The simulatorscan be run without copying the
  binaries, though.              .

  33..  RRuunnnniinngg tthhee ssiimmuullaattoorr

  The following is a guided tour to running the simulator. sim6811 on
  unix is used as example.

  33..11..  SSttaarrttiinngg uupp

  From the top directory, enter the commands

          % cd test/arch/m6811
          % ../../../src/boards/sim6811 68mon.s19
          PC=e06b A:B=0000 X=0000 Y=0000 SP=0000 CCR=d0(SXhInzvc) [0]
          e06b    8e 00 f6       lds  #00f6       STACK

  The simulator is ready to run. The CPU state is printed with registers
  (PC .. CCR), clock cycles (0) on the first line. All numbers are
  printed in hexadecimal (except for clock cycles). On the next line
  follows memory address, the unassembled instruction in hexadecimal and
  mnemonic format, and a symbol string the right.

  33..22..  GGeettttiinngg oonn--lliinnee hheellpp

          >h
          Breakpoint commands
                  b                       - list breakpoints
                  b [+|-] [addr]          - toggle, set(+) or clear(-) breakpoint
                  B s|c [addr]            - set/clear breakpoint
                  B C                     - clear all breakpoints
                  B E|e                   - break on error/no break on error
          Memory commands
                  md [addr [count]]       - memory display
                  mm  addr [hh hh..]      - memory modify
                  u  [addr [count]]       - unassemble
          Run commands
                  g [addr]                - go
                  s                       - step over subroutines
                  t                       - trace one instruction
                  R                       - jump to reset vector
          Stack commands
                  c                       - print call stack
                  C                       - print function calls on/off toggle
                  w [min max]             - set stack watches
          Miscellanous commands
                  l                       - list symbols
                  !Command                - pass 'Command' to shell
                  q                       - quit
          Register commands:
                  r p|a|b|c|d|x|y|s val   - modify register
          External event commands
                  i sci [hh|"ss"] ..        - io input hex digits or strings to SCI
                  i sci print               - print contents of SCI buffer
                  i spi [hh|"ss"] ..        - io input hex digits or strings to SPI
                  i spi print               - print contents of SPI buffer
                  i out [hex|ascii|\ascii]  - io output mode for displaying data

  33..33..  DDiissppllaayyiinngg tthhee ssoouurrccee

  The simulator can only display assembly language and convert numbers
  to global symbols.

          >u
          e06b    8e 00 f6       lds  #00f6       STACK
          e06e    86 20          ldaa #20 SP
          e070    ba 10 28       oraa  1028       SPCR
          e073    b7 10 28       staa  1028       SPCR
          e076    86 30          ldaa #30
          e078    b7 10 2b       staa  102b
          e07b    86 0c          ldaa #0c PTOF
          e07d    b7 10 2d       staa  102d       SCCR2
          e080    7f 00 fd       clr   00fd       FLAG
          e083    86 7e          ldaa #7e

  33..44..  SStteeppppiinngg tthhrroouugghh aann iinnssttrruuccttiioonn

          >t
          PC=e06e A:B=0000 X=0000 Y=0000 SP=00f6 CCR=d0(SXhInzvc) [3]
          e06e    86 20          ldaa #20 SP

  Pressing Enter wil repeat the last command and is well suited for
  stepping through several instructions in sequence.

  33..55..  SSeettttiinngg bbrreeaakk ppooiinntt

  We want to debug the routine GETIN, so we set a breakpoint at its
  entry point, and then list all breakpoints.

          >b GETIN
          Breakpoint at e1d8 set

          >b
          Active breakpoints:
          e1d8    GETIN

  33..66..  RRuunnnniinngg uunnttiill bbrreeaakkppooiinntt

          >g
          e06e: Running...

                         68Mon V1.2 (C) 1992 Keith Vasilakes

            SXHINZVC  AB AA  IX   IY   PC   SP
            11100110  A4 7E E6A4 7EE6 A47E 0000
          >Breakpoint before code execution, address e1d8!
          Subroutine: e1d8 GETIN
          PC=e1d8 A:B=3e03 X=e1fc Y=0000 SP=00f2 CCR=c8(SXhiNzvc) [8936]
          e1d8    b6 10 2e       ldaa  102e       SCSR

  The text printed between Running... and Breakpoint, is output from the
  program running under the simulator.

  33..77..  DDiissppllaayyiinngg tthhee ccaallll ssttaacckk

          >c
          Call stack:
          e1cd    CHRIN
          e1d8    GETIN

  We are in routine GETIN, that was called from routine CHRIN.

  33..88..  EEnntteerriinngg IIOO ppoorrtt ddaattaa

  There are two ways of entering IO port data into the simulator:

    Stop the simulator and change the IO port values, or in the case of
     serial interrupt, enter data into the serial buffer of the
     simulator.

    Serial data can be entered on standard input while the simulator is
     running.

  44..  AAddddiinngg ccooddee tthhaatt ssiimmuullaatteess yyoouurr hhaarrddwwaarree

  The 68xx family use memory mapped IO. For chips containing builtin IO
  ports, the memory is divided into two areas:

    Internal register area for on-chip IO ports

    Memory outside internal register area

  To add code simulating hardware connected to on-chip IO ports, proceed
  as described in subchapter "Simulator API for installing an IO port
  function".

  To add code simulating hardware connected to memory outside the
  internal register area, proceed as in subchapter "Simulator API for
  memory access".

  44..11..  SSiimmuullaattoorr AAPPII ffoorr iinnssttaalllliinngg aann IIOO ppoorrtt ffuunnccttiioonn

  The simulator has space to store a pointer to a function for each
  address in the internal register area.

  Put the installation code in the routine board_install(). This routine
  is called when the simulator starts up.

  To install an IO simulating function, use the macro

    ireg_install(offs,getb,putb)

     where

    offs         is the offset from the start of the IO area

    getb(offs)   is called to get a byte from the IO address

    putb(offs,b) is called to put a byte into the IO address

  See the example section for details.

  44..22..  SSiimmuullaattoorr AAPPII ffoorr ssttoorraaggee ooff IIOO ppoorrtt ddaattaa

  The simulator has a memory area called iram[] where IO port data can
  be stored. Functions installed with ireg_install() can use this area
  for storage of data, but it is not required.

  The simulator will access on-chip IO through the following macros:

    ireg_getb(addr)   - return a byte from memory

    ireg_getw(addr)   - return a word of two bytes from memory

    ireg_putb(addr,b) - put a byte into memory

    ireg_putw(addr,w) - put a word of two bytes into memory

  To store IO port data, use the ireg_put() routines.  To retrieve IO
  port data, use the ireg_get() routines.  See the example section for
  details.
  44..33..  SSiimmuullaattoorr AAPPII ffoorr mmeemmoorryy aacccceessss

  The simulator acesses all memory through the following routines:

    mem_getb(addr)   - return a byte from memory

    mem_getw(addr)   - return a word of two bytes from memory

    mem_putb(addr,b) - put a byte into memory

    mem_putw(addr,w) - put a word of two bytes into memory

  These routines were moved to reside in a header file
  (inc/arch/m68xx/memory.h), to make inlining possible.

  To simulate IO outside the internal register are, modify the file
  inc/arch/m68xx/memory.h to suit your needs.

  44..44..  EExxaammppllee

  The following simple example will show an example with polled IO, and
  is extended to use interrupt IO.

  To be portable to many environments, only the standard C iostream
  input/output routines are used for user interaction.

  A windowing environment could instead have drawn a LED and a switch,
  and let the user toggle the LED when the switch was pushed with the
  mouse.

  44..44..11..  HHaarrddwwaarree cciirrccuuiitt

  Assume a LED is conned to an output port, and a switch is connected to
  an input port as shown below.

          --------+       LED
               PA7|-----|>---------o +5V
                  |        ____ R
          CPU     |    +--|____|---o +5V
                  |    |
               PA6|----+
               ___|    |   ___ SW
               IRQ|----+---o o-----o 0V
          --------+

  When the user pushes the switch SW, the LED is to toggle. The switch
  input is pulled down to 0V when the switch is pushed, and the input is
  also connected to the interrupt input IRQ, to trig an interrupt.

  44..44..22..  PPoolllleedd IIOO

  When polled IO is used, the interrupt line is not used.

  44..44..22..11..  TTaarrggeett CCPPUU ((6688xxxx)) ccooddee

  The following code is to be compiled with a compiler targeted for a
  CPU in the 68xx series.

       char sw_curr; /* Current value of switch SW */
       char sw_last; /* Last value of switch SW */

       main ()
       {
               while (1) {
                       sw_curr = _porta & 0x40; /* read PA6 - switch */
                       if (sw_curr != sw_last) {
                               _porta ~= 0x80; /* write PA7 - LED */
                       }
                       sw_last = sw_curr;
               }
       }

  44..44..22..22..  SSiimmuullaattoorr ccooddee

  The following code is to be compiled with a compiler targeted for a
  the host on which the simulator runs.

  Write the following routines (src/boards/examp1.c).

  /*
   * Called when CPU reads from PORTA
   */
  examp1_porta_getb (offs)
  {
          pa6 = ireg_getb (offs) & 0x40;
          if (pa6) {
                  printf ("Input is ON\n");
          } else {
                  printf ("Input is OFF\n");
          }
          return ireg_getb (offs);
  }

  /*
   * Called when CPU writes to PORTA
   */
  examp1_porta_putb (offs, val)
  {
          pa7 = ireg_getb (offs) & 0x80;
          if (pa7) {
                  printf ("LED is ON\n");
          } else {
                  printf ("LED is OFF\n");
          }
          ireg_putb (offs);
  }

  /*
   * Called when user enters an unknown command or help from simulator prompt
   *
   *    Input             Return
   *      "h"               1
   *      "e" "sw" "on"     1
   *      "e" "sw" "off"    1
   *      other input       0
   */
  int
  examp1_cmd (argc, argv)
          int   argc;
          char *argv[];
  {
          if (argc < 1)
                  return 0;
          /*
           * If user typed 'h', supply some help and return
           */
          if (strncmp (argv[0], "h", strlen("h")) == 0) {
                  printf ("EXAMP1 commands:\n");
                  printf ("       e  sw [on|off] - set switch SW on or off\n");
                  return 1;
          }
          /*
           * Strip command prefix
           */
          if (strcmp (argv[0], "e") != 0) {
                  return 0;
          }
          argv++;
          argc--;
          if (strcmp (argv[0], "sw") == 0) {
                  if (argc > 1) {
                          if (strcmp (argv[1], "on") == 0) {
                                  sw = ON;
                          } else if (strcmp (argv[1], "off") == 0) {
                                  sw = OFF;
                          } else {
                                  printf ("sw can be 'on' or 'off' only\n");
                                  return 0;
                          }
                  }
                  switch(sw) {
                  case ON:
                          ireg_putb(PORTA, ireg_getb(PORTA) | 0x40);
                          return 1;
                  case OFF:
                          ireg_putb(PORTA, ireg_getb(PORTA) & ~0x40);
                          return 1;
                  }
          }
  }

  /*
   * board_install - install user functions
   *
   * Called when the simulator is starting.
   */
  board_install ()
  {
          command_install (examp1_cmd);
          ireg_install (PORTA, examp1_porta_getb, examp1_porta_putb);
  }

  Add the new target examp1 to the Makefile in the src/boards/ directory
  and compile.

  44..44..33..  IInntteerrrruupptt IIOO

  NB! The simulator has currently no way to install user defined
  functions for interrupt lines similar to that for internal registers.

  44..44..33..11..  TTaarrggeett CCPPUU ((6688xxxx)) ccooddee

  char sw_curr; /* Current value of switch SW */
  char sw_last; /* Last value of switch SW */

  /*
   * IRQ Interrupt handler
   *
   * Add required code to install the routine _irq() as an interrupt
   * handler here. Some compilers use #pragma interrupt@IRQADDRESS
   */
  _irq ()
  {
          sw_curr = _porta & 0x40; /* read PA6 - switch */
  }

  main ()
  {
          while (1) {
                  if (sw_curr != sw_last) {
                          _porta ~= 0x80;  /* write PA7 - LED */
                  }
                  sw_last = sw_curr;
          }
  }

  44..44..33..22..  SSiimmuullaattoorr ccooddee

  NB. This subchapter is incomplete!  Missing: How to change the value
  of the IRQ line. The simulator currently has no defined way to do
  this.

  In addition to Polled IO, add the following.

       irq_int ()
       {
       }

       instr_exec ()
       {
               :
               if (irq_int ()) {
                       /* IRQ interrupt occured */
               }
               :
       }

  55..  FFAAQQ -- FFrreeqquueennttllyy AAsskkeedd QQuueessttiioonnss

  55..11..  WWhhyy ddiidd yyoouu wwrriittee tthhiiss ssiimmuullaattoorr??

  I already had written the core of a small 6301 simulator, and needed a
  way to test 6811 and 6805 programs in a project. I tried some free and
  shareware simulators but found them buggy.

  55..22..  WWhhaatt iiss tthhee ddiiffffeerreennccee bbeettwweeeenn aa ssiimmuullaattoorr aanndd aann eemmuullaattoorr??

  Most definitions I have seen agree to the following:

  "An emulator is essentially a simulator running in real time".

  55..33..  WWhheenn ccaann II bbeenneeffiitt ffrroomm uussiinngg aa ssiimmuullaattoorr lliikkee tthhiiss??

    Abbreviations used

    Host - computer where code is written and compiled

    Target - stand alone board

  With these simulators, it is possible to test and debug new code in a
  controlled host environment.

    Scalable - easy to set up test with multiple simulators involved.

    Code is read from file - faster than transferring to a target board
     over a serial line.

    Can it replace hardware CPU emulator?  In some cases yes, in other
     cases, no. You can verify the logic in the simulator. If you have
     problems with the hardware signals between the CPU and external
     hardware, you must observe the electrical signals.

    Non HW specific code can be compiled and testet on host.

    For HW specific code, the user can observe the IO ports, or write
     HW simulating code and link it into the simulator.

  55..44..  WWhhaatt aarree tthhee ddeessiiggnn iiddeeaass bbeehhiinndd tthhee ssiimmuullaattoorr??

  The design ideas are as follows: To be useable, the simulator should
  be easy enough to use, simulate correctly and fast enough. It should
  offer the possibility to verify all signals to/from the CPU on the
  logical level.

  Ranking for useability:

  1. Correct simulation

  2. Easy to use

  3. Speed

  55..55..  WWhhyy iiss tthheerree nnoo DDOOSS vveerrssiioonn??

  Earlier versions of the simulator compiled with Turbo C 2.0 some years
  ago. I have tried to compile the last version with Borland C++ 3.0,
  but got the following error message when linking:

       Fatal: General error in module ../m68xx/io.c near module file offset 0x00000000

  To compile, I had to turn off all warnings, so its possible that even
  if it would link, it would not run.

  55..66..  HHooww ccaann II ccoommppiillee uunnddeerr DDOOSS??

  I have listed the answers so that the supposed least work is first.

  1. You can compile using the DJGPP compiler that needs a standard DOS
     extender environment.

  2. You can use GNU make and your favorite DOS C/C++ compiler. The
     problem so far is that the latest versions of GNU make (>=3.70)
     does not seem to be ported to DOS.

  3. You can the make/build supplied with your favorite DOS C/C++
     compiler. The shortest path to success here would be to make a
     subdirectory for each board, and let the compiler output all object
     files from the source tree in this directory.

  55..77..  WWhhyy aarree tthheerree ssoo mmaannyy ddiirreeccttoorriieess??

  It all started in a single directory for source, object and executable
  files. Then, it was splitted into many directories. Now, the directory
  structure is modeled similar to Linux with many directories that need
  to be traversed.

    The characteristics of the directory traversal are:

    The package will be more dependant on the shell and make utility
     programs, so in practice porting problems may occur.

    Many makefiles must be maintained.

    The code only needs to be compiled once.

    It can be difficult to get the overview.

  Separate source directories for framework and chip specific code, and
  a single object/executable directory for each chip specific board,
  looks as the best structure for this simulator.

  55..88..  HHooww ddooeess tthhee ssiimmuullaattoorr ssiimmuullaattee iinntteerrrruupptt??

  Before the fetching the next opcode, the simulator checks for
  simulated interrupt conditions and will transfer control to the
  interrupt vector with highest priority, if necessary.

  55..99..  WWhhaatt ootthheerr ssiimmuullaattoorrss eexxiisstt??

  55..99..11..  BBSSVVCC

  BSVC is promising. Some commands:

    view/edit memory

     Vieving: Scrollable hex memory dump is presented

     Editing: Clicking on a byte cell pops up a tiny input window

    view/edit registers

     Viewing: Scrollable list of registers is presented

     Editing: Double click a register on the list

    step/trace/run code

    view/edit breakpoints

  2.0 has more "normal menu layouts" (File, Edit, ...)  but basically
  the same functionality. Thus, no real 2.0.

  For source debugging, an absolute listing file must be present.
  Symbols are not supported.  No disassembly, but trace record for each
  instruction executed.

  To use it with sim68xx, the following changes are needed:

  Changes in sim68xx:

    Replace 1-2 char command set with BSVC's

    Modify device attachment ?

     Changes in BSVC:

    Add commands/windows for device input/output/status

    Modify source file display to understand #file:line (This point
     makes it more attractive to look at gdb)

  55..99..22..  UUMMPPSS

  Windows only.

  55..99..33..  NNOOIICCEE

  OK as model for sim68xx GUI.  Global symbols.

  55..99..44..  ttggddbb

  Couldnt get it running (tk4.1) Uses Tksteal, expect, wish and BLT.

  55..1100..  HHooww ttoo ssiimmuullaattee iinntteerrrruupptt wwhheenn uussiinngg tthhee ssiimmuullaattoorr??

  Normally by stopping the simulator and use a command that will cause a
  simulated interrupt event.  Example:

  55..1111..  rruunnnniinngg??  HHooww ttoo ssiimmuullaattee iinntteerrrruupptt tthhaatt hhaappppeennss wwhheenn tthhee ssiimmuu
  llaattoorr iiss

  By sending characters to the standard input of the simulator.

  The only way to get data into the simulator when it is running is to
  send the data to the simulator's standard input, which in most cases
  means the user must type in characters from the console.  The
  simulator will poll standard input between the execution of each N'th
  instruction (currently N=50). If a character can be read from standard
  input, it will be sent to the input routine (io_in???) for the current
  device.

  THERE IS CURRENTLY NO COMMAND TO CHANGE THE CURRENT INPUT DEVICE, IT
  IS ALWAYS SERIAL IN.

  A more flexible input mechanism could use pseudo devices (fifos or
  sockets or similar in an unix environment).

  55..1122..  HHooww ttoo ggeett IIOO ddaattaa iinnttoo tthhee ssiimmuullaattoorr??

  The following is possible without writing any new code:

  All on-chip IO that does not require interrupt (parallel ports, SPI,
  SCI) can be simulated by Enter data into the (symbolic) IO address.
  Example:

  The following is possible by writing a little code:

  55..1133..  HHooww ttoo ggeett IIOO ddaattaa oouutt ffrroomm tthhee ssiimmuullaattoorr??

  Ref. 'How to simulate interrupt that happens ...' above.  Serial
  output (SCI) go to standard output in one of three modes as descibed
  below.  Other output is not displayed in any form.  To get it
  displayed, see the example section.

  IO output modes sent to standard output:

  Ascii (direct output)

  Ascii with non-printable characters as backslash + hex

  Hex

  55..1144..  WWhhaatt iiss tthhee ddiiffffeerreennccee bbeettwweeeenn tthhee 66880000,, 66330011,, 66880055 aanndd 66881111??

  55..1144..11..  66880000 ffaammiillyy

  The 6800 includes no on-chip IO. This was added later in the 6801,
  together with a set of new instructions.

  55..1144..22..  66330011 ffaammiillyy

  The 6301 is basically a clone of the 6801, with a few (about 5) new
  instructions. It is not binary compatible with the 6801/6811 because
  of the opcode conflict with the CPX/XGDX instructions.

       Quick ref. guide to sim. compability                    Arne Riiber 1995

       Chip differences
       ================
       6801, 6301      - ROM on chip
       6803, 6303      - ROM less
       68701, 63701    - EPROM on chip
       V or R          - 128 byte RAM
       X               - 192 byte RAM, 2 Output Compare, Timer2, Sync/async SCI
       Y               - 256 byte RAM, 2 Output Compare, Timer2, Sync/async SCI

               <-----6801-----><---------6301---------><--------6303---------->
               HD6801S HD6801V HD6301V HD6301X HD6301Y HD6303R HD6303X HD6303Y
       ROM     2K      4K      4K      4K      16K     -       -       -
       RAM     128     128     128     192     256     128     192     256
       Timer   1x16    1x16    1x16    1x16*   1x16*   1x16    1x16*   1x16*
       Timer2  -       -       -       1x8     1x8     -       1x8     1x8
       SCI     Async   Async   Async   Sync/as Sync/as Async   Sync/as Sync/as

               * = 2 Output Compare

       sim6301 supports 6801/6301V/6303R series, but not the second timer and
       sync. SCI on X and Y series.

  55..1144..33..  66880055 ffaammiillyy

  The 6805 adds some bit test instructions to the 6800 instruction set.
  It has 8 bit accumulator (A) and index register (X).  The 68HC05C8 use
  the same SCI and SPI as the 68HC11.

  55..1144..44..  66881111 ffaammiillyy

  TO BE DONE!

  55..1155..  AArree tthheerree aannyy ddeessiiggnn nnootteess??

  Yes, and they are included here.

  55..1155..11..  DDeessiiggnn nnoottee 11

  ----------------------------------------------------------------------
  Command line options

  The simulator should have options like
          sim [options] filename
  where options are
          -Cxxx xxx is one of {6800, 6801, 6301, 6811e9, ...}
  that means each cpu has more or less different
          - number of regs available
          - opcodemap
          - hard registers

  ----------------------------------------------------------------------
  Memory interface

  Hard registers can be implemented with routines that provide
  read/write operations interface to memory:
          putmem (addr, value);           writemem (addr, value);
          value = getmem (addr);          value = readmem (addr);

  with the size variants for 8- and 16-bits:
          value = getbyte (addr);
          putbyte (addr, value);

          value = getword (addr);
          putword (addr);

  These routines must take special actions if address references
  a hard register. The actions may be different for each cpu type.

  Q:
          a) NOW WHO IS GOING TO FEED THESE ROUTINES WITH addr?
          b) AND WHO IS GOING TO UPDATE THE PROGRAM COUNTER?

  A:
  a) To give the best conditions to rules in section Detailed execution,
  each little routine that implements an instruction
  could at the detail level set the pc in small steps.

  Addr could be taken directly from the current program counter (pc),
  opcode   = getbyte (cpu.pc);
  operand1 = getbyte (cpu.pc+1) (if any),
  operand2 = getbyte (cpu.pc+2) (if any),

  b) Since some instructions (Bxx, JSR, JMP, RTS, SWI..)
  directly modifies the pc, the functions that implements instructions
  can modify the pc directly or return the new pc to the caller.

  The principal main loop would be

  cpuregs cpu;
  /* uchar   mem[65535]; interface via get/put[byte|word] */

  main()
  {
          fillmem (argv[1], mem); /* fill mem with
          for (;;)
                  exec_instr (opcodemap [getbyte (cpu.pc)]);
  }

  ----------------------------------------------------------------------

  Detailed execution

  A detailed model of the cpu would include the actions taken
  at each clock cycle. A simple implementation could be
  ldaa_imm ()
  {
          step1;
          clock(1);
          step2;
          clock(1);
          :
          stepN;
          clock(1);
  }

  This allow clock() to interrupt execution before an instruction
  is completed. Each instruction can be more or less detailed,
  thus allowing writing instruction in a coarse way first, like

  ldaa_imm ()
  {
          step1_N;
          clock(N);
  }
  ----------------------------------------------------------------------
  This part describes two possible solutions for decoding
  addressing mode.

  1) Storing addressing mode in an opcode array
          - Faster than 2)
          - Requires more storage than 2)
          - Constant delay

  2) Decoding addressing mode from the opcode
          - Delay varies, addressing mode can be done within 16 tests
          - slower than 1)
          - Requires less storage than 1)

  C code:
  1) Opcode table:
          :
          {0x02, 0, idiv,         inherent,       41,     "idiv"},
          :

  2)
          switch (*pc & 0xF0) {
                  case 0x10: /* inherent */
                  case 0x20: /* inherent, direct or indexed_x */
                  case 0x30: /* relative          */
                  case 0x40: /* A:inherent        */
                  case 0x50: /* B:inherent        */
                  case 0x60: /* indexed_x         */
                  case 0x70: /* extended          */
                  case 0x80: /* A:immediate       */
                  case 0x90: /* A:direct          */
                  case 0xa0: /* A:indexed_x       */
                  case 0xb0: /* A:extended        */
                  case 0xc0: /* B:immediate       */
                  case 0xd0: /* B:direct          */
                  case 0xe0: /* B:indexed_x       */
                  case 0xf0: /* B:extended        */
          }

  ----------------------------------------------------------------------
  Condition code register

  Below is a list of (flags, instructions) for all instructions
  that affects the same CCR flag bits
  (Except for instructions like CLI, CLV, ... where an unique
  instruction affect a single flag only.)

  Shift left/right instructions rotate either
  MSBit or LSBit into the C flag.

  Q: Is sub8(a,b) equivalent to add8(a,-b) (including flag settings)?

  CCR flags
  SXHINZVC        Instructions                    Comment
  ========        =======================         ===========================
  --H-NZVC        ABA,ADCA,ADCB,ADDA,ADDB         Flags set in add()

          /* Use set_nzvc_8/16(v1,v2) for all instr. that affect NZVC? */

  ----NZVC        ADDD,                           Flags set in add16()
                  ASL/LSL,ASLA/LSLA,              6)
                  ASLB/LSLB,ASLD/LSLD,            6)
                  ASRA,ASRB,                      6)
                  CBA,CMPA,CMPB,                  Flags set in sub8()
                  CPD,CPX,CPY,                    Flags set in sub16()
                  DAA,                            3)
                  NEG,NEGA,NEGB                   1) 2)
                  ROL,ROLA,RORB                   6)
                  SBA,SBCA,SBCB,                  Flags set in sub()
                  SUBA,SUBB,SUBD                  Flags set in sub()

  ----NZ0-        ANDA,ANDB,                      Flags set with
                  BCLR,BITA,BITB,BSET,            bittest8/16(value)
                  EORA,EORB,
                  LDAA,LDAB,LDD,LDS,LDX,LDY,
                  ORAA,ORAB,
                  STAA,STAB,STD,STS,STX,STY
                  TAB,TBA

  ----0100        CLR,CLRA,CLRB                   Flags set to 0x04 in clrbyte()

  ----NZ01        COM,COMA,COMB                   Flags set in com()
                                                  {bittest();sec();}

  ----NZV-        DEC,DECA,DECB,                  4) Flags set in dec8()?
                  INC,INCA,INCB                   5) Flags set in inc8()?

  -----Z--        DEX,DEY,INX,INY                 Flags set in inc16()

  -----ZVC        FDIV                            Flag set in div()

  -----Z0C        IDIV                            -"-

  ----0ZVC        LSR,LSRA,LSRB,LSRD              6)

  -------C        MUL                             11)

  SXHINZVC        RTI,TAP                         All flags set

  ----NZ00        TST,TSTA,TSTB                   Flags set in tst():
                                                  {bittest();clc();}

  Note (6301, assumed to be valid for 6811 too):
  ----------------------------------------------
  1)      NEG:            V = (result == 0x80);
  2)      NEG:            C = (result != 0x00);
  3)      DAA:            C = (C | BCD(msnibble(result)) > 9)
  4)      DEC:            V = (op before dec == 0x80)
  5)      INC:            V = (op before dec == 0x7F)
  6)      SHL,SHR:        V = (result.N xor result.C == 1)
  7)      LDX,LDS/STX/STS N = (result.bit15 == 1)
  11)     MUL:            C = (result.bit7 == 1)

   *  The addbyte and addword routines should be verified against a real cpu
   *
   *  CCR registers affected:
   *
   *      CCR_C = 1 if `val1' + `val2' + `carry' exceeds 255 (unsigned)
   *              0 else
   *      CCR_V = 1 if `val1' and `val2' has the same sign and
   *              the sign of `val1' + `val2' + `carry' is different
   *              (which means result is not a valid signed number),
   *              0 else
   *      CCR_N = sign of result
   *      CCR_Z = 1 if val1 + val2 is zero, else 0
   *      CCR_H = 1 if the addition of the lower nibbles of val1 and val2
   *              exceeds 0x0F.

   *
   *  The addbyte and addword routines should be verified against a real cpu
   *
   *  CCR registers affected:
   *
   *      CCR_C = 1 if `val1' + `val2' + `carry' exceeds 65535 (unsigned)
   *              0 else
   *      CCR_V = 1 if `val1' and `val2' has the same sign and
   *              the sign of `val1' + `val2' + `carry' is different
   *              (which means result is not a valid signed number),
   *              0 else
   *      CCR_N = sign of result
   *      CCR_Z = 1 if val1 + val2 is zero, else 0
   *      CCR_H = 1 if ??

  struct cpuregs {
          enum cputypes cputype;  /* Good or bad? what with hard regs? */
          struct acc {
                  unsigned a:8;
                  unsigned b:8;
          } acc;
          /*
           * By specifying 16 bits registers, result of additions etc.
           * will wrap-around the 64K range.
           * It may give a decrease in speed.
           */
          unsigned ix:16;
          unsigned iy:16;         /* 6811 only */
          unsigned sp:16;
          unsigned pc:16;
          /*
           * By avoiding bit flags, we
          unsigned char cflag;
          unsigned char
          /*
           * Most of the time, the flags will be set by LDAA/STAA
           * type instructions, and not TAP. Thus the most efficient
           * way to update flags would be:
           *        Z: if (val) ccr |= ZFLAG; else ccr &= ~ZFLAG;
           *        or ccr.z = (val == 0);
           *
           * It's undefined how a C compiler assigns the bit fields
           * => is #define'd bit masks more portable?
           *    Yes: (u_char) CCR and (u_char) MEM have the same storage
           *         layout.
           * Conclusion: If we need to transfer A -> CCR,
           * we can do it in one operation with (u_char) CCR,
           * else we must for each
           *      #define V 0x04
           *      :
           *      setvflag(A & V)...; /* cpu.ccr = (A & V != 0); */
           *      :
           */
          struct ccr {
                  unsigned c:1;   /* Carry/Borrow flag */
                  unsigned v:1;   /* Overflow flag */
                  unsigned z:1;   /* Zero flag */
                  unsigned i:1;   /* Interrupt disabled flag */
                  unsigned h:1;   /* Half carry flag (from bit 3) */
                  unsigned x:1;   /* X-interrupt disabled flag */
                  unsigned s:1;   /* Stop disable flag */
          } ccr;

          /*
           *  Debug registers: stack limits
           */
          struct {
                  unsigned min;
                  unsigned max;
          } stack;
  };
          /*
           * Get opcode from memory,
           * inc program counter to point to first operand
          /*
           * Decode and execute the opcode.
           *
           * By updating clock here, the same functions can be called
           * for (nearly) opcode compatible architectures (like 6301,
           * 6811) with different instr. cycle counts, at least
           * as long as the cycle count is constant.
           *
           * We don't care in detail about how each instruction
           * is executed, we just wait to update the cycle here.
           *
           * The function called must update the program counter
           * to the address of the the next instruction.
           */
           */

  55..1155..22..  DDeessiiggnn nnoottee 22

  1. Reducing number of files involved.
  2. Logical grouping of functions.

    2.1

    Let each cpu variant (6800, 6801, 6301, 6805, 6811) have its
    own 6800map.c, 6801map.c, 6301map.c, 6805map.c, 6811map.c.
    68xxmap.h can be a common include file containing the common
    struct opcodemap, getopcodep().

    Remove the 68xxext.h files - the functions are only used in 68xxmap.c
    Q: Should we also move 68xxext.c functions into a common file?
    A: The 6800/6801/6301/6811 functions may be merged into a common file.
       The 6805 functions are basically different (8-bits X-reg).

    Name proposals:
      m6800_aba_inh()
      m6800_adca_imm()
      :
      m6805_neg_ix0()
      :
      m6811_ldy_imm()

    These naming conventions clearly show the source module (m6800.c,
    m6801.c, m6801.c, m6805.c, m6811.c)
    Use -DNOMAP to not include the opcode map and the opcode map functions.
    All opcode maps could be of the most general type (m6811).

    2.2 CPU access

    CPU access should be done through the routines
      cpu_getreg_[a|b|x|y|pc|sp|ccr]      (or just cpu_get_[a|b|x|y|pc|sp|ccr])
      cpu_setreg_[a|b|x|y|pc|sp|ccr]
    in module cpu.c, to distinguish it from bittestbyte() etc.
    bittestbyte() and similar functions should also be renamed.

    2.3. Memory access

    Memory access should be done through the functions
      mem_getb (addr)
      mem_getw (addr)
      mem_setb (addr, val)
      mem_setw (addr, val)

    2.4. Arithmetic/logical operations

    Today, most of these operations are in the file basic.c.
    (addbyte/addword, ...) together with a couple of warning/error
    debug support function connected to push/pop.
    A more proper name would be alu.c, and it should be as "clean"
    as possible.

    3. Modules

      Module      Contents
      -------     --------

      cpu.c       cpu_getreg_[a,b,x,y,pc,sp,ccr]  ;Register access
                  cpu_setreg_[a,b,x,y,pc,sp,ccr]
                  cpu_getncycles()
                  cpu_getstackmin()
                  cpu_printregs
      alu.c       alu_add_bytes (left, right, dest)
                  alu_add_words (left, right, dest)
      m6301.c     m6301_aim_imm(), m6301_tim_imm(), ...
      m6800.c     m6800_aba_inh(), m6800_adca_imm(), ...
      m6801.c     m6801_abx_inh(), m6801_addd_imm(), ...
      m6805.c     m6805_brset0_btb(), ...
      m6811.c     m6811_aby_inh(), ...
      m68xx.c     m68xx_addbyte (b1, b2), m68xx_testbyte (b), ...
                  m68xx_negaddr (addr)
      mem.c       mem_getbyte (addr)
                  mem_setbyte (addr, value)
                  mem_fprint (fp, addr, nbytes) - display memory contents
      io.c        io_install ()
      ??.c        m6800_unassemble (addr)
                  m6801_unassemble (addr)
                  m6805_unassemble (addr)
      ??.c        single_step() - generic

    6811[A0,A1,A8,E0,E1,E9]:
      CPU core: extended 6800/6801

                                  Strongly connected to:
                                  Ports   Interrupts
      Memory (RAM/ROM/EPROM)      Y       Y
      Timer System                Y       Y
      SPI                         Y       Y
      SCI                         Y       Y

      The strong connection sugessts a single file
      Why not a single 6811 file with all aby_inh(), opcode map,
      etc?

      Make a (big) drawing of all the visible/non-visible functions.
      Interaction with environment. Different processor architectures.
      Encapsulate as appropriate.

    Separate a) cpu specific stuff (regs, instructions), b) on-chip IO
    Should be easy to fill in tables or similar to adapt to a new cpu.
    Could be:

          m6301/instr.c           6301 instructions (extensions)
          m6301/tables.c          Tables for opcode, interrupts, on-chip IO
          m6301/memmap.c          Memory map (incl. IO + interrupts?)
          m6301/io.c              On-chip io functions (SCI, timers)
          m6301/
          m6811/
          m6811/
          m6805/
          m6805/

    General routines, inheritance
                  - Avoid indirect function calls where direct can be used,
                    i.e. single_step()
                  - single_step() must check for interrupts => chip dependant
                  - unassemble() { call cpu specific function ptr, m6811_unassemble}

  =========================================================================
  IDEAS

  Some not-so-important ideas:

  Install the routine to be called when the processor
  wants to output a byte from the SCI. The default routine
  should call putchar() or write (fileno(stdout), buf, nbytes)
  To increase efficiency, a buffered approach should be used,
  but how to determine when to flush the buffer?
  This is application specific. The default application should
  flush after each byte, and a specific application may install
  own logic around the SCI output using io_install().
  Example: io_nc24r: flushing after each 6 byte.

  We could add a stderr channel to the processor reg. dump
  routines. This channel could be an address in the processor's
  memory map. Problem: when operating in simulated env.,
  the reg. dump is outputted to both SCI (net) and stderr.

  Or install a hook into the SWI vector???
  When SWI is executed, redirect SCI output to stderr,
  don't let it go to the net.

  Using SCI as stdin/stdout/stderr
  --------------------------------

  Useful for cpu monitor programs that runs interactively with user connected
  to SCI of the cpu.
  CPU running:
          read from sci <=> read from stdin
                  problem:
                          let cpu do full work when no characters typed
                  solutions:
                          a) Assume monitor programs programs doesn't do much
                          work except for polling (false: download!)
                          poll stdin between each instruction.
                          b) Use select() with null timeout between each
                          instruction. Adds overhead and flexibility: sci
                          and spi (and other io-ports) become reachable
                          from other processes as separate files.
                          c) Use SIGIO. Does't work on some systems (linux)

                          Solutions b) and c) in general work on unix systems,
                          but are not portable to simpler platforms (do$ etc)
          write to sci <=> write to stdout
                  easy.

  55..1155..33..  DDeessiiggnn nnoottee 33

  Makefile targets:
  General cpu:
          sim6800
          sim6801
          sim6301
          sim6805
          sim6811
  Application specific:
          simnccpu

  Procedure for adding new simulator targets:
  General cpu:
          68xx type cpu chip:
                  Add subdir src/68xx/CHIP
                  where CHIP is the name of the cpu type
                  Example: src/68xx/6816
          Other:
                  Add subdir src/FAMILY/CHIP
                  Example: src/80xx/8086

  Application specific:
          Create file src/FAMILY/usr/APP
          where
                  FAMILY is the name of the cpu family (f.ex. 68xx)
                  APP is the name of the file containing application specific
                  code.
          Example:
                  src/68xx/usr/nccpu contains application specific code for
                  a simulator of NC-CPU card w/6811 chip.

  Common:
          Add target to src/makefile.

  Procedure for making target:
          Enter directory src.
          Type 'make' to make all targets
          or   'make TARGET' where TARGET is the name of a specific target.

  Instruction set hierarchy:

  6800
   |    (subset)
   +-----------+
   |          6805
  6801
   |
   +----+
   |    |
  6301 6811

  A better figure would show this as sets with unions and intersections.

  Inheritance
          sim6800 Bare bone mother of Motorola CPU's simulated
          sim6801 Inherits 6800
                  On-chip ports, timer, sci.
          sim6301 Inherits 6800, 6801
                  Main difference to 6801 are a few instructions.
          sim6805 Inherits 6800
                  Same spi as 6811.
          sim6811 Inherits 6800, 6801

  Application specific:
          simnccpu Simulates 6811 w/additional equipment connected to I/O

  Implementation:
          opfunc.c        Unique functions simulating instruction execution.
          optab.c         Table of pointers to instruction executing functions.

  55..1155..44..  DDeessiiggnn nnoottee 44 -- rreessuullttss ooff iinnlliinniinngg

       INLINING

       To increase execution speed to a level practical for testing of
       real programs in a simulated environment, inlining was performed
       on the simulator in stages.

       gcc flags: -O2 -finline-functions:
       Time in seconds (16MHz 386 @2.0 BogoMIPS)

       Step:                                   A   B      C      D        E
       Macroized/inlined:                      -   +reg.h +cpu.h +mem.h   +spi.h
                                                                 +ireg.h  +sci.h
                                                                          +timer.h

       simnccpu ~/nc2/ncr/test/delaytest.s19:  3   a)                       1.5

       simncpan ~/nc2/ncp/test/testdip.s19:    46  32      31     22        20
       simncpan ~/nc2/ncp/6805-smallc/ncp.s19  32                 16        15

       a) Simulator runtime errors
          (as result of cc flags?)
          No, bug in macro reg_setaccd().

       COMMENTS

       Simulation of NC-PAN gained a performance increase to about double speed
       when inlining/macros was implemented.

       With no inlining, simncpan ~/nc2/ncp/6805-smallc/ncp.s19 had a blink time
       of about 32s. With inlining, time was reduced to about 16s.

       Considering the step from D to E, 3 function calls were inlined, with a
       speed increase of about 10%. Each of these functions is called at most
       once per instruction.

       At stage E, there are about 2 more functions that can be inlined
       (instr_exec() and timer_inc()), which is expected to give another
       10% speed increase.

       The relative changes in speed follows the number of times a
       function is called. The reg/ireg/mem functions are often called,
       (how many times per instruction? Min:.. Max:.. Average:.. )
       inlining them gave most impact on execution speed.

  55..1155..55..  DDeessiiggnn nnoottee 55 -- cchhaarraacctteerr uusseerr iinntteerrffaaccee

  Suggested layout for sim68xx tool

  1996-06-25/AR
  ------------------------------------------------------------------------------
  File    Memory          Run             Breakpoint
  ->Load  ->Display       ->Trace         ->List
  ->Exit  ->Modify        ->Step over     ->Set
                          ->Go            ->On error
                          ->Reset         ->On warning
  View            Edit
  ->Memory        ->Memory
  ->Register      ->Register
  ->Breakpoints   ->Breakpoints

  Windows:
          Register
          Asm/src
          Memory
          Callstack
          IO

  1996-08-12/AR   Suggested window contents
  -------------------------------------------------------------------------------
  Register Window (~ = input field too)
          PC=0000 A:B=0000 X=0000 Y=0000 SP=0000 CCR=d0(SXhInzvc) [0]
             ~~~~     ~~~~   ~~~~   ~~~~    ~~~~     ~~
  Memory Window
          Output
          aaa0 h0 h1 h2 h3 h4 h5 h6 h7 h8 h9 ha hb hc hd he hf   0123456789abcdef
          aaa1 h0 h1 h2 h3 h4 h5 h6 h7 h8 h9 ha hb hc hd he hf   0123456789abcdef
          aaa2 h0 h1 h2 h3 h4 h5 h6 h7 h8 h9 ha hb hc hd he hf   0123456789abcdef
          aaa3 h0 h1 h2 h3 h4 h5 h6 h7 h8 h9 ha hb hc hd he hf   0123456789abcdef
          aaa4 h0 h1 h2 h3 h4 h5 h6 h7 h8 h9 ha hb hc hd he hf   0123456789abcdef

          Input
          aaan        h0 h1 h2 ... hf
          ~~~~~~~~~~~ ~~~~~~~~~~~~~~~
          Comment: symbol may be used instead of address 'aaan'

  Callstack
          aaa1    f1      sym1
          aaa2    f2      sym2
          aaa3    f3      sym3

  Asm/src - should display current subroutine too!

          911f    3c             pshx
          9120    bd af a1       jsr   afa1       _timer_init
          9123    38             pulx
          9124    bd a1 48       jsr   a148       _net_init
          9127    bd 93 56       jsr   9356       _func_init
          912a    ce 00 09       ldx  #0009
          912d    3c             pshx
          912e    ce 14 43       ldx  #1443       _buttons
          9131    3c             pshx
          9132    bd b8 f2       jsr   b8f2       _relay_read

          To get C or asm source intermixed, the file and the line
          number must be available, either in the executable,
          or as a file containing lines with the information
                  address file line
          Changes required:
                  Motorola freeware asm:
                          Output file while source is processed
                  Gcc/aslink:
                          Modify gcc, asXXXX, aslink.

  1996-08-20/AR
  ------------------------------------------------------------------------------
  Breakpoints
          Edit->
                  Input
                  aaan
                  ~~~~~~~~~~~
                  [Set] [Clear] [Cancel]
          View

          Output
          aaan    symbol
          :

          Comment: symbol may be used instead of address 'aaan'
                  This is a typical list operation?
                          Set=AddToList, Clear=DeleteFromList
          +-Breakpoints-------------------+
          |       Address Symbol          +
          |       +---------------+       |
          |       | aaan  symbol  A       |
          |       |               |       |
          |       |               v       |
          |       +---------------+       |
          |       +---------------+       |
          |       | _printf       |       |
          |       +~~~~~~~~~~~~~~~+       |
          |       [Add] [Delete]          |
          +-------------------------------+

  Implemetation solutions

          o Use sim68xx as a backend to gdb/tkgdb.
                  This is more a solution for stepping C/C++ source,
                  typically in a Unix environment.
          o Use curses to be portable
                  Can translate Mouse events to keypresses in X
                  Is this possible in dos/windows environments?
          o Use Tcl/Tk
                  o let sim68xx commands be part of Tcl/Tk interpreter
                          + Available on many platforms
                          + Easy customizable
                          - Tight integration
                                  (must be compatible w/Tk version)
                  o Use TkSteal
                          Can start the simulator as a process
                          in a window and send keypushes to it,
                          similar to tty window in Xview
          o Use WxWin that has many back ends
                  Xview, Curses, Windows

          It should be possible to send commands between separate types
          and instances of sim68xx to simulate the communication on a
          serial line. This is possible with

                  o Unix like IPC and command line driven interface
                          IPC can be pipe or socket.
                          Sockets are also now avilable in Windows.
                  o Tcl/Tk in Unix environment:
                          o Command line interface and TkSteal
                                  Works in Unix
                          o Integrated with Tk
                                  Also works in Windows?
          There is one question related to implementing sim68xx as a part of Tk.
          Will a running copy of tksim68xx block the user interface?
          The job of a running simulator is to run as fast as it can,
          must a poll-back to Tk be implemented in the execution loop?
          Today, the command line driven sim68xx does a poll for IO
          after the interpretation of some (say 50) instructions.

  55..1155..66..  DDeessiiggnn nnoottee 66 -- hhooww tthhee SSPPII iiss ssiimmuullaatteedd

       1997-01-24/A.Riiber

       Mechanism for simulating SPI input/output
       -----------------------------------------

       DATA FLOW

              user data in `buf'
                   |
                   | spi_in(buf, buflen) /* user wants to clock in data to SPI */
                   |
                   V
        0 1 ... spi_rx_nbytes
       +----------------------
       | spi_rx_buffer                 /* Data is stored until CPU is ready */
       +----------------------
                |
                | spdr_putb()          /* CPU writes to SPI data register */
                v                      /* Data is transferred from buffer to SPDR */
             +------+
             | SPDR |
             +------+
                |
                | spdr_getb()          /* CPU reads from SPI data register */
                v

       DESCRIPTION

       The user calls spi_in() to enter data to send into the SPI.
       Each time spi_putb(SPDR) is called, a byte is transferred to the SPI data
       register SPDR. SPDR can be read from the CPU by calling spi_getb(SPDR).

  55..1155..77..  DDeessiiggnn nnoottee 77 -- II22CC

  I2C protocol
  ============

  - Data transfer is initiated  with START
  - Each byte transferred must be ACK'ed by receiver (whether master or slave)
  - Data transfer is terminated with STOP or a new START

  1. Master sends data to slave
  -----------------------------

    1         7        1    1  8         1        8      1   1   <- bits
        +----------------+     +------+        +------+
  START | ADDRESS | R/~W | ACK | DATA | ACK .. | DATA | ACK STOP
        +----------------+     +------+        +------+
                     '0'        <----n data bytes----->

  2. Master reads data from slave
  -------------------------------

    1         7        1    1  8         1        8      1   1   <- bits
        +----------------+     +------+        +------+
  START | ADDRESS | R/~W | ACK | DATA | ACK .. | DATA | ACK STOP
        +----------------+     +------+        +------+
                     '1'        <----n data bytes----->

  3. Address format
  -----------------

  MSB     R/W~

  0000 000 0      General call address. Next byte follows:
                  a)      02h   - Enter mode to get slave address from SW
                  b)      04h   - Latch slave address from HW
                          06h   - Reset + a) + b)
                          other - Reserved, ignore
  0000 000 1      General call address. Next byte is master's address.

  0000 001 x      CBUS address
  0000 010 x      -+
   :               +- Reserved
  0000 111 x      -+

  0001 xxx x       -+
   :                +- Vendor addresses
  1110 xxx x       -+

  1111 xxx x      Reserved for future extension

  Xicor X9241
  ============

  1. Master sends data to slave
  -----------------------------

    1      4        4       1     8      1        8      1   1   <- bits
        +-------+--------+     +------+        +------+
  START |    ADDRESS     | ACK | CMD  | ACK .. | DATA | ACK STOP
        +-------+--------+     +------+        +------+
          0x09   instance       <----n data bytes----->

  Data direction is given by the command byte (CMD).
  Are there generalities in this Xicor specific protocol?

  CMD

  Each instance has 4 potmerers.
  Each potmeter (P) has a wiper and 4 NVRAM registers (R).

    4     2   2   <- bits
  +-----+---+---+ +----+
  |instr|pot|reg| |Data|  Mnemonic        Description
  +-----+---+---+ +----+
    1     -    R    -     RESTORE_WIPERS  Transfer R to wiper for all potmeters
    2     P    -    1     INC_DEC_WIPER   Inc/dec wiper for potmeter P
    8     -    R    -     STORE_WIPERS    Transfer wiper to R for all potmeters
    9     P    -    r     READ_WIPER      Read wiper for potmeter P
    a     P    -    w     WRITE_WIPER     Write wiper for potmeter P
    b     P    R    r     READ_STORE      Read reg R for potmeter P
    c     P    R    w     WRITE_STORE     Write reg R for potmeter P
    d     P    R    -     RESTORE_WIPER   Transfer R->P
    e     P    R    -     STORE_WIPER     Transfer P->R
   other                  Undefined

  1 = 1 bits data, sampled on each clock transition, unlimited length,
      no ack, terminated by stop
  r = 8 bits data from slave to master
  w = 8 bits data from master to slave

  Suitable API:

  write_wiper (pot, val);
  read_wiper  (pot, &val);

  store_wipers   (reg);
  restore_wipers (reg);
  store_wiper    (pot, reg); /* Could have param pot=ALL_WIPERS */
  restore_wiper  (pot, reg); /* -"- */
  read_store     (pot, reg, &val);
  write_store    (pot, reg, val);

  inc_wiper (pot, step); /* +/- */

                            TTaabbllee ooff CCoonntteennttss

  1. Introduction  . . . . . . . . . . . . . . . . . . . . . . . . .   4
  1.1. Features  . . . . . . . . . . . . . . . . . . . . . . . . . .   4
  1.2. Future  . . . . . . . . . . . . . . . . . . . . . . . . . . .   4
  1.2.1. Graphical window user interface . . . . . . . . . . . . . .   4
  1.2.2. Character window user interface . . . . . . . . . . . . . .   5
  1.2.3. Symbolic C debugging  . . . . . . . . . . . . . . . . . . .   5
  1.2.4. Dynamic Linking for simulating on-chip and external IO
   . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   5
  1.3. Revision history  . . . . . . . . . . . . . . . . . . . . . .   5
  2. Installing the simulator  . . . . . . . . . . . . . . . . . . .   6
  2.1. Getting the simulator . . . . . . . . . . . . . . . . . . . .   6
  2.2. Installing on unix  . . . . . . . . . . . . . . . . . . . . .   6
  2.2.1. Extracting the archive  . . . . . . . . . . . . . . . . . .   6
  2.2.2. Compiling the source code . . . . . . . . . . . . . . . . .   6
  2.2.3. Installing the binaries . . . . . . . . . . . . . . . . . .   6
  2.3. Installing on DOS/Windows . . . . . . . . . . . . . . . . . .   6
  2.3.1. Extracting the archive  . . . . . . . . . . . . . . . . . .   7
  2.3.2. Compiling the source code . . . . . . . . . . . . . . . . .   7
  2.3.3. Installing the binaries . . . . . . . . . . . . . . . . . .   7
  3. Running the simulator . . . . . . . . . . . . . . . . . . . . .   8
  3.1. Starting up . . . . . . . . . . . . . . . . . . . . . . . . .   8
  3.2. Getting on-line help  . . . . . . . . . . . . . . . . . . . .   8
  3.3. Displaying the source . . . . . . . . . . . . . . . . . . . .   9
  3.4. Stepping through an instruction . . . . . . . . . . . . . . .   9
  3.5. Setting break point . . . . . . . . . . . . . . . . . . . . .  10
  3.6. Running until breakpoint  . . . . . . . . . . . . . . . . . .  10
  3.7. Displaying the call stack . . . . . . . . . . . . . . . . . .  10
  3.8. Entering IO port data . . . . . . . . . . . . . . . . . . . .  11
  4. Adding code that simulates your hardware  . . . . . . . . . . .  12
  4.1. Simulator API for installing an IO port function  . . . . . .  12
  4.2. Simulator API for storage of IO port data . . . . . . . . . .  12
  4.3. Simulator API for memory access . . . . . . . . . . . . . . .  13
  4.4. Example . . . . . . . . . . . . . . . . . . . . . . . . . . .  13
  4.4.1. Hardware circuit  . . . . . . . . . . . . . . . . . . . . .  13
  4.4.2. Polled IO . . . . . . . . . . . . . . . . . . . . . . . . .  13
  4.4.2.1. Target CPU (68xx) code  . . . . . . . . . . . . . . . . .  14
  4.4.2.2. Simulator code  . . . . . . . . . . . . . . . . . . . . .  14
  4.4.3. Interrupt IO  . . . . . . . . . . . . . . . . . . . . . . .  16
  4.4.3.1. Target CPU (68xx) code  . . . . . . . . . . . . . . . . .  16
  4.4.3.2. Simulator code  . . . . . . . . . . . . . . . . . . . . .  17
  5. FAQ - Frequently Asked Questions  . . . . . . . . . . . . . . .  18
  5.1. Why did you write this simulator?   . . . . . . . . . . . . .  18
  5.2. What is the difference between a simulator and an emula
  tor?   . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  18
  5.3. When can I benefit from using a simulator like this?  . . . .  18
  5.4. What are the design ideas behind the simulator?   . . . . . .  18
  5.5. Why is there no DOS version?  . . . . . . . . . . . . . . . .  19
  5.6. How can I compile under DOS?  . . . . . . . . . . . . . . . .  19
  5.7. Why are there so many directories?  . . . . . . . . . . . . .  19
  5.8. How does the simulator simulate interrupt?  . . . . . . . . .  20
  5.9. What other simulators exist?  . . . . . . . . . . . . . . . .  20
  5.9.1. BSVC  . . . . . . . . . . . . . . . . . . . . . . . . . . .  20
  5.9.2. UMPS  . . . . . . . . . . . . . . . . . . . . . . . . . . .  20
  5.9.3. NOICE . . . . . . . . . . . . . . . . . . . . . . . . . . .  21
  5.9.4. tgdb  . . . . . . . . . . . . . . . . . . . . . . . . . . .  21
  5.10. How to simulate interrupt when using the simulator?  . . . .  21
  5.11. How to simulate interrupt that happens when the simula
  tor is . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  21
  5.12. How to get IO data into the simulator?   . . . . . . . . . .  21
  5.13. How to get IO data out from the simulator?   . . . . . . . .  21
  5.14. What is the difference between the 6800, 6301, 6805 and
  6811?  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  22
  5.14.1. 6800 family  . . . . . . . . . . . . . . . . . . . . . . .  22
  5.14.2. 6301 family  . . . . . . . . . . . . . . . . . . . . . . .  22
  5.14.3. 6805 family  . . . . . . . . . . . . . . . . . . . . . . .  22
  5.14.4. 6811 family  . . . . . . . . . . . . . . . . . . . . . . .  22
  5.15. Are there any design notes?  . . . . . . . . . . . . . . . .  23
  5.15.1. Design note 1  . . . . . . . . . . . . . . . . . . . . . .  23
  5.15.2. Design note 2  . . . . . . . . . . . . . . . . . . . . . .  28
  5.15.3. Design note 3  . . . . . . . . . . . . . . . . . . . . . .  31
  5.15.4. Design note 4 - results of inlining  . . . . . . . . . . .  33
  5.15.5. Design note 5 - character user interface . . . . . . . . .  33
  5.15.6. Design note 6 - how the SPI is simulated . . . . . . . . .  36
  5.15.7. Design note 7 - I2C  . . . . . . . . . . . . . . . . . . .  36

