home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / emulate / systems / 6800 / 68em.txt < prev    next >
Text File  |  1991-05-06  |  48KB  |  1,275 lines

  1.                                                             
  2.  
  3.  
  4.  
  5.  
  6.  
  7.                               
  8.                   MOTOROLA M6800 EMULATOR
  9.                               
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.                         Version 1.0
  27.  
  28.                        1 - May - 1991
  29.  
  30.                        Kevin Bertram
  31.  
  32.  
  33.                       INTRODUCTION
  34.  
  35.      This implementation  of the  M6800 Emulator  is version
  36. 1.0. If you find any errors with the Emulator or debugger or
  37. maybe there  are a  few suggestions  as to  what  you  might
  38. like   to see  in the program to enhance its usefulness then
  39. please let  me know.  My address  is further  down  in  this
  40. manual.
  41.  
  42.      Also this  program and  manual can  be copied  as  many
  43. times as you  want and given to friends if you please. There
  44. is no  hassle with  this. But do not sell it! The program is
  45. public domain and not for profit making.
  46.  
  47.      The purpose  of  this  Emulator  is  to  replicate  the
  48. instruction set  execution of  a CPU  not present within the
  49. hardware design  of the IBM-pc-xt/at or a clone there-of. Or
  50. for that  matter  any  host  computer  that  is  capable  of
  51. executing programs.  The instruction set of the emulated CPU
  52. must be  adhered to  exactly otherwise  programs written for
  53. the emulated  CPU will  not perform  correctly in the target
  54. system. This  program in particular has been adapted to suit
  55. the Motorola M6800 8 bit CPU.
  56.  
  57.      An emulator  can be a useful program. Especially if you
  58. are into  constructing   and  programming  your  own  micro-
  59. controllers. They  provide for  a safe  environment at which
  60. new code can be tested under reasonably tight control before
  61. being downloaded  to the  target machine and let loose. Also
  62. the emulator  allows for  a foreign  CPU's machine  code  to
  63. execute under  a host  CPU. Which  is most  likely where the
  64. cross-assembler will  reside too.  All this  adds to  faster
  65. implementation of  your   program and gets you to using your
  66. hardware sooner.
  67.  
  68.      I will  not enter into the reasons as to why a designer
  69. might use  8 bit  CPU's as opposed to 16 of 32 bit CPU's but
  70. rather that what ever his or her choice is they might find a
  71. need to  check out  the integrity of the program code before
  72. 'burning it  in'. It  could be that the program will have to
  73. be executed  step by  step to find an illusive fault. And in
  74. this case  an emulator  could prove  useful. If  the  target
  75. machine already  has a debugger built in then there might be
  76. no need for an emulator but if there is not then an emulator
  77. will be needed.
  78.  
  79.  
  80.      My reason  for producing  an Emulator  for the M6800 is
  81. mainly because it was the first CPU I had encountered and so
  82. I am  biased towards it. Another is that, as far I am aware,
  83. there are  no other  programs that  will emulate a M6800 CPU
  84. running under  an Intel  CPU and  as I  have a  need for one
  85. right now I wrote this program as a response. So here it is.
  86. It was a joy to work on and I hope you find it useful.
  87.  
  88.           Kevin Bertram
  89.  
  90.      Electronic mail
  91.  
  92.           ACSNET - kevin@latcs1.oz
  93.  
  94.      Surface mail:
  95.  
  96.           Department of Computer Science
  97.           La-trobe University
  98.           Plenty  road
  99.           Bundoora, 3083
  100.           Melbourne,  Victoria
  101.           Australia.
  102.  
  103.                       ACKNOWLEDGEMENTS
  104.  
  105.      I would  like to  thank Ira  Baxter for  his  excellent
  106. suggestions in speeding up the Emulator to the effect of ten
  107. times as compared to its intial implementation.
  108.  
  109.      I would  like to  thank Mark  Seiffert also  who, along
  110. with Ira,  sourced me  with M6800  code to  run through  the
  111. Emulator to  test its validity. [I find it is much better to
  112. have someone  else test  my software  because they  will not
  113. step around the precarious parts of the program.]
  114.  
  115.  
  116.                       DISTRIBUTION FILES
  117.  
  118.  
  119.  
  120.  
  121.  
  122.      There should  be the  following files  contained within
  123. the archive file.
  124.  
  125.      68EM.COM            M6800  Emulator  configured  for  a
  126.                          standard IBM-pc-xt/at
  127.  
  128.      68EMV.COM           M6800 Emulator  configured  for  an
  129.                          IBM-pc with  a VT-100  terminal  as
  130.                          its console.
  131.  
  132.      68EM.TXT            This file  - it describes the usage
  133.                          and  other  things  present  within
  134.                          this version of the M6800 emulator.
  135.  
  136.      68EM.PIF            Windows  information  file  to  get
  137.                          this emulator to run in a window.
  138.  
  139.      68EM.ICO            Icon for emulator to suit Microsoft
  140.                          Windows V3.0.
  141.  
  142.      MIPS.o68            Runs through a general selection of
  143.                          M6800 instruction  65535 times.  By
  144.                          timing this  an indication  of  the
  145.                          instruction  through-put   can   be
  146.                          calculated. See Appendix D
  147.  
  148.      TASM68.TAB          M6800 opcode table suited to SPEECH
  149.                          TECHNOLOGY INCORPORATED  (C) tasm22
  150.                          table    driven     cross-assembler
  151.                          version 2.2
  152.  
  153.      AS0.EXE             M6800 assembler  from  Motorola  as
  154.                          freeware software.
  155.  
  156.      AS0.DOC             Document    for     the    Motorola
  157.                          assembler.
  158.  
  159.      MAIN.S19            Sample    multitasking    operating
  160.                          system  that  will  run  under  the
  161.                          control of the this CPU emulator.
  162.  
  163.      MAIN.DOC            A brief  description of  the sample
  164.                          operating system (MAIN.S19) and how
  165.                          to use it.
  166.  
  167. Note  that   the  cross-assembler   by   SPEECH   TECHNOLOGY
  168. INCORPORATED has  not been  included. Their  program can  be
  169. acquired from  any BBS  that has  it and will most likely be
  170. named as TASM22.ARC
  171.  
  172.      Notes on  how to  use TASM  will come  with the archive
  173. file. Also  see the  section  in  this  document  on  "Extra
  174. instructions"  for   extra  details  concerning  the  cross-
  175. assembler in relation to this program.
  176.  
  177.                          DISPLAY TYPE
  178.  
  179.  
  180.      There is  nothing very  special about  the way in which
  181. the debugger  or Emulator  will  display  its  data  to  the
  182. console. That  is there  are no  fancy windows  or  graphics
  183. included to  improve the  overall look of things. But rather
  184. the output is simple.
  185.  
  186.      There is,  however, a  need to  setting certain  things
  187. such as  high brightness  characters,  a  limied  number  of
  188. cursor addressing  movements and  clearing the whole screen.
  189. For these  I have catered for two environments on which this
  190. program could  run. The  first is  the standard  "run of the
  191. mill"  IBM-PC-xt/at with what ever graphics card being used.
  192.  
  193.      The second  is for a IBM-PC type computer that runs the
  194. same programs  but uses  a  VT-100 character terminal as its
  195. console. These do exist (I've got one!) and therefore I have
  196. adapted the  program to  suit  them  too.  In  fact  if  the
  197. standard XT/AT  were to  have  the  device  driver  ANSI.SYS
  198. installed then  there would  be no  problems in  running the
  199. later program on either machine.
  200.  
  201.      I have  thought about  using a  soft switch  within the
  202. command line  when the  program is invoked to indicate which
  203. console type  is being  used but  decided against  that,  at
  204. least for the moment, to opt for two programs. One setup for
  205. a standard  console using graphics cards and the other being
  206. setup up  for VT-100  consoles. It is no big deal to do this
  207. as all  it requires is one variable to be changed within the
  208. source at assembly time.
  209.  
  210.      The main  reason for  this approach  is  to  take  into
  211. account those times when a programmer is fanatically working
  212. at great  pace and  would much  rather type a simple name to
  213. start the  program instead  of the  name  and  a  string  of
  214. softswitches. It can be discouraging to start the program in
  215. the wrong  mode and  wonder why all these strange characters
  216. are appearing on the screen.
  217.  
  218.      Anyway it remains to be seen as to whether softswitches
  219. are included or not later. But at this moment they are not.
  220.                               
  221.                     INVOKING THE EMULATOR
  222.  
  223.  
  224.      To start  the program  it is  a simple matter of typing
  225. its name then pressing return. The program will load and run
  226. and the command line prompt '-' will appear.
  227.  
  228.      If there is a data file to loaded as well then this can
  229. be  done  by  including  the  data  file's  name  after  the
  230. emulators invocation name.
  231.  
  232.      For example   C:> 68em example.o68
  233.  
  234.      Will   load   example.o68   into the  Emulators  memory
  235.      after it  itself has  been loaded  and run.  All of the
  236.      error checking  steps that  are done by the 'L' command
  237.      apply. If  there is  an error  loading the file then an
  238.      error message  describing the  problem will  be printed
  239.      and the  loading terminated.  The Emulator  will return
  240.      with its  prompt waiting for a command but with no data
  241.      in memory.  If the  file loaded correctly then the byte
  242.      count will  be  displayed  followed  a  report  on  the
  243.      highest and  lowest address  data was  stored  at,  the
  244.      Emulator's signon  message and  then the  prompt '-' on
  245.      the last  line. The  debugger and  emulator will now be
  246.      ready to use.
  247.  
  248. Note that  the hello message after starting will contain the
  249. current version  number, the  initial release  date and  its
  250. version number  and  finally  the  current  version  of  the
  251. program along  with its  release date.  This should give the
  252. user an  indication of what version of the program they have
  253. and whether it is as recent as it should be.
  254.  
  255. After a  succesful load  of a  data  file  on  starting  the
  256. Emulator the  Program Counter  (PC) and  all of  the default
  257. addresses used  within the debuggers commands will be set to
  258. the same  value as  the lowest  address data  was stored at.
  259. This makes  for a  quick and  easy startup of a 6800 program
  260. that will  require the  user to merly enter a 'G' command to
  261. start the application.
  262.  
  263.  
  264.                       DEBUGING COMMANDS
  265.  
  266.      In order to make the Emulator useful then there must be
  267. some way  of reading  and writing  to the  Emulators memory,
  268. tracing execution  of test  programs, examining or changing,
  269. registers and  loading data  from files  which will  be more
  270. than likely  be  output  from  cross-assemblers.  The  M6800
  271. Emulator has  these functions  and they  will  be  described
  272. here.
  273.  
  274. The usual format will be:
  275.  
  276.       command <start address> <end address> <constant>
  277.  
  278. If an  8 bit constant is required in any of the commands and
  279. a 16   bit  constant was  entered then  only the last 8 bits
  280. will be retained.
  281.  
  282.  
  283.                         MISCELLANEOUS
  284.  
  285.    S
  286.    Q
  287.    ?
  288.  
  289.  
  290. *  S
  291.  
  292.      Toggles the  mode in  which the  emulated code will run
  293. in. Initially, after begining the emulator, the program will
  294. be executed  in  the  'Supervised'  mode  in  which  program
  295. execution can be stopped at any time by entering a ^C. A 'G'
  296. command  will  return  the  program  back  to  its  previous
  297. position unchanged before the interupt was encounted.
  298.  
  299.      By  issuing  the  'S'  command  and  toggling  to  'Non
  300. supervised' mode  programs will run until a breakpoint or an
  301. illegal opcode is found. There is no other way to exit. Mind
  302. you though  that the later mode performs 3 times better than
  303. the 'Supervised'  mode. The  use  of  either  mode  will  be
  304. determined by whether you trust the code or not.
  305.  
  306.      If a  program is  running in  unsupervised mode  and  a
  307. control-c was  entered at  the keyboard  then this character
  308. will be passed onto the internal keyboard buffer ready to be
  309. read by  the 6800  program through  the CHINT A instruction.
  310. This will  allow for  a reasonable  emulated environment for
  311. the 6800  program to  work in.  That is: a control-c will be
  312. allowed to  be processed  by the program as if it was on its
  313. target machine.
  314.  
  315.  
  316. *  Q
  317.  
  318.      Quit from the Emulators debugger and return to DOS. The
  319. return code given to DOS will be $00.
  320.  
  321.  
  322. *  ?
  323.  
  324.      Prints the quick help menu to the console.
  325.  
  326.  
  327.                     SETTING CPU REGISTERS
  328.  
  329.    R  <register name> <const>
  330.  
  331.    R  A < 8 bit constant>
  332.    R  B < 8 bit constant>
  333.    R  X <16 bit constant>
  334.    R  S <16 bit constant>
  335.    R  P <16 bit constant>
  336.    R  F < 8 bit constant>
  337.  
  338.  
  339.  
  340. *  A, B, X, S, P, and F
  341.  
  342.      As  with  any  M6800  CPU  chip  there  are  five  user
  343. registers which  can be changed under program control and as
  344. such they  can be modified at anytime through the use of the
  345. above commands.  The Flag  register, although  not ideal for
  346. storing data  in, can  have it's  contents changed too. This
  347. would most  likely be  used to  set up  key situations which
  348. would test  program integrity at a point without the need to
  349. execute code before it.
  350.  
  351.      'A' - sets the A accumulator
  352.      'B' - sets the B accumulator
  353.      'F' - sets the status flags
  354.      'X' - sets the index register
  355.      'S' - sets the stack pointer
  356.      'P' - sets the program counter
  357.  
  358.  
  359.  
  360. *  R
  361.  
  362.      Without a  register name will print the entire register
  363. list along  with the  disassembly of  the next  instruction.
  364. Note that  if a  register name is given of which the program
  365. does not  understand then  the register list will be printed
  366. instead of  an error  message. A  print of the register list
  367. will have  the flags  printed as  a hex  number and a single
  368. letter description  of each  flag bit,  the contents  of the
  369. five other CPU registers that are relavent to the M6800 CPU,
  370. and a disassembly of the next instruction to be executed.
  371.  
  372. A typical register list would look like this:
  373.  
  374.  
  375. F - FF    - - H I N Z Ov C
  376. A = 12    B = F7    X = 0147    S = FFF8    PC = 0100
  377.  
  378. 0100  86 45           LDA    A,#$45
  379.  
  380. -_
  381.  
  382.  
  383. The Flags list mean:
  384.  
  385.      H  - Half carry flag
  386.      I  - Interupt enable flag
  387.      N  - Sign bit flag
  388.      Z  - Zero flag
  389.      Ov - Overflow flag
  390.      C  - Carry flag
  391.  
  392.  
  393.                        MEMORY MODIFING
  394.  
  395.    C <start address> <end address> <constant>
  396.    E <address>
  397.  
  398. *  C
  399.  
  400.      The 'C' or 'fill memory with Constant' command will, by
  401. default, fill  all of  the Emulators  64K memory  space with
  402. $00. Thus  the work space can begin from a clean slate. If a
  403. start address  is given, as the  only parameter, then it and
  404. the following  256 bytes of memory will be set to null, $00.
  405. If a  start address is given with an end address but with no
  406. constant then  that area  of  memory  within  the  start-end
  407. address will be filled with nulls, $00. But if a constant is
  408. supplied that  range of  memory will  be  filled  with  that
  409. constant.
  410.  
  411. For example : C 100 200 01    will fill  the  address  range
  412.                               from $100  to  $200  with  $01
  413.                               which are "nop's".
  414.  
  415.  
  416. *  E
  417.  
  418.      'E' or  'memory Examine'  and change  will allow single
  419. steps through the Emulators memory space. At a point where a
  420. byte is  to be changed then a new value can be entered, or a
  421. string of  new data can be entered each seperated by a space
  422. character. When  the [return]  is entered  then that data is
  423. stored to  memory and  the next  unused address is displayed
  424. ready for  new data.  To exit  this mode a '.' with no other
  425. data on the line should be entered followed by a [return].
  426.  
  427.   Example:  -E 100
  428.  
  429.                  0100 00 > _           will be the response.
  430.                                    Entering  data   will  be
  431.                                    like this:
  432.  
  433.              0100 00 > 01 02 03 04 [return]
  434.              0104 34 > _
  435.  
  436.                                    with only  a [return]  on
  437.                                    the input  line then  the
  438.                                    address being  looked  at
  439.                                    will increment by one.
  440.  
  441.              0104 34 > [return]
  442.              0105 31 > _
  443.  
  444.                                    To exit now just enter
  445.                                    '.' [return]
  446.  
  447.              0105 31 > . [return]
  448.              -_
  449.  
  450.  
  451.                        MEMORY DISPLAY
  452.  
  453.    U <start address> <end address>
  454.    Z
  455.    D <start address> <end address>
  456.    H <start address> <end address>
  457.  
  458.  
  459. *  D
  460. *  H
  461.  
  462.      Dump or  Hex dump  will both do the same thing; print a
  463. block of  data using  byte size  data along  with  it  being
  464. printed as  an ASCII  character as  it would  appear on  the
  465. screen. After  using many  different types of debuggers some
  466. use 'D' for this function and others 'H'. When changing from
  467. one to  the other  more than  likely  'D'  will  be  entered
  468. instead of  'H' and visa-vers. So I've included these two to
  469. do the same thing to accommodate for my limitation at least.
  470.  
  471.      The default  block dump size is 256 bytes but if an end
  472. address is  given then  the hex  dump will  end at  the  end
  473. address. Note  that both  the start  and end address will be
  474. rounded off  to the  lowest 16 byte field. That is $102 will
  475. be taken as $100, $159 will be taken as $150 etc.
  476.  
  477.      The output will be:
  478.           address,  16 bytes of data,  ASCII field
  479.  
  480. As an example:
  481.                 -D 100 110
  482.  
  483. 0100 - 01 02 03 04 34 31 0 45 20 10 11 13 45 48 2a 20       
  484. .41.E ...EH*
  485.  
  486. -_
  487.  
  488. will result.  Note  that  all  unprintable  characters  will
  489. appear as a single '.' in the ASCII field.
  490.  
  491.  
  492. *  U
  493.  
  494.      Uncompile will  disassemble a  section of code from the
  495. M6800's memory.  The default listing length will be 16 lines
  496. of disassembly  but given  a start  and end address then the
  497. disassembly will  continue until  the end  address has  been
  498. reached. If  only a  start address  was  supplied  then  the
  499. disassembly will  print 16  lines of  disassembly from  that
  500. address.
  501.  
  502.      If  an   address  of  an  instruction  appears  in  the
  503. breakpoint list  then  that  line  of  disassembly  will  be
  504. highlighted to  make easier  viewing of  the  code  and  the
  505. breakpoints position within it.
  506.  
  507.      The disassembler follows the usual rules concerning the
  508. M6800 instruction  set as  it appeared on the day. But there
  509. is one  exception to  the rule. When printing an instruction
  510. that uses INDIRECT addressing mode then the disassembly will
  511. have 3 parts to its opcode field.
  512.  
  513. For example: LDA A 2,X    will appear as    LDA A,2,X
  514.  
  515.      Most assemblers  will not  accept this kind of notation
  516. but in preference for neatness I have opted for this instead
  517. of the  alternatives. Motorola  had  changed  the  Mnemonics
  518. somewhat to  accommodate for  this problem it seems by using
  519. LDA or LDB in the 6809 series rather than LDA A or LDA B.
  520.  
  521.  
  522. *  Z
  523.  
  524.      This  command  will  print  the  last  twenty  executed
  525. instructions that  the emulator  has just  worked on  before
  526. exiting the 6800 program. The very last instruction printed,
  527. which is  more than  likely to be the cause of the exit, was
  528. the last instruction processed.
  529.  
  530.      The purpose of the command and instruction tracing will
  531. be seen  when you  are trying  to find  a reason  to  why  a
  532. program has become a "run-away". Or why a program sourced by
  533. someone  else   always  exits  without  performing  anything
  534. useful.
  535.  
  536.      It should  be pointed  out that  no instruction tracing
  537. will  be   performed  when   the  emulator   is  running  in
  538. unsupervised mode.  In fact  not much  is done  eccept  6800
  539. instruction execution  in this  mode. All of the goodies are
  540. done in  the supervised  mode. Also when a program is run in
  541. unsupervised mode  the instruction  trace buffer  is cleared
  542. thus to  issue a  "Z"  command  after  a  program  has  been
  543. executed the  buffer will be reported as empty. This happens
  544. even if it was full before execution in unsupervised mode.
  545.  
  546.  
  547.                               
  548.                       PROGRAM EXECUTION
  549.  
  550.    G <start address>
  551.    T <n steps>
  552.    B <#> <address>
  553.    P
  554.  
  555.  
  556.      Executing any  M6800 program  is  simply  a  matter  of
  557. loading the  opcodes and data into the Emulators memory then
  558. instructing the emulator to take control. Three instructions
  559. are  provided  to  help  do  this.  Their  usage  desription
  560. follows.
  561.  
  562.  
  563. *  G
  564.  
  565.      Goto will  cause the  execution of  M6800  instructions
  566. from the  address '<start  address>' if  given or  from  the
  567. current value  contained within  the M6800's Program Counter
  568. (PC). The command line address will always override the PC's
  569. current state.
  570.  
  571.      If at  anytime the  Emulator tries  to execute  illegal
  572. instructions then  the CPU's current state will be saved and
  573. program execution ceased. A message will then be printed and
  574. the program  returned back  to the command line entry level.
  575. To gain an understanding of what the CPU's current state was
  576. use the  Register command.  See the  'R' command  for  usage
  577. description.
  578.  
  579.  
  580. *  T
  581.  
  582.      Causes the Emulator to trace 'n' instructions at a time
  583. then return back to the command level. The default value for
  584. 'n' is  one (1)  but can  contain values upto 255. This will
  585. make it  easy to  get  passed  those  loops  that  might  be
  586. contained within the program under test.
  587.  
  588.      The actual  execution address  is read  from the  CPU's
  589. Program Counter  (PC) and  instructions  taken  from  there.
  590. There is  no provision  for overriding  the Program  Counter
  591. within this command.
  592.  
  593.      The current  state of  CPU is  saved away  for  viewing
  594. later and  control returned to the command level. If illegal
  595. instructions are  encountered then the Emulator performs the
  596. same abort sequence as described in the 'G' command.
  597.  
  598.  
  599. *  B
  600.  
  601.      Breakpoints set  or cleared  within the  M6800 program.
  602. Upto eight  breakpoints can  be set  at any one time and the
  603. list will  be shown when the 'B' command, alone, is entered.
  604. If a  breakpoint number  is given but no address stated then
  605. that breakpoint will be cleared from the list and finally if
  606. an address is given with a breakpoint number then it will be
  607. set; or changed if that breakpoint number already exists.
  608.  
  609.      Note that  a breakpoint  address of  the value of $FFF8
  610. will clear  the breakpoint  from the  list. I have used this
  611. value  instead  of  the  usual  $0000  to  indicate  cleared
  612. breakpoint. Why?  Because  those  values  contained  at  the
  613. address $FFF8  - $FFFF are autovectors for interupt control.
  614. They are  never instructions,  or if  they  are  then    the
  615. function of the M6800 could be eratic at times. As there are
  616. no interupt  functions other than a software interupt, built
  617. into the Emulator then it would be reasonable to use this as
  618. a sort of null value or useless address and in this case 'no
  619. breakpoint'.
  620.  
  621.  
  622. *  P
  623.  
  624.      Will  cause   execution  of  the  next  instruction  to
  625. completion. If  it happens  that the  next instruction  is a
  626. subroutine call  then the  subroutine will  be executed  and
  627. allowed to complete and  return to its caller. At this point
  628. the program  execution will  stop and the register list will
  629. be printed as would any trace command do.
  630.  
  631.      This command  is extremely  useful in  step over  those
  632. subroutines that  have been  tested and proved working. Thus
  633. preventing worthless tracing of code that has been verified.
  634.  
  635.                       SETTING INTERUPTS
  636.  
  637.    I
  638.    I N <const>
  639.    I I <const>
  640.  
  641. *  I
  642.  
  643.      The M6800  emulator version  0.3  and  up  all  support
  644. interupt handling  for all  of the  interupt types supported
  645. within the  M6800 CPU.  Versions before 0.3 only catered for
  646. the Software  interupt. In  order to implement the other two
  647. interupts other  than reset  this command  exists. Note that
  648. when an  interupt is to occur the service routine address is
  649. read from  the NMI  and  IRQ  vectors  at  $FFFC  and  $FFF8
  650. resepectively.
  651.  
  652.      Entering "I"  with no  parameters will print the status
  653. of the  registers that  will keep track of when Non Maskable
  654. and Maskable  interupts  should  occur.  The  mechanism  for
  655. determining when  either of  the interupts should be invoked
  656. is by  instruction count  rather than  an external signal of
  657. some type.  Therefor you  will have  to work  out  how  many
  658. instructions the  target CPU  will execute  before the  next
  659. interupt will  occur. This is by no means the best answer to
  660. interupt servicing  for all target environments but at least
  661. it does  give you  the user  a way  to test  if an  interupt
  662. service routine will work with the reset of the program.
  663.  
  664.      For those  instances  that  required  regular  interupt
  665. signals such  as 20  millisecond clocks  in real time can be
  666. tested using  the interupts  within this  emulator.  As  the
  667. speed of the system that this Emulator will be run on varies
  668. from system  to system  calculation of the instruction count
  669. per 20  milliseconds will  differ and  assuming you want the
  670. program under  development to  appear as  real as posible in
  671. real time then the Emulator speed has to be worked out. (See
  672. Appendix D for more information on this)
  673.  
  674.      The interupt  priorities appear  as they  would in  the
  675. real thing.  That is NMI has the most priority, then the IRQ
  676. interupt that  will occur  only if  the interupt mask in the
  677. status flag  is clear.  An IRQ  interupt can not interupt an
  678. interupt service routine already in process, whether it be a
  679. NMI or IRQ service routine running. But a NMI can interupt a
  680. IRQ or  NMI service  routine in  process. Here lies a danger
  681. that is  not protected against. If the NMI instruction count
  682. is set  to a  value lower  than will  allow  a  NMI  service
  683. routine to  finish to  completion and  return on  the  first
  684. interupt then  nested  interupt  servicing  will  occur  and
  685. before long  the whole  memory space  will be overwritten by
  686. the stack thus destroying the users program.
  687.  
  688. *  I N <const>
  689.  
  690.      Loads  the  Non  Maskable  Interupt  instruction  count
  691. register with a constant. If the constant was equal to $1000
  692. then the  program will  be interupted  by a  NMI every  4096
  693. instructions executed.
  694.  
  695. *  I I <const>
  696.  
  697.      Loads the maskable interupt request register (IRQ) with
  698. the value  constant. If  the constant  was $200 then the IRQ
  699. interupt will  occur every  512 instructions but only if the
  700. interupt mask is clear.
  701.  
  702.  
  703.                         LOADING FILES
  704.  
  705.    L <filename.ext>
  706.  
  707. *  L
  708.  
  709.      Load file from disk of the filename <filename.ext> will
  710. cause the  debugger to  attempt to  load data  from  a  mass
  711. storage device.  But before  this can occur four checks will
  712. be done.
  713.  
  714. (1)  The filename's extension string will be checked for one
  715.      of eight  types. They  are: .S1  .S2 .S3 .O80 .O68 .HEX
  716.      .COM .EXE      If  the extension  string does not match
  717.      with any  of these then an error message is printed and
  718.      the function terminated.
  719.  
  720. (2)  An attempt to open the file proceeds. If this cannot be
  721.      done for  some reason  then the reason is displayed and
  722.      the function terminated.
  723.  
  724. (3)  If the  file is  of type  .COM or  .EXE then a straight
  725.      binary load  is performed  and load exits. But if it is
  726.      anyone of  the other  type of  files then  the debugger
  727.      will interpret  what type  of format the data is stored
  728.      as then  decode and store it into the Emulators memory.
  729.      The format  is determined  by the data contained in the
  730.      file. Any  one of  the Motorola  formats or  Intel  hex
  731.      format can be read. As these follow strict layouts then
  732.      the type can be determined and the data checked against
  733.      checksum values.  After the  end-of-file signature  has
  734.      been found the debugger exits from loading the data.
  735.  
  736. (4)  If this  is a  load on entry to the emulator. That is a
  737.      filename was  stated in  the command  line at  startup.
  738.      Then the program counter (PC) will be set to the lowest
  739.      address data  was stored  at. All default values within
  740.      the debuggers  commands will also be set to reflect the
  741.      contents of the PC.
  742.  
  743. If no  filename is given then the last used filename will be
  744. used. That  is assuming  a file  has been  loaded within the
  745. same session.
  746.  
  747. After a  succesful load  has been  completed the  lowest and
  748. highest address  that had  data stored to it from the source
  749. file will  be displayed. This will help in determining where
  750. that run-away data went.
  751.  
  752.  
  753.      More detailed information on the format of any of the
  754. Hex formats can be found in APPENDIX B and APPENDIX C. These
  755. should describe it sufficiently enough.
  756.  
  757.  
  758.                       EXTRA INSTRUCTIONS
  759.  
  760.  
  761.      One of the great advantages that came with writing this
  762. emulator is  that of  creating my  own instructions. Athough
  763. the  instructions  that  have  been  added  to  the  MM6800-
  764. Emulators repertoire  are simple ones it is not unreasonable
  765. to include  instructions that  are  very  complex  in  there
  766. nature. That  would mean  that a  Float Point  Unit could be
  767. emulated along  side the  M6800 CPU  with the intention that
  768. this FPU  chip will  be included  into the final system. All
  769. aspects of  the two   chips  could be  tested. Albeit at the
  770. software level only.
  771.  
  772.      FPU functions  have not been implemented in the MM6800-
  773. Emulator but  instructions a  little more  basic have. These
  774. are supplied  as an  interface to  the IBM-pc's hardware and
  775. console.  Their  purpose  is  to  allow  information  to  be
  776. displayed by  the M6800  code to  the  user  under  its  own
  777. control rather  than the  interuption of  processing by  the
  778. debugger.
  779.  
  780.      Four other instructions for reading and writting to the
  781. IBM-pc's input/output  ports are  supplied also to allow I/O
  782. chips to  be used and controlled under the M6800 program. If
  783. ever you  have had to develop programs for micro-controllers
  784. that look  after the up-keep of peripherals, and there is no
  785. way of  doing this  in the  development system,  it  can  be
  786. frustrating. Its  never quite  known for  sure  whether  the
  787. perihperals' registers  have been  set right.  Even a bit of
  788. real time,  real world,  implementation could  be undertaken
  789. using the IBM-pc's I/O ports.
  790.  
  791.      In the  end it's  all up  to the  developer as  to  how
  792. testing is  implemented. And  if you wish to use these extra
  793. instructions then  by all  means do  so that's what they are
  794. there for.  There  are  however  two  protection  mechanisms
  795. included to  prevent these  opcodes from being included into
  796. the target  systems environment  and  these  appear  in  the
  797. debugger's Uncompile  command and  at the  Cross-assembler's
  798. level.
  799.  
  800.      The Uncompiler will show the extra instruction by
  801. displaying them in brackets like this
  802.  
  803.                  0100  41      (CHOUT   A)
  804.  
  805. And the  assembler will have to have a mask value set within
  806. the invocation  command line to cause the instructions to be
  807. assembled correctly.  Normally the  mask will  default to  a
  808. value that will not allow these instructions to be assembled
  809. and an error message displayed.
  810.  
  811.      The command        "tasm -68  test.asm"       will  not
  812. assemble the  new instructions into the final program and if
  813. they are present will cause error messages to be printed.
  814.  
  815.      The command  "tasm -68 -x1 test.asm"  will assemble the
  816. new instructions successfully into the output.
  817.  
  818.      With  all   this  said   it  only   remains  that   the
  819. instructions be  listed. But  be aware  that  none  of  them
  820. affect the  status flags  of the  CPU. Unlike  most register
  821. modifing instructions  within the M6800 standard instruction
  822. set.
  823.  
  824.                                
  825.      Character output to console                     CHOUT
  826.  
  827. Operation:          ACCX -> IBM-pc-xt/at standard output
  828.  
  829. Description:           The 8 bit value taken from the A or B
  830.                     accumulator will be sent to the standard
  831.                     output device of the host computer.
  832.  
  833. Condition Codes:    None
  834.  
  835. Addressing format:
  836.                     Immediate.
  837.  
  838.   +-----------+-----------+-----------+---------------------+
  839.    Addressing | Execution | Number of |  Opcode description
  840.      Modes    |    time   |  bytes    |         HEX
  841.   +-----------+-----------+-----------+---------------------+
  842.     A  IMM    | Undefined |     1     |          41
  843.   +-----------+-----------+-----------+---------------------+
  844.  
  845.  
  846. Example:
  847.  
  848.           LDA  A,#'e'
  849.           CHOUT     A         ;PRINT 'e' TO STANDARD OUTPUT
  850.  
  851.      Character input from console                     CHINT
  852.  
  853. Operation:          ACCX <- IBM-pc-xt/at standard input
  854.  
  855. Description:        An 8 bit value is read from the standard
  856.                     input of  the  IBM-pc-xt/at  and  stored
  857.                     into the  accumulator defined within the
  858.                     instruction
  859.  
  860. Condition Codes:    None
  861.  
  862. Addressing format:
  863.                     Immediate.
  864.  
  865.  
  866.   +-----------+-----------+-----------+---------------------+
  867.    Addressing | Execution | Number of |  Opcode description
  868.      Modes    |    time   |  bytes    |          HEX
  869.   +-----------+-----------+-----------+---------------------+
  870.     A  IMM    | Undefined |     1     |          51
  871.   +-----------+-----------+-----------+---------------------+
  872.  
  873.  
  874. Example:
  875.  
  876.           CHINT     A         ;READ CHAR FROM STANDARD INPUT
  877.           CMP       A,#$D     ;CARRIAGE RETURNED ENTERED
  878.                               ;YET?
  879.           BNE       Example
  880.  
  881.      Read a byte from the 80x86 I/O bus               IN
  882.  
  883. Operation:          ACCX <- (XREG)
  884.  
  885. Description:         The X register is placed onto the 80x86
  886.                     input/output bus  and an  8 bit value is
  887.                     read  from   it  storing   it   to   the
  888.                     Accumulator defined.
  889.  
  890. Condition Codes:    None
  891.  
  892. Addressing format:
  893.                     Immediate.
  894.  
  895.  
  896.   +-----------+-----------+-----------+---------------------+
  897.    Addressing | Execution | Number of | Opcode description
  898.      Modes    |    time   |  bytes    |         HEX
  899.   +-----------+-----------+-----------+---------------------+
  900.     A  IMM    | Undefined |     1     |         61
  901.     B  IMM    | Undefined |     1     |         62
  902.   +-----------+-----------+-----------+---------------------+
  903.  
  904.  
  905. Example:
  906.  
  907.           LDX  #$1000
  908.           IN   A,X       ;READ I/O PORT ADDRESS AND STORE
  909.                          ;THE RESULT INTO THE A-REG
  910.  
  911.      Write the Accumulator to the I/O bus              OUT
  912.  
  913. Operation:          ACCX -> (XREG)
  914.  
  915. Description:         The X register is placed onto the 80x86
  916.                     input/output bus  and an  8 bit value is
  917.                     written  to   it  from  the  Accumulator
  918.                     defined.
  919.  
  920. Condition Codes:    None
  921.  
  922. Addressing format:
  923.                     Immediate.
  924.  
  925.  
  926.   +-----------+-----------+-----------+---------------------+
  927.    Addressing | Execution | Number of | Opcode description
  928.      Modes    |    time   |  bytes    |          HEX
  929.   +-----------+-----------+-----------+---------------------+
  930.     A  IMM    | Undefined |     1     |          71
  931.     B  IMM    | Undefined |     1     |          72
  932.   +-----------+-----------+-----------+---------------------+
  933.  
  934.  
  935. Example:
  936.  
  937.           LDX  #$102
  938.           OUT  X,A       ;STORE THE A-REG TO THE PORT
  939.  
  940.                           APPENDIX A
  941.  
  942.  
  943.                     OPCODE CONSTRUCTION
  944.  
  945.  
  946.  
  947.    Opcode    b7  b6  b5  b4  b3  b2  b1  b0
  948.              |   |   |   |   |   |   |   |
  949.              |   |   |   |   |   |   |   |
  950.              |   |   |   |   -------------- Function
  951.              |   |   |   |
  952.              |   |   ---------------------- Addressing Mode
  953.              |   |
  954.              |   |
  955.              |   |
  956.              ------------------------------ Set selection
  957.  
  958.  
  959.  
  960.      
  961.      Opcodes from $00 - $3F seem to be of no set pattern but
  962. rather allocated  a random  place. The  other three  sets of
  963. instruction, however,  do follow  an easy pattern. It can be
  964. considered that bit-6 determines which register will be used
  965. as follows.
  966.  
  967.  
  968.  
  969.            b6         Register selected
  970.            ---------------------------------
  971.            0     A register   Index register
  972.            1     B register   Stack pointer
  973.            
  974.  
  975.  
  976.      The Operation  that is  to be  perform on  the SETS  is
  977. contains within  b0 -  b3. The  function is described in the
  978. SETS tables  below. Each SET for each group of instructions.
  979. The instruction SETS follow:
  980.  
  981.  
  982. 0 - NEGate                         8 - Arithmetic Shift Left
  983. 1 - illegal opcode                 9 - ROtate Left
  984. 2 - illegal opcode                 A - DECrement
  985. 3 - COMpliment reg                 B - illegal opcode
  986. 4 - Logical Shift Left             C - INCrement
  987. 5 - illegal opcode                 D - TeST
  988. 6 - ROtate Right                   E - JuMP
  989. 7 - Arithmetic Shift right         F - CLeaR
  990.  
  991.  
  992.  
  993.                 b5  b4      Addressing Mode
  994.                 ---------------------------
  995.                  0   0           A
  996.                  0   1           B
  997.                  1   0        Indirect
  998.                  1   1        Extended
  999.                 
  1000.  
  1001.  
  1002.                      SET 2  ($40 - $7F)
  1003.  
  1004.  
  1005.  
  1006. 0 - SUBtract             Areg 8 - Exclusive OR         Areg
  1007. 1 - CoMPare              Areg 9 - ADd with Carry       Areg
  1008. 2 - SuBtract with Carry  Areg A - OR Accumulator       Areg
  1009. 3 - illegal opcode       Areg B - ADD                  Areg
  1010. 4 - AND                  Areg C - ComPare reg (16 bit) Xreg
  1011. 5 - BIT test             Areg D - Subroutine call
  1012. 6 - LoaD Accumulator     Areg E - LoaD reg    (16 bit) Xreg
  1013. 7 - STore Accumulator    Areg F - STore reg   (16 bit) Xreg
  1014.  
  1015.  
  1016.  
  1017.  
  1018.                b5  b4      Addressing Mode
  1019.                ---------------------------
  1020.                 0   0        Immediate
  1021.                 0   1        Direct
  1022.                 1   0        Indirect
  1023.                 1   1        Extended
  1024.                
  1025.  
  1026.  
  1027.                      SET 3  ($80 - $BF)
  1028.  
  1029.  
  1030.  
  1031. 0 - SUBtract             Breg 8 - Exclusive OR         Breg
  1032. 1 - CoMPare              Breg 9 - ADd with Carry       Breg
  1033. 2 - SuBtract with Carry  Breg A - OR Accumulator       Breg
  1034. 3 - illegal opcode       Breg B - ADD                  Breg
  1035. 4 - AND                  Breg C - ComPare reg (16 bit) Xreg
  1036. 5 - BIT test             Breg D - Subroutine call
  1037. 6 - LoaD Accumulator     Breg E - LoaD reg    (16 bit) Xreg
  1038. 7 - STore Accumulator    Breg F - STore reg   (16 bit) Xreg
  1039.                               
  1040.  
  1041.  
  1042.                b5  b4      Addressing Mode
  1043.                ---------------------------
  1044.                 0   0       Immediate
  1045.                 0   1       Direct
  1046.                 1   0       Indirect
  1047.                 1   1       Extended
  1048.                
  1049.  
  1050.  
  1051.                      SET 4  ($C0 - $FF)
  1052.  
  1053.                           APPENDIX B
  1054.  
  1055.                   INTEL HEX FORMAT RECORDS
  1056.  
  1057.  
  1058.      The Intel  Hex format  data records are pretty straight
  1059. forward. They  are constructed  with a character to indicate
  1060. the record  is starting  ':', an address field of 16 bits, a
  1061. record type field, a data field and the checksum. All of the
  1062. values printed  are first  converted to  an ASCII equivalent
  1063. then sent.  So to  send, in  the address  field, a  value of
  1064. $4090 as a string would be '4090' but to view that number as
  1065. byte values  will be  $34 $30  $39 $30.  Each four bits have
  1066. been converted  to an  ASCII equivalent. This applies to all
  1067. values that  appear within  the record  bounderies. Moreover
  1068. the whole  record is  printable and  any system dealing with
  1069. these records  will not  hangup or  perform  strange  things
  1070. while trying to dump it to the serial port.
  1071.  
  1072.  +---+----+---------+------+-------------------------+----+
  1073.  | : | CC |  AAAA   |  TT  |         DD .. DDn       | XX |
  1074.  +---+----+---------+------+-------------------------+----+
  1075.  
  1076.  
  1077.  ':'      Start of record character                   char
  1078.  'CC'     Byte count. Size in bytes of Data field.    8 bits
  1079.  'AAAA'   Address field.                             16 bits
  1080.  'TT'     Record type.
  1081.           00 = normal data, 01 = last record.         8 bits
  1082.  'DD'     Data in bytes, no spaces between any values.
  1083.           The data field can be of 1 to 255 bytes long.
  1084.                                                       8 bits
  1085.  'XX'     Checksum.                                   8 bits
  1086.  
  1087.  
  1088. The checksum is calculated like this:
  1089.  
  1090.      Temp = CC + AA(high) + AA(low) + TT + (DD .. DDn)
  1091.  
  1092.      XX   = 0 - Temp
  1093.  
  1094. Therefore to verify a record against its checksum simply add
  1095. all of the fields together and the answer should be $00
  1096.  
  1097.      00   = CC + AA(high) + AA(low) + TT + (DD .. DDn) + XX
  1098.  
  1099. To determine  the end  of the  total file two methods can be
  1100. used. One is to check the 'TT' field for a value of $01. But
  1101. this can  be a  bit dubious  as some  programs that generate
  1102. Intel hex  format records  don't worry  about this field and
  1103. leave it  with a value of null, $00. The second method is to
  1104. check if  the 'CC' field has a null value in it. When it has
  1105. then it  can be  assumed that no more data will follow. This
  1106. seems to  be the  accepted way  of terminating  an Intel hex
  1107. record.
  1108.  
  1109.      :0401000001020304F1
  1110.  
  1111.                This Example  has data  in it  that came from
  1112.                addresses $100 - $104. That data is $01, $02,
  1113.                $03, and  $04. The  Data  field  byte  count,
  1114.                'CC', is  $04 and  the record  type is $00; a
  1115.                normal data record. The checksum is $F1.
  1116.  
  1117.                               
  1118.                           APPENDIX C
  1119.  
  1120.                 MOTOROLA 'S' FORMAT RECORDS
  1121.  
  1122.  
  1123.      There are three types of 'S' format records that can be
  1124. generated by  a cross-assembler. Although you can be assured
  1125. that the  'S1' format  records will  be generated  by  M6800
  1126. assemblers I  will include  the other  two for completeness.
  1127. These are  'S1', 'S2', and 'S3' formats. See the table below
  1128. for a  full layout  of them  but mainly  the value 1, 2 or 3
  1129. indicates what size the address is in the Address field. The
  1130. end of  file 'S'  values indicate that this will be the very
  1131. last record  within that  file. Nine  times out  of ten 'S9'
  1132. will be  used in all cases but it is a good idea to test for
  1133. all three anyway. That is assuming your loader is programmed
  1134. to decode all three.
  1135.  
  1136.      The  construction   of  the   record  is  the  starting
  1137. character 'S',  record type, byte count, address, data field
  1138. and finally  the checksum.  It must  be pointed out that the
  1139. calculation of the checksum is slightly different to that of
  1140. the Intel hex format. Instead of  a  value  of  $00 when all
  1141. fields have  been added together $FF is the result. But this
  1142. will be described in detail later.
  1143.  
  1144.      As with  Intel hex  records all  byte quanties  are  of
  1145. printable form  so every four bits are converted to an ASCII
  1146. equivalent.
  1147.  
  1148.  
  1149.      S0   -    Data field contains name of the source file.
  1150.  The address field will usually be a 16 bit null, $0000.
  1151.      
  1152.      S1   -    16 Bit address field    End of file  -> S9
  1153.  
  1154.      S2   -    24 Bit address field    End of file  -> S8
  1155.  
  1156.      S3   -    32 Bit address field    End of file  -> S7
  1157.  
  1158.  Table  1
  1159.  
  1160.  
  1161.  
  1162.  
  1163.                       S-format layout
  1164.  
  1165.   +---+---+----+--------+------------------------+----+
  1166.   | S | T | CC |  AAAA  |       DD .. DDn        | XX |
  1167.   +---+---+----+--------+------------------------+----+
  1168.  
  1169.  
  1170. S    -    Starting character for the record          Char
  1171. T    -    Record type.                             4 bits
  1172. CC   -    Byte count. Includes address field, data field and
  1173.           checksum field in the count.
  1174.                                                    8 bits
  1175. AAAA -    Address field. For 'S1' type.           16 bits
  1176. DD   -    Data field. No spaces between the bytes  8 bits
  1177. XX   -    Checksum                                 8 bits
  1178.  
  1179.  
  1180. Calculating the checksum is as follows:
  1181.  
  1182.      Temp = CC + AA(high) + AA(low) + (DD .. DDn)
  1183.  
  1184.      XX   = $FF - Temp
  1185.  
  1186.  
  1187. Verifing the  Integrity of  a record  with the  checksum the
  1188. following should be done.
  1189.  
  1190.      $FF  = CC + AA(high) + AA(low) + (DD .. DDn) + XX
  1191.  
  1192. But for  even  easier  checking  of  the  record  against  a
  1193. checksum instead  of clearing the accumulator that will keep
  1194. a tally of the checksum calculations start it with $01. Then
  1195. when the  final value,  the 'XX'  field,  is  added  to  the
  1196. accumulator the  result will  be zero.  Z flag  gets set, no
  1197. need to compare it against $FF.
  1198.  
  1199.      To further  describe the 'S0' record which contains the
  1200. source files  name or  anything else  look  at  the  example
  1201. below. The  source file's  name is contained within the data
  1202. field but  each byte that makes up each letter in the source
  1203. file's name  'test.asm' is  taken  as  a  byte  literal  and
  1204. converted to  printable form  like  any  other  byte  to  be
  1205. inserted into the record. Other than that the record follows
  1206. the same  rules as  would any  other record  type within the
  1207. file.
  1208.  
  1209.      S0110000746573742E61736DBF <- "BF" = Checksum
  1210.              ----------------
  1211.                      ^------------ Source filename
  1212. 'test.asm'
  1213.  
  1214.  
  1215.      S107010001020304ED
  1216.      S9
  1217.  
  1218.           This 'S1'  record has  in it  data from  addresses
  1219.           $0100-$0104 of  the value  $01, $02,  $03, and $04
  1220.           the data  field is  'CC' - 3 (ie: $07 - $03) = $04
  1221.           and the checksum is $ED
  1222.           The next  line has on it an S9 which indicates the
  1223.           end of file.
  1224.  
  1225.                           APPENDIX D
  1226.                               
  1227.                               
  1228.                         PERFORMANCE
  1229.  
  1230.      To  calculate  the  speed  at  which  the  Emulator  is
  1231. processing M6800  instructions run the program MIPS.o68 with
  1232. supervisor mode  turned off  (use  'S'  command)  and  begin
  1233. execution with  'G 100  [return]'. At  the same  time  start
  1234. timing  with   your  trusty   time-piece  until  an  illegal
  1235. instruction exception  is reported.  Stop timing. This value
  1236. is now time.
  1237.  
  1238.      Now put  the value  time through the following formulae
  1239. to get  instruction through-put  (IPS) and  equivalent clock
  1240. speed (clk)  that a  real M6800 cpu would have to be running
  1241. at to equal the performance of the Emulator.
  1242.  
  1243.  
  1244.           IPS = (3 + (46 * 65535))/time  (seconds)
  1245.           clk = (9 + (152 * 65535))/time (seconds)
  1246.  
  1247.  
  1248. Here are  some figures  that I have gained from various test
  1249. machines. All IBM-pc compatable.
  1250.  
  1251. 80386 @ 20MHz.   Time = 25.3 seconds
  1252. Calculated: IPS = 119,154 Instructions per second.
  1253. Calculated: clk = 393,728 Hz M6800 cpu.
  1254.  
  1255. 80286 @ 12 Mhz.  Time = 37.8 seconds
  1256. Calculated: IPS = 79,751 Instructions per second.
  1257. Calculated: clk = 263,527 Hz M6800 cpu.
  1258.  
  1259. 80286 @ 8MHz.    Time = 64.7 seconds
  1260. Calculated: IPS = 46,593 Instructions per second.
  1261. Calculated: clk = 153,962 Hz M6800 cpu.
  1262.  
  1263. 80186 @ 10Mhz.   Time = 65.1 seconds
  1264. Calculated: IPS = 46,307 Instructions per second.
  1265. Calculated: clk = 153,106 Hz M6800 cpu.
  1266.  
  1267. 80c86 @ 9.5 Mhz. Time = 81.3 seconds
  1268. Calculated: IPS = 37,080 Instructions per second.
  1269. Calculated: clk = 122,525 Hz M6800 cpu.
  1270.  
  1271. 80c86 @ 4.77Mhz. Time = 163.3 seconds
  1272. Calculated: IPS = 16,855 Instructions per second.
  1273. Calculated: clk = 61,000 Hz M6800 cpu.
  1274.  
  1275.