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