                                                            





                              
                  MOTOROLA M6800 EMULATOR
                              
















                        Version 1.0

                       1 - May - 1991

                       Kevin Bertram


                      INTRODUCTION

     This implementation  of the  M6800 Emulator  is version
1.0. If you find any errors with the Emulator or debugger or
maybe there  are a  few suggestions  as to  what  you  might
like   to see  in the program to enhance its usefulness then
please let  me know.  My address  is further  down  in  this
manual.

     Also this  program and  manual can  be copied  as  many
times as you  want and given to friends if you please. There
is no  hassle with  this. But do not sell it! The program is
public domain and not for profit making.

     The purpose  of  this  Emulator  is  to  replicate  the
instruction set  execution of  a CPU  not present within the
hardware design  of the IBM-pc-xt/at or a clone there-of. Or
for that  matter  any  host  computer  that  is  capable  of
executing programs.  The instruction set of the emulated CPU
must be  adhered to  exactly otherwise  programs written for
the emulated  CPU will  not perform  correctly in the target
system. This  program in particular has been adapted to suit
the Motorola M6800 8 bit CPU.

     An emulator  can be a useful program. Especially if you
are into  constructing   and  programming  your  own  micro-
controllers. They  provide for  a safe  environment at which
new code can be tested under reasonably tight control before
being downloaded  to the  target machine and let loose. Also
the emulator  allows for  a foreign  CPU's machine  code  to
execute under  a host  CPU. Which  is most  likely where the
cross-assembler will  reside too.  All this  adds to  faster
implementation of  your   program and gets you to using your
hardware sooner.

     I will  not enter into the reasons as to why a designer
might use  8 bit  CPU's as opposed to 16 of 32 bit CPU's but
rather that what ever his or her choice is they might find a
need to  check out  the integrity of the program code before
'burning it  in'. It  could be that the program will have to
be executed  step by  step to find an illusive fault. And in
this case  an emulator  could prove  useful. If  the  target
machine already  has a debugger built in then there might be
no need for an emulator but if there is not then an emulator
will be needed.


     My reason  for producing  an Emulator  for the M6800 is
mainly because it was the first CPU I had encountered and so
I am  biased towards it. Another is that, as far I am aware,
there are  no other  programs that  will emulate a M6800 CPU
running under  an Intel  CPU and  as I  have a  need for one
right now I wrote this program as a response. So here it is.
It was a joy to work on and I hope you find it useful.

          Kevin Bertram

     Electronic mail

          ACSNET - kevin@latcs1.oz

     Surface mail:

          Department of Computer Science
          La-trobe University
          Plenty  road
          Bundoora, 3083
          Melbourne,  Victoria
          Australia.

                      ACKNOWLEDGEMENTS

     I would  like to  thank Ira  Baxter for  his  excellent
suggestions in speeding up the Emulator to the effect of ten
times as compared to its intial implementation.

     I would  like to  thank Mark  Seiffert also  who, along
with Ira,  sourced me  with M6800  code to  run through  the
Emulator to  test its validity. [I find it is much better to
have someone  else test  my software  because they  will not
step around the precarious parts of the program.]


                      DISTRIBUTION FILES





     There should  be the  following files  contained within
the archive file.

     68EM.COM            M6800  Emulator  configured  for  a
                         standard IBM-pc-xt/at

     68EMV.COM           M6800 Emulator  configured  for  an
                         IBM-pc with  a VT-100  terminal  as
                         its console.

     68EM.TXT            This file  - it describes the usage
                         and  other  things  present  within
                         this version of the M6800 emulator.

     68EM.PIF            Windows  information  file  to  get
                         this emulator to run in a window.

     68EM.ICO            Icon for emulator to suit Microsoft
                         Windows V3.0.

     MIPS.o68            Runs through a general selection of
                         M6800 instruction  65535 times.  By
                         timing this  an indication  of  the
                         instruction  through-put   can   be
                         calculated. See Appendix D

     TASM68.TAB          M6800 opcode table suited to SPEECH
                         TECHNOLOGY INCORPORATED  (C) tasm22
                         table    driven     cross-assembler
                         version 2.2

     AS0.EXE             M6800 assembler  from  Motorola  as
                         freeware software.

     AS0.DOC             Document    for     the    Motorola
                         assembler.

     MAIN.S19            Sample    multitasking    operating
                         system  that  will  run  under  the
                         control of the this CPU emulator.

     MAIN.DOC            A brief  description of  the sample
                         operating system (MAIN.S19) and how
                         to use it.

Note  that   the  cross-assembler   by   SPEECH   TECHNOLOGY
INCORPORATED has  not been  included. Their  program can  be
acquired from  any BBS  that has  it and will most likely be
named as TASM22.ARC

     Notes on  how to  use TASM  will come  with the archive
file. Also  see the  section  in  this  document  on  "Extra
instructions"  for   extra  details  concerning  the  cross-
assembler in relation to this program.

                         DISPLAY TYPE


     There is  nothing very  special about  the way in which
