home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 2 / FFMCD02.bin / new / misc / emu / z80 / z80.a < prev    next >
Text File  |  1993-12-21  |  27KB  |  839 lines

  1. ** Main file of the Z80 emulator. Compiles to linkable code, using the
  2. ** following settings:
  3.  
  4. ** VERBOSE
  5. ** Boring Messages During Compilation.
  6.  
  7. PROCESSOR EQU 68030
  8. ** Define to any of 68000, 68010, 68020, 68030 or 68040. The 68000 version
  9. ** uses the Move from Status Register instruction. Presently, the > 68000
  10. ** versions are all the same.
  11.  
  12. ** GENERIC_OBJECT SET 1
  13. ** Define to compile generic Z80 emulator object file, which needs
  14. ** linking with separately compiled routines for implementation-
  15. ** dependent instructions. If not defined, macros from "machine_macs.i"
  16. ** are used and are inline expanded. See the files "extern_instr.a" and
  17. ** "impldept.i" for more information about this.
  18.  
  19. Z80_MEMCHECK SET 1
  20. ** Define to use memory write access checking.
  21. ** See MemoryHandler below for more information about this.
  22.  
  23. UPDATECACHE SET 1
  24. ** Define to update the cache on every write to Z80 memory. This is done
  25. ** by simply clearing the corresponding word in the cache. If this option
  26. ** is not used, modified code will never work.
  27.  
  28. MODIFIEDCODE SET 1
  29. ** Define to detect (and allow) modified code even in multi-byte opcodes.
  30. ** Pretty damn useless if UPDATECACHE is not defined. If this option is
  31. ** not used, then such modifications that only change the second or third
  32. ** bytes of an opcode, but not the first byte, will not be detected.
  33.  
  34. ** UNDOCINSTR_UNDEF SET 1
  35. ** Define if you want the "undocumented" instructions to be considered
  36. ** as undefined instructions.
  37.  
  38. BCDFLAGS
  39. ** Define if you want the arithmetic instructions to store information
  40. ** so that a following Daa will work correctly (see the file "notes.txt"
  41. ** for details). BASIC interpreters and other programs that work in
  42. ** decimal base often use BCD, while most games do not. The main use there
  43. ** seems to be for score counter displays.
  44. **   If this flag is not defined, then calling the Daa instruction will
  45. ** write a nonzero value into the Z80_BCD_OP field, which otherwise will
  46. ** always be zero. That way it should be easy to see if it is the missing
  47. ** BCD handling that causes any erroneous behaviour.
  48.  
  49. ** AFPUSHPOP_CCR
  50. ** Define if you want the Push/Pop AF instructions to store the F register
  51. ** on 680x0 CCR form, instead of the real Z80 form. The difference lies in
  52. ** how the flags are ordered within the byte. For instance, in the 680x0,
  53. ** bit 3 is the sign flag; in the Z80, it is bit 7. Only programs that
  54. ** inspect the pushed flags (like a debugger) will ever notice this. The
  55. ** CCR version is, of course, a bit quicker, and could be used for games.
  56. **   In neither case are bits in the unused positions (including H and N)
  57. ** guaranteed to survive an operation that affects any of the flags.
  58. ** Is IS guaranteed, that a Pop AF with a following Push AF (or vice versa)
  59. ** and no flag-affecting instructions there inbetween, will preserve all
  60. ** the transferred bits.
  61.  
  62. ** AFPUSHPOP_BCD
  63. ** Define if you want the Push/Pop AF instructions to preserve BCD data.
  64. ** If used, the information used for BCD will be stored separately in an
  65. ** internal circular stack that keeps the last 7 pushed data units.
  66. ** The time penalty is reasonable, but this option is hardly ever needed.
  67. ** (Interrupts could be a problem. See the file "notes.txt" for details.)
  68. **   For game-playing only, this should definitely be turned off. Many
  69. ** games use Push/Pop AF/BC/DE/HL/IX/IY to transfer graphics data quickly.
  70.  
  71. ** ======================================================================
  72.  
  73.  
  74. ** Register aliases used (see the file Z80_coding.i for definitions):
  75.  
  76. **     TableB    pointer to TableBase
  77. **     Work    pointer to the Z80_Workspace longword
  78. **     PPC    Pseudo-PC
  79. **     ZSP    Z80 Stack Pointer (only lower word used)
  80. **     Z0    pointer to Z80 address zero
  81. **     CacheB    pointer to CacheBase (corresponding to Z0)
  82. **     FlagsB    pointer to FlagsBase (corresponding to Z0)
  83. **     InstrB    pointer to InstructionBase
  84.  
  85. ** Be careful!! Some aliases might stand for the same register!
  86. ** (TableB and Work are presently the same.)
  87.  
  88. ** ---------------------------------------------------------------------
  89.  
  90. Z80_MAIN = -1    ;Tell include file we are compiling the main file.
  91.  
  92.     INCLUDE user.i    ;User definitions. ALWAYS included first of all.
  93.  
  94.     INCLUDE    Z80.i
  95.  
  96.     INCLUDE Z80_struct.i
  97.  
  98.     INCLUDE Z80_coding.i
  99.  
  100.     INCLUDE tables.i
  101.  
  102.     INCLUDE helpfuncts.i
  103.  
  104. ** ----------------------------------------------------------------------
  105.  
  106. ** When calling Z80_Init, Z80_Coldstart or Z80_Continue, a pointer to the
  107. ** control structure is always passed in a0, and a return value is passed
  108. ** in d0. All other registers are automatically protected
  109.  
  110. ProtectedRegs REG    d1-d7/a1-a6    ;push/pop these at entry/exit
  111.  
  112. ** Registers stored at Z80_RegStorage at exit,
  113. ** and restored upon continuing:
  114.  
  115. StoredRegs REG    d0-d5/a2-a6
  116.     ;a0 (TableB) always comes as a parameter.
  117.     ;a1 (PPC) is recalculated from Real-PC at Continue.
  118.     ;d6 is recalculated from F at Continue.
  119.     ;d7 is garbage anyway.
  120.  
  121. **    Remember: if you change this, you must also change the labels
  122. **    in the Z80_RegStorage table in Z80_struct.i.
  123.  
  124. ** ======================================================================
  125.  
  126. ** EMULATOR ENTRY POINTS
  127.  
  128.  
  129. ** Before beginning emulation, the control structure must be initialised
  130. ** by calling Z80_Init.
  131. **   a0 must point to the control structure. The fields Z80_Memory and
  132. **      Z80_Cachemem must be pointing to allocated memory.
  133. **      If the memory write access checking feature is used, the field
  134. **      Z80_Flagmem must also be set, and if Z80_MemHandler is nonzero
  135. **      it is supposed to point to a user memory exception handler. See
  136. **      MemoryHandler below for details.
  137. **      The user environment data area is not changed. All other fields
  138. **      are automatically initialised to zero.
  139. **   The return value in d0 is nonzero if an error occurred, and zero
  140. ** otherwise. All other registers are automatically protected.
  141.  
  142. Z80_Init
  143.         movem.l    a0/a1/a2,-(sp)    ;temporaries
  144.  
  145.     ;Save the protected control structure entries on the stack:
  146.         move.w    #(PROT_SIZE>>1)-1,d0    ;word count
  147.         lea    PROT_FIELDS(a0),a2    ;source ptr in a2
  148. .prot_save    move.w    (a2)+,-(sp)
  149.         dbf    d0,.prot_save
  150.  
  151.     ;Then clear all entries below envdata:
  152.         move.l    a0,a1
  153.         move.w    #(Z80_Envdata>>1)-1,d0    ;envdata offset is even
  154. .clr_struct    clr.w    (a1)+
  155.         dbf    d0,.clr_struct
  156.  
  157.     ;and restore the saved entries (a2 has retained its value):
  158.         move.w    #(PROT_SIZE>>1)-1,d0    ;word count
  159. .prot_rest    move.w    (sp)+,-(a2)
  160.         dbf    d0,.prot_rest
  161.  
  162.     ;Set all entries in the cache (skipping the low end buffer)
  163.     ;to 'changed', that is, not decoded:
  164.         move.l    Z80_Cachemem(a0),a1
  165.         add.l    #Z80_LBUFSIZE,a1
  166.         move.l    #Z80_MEMSIZE,d0 ;word count
  167. .clr_cache    clr.w    (a1)+
  168.         subq.l    #1,d0    ;possibly too large to use dbf
  169.         bne.s    .clr_cache
  170.     ;(a1 should now point to the first entry in the high buffer)
  171.  
  172.     ;Set all entries in the high buffer to 'out of bounds':
  173.         move.w    #(Z80_HBUFSIZE>>1)-1,d0   ;buffers are even sized
  174. .set_hibuf    move.w    #out_of_bounds,(a1)+
  175.         dbf    d0,.set_hibuf
  176.  
  177.     ;Now copy the tables to their places in the structure:
  178.  
  179.         ;The parity table
  180.         lea    ParityTable(pc),a1
  181.         lea    Z80_Parity(a0),a2
  182.         move.w    #256-1,d0
  183. .cp_parity    move.b    (a1)+,(a2)+
  184.         dbf    d0,.cp_parity
  185.  
  186.     ;Calculate the 'address zero' pointers:
  187.     
  188.         move.l    Z80_Memory(a0),a1
  189.         add.l    #Z80_0_OFFSET,a1
  190.         move.l    a1,Z80_zero(a0)
  191.  
  192.         move.l    Z80_Cachemem(a0),a1
  193.         add.l    #CACHE_0_OFFSET,a1
  194.         move.l    a1,Z80_cachezero(a0)
  195.  
  196.         IFD    Z80_MEMCHECK
  197.         move.l    Z80_Flagmem(a0),a1
  198.         add.l    #FLAGS_0_OFFSET,a1
  199.         move.l    a1,Z80_flagzero(a0)
  200.         ENDC
  201.  
  202.     ;Create an initial "saved CPU status" frame, so we can
  203.     ;call Z80_Continue without calling Z80_Coldstart first.
  204.         movem.l ProtectedRegs,-(sp)
  205.         bsr    InitRegisters    ;(only use aliases from now)
  206.         ;Initially look like after a reset.
  207.         move.l    CacheB,PPC        ;PC = address zero
  208.         move.b    #-1,Z80_INTMOD(TableB)    ;Intmode 0
  209.         movem.l StoredRegs,Z80_RegStorage(TableB)
  210.         movem.l (sp)+,ProtectedRegs
  211.  
  212.         movem.l    (sp)+,a0/a1/a2 ;restore temporaries
  213.  
  214.         moveq    #0,d0    ;signal 'no error'
  215.         rts
  216.  
  217. ** ----------------------------------------------------------------------
  218.  
  219.  
  220. ** Enter here to start emulation 'from scratch', with a CPU reset.
  221. **   a0 must point to the control structure, which must be initialised
  222. ** (see Z80_Init above).
  223. **   The return value in d0 is nonzero if a