home *** CD-ROM | disk | FTP | other *** search
/ Emulator Universe CD / emulatoruniversecd1998.iso / Speccy / Emulators / winemu / SOURCES / Z80 / KERNEL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-25  |  5.9 KB  |  194 lines

  1. /* Kernel.c: Z80 initialization and main cycle - basic support routines.
  2.  *
  3.  * Copyright 1996 Rui Fernando Ferreira Ribeiro.
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. /*
  21.  * History:
  22.  *    4th April 96:
  23.  *                  . Modified R register handling -- about 10% speed
  24.  *        increase -- see also [ld8bits.c]
  25.  *                      . Modified central loop of emulation (execute()) for
  26.  *              a faster emulation
  27.  *                        . Spoted an error in Z80 emulation - handling IX or IY
  28.  *        prefixes, if next instruction is not a HL instruction,
  29.  *              the prefix will affect all instructions until if founds
  30.  *              a HL instruction or a ED prefix -- but it's surprising
  31.  *              how failed only 4 of nearly 2000 spectrum programs
  32.  *              tested.
  33.  *
  34.  *    5th April 96:
  35.  *            . Modified handling of IX and IY prefixes --
  36.  *        extensive changes in the code. This will fix the error
  37.  *        spoted and will increase once more the emulation speed.
  38.  */
  39.  
  40. #include "env.h"
  41. #include "ivars.h"
  42.  
  43. /* Increment the lower 7 bits of R in each M1 cycle
  44. */
  45. #define inc_R() (R++)
  46.  
  47. /* Opcode being interpreted - in IX or IY */
  48. static UCHAR opcode;
  49.  
  50. /*=========================================================================*
  51.  *                            do_reset                                     *
  52.  *=========================================================================*/
  53. void do_reset()
  54. {
  55.    /* CPU internal flags  */
  56.    _IM = IFF1 = IFF2 =
  57.  
  58.     /* CPU registers */
  59.    R_BIT7 = R = I =
  60.  
  61.    HL = BC = DE = AF = IX = IY = SP =
  62.  
  63.    /* alternative registers */
  64.    HL2 = BC2 = DE2 = AF2 =
  65.  
  66.    /* flags CPU */
  67.    flags._S = flags._Z = flags._X = flags._H = flags._Y =
  68.    flags._P = flags._N = flags._C = 0;
  69.    /* Interrupt counter */
  70.    ResetTickCounter();
  71.    /* Program Counter */
  72.    PutPC(0);
  73. }
  74.  
  75. /*=========================================================================*
  76.  *                            execute                                      *
  77.  *=========================================================================*/
  78. void execute()
  79. {
  80.   /* Z80 main cycle */
  81.   /* --> 0xDD e 0xFD are only 'switches' wich map IX or IY in HL
  82.       till instruction end [but not in instructions prefixed by ED]
  83.      --> 0xED, 0xCB are 'gates' to another sets of instructions
  84.    */
  85.   if(DelayEmVal)
  86.      {
  87.  
  88.      while(clock_ticks < INT_TIME)
  89.     {
  90.     inc_R();
  91.     /* Call funtion indexed by opcode */
  92.     (*instruc_tabl[Getnextbyte()])();
  93.     }
  94.  
  95.     // Spend a bit of time ---
  96.     {
  97.     USHORT i;
  98.  
  99.     i = DelayEmVal;
  100.     while(i)
  101.     {
  102.        (void)do_nothing(&i);
  103.        {
  104.        USHORT j = i;
  105.  
  106.        while(j)
  107.           (void)do_nothing(&j);
  108.            }
  109.     }
  110.         }
  111.      }
  112.   else
  113.      {
  114.      while(clock_ticks < INT_TIME)
  115.     {
  116.     inc_R();
  117.     /* Call funtion indexed by opcode */
  118.     (*instruc_tabl[Getnextbyte()])();
  119.     }
  120.      }
  121.   /* do_int_tasks(); */
  122.   /* if interrupts activated */
  123.   if(IFF1)
  124.      {
  125.      do_interrupt();
  126.      }
  127.   else
  128.      ResetTickCounter();
  129. }
  130.  
  131. /*=========================================================================*
  132.  *                            execute_IX                                   *
  133.  *=========================================================================*/
  134. static void execute_IX()
  135. {
  136.    inc_R();    /* It appears to be this way */
  137.  
  138.    (*instruc_tablIX[Getnextbyte()])();
  139. }
  140.  
  141. /*=========================================================================*
  142.  *                            execute_IY                                   *
  143.  *=========================================================================*/
  144. static void execute_IY()
  145. {
  146.    inc_R();    /* It appears to be this way */
  147.  
  148.    /* Call function acording to opcode */
  149.    (*instruc_tablIY[Getnextbyte()])();
  150. }
  151.  
  152. /*=========================================================================*
  153.  *                            execute_CB                                   *
  154.  *=========================================================================*/
  155. static void execute_CB()
  156. {
  157.    inc_R();
  158.    (*instruc_tablCB[Getnextbyte()])(); 
  159. }  
  160.  
  161. /*=========================================================================*
  162.  *                          execute_IXCB                                   *
  163.  *=========================================================================*/
  164. static void execute_IXCB()
  165. {
  166.    /*If IX or IY is active, then the next byte isn∩t
  167.      a instruction, but a displacement for IX or IY
  168.    */
  169.    lastbyte = Getnextbyte();
  170.    (*instruc_tablIXCB[Getnextbyte()])();
  171. }
  172.  
  173. /*=========================================================================*
  174.  *                            execute_CB                                   *
  175.  *=========================================================================*/
  176. static void execute_IYCB()
  177. {
  178.    /*If IX or IY is active, then the next byte isn∩t
  179.      a instruction, but a displacement for IX or IY
  180.    */
  181.    lastbyte = Getnextbyte();
  182.    (*instruc_tablIYCB[Getnextbyte()])();
  183. }
  184.  
  185. /*=========================================================================*
  186.  *                            execute_ED                                   *
  187.  *=========================================================================*/
  188. static void execute_ED()
  189. {
  190.    inc_R();
  191.    (*instruc_tablED[Getnextbyte()])();
  192. }
  193.  
  194. /* EOF: Kernel.c */