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

  1. ** Helper functions (that is, the emulator would work without them,
  2. ** but you wouldn't want to be without them).
  3.  
  4. ** ======================================================================
  5.  
  6.     IFD VERBOSE
  7.     LIST
  8. ** Compiling the helpfuncts.i file.
  9.     NOLIST
  10.     ENDC
  11.  
  12. ** This subroutine makes the emulator update the private fields of the
  13. ** control structure when changes to any of the public fields have taken
  14. ** place, for instance if the Z80_Memory field is changed. Do not call
  15. ** this routine while the emulator is running.
  16. **   Call Z80_Exitreq and make sure the emulator has stopped before
  17. ** reallocating memory (remember to copy the old memory contents to the
  18. ** new areas), then update the corresponding entries in the control
  19. ** structure (Z80_Memory, Z80_Cachemem and Z80_Flagmem). Calling
  20. ** Z80_NewSettings will then make sure that Z80_Continue will properly
  21. ** resume the emulation from the new addresses.
  22. **   a0 must point to the control structure.
  23. **   The return value in d0 is nonzero if an error occurred, and zero
  24. ** otherwise.
  25.  
  26. Z80_NewSettings    ;(a0)    (ctrl)
  27.         move.l    Z80_Memory(a0),d0
  28.         add.l    #Z80_0_OFFSET,d0
  29.         move.l    d0,Z80_Z0(a0)
  30.         move.l    d0,Z80_zero(a0)
  31.  
  32.         move.l    Z80_Cachemem(a0),d0
  33.         add.l    #CACHE_0_OFFSET,d0
  34.         move.l    d0,Z80_CacheB(a0)
  35.         move.l    d0,Z80_cachezero(a0)
  36.  
  37.         IFD    Z80_MEMCHECK
  38.         move.l    Z80_Flagmem(a0),d0
  39.         add.l    #FLAGS_0_OFFSET,d0
  40.         move.l    d0,Z80_FlagsB(a0)
  41.         move.l    d0,Z80_flagzero(a0)
  42.         ENDC
  43.  
  44.         moveq    #0,d0
  45.         rts    ;return zero (No Error)
  46.  
  47. ** ----------------------------------------------------------------------
  48.  
  49. ** These routines access the Z80 address space, mirroring any changes
  50. ** in the cache and handling the wraparound of addresses transparently.
  51. ** They do *not* respect any memory protection flags - a write always
  52. ** takes effect.
  53. ** I recommend that they are used rathed than writing directly into
  54. ** the Z80 address space.
  55. **
  56. **    Z80_SetByte    (a0,d0,d1)    (ctrl, addr, BYTE val)
  57. **    Z80_SetWordLH    (a0,d0,d1)    (ctrl, addr, WORD val)
  58. **    Z80_GetByte    (a0,d0)        (ctrl, addr)
  59. **    Z80_GetWordLH    (a0,d0)        (ctrl, addr)
  60. **    Z80_SetBlock    (a0,d0,d1,d2)    (ctrl, start_addr, size, BYTE val)
  61. **    Z80_ReadBlock    (a0,a1,d0,d1)    (ctrl, buf, start_addr, size)
  62. **    Z80_WriteBlock    (a0,a1,d0,d1)    (ctrl, buf, start_addr, size)
  63. **
  64. **   All need a pointer to the control structure in a0. The Z80 address
  65. ** (word-sized) is passed in d0 (for block functions this is the
  66. ** block start address).
  67. **   Z80_SetByte is passed a byte value to be written in d1. It returns
  68. ** nothing.
  69. **   Z80_SetWordLH is passed a (high-end first) word value to be written
  70. ** in d1 and writes it low-end first. It returns nothing.
  71. **   Z80_GetByte returns the byte value in d0.
  72. **   Z80_GetWordLH reads a (low-end first) word value and returns it
  73. ** high-end first in d0.
  74. **   All block functions are passed the block size (an unsigned longword)
  75. ** in d1. They return nothing.
  76. **   Z80_SetBlock is passed the byte value to be written in d2.
  77. **   Z80_ReadBlock and Z80_WriteBlock are passed the buffer address
  78. ** (in the 680x0 address space) in a1.
  79. **   All Z80 address arithmetic is word-sized. For instance, calling
  80. ** Z80_SetWordLH(ctrl, $ffff, $1234) will set address $ffff to $34 and
  81. ** address $0000 to $12. The block functions will also wrap at $ffff.
  82.  
  83.  
  84. Z80_SetByte    ;(a0,d0,d1)    (ctrl, addr, BYTE val)
  85.         move.l    a1,-(a7)
  86.         move.l    Z80_zero(a0),a1
  87.         move.b    d1,(a1,d0.w)
  88.         move.l    Z80_cachezero(a0),a1
  89.         add.w    d0,a1
  90.         clr.w    (a1,d0.w)
  91.         move.l    (a7)+,a1
  92.         rts    ;return nothing
  93. ** ------------
  94.  
  95. Z80_SetWordLH    ;(a0,d0,d1)    (ctrl, addr, WORD val)
  96.         move.l    a1,-(a7)
  97.         movea.l    Z80_zero(a0),a1
  98.         move.b    d1,(a1,d0.w)
  99.         lsr.w    #8,d1
  100.         addq.w    #1,d0    ;second byte
  101.         move.b    d1,(a1,d0.w)
  102.         move.l    Z80_cachezero(a0),a1
  103.         movea.l    a1,a0 ;keep cachezero
  104.         add.w    d0,a1
  105.         clr.w    (a1,d0.w) ;mark cache
  106.         subq.w    #1,d0    ;first byte
  107.         movea.l    a0,a1 ;get cachezero
  108.         add.w    d0,a1
  109.         clr.w    (a1,d0.w) ;mark cache
  110.         move.l    (a7)+,a1
  111.         rts    ;return nothing
  112. ** ------------
  113.  
  114. Z80_GetByte    ;(a0,d0)        (ctrl, addr)
  115.         movea.l    Z80_zero(a0),a0
  116.         move.b    (a0,d0.w),d0
  117.         ext.w    d0    ;sign extend
  118.         ext.l    d0
  119.         rts    ;return (signed) byte in d0
  120. ** ------------
  121.  
  122. Z80_GetWordLH    ;(a0,d0)        (ctrl, addr)
  123.         movea.l    Z80_zero(a0),a0
  124.         move.w    d0,-(sp)    ;create word on stack
  125.         move.b    (a0,d0.w),1(sp)    ;low byte
  126.         addq.w    #1,d0
  127.         move.b    (a0,d0.w),(sp)    ;high byte
  128.         move.w    (sp)+,d0
  129.         ext.l    d0    ;sign extend
  130.         rts    ;return (signed) word in d0
  131. ** ------------
  132.  
  133. Z80_SetBlock    ;(a0,d0,d1,d2)    (ctrl, start_addr, size, BYTE val)
  134.         movem.l    a1/a2,-(a7)
  135.         movea.l    Z80_zero(a0),a1
  136.         movea.l    Z80_cachezero(a0),a2
  137. .loop        move.b    d2,(a1,d0.w)
  138.         movea.l    a2,a0
  139.         adda.w    d0,a0
  140.         clr.w    (a0,d0.w) ;mark cache
  141.         addq.w    #1,d0
  142.         subq.l    #1,d1
  143.         bne.s    .loop
  144.         movem.l    (a7)+,a1/a2
  145.         rts    ;return nothing
  146. ** ------------
  147.  
  148. Z80_ReadBlock    ;(a0,a1,d0,d1)    (ctrl, buf, start_addr, size)
  149.         movea.l    Z80_zero(a0),a0
  150. .loop        move.b    (a0,d0.w),(a1)+
  151.         addq.w    #1,d0
  152.         subq.l    #1,d1
  153.         bne.s    .loop
  154.         rts    ;return nothing
  155. ** ------------
  156.  
  157. Z80_WriteBlock    ;(a0,a1,d0,d1)    (ctrl, buf, start_addr, size)
  158.         movem.l    a2/a3,-(a7)
  159.         movea.l    Z80_zero(a0),a2
  160.         movea.l    Z80_cachezero(a0),a3
  161. .loop        move.b    (a1)+,(a2,d0.w)
  162.         movea.l    a3,a0
  163.         adda.w    d0,a0
  164.         clr.l    (a0,d0.w) ;mark cache
  165.         addq.w    #1,d0
  166.         subq.l    #1,d1
  167.         bne.s    .loop
  168.         movem.l    (a7)+,a2/a3
  169.         rts    ;return nothing
  170.  
  171. ** ------------------------------------------------------------------------
  172.  
  173. ** This routine sets Z80 memory control flags. If the Z80_Flagmem field
  174. ** in the control structure is zero, the function has no effect.
  175. **    Z80_SetMemFlag    (a0,d0,d1,d2)    (ctrl, start_addr, size, flag)
  176. **
  177. ** As for the memory access functions, the Z80 address is word-sized and
  178. ** passed in d0, and the size is an unsigned longword. The flag is a
  179. ** byte-sized value, and its possible meanings are defined in Z80.i.
  180. ** Nothing is returned.
  181.  
  182. Z80_SetMemFlag    ;(a0,d0,d1,d2)    (ctrl, start_addr, size, flag)
  183.         tst.l    Z80_Flagmem(a0)
  184.         beq.s    .end
  185.         move.l    Z80_flagzero(a0),a0
  186. .loop        move.b    d2,(a0,d0.w)
  187.         addq.w    #1,d0
  188.         subq.l    #1,d1
  189.         bne.s    .loop
  190. .end        rts    ;return nothing
  191.  
  192.  
  193. ** This routine returns the memory control flag for an address, in case
  194. ** you should forget it. If the Z80_Flagmem field in the control
  195. ** structure is zero, the function has no effect, and returns zero (RAM).
  196. **    Z80_GetMemFlag    (a0,d0)    (ctrl, addr)
  197. **
  198. ** The Z80 address is word-sized and passed in d0. The flag value is
  199. ** returned in (the whole of) d0, and has the range -128 to +127.
  200.  
  201. Z80_GetMemFlag    ;(a0,d0)    (ctrl, addr)
  202.         tst.l    Z80_Flagmem(a0)
  203.         beq.s    .end
  204.         move.l    Z80_flagzero(a0),d1
  205.         move.b    (a0,d0.w),d0
  206.         ext.w    d0
  207.         ext.l    d0
  208. .end        rts    ;return flag in d0
  209.  
  210. ** =====================================================================
  211.