the debugger  or Emulator  will  display  its  data  to  the
console. That  is there  are no  fancy windows  or  graphics
included to  improve the  overall look of things. But rather
the output is simple.

     There is,  however, a  need to  setting certain  things
such as  high brightness  characters,  a  limied  number  of
cursor addressing  movements and  clearing the whole screen.
For these  I have catered for two environments on which this
program could  run. The  first is  the standard  "run of the
mill"  IBM-PC-xt/at with what ever graphics card being used.

     The second  is for a IBM-PC type computer that runs the
same programs  but uses  a  VT-100 character terminal as its
console. These do exist (I've got one!) and therefore I have
adapted the  program to  suit  them  too.  In  fact  if  the
standard XT/AT  were to  have  the  device  driver  ANSI.SYS
installed then  there would  be no  problems in  running the
later program on either machine.

     I have  thought about  using a  soft switch  within the
command line  when the  program is invoked to indicate which
console type  is being  used but  decided against  that,  at
least for the moment, to opt for two programs. One setup for
a standard  console using graphics cards and the other being
setup up  for VT-100  consoles. It is no big deal to do this
as all  it requires is one variable to be changed within the
source at assembly time.

     The main  reason for  this approach  is  to  take  into
account those times when a programmer is fanatically working
at great  pace and  would much  rather type a simple name to
start the  program instead  of the  name  and  a  string  of
softswitches. It can be discouraging to start the program in
the wrong  mode and  wonder why all these strange characters
are appearing on the screen.

     Anyway it remains to be seen as to whether softswitches
are included or not later. But at this moment they are not.
                              
                    INVOKING THE EMULATOR


     To start  the program  it is  a simple matter of typing
its name then pressing return. The program will load and run
and the command line prompt '-' will appear.

     If there is a data file to loaded as well then this can
be  done  by  including  the  data  file's  name  after  the
emulators invocation name.

     For example   C:> 68em example.o68

     Will   load   example.o68   into the  Emulators  memory
     after it  itself has  been loaded  and run.  All of the
     error checking  steps that  are done by the 'L' command
     apply. If  there is  an error  loading the file then an
     error message  describing the  problem will  be printed
     and the  loading terminated.  The Emulator  will return
     with its  prompt waiting for a command but with no data
     in memory.  If the  file loaded correctly then the byte
     count will  be  displayed  followed  a  report  on  the
     highest and  lowest address  data was  stored  at,  the
     Emulator's signon  message and  then the  prompt '-' on
     the last  line. The  debugger and  emulator will now be
     ready to use.

Note that  the hello message after starting will contain the
current version  number, the  initial release  date and  its
version number  and  finally  the  current  version  of  the
program along  with its  release date.  This should give the
user an  indication of what version of the program they have
and whether it is as recent as it should be.

After a  succesful load  of a  data  file  on  starting  the
Emulator the  Program Counter  (PC) and  all of  the default
addresses used  within the debuggers commands will be set to
the same  value as  the lowest  address data  was stored at.
This makes  for a  quick and  easy startup of a 6800 program
that will  require the  user to merly enter a 'G' command to
start the application.


                      DEBUGING COMMANDS

     In order to make the Emulator useful then there must be
some way  of reading  and writing  to the  Emulators memory,
tracing execution  of test  programs, examining or changing,
registers and  loading data  from files  which will  be more
than likely  be  output  from  cross-assemblers.  The  M6800
Emulator has  these functions  and they  will  be  described
here.

The usual format will be:

      command <start address> <end address> <constant>

If an  8 bit constant is required in any of the commands and
a 16   bit  constant was  entered then  only the last 8 bits
will be retained.


                        MISCELLANEOUS

   S
   Q
   ?


*  S

     Toggles the  mode in  which the  emulated code will run
in. Initially, after begining the emulator, the program will
be executed  in  the  'Supervised'  mode  in  which  program
execution can be stopped at any time by entering a ^C. A 'G'
command  will  return  the  program  back  to  its  previous
position unchanged before the interupt was encounted.

     By  issuing  the  'S'  command  and  toggling  to  'Non
supervised' mode  programs will run until a breakpoint or an
illegal opcode is found. There is no other way to exit. Mind
you though  that the later mode performs 3 times better than
the 'Supervised'  mode. The  use  of  either  mode  will  be
determined by whether you trust the code or not.

     If a  program is  running in  unsupervised mode  and  a
control-c was  entered at  the keyboard  then this character
will be passed onto the internal keyboard buffer ready to be
read by  the 6800  program through  the CHINT A instruction.
This will  allow for  a reasonable  emulated environment for
the 6800  program to  work in.  That is: a control-c will be
allowed to  be processed  by the program as if it was on its
target machine.


*  Q

     Quit from the Emulators debugger and return to DOS. The
return code given to DOS will be $00.


*  ?

     Prints the quick help menu to the console.


                    SETTING CPU REGISTERS

   R  <register name> <const>

   R  A < 8 bit constant>
   R  B < 8 bit constant>
   R  X <16 bit constant>
   R  S <16 bit constant>
   R  P <16 bit constant>
   R  F < 8 bit constant>



*  A, B, X, S, P, and F

     As  with  any  M6800  CPU  chip  there  are  five  user
registers which  can be changed under program control and as
such they  can be modified at anytime through the use of the
above commands.  The Flag  register, although  not ideal for
storing data  in, can  have it's  contents changed too. This
would most  likely be  used to  set up  key situations which
would test  program integrity at a point without the need to
execute code before it.

     'A' - sets the A accumulator
     'B' - sets the B accumulator
     'F' - sets the status flags
     'X' - sets the index register
     'S' - sets the stack pointer
     'P' - sets the program counter



*  R

     Without a  register name will print the entire register
list along  with the  disassembly of  the next  instruction.
Note that  if a  register name is given of which the program
does not  understand then  the register list will be printed
instead of  an error  message. A  print of the register list
will have  the flags  printed as  a hex  number and a single
letter description  of each  flag bit,  the contents  of the
five other CPU registers that are relavent to the M6800 CPU,
and a disassembly of the next instruction to be executed.

A typical register list would look like this:


F - FF    - - H I N Z Ov C
A = 12    B = F7    X = 0147    S = FFF8    PC = 0100

0100  86 45           LDA    A,#$45

-_


The Flags list mean:

     H  - Half carry flag
     I  - Interupt enable flag
     N  - Sign bit flag
     Z  - Zero flag
     Ov - Overflow flag
     C  - Carry flag


                       MEMORY MODIFING

   C <start address> <end address> <constant>
   E <address>

*  C

     The 'C' or 'fill memory with Constant' command will, by
default, fill  all of  the Emulators  64K memory  space with
$00. Thus  the work space can begin from a clean slate. If a
start address  is given, as the  only parameter, then it and
the following  256 bytes of memory will be set to null, $00.
If a  start address is given with an end address but with no
constant then  that area  of  memory  within  the  start-end
address will be filled with nulls, $00. But if a constant is
supplied that  range of  memory will  be  filled  with  that
constant.

For example : C 100 200 01    will fill  the  address  range
                              from $100  to  $200  with  $01
                              which are "nop's".


*  E

     'E' or  'memory Examine'  and change  will allow single
steps through the Emulators memory space. At a point where a
byte is  to be changed then a new value can be entered, or a
string of  new data can be entered each seperated by a space
character. When  the [return]  is entered  then that data is
stored to  memory and  the next  unused address is displayed
ready for  new data.  To exit  this mode a '.' with no other
data on the line should be entered followed by a [return].

  Example:  -E 100

                 0100 00 > _           will be the response.
                                   Entering  data   will  be
                                   like this:

             0100 00 > 01 02 03 04 [return]
             0104 34 > _

                                   with only  a [return]  on
                                   the input  line then  the
                                   address being  looked  at
                                   will increment by one.

             0104 34 > [return]
             0105 31 > _

                                   To exit now just enter
                                   '.' [return]

             0105 31 > . [return]
             -_


                       MEMORY DISPLAY

   U <start address> <end address>
   Z
   D <start address> <end address>
   H <start address> <end address>


*  D
*  H

     Dump or  Hex dump  will both do the same thing; print a
block of  data using  byte size  data along  with  it  being
printed as  an ASCII  character as  it would  appear on  the
screen. After  using many  different types of debuggers some
use 'D' for this function and others 'H'. When changing from
one to  the other  more than  likely  'D'  will  be  entered
instead of  'H' and visa-vers. So I've included these two to
do the same thing to accommodate for my limitation at least.

     The default  block dump size is 256 bytes but if an end
address is  given then  the hex  dump will  end at  the  end
address. Note  that both  the start  and end address will be
rounded off  to the  lowest 16 byte field. That is $102 will
be taken as $100, $159 will be taken as $150 etc.

     The output will be:
          address,  16 bytes of data,  ASCII field

As an example:
                -D 100 110

0100 - 01 02 03 04 34 31 0 45 20 10 11 13 45 48 2a 20       
.41.E ...EH*

-_

will result.  Note  that  all  unprintable  characters  will
appear as a single '.' in the ASCII field.


*  U

     Uncompile will  disassemble a  section of code from the
M6800's memory.  The default listing length will be 16 lines
of disassembly  but given  a start  and end address then the
disassembly will  continue until  the end  address has  been
reached. If  only a  start address  was  supplied  then  the
disassembly will  print 16  lines of  disassembly from  that
address.

     If  an   address  of  an  instruction  appears  in  the
breakpoint list  then  that  line  of  disassembly  will  be
highlighted to  make easier  viewing of  the  code  and  the
breakpoints position within it.

     The disassembler follows the usual rules concerning the
M6800 instruction  set as  it appeared on the day. But there
is one  exception to  the rule. When printing an instruction
that uses INDIRECT addressing mode then the disassembly will
have 3 parts to its opcode field.

For example: LDA A 2,X    will appear as    LDA A,2,X

     Most assemblers  will not  accept this kind of notation
but in preference for neatness I have opted for this instead
of the  alternatives. Motorola  had  changed  the  Mnemonics
somewhat to  accommodate for  this problem it seems by using
LDA or LDB in the 6809 series rather than LDA A or LDA B.


*  Z

     This  command  will  print  the  last  twenty  executed
instructions that  the emulator  has just  worked on  before
exiting the 6800 program. The very last instruction printed,
which is  more than  likely to be the cause of the exit, was
the last instruction processed.

     The purpose of the command and instruction tracing will
be seen  when you  are trying  to find  a reason  to  why  a
program has become a "run-away". Or why a program sourced by
someone  else   always  exits  without  performing  anything
useful.

     It should  be pointed  out that  no instruction tracing
will  be   performed  when   the  emulator   is  running  in
unsupervised mode.  In fact  not much  is done  eccept  6800
instruction execution  in this  mode. All of the goodies are
done in  the supervised  mode. Also when a program is run in
unsupervised mode  the instruction  trace buffer  is cleared
thus to  issue a  "Z"  command  after  a  program  has  been
executed the  buffer will be reported as empty. This happens
even if it was full before execution in unsupervised mode.


                              
                      PROGRAM EXECUTION

   G <start address>
   T <n steps>
   B <#> <address>
   P


     Executing any  M6800 program  is  simply  a  matter  of
loading the  opcodes and data into the Emulators memory then
instructing the emulator to take control. Three instructions
are  provided  to  help  do  this.  Their  usage  desription
follows.


*  G

     Goto will  cause the  execution of  M6800  instructions
from the  address '<start  address>' if  given or  from  the
current value  contained within  the M6800's Program Counter
(PC). The command line address will always override the PC's
current state.

     If at  anytime the  Emulator tries  to execute  illegal
instructions then  the CPU's current state will be saved and
program execution ceased. A message will then be printed and
the program  returned back  to the command line entry level.
To gain an understanding of what the CPU's current state was
use the  Register command.  See the  'R' command  for  usage
description.


*  T

     Causes the Emulator to trace 'n' instructions at a time
then return back to the command level. The default value for
'n' is  one (1)  but can  contain values upto 255. This will
make it  easy to  get  passed  those  loops  that  might  be
contained within the program under test.

     The actual  execution address  is read  from the  CPU's
Program Counter  (PC) and  instructions  taken  from  there.
There is  no provision  for overriding  the Program  Counter
within this command.

     The current  state of  CPU is  saved away  for  viewing
later and  control returned to the command level. If illegal
instructions are  encountered then the Emulator performs the
same abort sequence as described in the 'G' command.


*  B

     Breakpoints set  or cleared  within the  M6800 program.
Upto eight  breakpoints can  be set  at any one time and the
list will  be shown when the 'B' command, alone, is entered.
If a  breakpoint number  is given but no address stated then
that breakpoint will be cleared from the list and finally if
an address is given with a breakpoint number then it will be
set; or changed if that breakpoint number already exists.

     Note that  a breakpoint  address of  the value of $FFF8
will clear  the breakpoint  from the  list. I have used this
value  instead  of  the  usual  $0000  to  indicate  cleared
breakpoint. Why?  Because  those  values  contained  at  the
address $FFF8  - $FFFF are autovectors for interupt control.
They are  never instructions,  or if  they  are  then    the
function of the M6800 could be eratic at times. As there are
no interupt  functions other than a software interupt, built
into the Emulator then it would be reasonable to use this as
a sort of null value or useless address and in this case 'no
breakpoint'.


*  P

     Will  cause   execution  of  the  next  instruction  to
completion. If  it happens  that the  next instruction  is a
subroutine call  then the  subroutine will  be executed  and
allowed to complete and  return to its caller. At this point
the program  execution will  stop and the register list will
be printed as would any trace command do.

     This command  is extremely  useful in  step over  those
subroutines that  have been  tested and proved working. Thus
preventing worthless tracing of code that has been verified.

                      SETTING INTERUPTS

   I
   I N <const>
   I I <const>

*  I

     The M6800  emulator version  0.3  and  up  all  support
interupt handling  for all  of the  interupt types supported
within the  M6800 CPU.  Versions before 0.3 only catered for
the Software  interupt. In  order to implement the other two
interupts other  than reset  this command  exists. Note that
when an  interupt is to occur the service routine address is
read from  the NMI  and  IRQ  vectors  at  $FFFC  and  $FFF8
resepectively.

     Entering "I"  with no  parameters will print the status
of the  registers that  will keep track of when Non Maskable
and Maskable  interupts  should  occur.  The  mechanism  for
determining when  either of  the interupts should be invoked
is by  instruction count  rather than  an external signal of
some type.  Therefor you  will have  to work  out  how  many
instructions the  target CPU  will execute  before the  next
interupt will  occur. This is by no means the best answer to
interupt servicing  for all target environments but at least
it does  give you  the user  a way  to test  if an  interupt
service routine will work with the reset of the program.

     For those  instances  that  required  regular  interupt
signals such  as 20  millisecond clocks  in real time can be
tested using  the interupts  within this  emulator.  As  the
speed of the system that this Emulator will be run on varies
from system  to system  calculation of the instruction count
per 20  milliseconds will  differ and  assuming you want the
program under  development to  appear as  real as posible in
real time then the Emulator speed has to be worked out. (See
Appendix D for more information on this)

     The interupt  priorities appear  as they  would in  the
real thing.  That is NMI has the most priority, then the IRQ
interupt that  will occur  only if  the interupt mask in the
status flag  is clear.  An IRQ  interupt can not interupt an
interupt service routine already in process, whether it be a
NMI or IRQ service routine running. But a NMI can interupt a
IRQ or  NMI service  routine in  process. Here lies a danger
that is  not protected against. If the NMI instruction count
is set  to a  value lower  than will  allow  a  NMI  service
routine to  finish to  completion and  return on  the  first
interupt then  nested  interupt  servicing  will  occur  and
before long  the whole  memory space  will be overwritten by
the stack thus destroying the users program.

*  I N <const>

     Loads  the  Non  Maskable  Interupt  instruction  count
register with a constant. If the constant was equal to $1000
then the  program will  be interupted  by a  NMI every  4096
instructions executed.

*  I I <const>

     Loads the maskable interupt request register (IRQ) with
the value  constant. If  the constant  was $200 then the IRQ
interupt will  occur every  512 instructions but only if the
interupt mask is clear.


                        LOADING FILES

   L <filename.ext>

*  L

     Load file from disk of the filename <filename.ext> will
cause the  debugger to  attempt to  load data  from  a  mass
storage device.  But before  this can occur four checks will
be done.

(1)  The filename's extension string will be checked for one
     of eight  types. They  are: .S1  .S2 .S3 .O80 .O68 .HEX
     .COM .EXE      If  the extension  string does not match
     with any  of these then an error message is printed and
     the function terminated.

(2)  An attempt to open the file proceeds. If this cannot be
     done for  some reason  then the reason is displayed and
     the function terminated.

(3)  If the  file is  of type  .COM or  .EXE then a straight
     binary load  is performed  and load exits. But if it is
     anyone of  the other  type of  files then  the debugger
     will interpret  what type  of format the data is stored
     as then  decode and store it into the Emulators memory.
     The format  is determined  by the data contained in the
     file. Any  one of  the Motorola  formats or  Intel  hex
     format can be read. As these follow strict layouts then
     the type can be determined and the data checked against
     checksum values.  After the  end-of-file signature  has
     been found the debugger exits from loading the data.

(4)  If this  is a  load on entry to the emulator. That is a
     filename was  stated in  the command  line at  startup.
     Then the program counter (PC) will be set to the lowest
     address data  was stored  at. All default values within
     the debuggers  commands will also be set to reflect the
     contents of the PC.

If no  filename is given then the last used filename will be
used. That  is assuming  a file  has been  loaded within the
same session.

After a  succesful load  has been  completed the  lowest and
highest address  that had  data stored to it from the source
file will  be displayed. This will help in determining where
that run-away data went.


     More detailed information on the format of any of the
Hex formats can be found in APPENDIX B and APPENDIX C. These
should describe it sufficiently enough.


                      EXTRA INSTRUCTIONS


     One of the great advantages that came with writing this
emulator is  that of  creating my  own instructions. Athough
the  instructions  that  have  been  added  to  the  MM6800-
Emulators repertoire  are simple ones it is not unreasonable
to include  instructions that  are  very  complex  in  there
nature. That  would mean  that a  Float Point  Unit could be
emulated along  side the  M6800 CPU  with the intention that
this FPU  chip will  be included  into the final system. All
aspects of  the two   chips  could be  tested. Albeit at the
software level only.

     FPU functions  have not been implemented in the MM6800-
Emulator but  instructions a  little more  basic have. These
are supplied  as an  interface to  the IBM-pc's hardware and
console.  Their  purpose  is  to  allow  information  to  be
displayed by  the M6800  code to  the  user  under  its  own
control rather  than the  interuption of  processing by  the
debugger.

     Four other instructions for reading and writting to the
IBM-pc's input/output  ports are  supplied also to allow I/O
chips to  be used and controlled under the M6800 program. If
ever you  have had to develop programs for micro-controllers
that look  after the up-keep of peripherals, and there is no
way of  doing this  in the  development system,  it  can  be
frustrating. Its  never quite  known for  sure  whether  the
perihperals' registers  have been  set right.  Even a bit of
real time,  real world,  implementation could  be undertaken
using the IBM-pc's I/O ports.

     In the  end it's  all up  to the  developer as  to  how
testing is  implemented. And  if you wish to use these extra
instructions then  by all  means do  so that's what they are
there for.  There  are  however  two  protection  mechanisms
included to  prevent these  opcodes from being included into
the target  systems environment  and  these  appear  in  the
debugger's Uncompile  command and  at the  Cross-assembler's
level.

     The Uncompiler will show the extra instruction by
displaying them in brackets like this

                 0100  41      (CHOUT   A)

And the  assembler will have to have a mask value set within
the invocation  command line to cause the instructions to be
assembled correctly.  Normally the  mask will  default to  a
value that will not allow these instructions to be assembled
and an error message displayed.

     The command        "tasm -68  test.asm"       will  not
assemble the  new instructions into the final program and if
they are present will cause error messages to be printed.

     The command  "tasm -68 -x1 test.asm"  will assemble the
new instructions successfully into the output.

     With  all   this  said   it  only   remains  that   the
instructions be  listed. But  be aware  that  none  of  them
affect the  status flags  of the  CPU. Unlike  most register
modifing instructions  within the M6800 standard instruction
set.

                              
     Character output to console                     CHOUT

Operation:          ACCX -> IBM-pc-xt/at standard output

Description:           The 8 bit value taken from the A or B
                    accumulator will be sent to the standard
                    output device of the host computer.

Condition Codes:    None

Addressing format:
                    Immediate.

  +-----------+-----------+-----------+---------------------+
   Addressing | Execution | Number of |  Opcode description
     Modes    |    time   |  bytes    |         HEX
  +-----------+-----------+-----------+---------------------+
    A  IMM    | Undefined |     1     |          41
  +-----------+-----------+-----------+---------------------+


Example:

          LDA  A,#'e'
          CHOUT     A         ;PRINT 'e' TO STANDARD OUTPUT

     Character input from console                     CHINT

Operation:          ACCX <- IBM-pc-xt/at standard input

Description:        An 8 bit value is read from the standard
                    input of  the  IBM-pc-xt/at  and  stored
                    into the  accumulator defined within the
                    instruction

Condition Codes:    None

Addressing format:
                    Immediate.


  +-----------+-----------+-----------+---------------------+
   Addressing | Execution | Number of |  Opcode description
     Modes    |    time   |  bytes    |          HEX
  +-----------+-----------+-----------+---------------------+
    A  IMM    | Undefined |     1     |          51
  +-----------+-----------+-----------+---------------------+


Example:

          CHINT     A         ;READ CHAR FROM STANDARD INPUT
          CMP       A,#$D     ;CARRIAGE RETURNED ENTERED
                              ;YET?
          BNE       Example

     Read a byte from the 80x86 I/O bus               IN

Operation:          ACCX <- (XREG)

Description:         The X register is placed onto the 80x86
                    input/output bus  and an  8 bit value is
                    read  from   it  storing   it   to   the
                    Accumulator defined.

Condition Codes:    None

Addressing format:
                    Immediate.


  +-----------+-----------+-----------+---------------------+
   Addressing | Execution | Number of | Opcode description
     Modes    |    time   |  bytes    |         HEX
  +-----------+-----------+-----------+---------------------+
    A  IMM    | Undefined |     1     |         61
    B  IMM    | Undefined |     1     |         62
  +-----------+-----------+-----------+---------------------+


Example:

          LDX  #$1000
          IN   A,X       ;READ I/O PORT ADDRESS AND STORE
                         ;THE RESULT INTO THE A-REG

     Write the Accumulator to the I/O bus              OUT

Operation:          ACCX -> (XREG)

Description:         The X register is placed onto the 80x86
                    input/output bus  and an  8 bit value is
                    written  to   it  from  the  Accumulator
                    defined.

Condition Codes:    None

Addressing format:
                    Immediate.


  +-----------+-----------+-----------+---------------------+
   Addressing | Execution | Number of | Opcode description
     Modes    |    time   |  bytes    |          HEX
  +-----------+-----------+-----------+---------------------+
    A  IMM    | Undefined |     1     |          71
    B  IMM    | Undefined |     1     |          72
  +-----------+-----------+-----------+---------------------+


Example:

          LDX  #$102
          OUT  X,A       ;STORE THE A-REG TO THE PORT

                          APPENDIX A


                    OPCODE CONSTRUCTION


 
   Opcode    b7  b6  b5  b4  b3  b2  b1  b0
             |   |   |   |   |   |   |   |
             |   |   |   |   |   |   |   |
             |   |   |   |   -------------- Function
             |   |   |   |
             |   |   ---------------------- Addressing Mode
             |   |
             |   |
             |   |
             ------------------------------ Set selection
 


     
     Opcodes from $00 - $3F seem to be of no set pattern but
rather allocated  a random  place. The  other three  sets of
instruction, however,  do follow  an easy pattern. It can be
considered that bit-6 determines which register will be used
as follows.


 
           b6         Register selected
           ---------------------------------
           0     A register   Index register
           1     B register   Stack pointer
           


     The Operation  that is  to be  perform on  the SETS  is
contains within  b0 -  b3. The  function is described in the
SETS tables  below. Each SET for each group of instructions.
The instruction SETS follow:


0 - NEGate                         8 - Arithmetic Shift Left
1 - illegal opcode                 9 - ROtate Left
2 - illegal opcode                 A - DECrement
3 - COMpliment reg                 B - illegal opcode
4 - Logical Shift Left             C - INCrement
5 - illegal opcode                 D - TeST
6 - ROtate Right                   E - JuMP
7 - Arithmetic Shift right         F - CLeaR


 
                b5  b4      Addressing Mode
                ---------------------------
                 0   0           A
                 0   1           B
                 1   0        Indirect
                 1   1        Extended
                


                     SET 2  ($40 - $7F)



0 - SUBtract             Areg 8 - Exclusive OR         Areg
1 - CoMPare              Areg 9 - ADd with Carry       Areg
2 - SuBtract with Carry  Areg A - OR Accumulator       Areg
3 - illegal opcode       Areg B - ADD                  Areg
4 - AND                  Areg C - ComPare reg (16 bit) Xreg
5 - BIT test             Areg D - Subroutine call
6 - LoaD Accumulator     Areg E - LoaD reg    (16 bit) Xreg
7 - STore Accumulator    Areg F - STore reg   (16 bit) Xreg



 
               b5  b4      Addressing Mode
               ---------------------------
                0   0        Immediate
                0   1        Direct
                1   0        Indirect
                1   1        Extended
               


                     SET 3  ($80 - $BF)



0 - SUBtract             Breg 8 - Exclusive OR         Breg
1 - CoMPare              Breg 9 - ADd with Carry       Breg
2 - SuBtract with Carry  Breg A - OR Accumulator       Breg
3 - illegal opcode       Breg B - ADD                  Breg
4 - AND                  Breg C - ComPare reg (16 bit) Xreg
5 - BIT test             Breg D - Subroutine call
6 - LoaD Accumulator     Breg E - LoaD reg    (16 bit) Xreg
7 - STore Accumulator    Breg F - STore reg   (16 bit) Xreg
                              

 
               b5  b4      Addressing Mode
               ---------------------------
                0   0       Immediate
                0   1       Direct
                1   0       Indirect
                1   1       Extended
               


                     SET 4  ($C0 - $FF)

                          APPENDIX B

                  INTEL HEX FORMAT RECORDS


     The Intel  Hex format  data records are pretty straight
forward. They  are constructed  with a character to indicate
the record  is starting  ':', an address field of 16 bits, a
record type field, a data field and the checksum. All of the
values printed  are first  converted to  an ASCII equivalent
then sent.  So to  send, in  the address  field, a  value of
$4090 as a string would be '4090' but to view that number as
byte values  will be  $34 $30  $39 $30.  Each four bits have
been converted  to an  ASCII equivalent. This applies to all
values that  appear within  the record  bounderies. Moreover
the whole  record is  printable and  any system dealing with
these records  will not  hangup or  perform  strange  things
while trying to dump it to the serial port.

 +---+----+---------+------+-------------------------+----+
 | : | CC |  AAAA   |  TT  |         DD .. DDn       | XX |
 +---+----+---------+------+-------------------------+----+


 ':'      Start of record character                   char
 'CC'     Byte count. Size in bytes of Data field.    8 bits
 'AAAA'   Address field.                             16 bits
 'TT'     Record type.
          00 = normal data, 01 = last record.         8 bits
 'DD'     Data in bytes, no spaces between any values.
          The data field can be of 1 to 255 bytes long.
                                                      8 bits
 'XX'     Checksum.                                   8 bits


The checksum is calculated like this:

     Temp = CC + AA(high) + AA(low) + TT + (DD .. DDn)

     XX   = 0 - Temp

Therefore to verify a record against its checksum simply add
all of the fields together and the answer should be $00

     00   = CC + AA(high) + AA(low) + TT + (DD .. DDn) + XX

To determine  the end  of the  total file two methods can be
used. One is to check the 'TT' field for a value of $01. But
this can  be a  bit dubious  as some  programs that generate
Intel hex  format records  don't worry  about this field and
leave it  with a value of null, $00. The second method is to
check if  the 'CC' field has a null value in it. When it has
then it  can be  assumed that no more data will follow. This
seems to  be the  accepted way  of terminating  an Intel hex
record.

     :0401000001020304F1

               This Example  has data  in it  that came from
               addresses $100 - $104. That data is $01, $02,
               $03, and  $04. The  Data  field  byte  count,
               'CC', is  $04 and  the record  type is $00; a
               normal data record. The checksum is $F1.

                              
                          APPENDIX C

                MOTOROLA 'S' FORMAT RECORDS


     There are three types of 'S' format records that can be
generated by  a cross-assembler. Although you can be assured
that the  'S1' format  records will  be generated  by  M6800
assemblers I  will include  the other  two for completeness.
These are  'S1', 'S2', and 'S3' formats. See the table below
for a  full layout  of them  but mainly  the value 1, 2 or 3
indicates what size the address is in the Address field. The
end of  file 'S'  values indicate that this will be the very
last record  within that  file. Nine  times out  of ten 'S9'
will be  used in all cases but it is a good idea to test for
all three anyway. That is assuming your loader is programmed
to decode all three.

     The  construction   of  the   record  is  the  starting
character 'S',  record type, byte count, address, data field
and finally  the checksum.  It must  be pointed out that the
calculation of the checksum is slightly different to that of
the Intel hex format. Instead of  a  value  of  $00 when all
fields have  been added together $FF is the result. But this
will be described in detail later.

     As with  Intel hex  records all  byte quanties  are  of
printable form  so every four bits are converted to an ASCII
equivalent.


     S0   -    Data field contains name of the source file.
 The address field will usually be a 16 bit null, $0000.
     
     S1   -    16 Bit address field    End of file  -> S9
 
     S2   -    24 Bit address field    End of file  -> S8
 
     S3   -    32 Bit address field    End of file  -> S7
 
 Table  1
 



                      S-format layout

  +---+---+----+--------+------------------------+----+
  | S | T | CC |  AAAA  |       DD .. DDn        | XX |
  +---+---+----+--------+------------------------+----+


S    -    Starting character for the record          Char
T    -    Record type.                             4 bits
CC   -    Byte count. Includes address field, data field and
          checksum field in the count.
                                                   8 bits
AAAA -    Address field. For 'S1' type.           16 bits
DD   -    Data field. No spaces between the bytes  8 bits
XX   -    Checksum                                 8 bits


Calculating the checksum is as follows:

     Temp = CC + AA(high) + AA(low) + (DD .. DDn)

     XX   = $FF - Temp


Verifing the  Integrity of  a record  with the  checksum the
following should be done.

     $FF  = CC + AA(high) + AA(low) + (DD .. DDn) + XX

But for  even  easier  checking  of  the  record  against  a
checksum instead  of clearing the accumulator that will keep
a tally of the checksum calculations start it with $01. Then
when the  final value,  the 'XX'  field,  is  added  to  the
accumulator the  result will  be zero.  Z flag  gets set, no
need to compare it against $FF.

     To further  describe the 'S0' record which contains the
source files  name or  anything else  look  at  the  example
below. The  source file's  name is contained within the data
field but  each byte that makes up each letter in the source
file's name  'test.asm' is  taken  as  a  byte  literal  and
converted to  printable form  like  any  other  byte  to  be
inserted into the record. Other than that the record follows
the same  rules as  would any  other record  type within the
file.

     S0110000746573742E61736DBF <- "BF" = Checksum
             ----------------
                     ^------------ Source filename
'test.asm'


     S107010001020304ED
     S9

          This 'S1'  record has  in it  data from  addresses
          $0100-$0104 of  the value  $01, $02,  $03, and $04
          the data  field is  'CC' - 3 (ie: $07 - $03) = $04
          and the checksum is $ED
          The next  line has on it an S9 which indicates the
          end of file.

                          APPENDIX D
                              
                              
                        PERFORMANCE

     To  calculate  the  speed  at  which  the  Emulator  is
processing M6800  instructions run the program MIPS.o68 with
supervisor mode  turned off  (use  'S'  command)  and  begin
execution with  'G 100  [return]'. At  the same  time  start
timing  with   your  trusty   time-piece  until  an  illegal
instruction exception  is reported.  Stop timing. This value
is now time.

     Now put  the value  time through the following formulae
to get  instruction through-put  (IPS) and  equivalent clock
speed (clk)  that a  real M6800 cpu would have to be running
at to equal the performance of the Emulator.


          IPS = (3 + (46 * 65535))/time  (seconds)
          clk = (9 + (152 * 65535))/time (seconds)


Here are  some figures  that I have gained from various test
machines. All IBM-pc compatable.

80386 @ 20MHz.   Time = 25.3 seconds
Calculated: IPS = 119,154 Instructions per second.
Calculated: clk = 393,728 Hz M6800 cpu.

80286 @ 12 Mhz.  Time = 37.8 seconds
Calculated: IPS = 79,751 Instructions per second.
Calculated: clk = 263,527 Hz M6800 cpu.

80286 @ 8MHz.    Time = 64.7 seconds
Calculated: IPS = 46,593 Instructions per second.
Calculated: clk = 153,962 Hz M6800 cpu.

80186 @ 10Mhz.   Time = 65.1 seconds
Calculated: IPS = 46,307 Instructions per second.
Calculated: clk = 153,106 Hz M6800 cpu.

80c86 @ 9.5 Mhz. Time = 81.3 seconds
Calculated: IPS = 37,080 Instructions per second.
Calculated: clk = 122,525 Hz M6800 cpu.

80c86 @ 4.77Mhz. Time = 163.3 seconds
Calculated: IPS = 16,855 Instructions per second.
Calculated: clk = 61,000 Hz M6800 cpu.

