home *** CD-ROM | disk | FTP | other *** search
- ** Helper functions (that is, the emulator would work without them,
- ** but you wouldn't want to be without them).
-
- ** ======================================================================
-
- IFD VERBOSE
- LIST
- ** Compiling the helpfuncts.i file.
- NOLIST
- ENDC
-
- ** This subroutine makes the emulator update the private fields of the
- ** control structure when changes to any of the public fields have taken
- ** place, for instance if the Z80_Memory field is changed. Do not call
- ** this routine while the emulator is running.
- ** Call Z80_Exitreq and make sure the emulator has stopped before
- ** reallocating memory (remember to copy the old memory contents to the
- ** new areas), then update the corresponding entries in the control
- ** structure (Z80_Memory, Z80_Cachemem and Z80_Flagmem). Calling
- ** Z80_NewSettings will then make sure that Z80_Continue will properly
- ** resume the emulation from the new addresses.
- ** a0 must point to the control structure.
- ** The return value in d0 is nonzero if an error occurred, and zero
- ** otherwise.
-
- Z80_NewSettings ;(a0) (ctrl)
- move.l Z80_Memory(a0),d0
- add.l #Z80_0_OFFSET,d0
- move.l d0,Z80_Z0(a0)
- move.l d0,Z80_zero(a0)
-
- move.l Z80_Cachemem(a0),d0
- add.l #CACHE_0_OFFSET,d0
- move.l d0,Z80_CacheB(a0)
- move.l d0,Z80_cachezero(a0)
-
- IFD Z80_MEMCHECK
- move.l Z80_Flagmem(a0),d0
- add.l #FLAGS_0_OFFSET,d0
- move.l d0,Z80_FlagsB(a0)
- move.l d0,Z80_flagzero(a0)
- ENDC
-
- moveq #0,d0
- rts ;return zero (No Error)
-
- ** ----------------------------------------------------------------------
-
- ** These routines access the Z80 address space, mirroring any changes
- ** in the cache and handling the wraparound of addresses transparently.
- ** They do *not* respect any memory protection flags - a write always
- ** takes effect.
- ** I recommend that they are used rathed than writing directly into
- ** the Z80 address space.
- **
- ** Z80_SetByte (a0,d0,d1) (ctrl, addr, BYTE val)
- ** Z80_SetWordLH (a0,d0,d1) (ctrl, addr, WORD val)
- ** Z80_GetByte (a0,d0) (ctrl, addr)
- ** Z80_GetWordLH (a0,d0) (ctrl, addr)
- ** Z80_SetBlock (a0,d0,d1,d2) (ctrl, start_addr, size, BYTE val)
- ** Z80_ReadBlock (a0,a1,d0,d1) (ctrl, buf, start_addr, size)
- ** Z80_WriteBlock (a0,a1,d0,d1) (ctrl, buf, start_addr, size)
- **
- ** All need a pointer to the control structure in a0. The Z80 address
- ** (word-sized) is passed in d0 (for block functions this is the
- ** block start address).
- ** Z80_SetByte is passed a byte value to be written in d1. It returns
- ** nothing.
- ** Z80_SetWordLH is passed a (high-end first) word value to be written
- ** in d1 and writes it low-end first. It returns nothing.
- ** Z80_GetByte returns the byte value in d0.
- ** Z80_GetWordLH reads a (low-end first) word value and returns it
- ** high-end first in d0.
- ** All block functions are passed the block size (an unsigned longword)
- ** in d1. They return nothing.
- ** Z80_SetBlock is passed the byte value to be written in d2.
- ** Z80_ReadBlock and Z80_WriteBlock are passed the buffer address
- ** (in the 680x0 address space) in a1.
- ** All Z80 address arithmetic is word-sized. For instance, calling
- ** Z80_SetWordLH(ctrl, $ffff, $1234) will set address $ffff to $34 and
- ** address $0000 to $12. The block functions will also wrap at $ffff.
-
-
- Z80_SetByte ;(a0,d0,d1) (ctrl, addr, BYTE val)
- move.l a1,-(a7)
- move.l Z80_zero(a0),a1
- move.b d1,(a1,d0.w)
- move.l Z80_cachezero(a0),a1
- add.w d0,a1
- clr.w (a1,d0.w)
- move.l (a7)+,a1
- rts ;return nothing
- ** ------------
-
- Z80_SetWordLH ;(a0,d0,d1) (ctrl, addr, WORD val)
- move.l a1,-(a7)
- movea.l Z80_zero(a0),a1
- move.b d1,(a1,d0.w)
- lsr.w #8,d1
- addq.w #1,d0 ;second byte
- move.b d1,(a1,d0.w)
- move.l Z80_cachezero(a0),a1
- movea.l a1,a0 ;keep cachezero
- add.w d0,a1
- clr.w (a1,d0.w) ;mark cache
- subq.w #1,d0 ;first byte
- movea.l a0,a1 ;get cachezero
- add.w d0,a1
- clr.w (a1,d0.w) ;mark cache
- move.l (a7)+,a1
- rts ;return nothing
- ** ------------
-
- Z80_GetByte ;(a0,d0) (ctrl, addr)
- movea.l Z80_zero(a0),a0
- move.b (a0,d0.w),d0
- ext.w d0 ;sign extend
- ext.l d0
- rts ;return (signed) byte in d0
- ** ------------
-
- Z80_GetWordLH ;(a0,d0) (ctrl, addr)
- movea.l Z80_zero(a0),a0
- move.w d0,-(sp) ;create word on stack
- move.b (a0,d0.w),1(sp) ;low byte
- addq.w #1,d0
- move.b (a0,d0.w),(sp) ;high byte
- move.w (sp)+,d0
- ext.l d0 ;sign extend
- rts ;return (signed) word in d0
- ** ------------
-
- Z80_SetBlock ;(a0,d0,d1,d2) (ctrl, start_addr, size, BYTE val)
- movem.l a1/a2,-(a7)
- movea.l Z80_zero(a0),a1
- movea.l Z80_cachezero(a0),a2
- .loop move.b d2,(a1,d0.w)
- movea.l a2,a0
- adda.w d0,a0
- clr.w (a0,d0.w) ;mark cache
- addq.w #1,d0
- subq.l #1,d1
- bne.s .loop
- movem.l (a7)+,a1/a2
- rts ;return nothing
- ** ------------
-
- Z80_ReadBlock ;(a0,a1,d0,d1) (ctrl, buf, start_addr, size)
- movea.l Z80_zero(a0),a0
- .loop move.b (a0,d0.w),(a1)+
- addq.w #1,d0
- subq.l #1,d1
- bne.s .loop
- rts ;return nothing
- ** ------------
-
- Z80_WriteBlock ;(a0,a1,d0,d1) (ctrl, buf, start_addr, size)
- movem.l a2/a3,-(a7)
- movea.l Z80_zero(a0),a2
- movea.l Z80_cachezero(a0),a3
- .loop move.b (a1)+,(a2,d0.w)
- movea.l a3,a0
- adda.w d0,a0
- clr.l (a0,d0.w) ;mark cache
- addq.w #1,d0
- subq.l #1,d1
- bne.s .loop
- movem.l (a7)+,a2/a3
- rts ;return nothing
-
- ** ------------------------------------------------------------------------
-
- ** This routine sets Z80 memory control flags. If the Z80_Flagmem field
- ** in the control structure is zero, the function has no effect.
- ** Z80_SetMemFlag (a0,d0,d1,d2) (ctrl, start_addr, size, flag)
- **
- ** As for the memory access functions, the Z80 address is word-sized and
- ** passed in d0, and the size is an unsigned longword. The flag is a
- ** byte-sized value, and its possible meanings are defined in Z80.i.
- ** Nothing is returned.
-
- Z80_SetMemFlag ;(a0,d0,d1,d2) (ctrl, start_addr, size, flag)
- tst.l Z80_Flagmem(a0)
- beq.s .end
- move.l Z80_flagzero(a0),a0
- .loop move.b d2,(a0,d0.w)
- addq.w #1,d0
- subq.l #1,d1
- bne.s .loop
- .end rts ;return nothing
-
-
- ** This routine returns the memory control flag for an address, in case
- ** you should forget it. If the Z80_Flagmem field in the control
- ** structure is zero, the function has no effect, and returns zero (RAM).
- ** Z80_GetMemFlag (a0,d0) (ctrl, addr)
- **
- ** The Z80 address is word-sized and passed in d0. The flag value is
- ** returned in (the whole of) d0, and has the range -128 to +127.
-
- Z80_GetMemFlag ;(a0,d0) (ctrl, addr)
- tst.l Z80_Flagmem(a0)
- beq.s .end
- move.l Z80_flagzero(a0),d1
- move.b (a0,d0.w),d0
- ext.w d0
- ext.l d0
- .end rts ;return flag in d0
-
- ** =====================================================================
-