IFND Z80_INCLUDE Z80_INCLUDE SET 1 ** General Z80 emulator definitions and declarations. ** The control structure is defined in Z80_struct.i ** ===================================================================== IFD VERBOSE LIST ** Compiling the Z80.i file. NOLIST ENDC ** All sizes and offsets are in bytes: ;The amount of bytes needed for the Z80 memory space Z80_MEMSIZE EQU $10000 Z80_LBUFSIZE EQU 16 ;Uninteresting to the normal user Z80_HBUFSIZE EQU 16 Z80_0_OFFSET EQU $8000 CACHE_0_OFFSET EQU Z80_LBUFSIZE+(2*Z80_0_OFFSET) FLAGS_0_OFFSET EQU Z80_0_OFFSET ;The size of the memory used for the cache. ;It must be word-aligned! Z80_CACHESIZE EQU (2*Z80_MEMSIZE)+Z80_LBUFSIZE+Z80_HBUFSIZE ;The space needed for memory control flags Z80_FLAGMEMSIZE EQU Z80_MEMSIZE ** Memory write access control flags: ;Memory flag values (signed byte): ; -1 to -128 read-only ; 0 ok to write (no detection) ; 1 to 16 access counters 1 to 16 ; 17 to 63 reserved ; 64 to 127 user exception ** Call Z80_SetMemFlag (described below) to set these flags. ** A zero flag marks ordinary RAM, and no detection is made. ** A negative flag (use Z80_MEM_ROM) marks read-only memory. Attempts ** to write are ignored. ** A value in the range Z80_MEM_CNT to Z80_MEM_CNT+Z80_MEM_CNTNUM-1 ** corresponds to write a access counter from 0 to Z80_MEM_CNTNUM-1. ** On each write access, the corresponding counter in the Z80_AccessCnt ** array is incremented by one. If the corresponding flag in the ** Z80_CntType array is zero, the value is written, otherwise the attempt ** to write is ignored. ** A value in the range Z80_MEM_USR to Z80_MEM_USR+Z80_MEM_USRNUM-1 ** corresponds to a user memory exception from 0 to Z80_MEM_USRNUM-1. ** If the Z80_MemHandler pointer is nonzero (non-NULL), the routine it ** points to is called with the following parameters: ** d1 contains the exception number (word). ** d2 contains the value (byte). ** a1 contains the Z80 address (word). ** a2 is scratch (address of user-def routine). ** Changes to a1 and a2 have no effect. The handler must protect any other ** registers it uses, and return the following values: ** d1 zero (longword) if value should be written, nonzero if not. ** d2 countains the value (byte). ** The memory handler call is mostly intended for more complex cases of ** write access detection than the simple counters can handle. Not many ** details can be found out about the current Cpu status from the memory ** handler, since it is called in mid-execution of an instruction, and only ** the base pointer registers TableB, Z0, CacheB and FlagsB can be trusted ** to have correct values. For a list of register aliases, see the file ** Z80_coding.i. ** Example in C: ** Z80_SetMemFlag(Control, $4000, $1B00, Z80_MEM_CNT+5); ** flags the area from $4000 to $5AFF as access counter 5. ** Z80_CntType[5] = 1; ** sets the type of counter 5 to 'do not write'. ** (Remember: the range is from 0 to Z80_MEM_CNTNUM - 1.) ;(These values are hard-coded in the detection routine.) Z80_MEM_ROM EQU -1 Z80_MEM_CNT EQU 1 Z80_MEM_CNTNUM EQU 16 Z80_MEM_USR EQU 64 Z80_MEM_USRNUM EQU 128-Z80_MEM_USR ** ------------ ** Cross-references: ;Depending on whether Z80_MAIN is defined or not, this ;defines a macro to either XREF or XDEF a program label. IFD Z80_MAIN ;XDEF in all cases if compiling emulator Z80_PUB MACRO ;label XDEF \1 ENDM ELSE Z80_PUB MACRO ;label ;otherwise XREF program label XREF \1 ENDM ENDC ;IFD Z80_MAIN ** Function labels Z80_PUB Z80_Init ** Before beginning emulation, the control structure must be initialised ** by calling Z80_Init. ** a0 must point to the control structure. The fields Z80_Memory and ** Z80_Cachemem must be pointing to allocated memory. ** If the memory write access checking feature is used, the field ** Z80_Flagmem must also be set, and if Z80_MemHandler is nonzero ** it is assumed to point to a user memory exception handler. See ** MemoryHandler below for details. ** The user environment data area is not changed. All other fields ** are automatically initialised. The Cpu Status fields are set up ** as after a reset. ** The return value in d0 is nonzero if an error occurred, and zero ** otherwise. All other registers are automatically protected. ** ------------------------------------------------------------------- Z80_PUB Z80_Coldstart ** Start emulation 'from scratch', with a CPU reset. ** a0 must point to the control structure, which must be initialised ** (see Z80_Init above). ** The return value in d0 is nonzero if an error occurred, and zero ** otherwise. All other registers are automatically protected. ** ------------------------------------------------------------------- Z80_PUB Z80_Continue ** Continue with the as if nothing happened since last exit (unless the ** saved processor status has been manipulated). ** Changes to other fields than the CPU status structure entries ** are not recommended; calling Z80_Continue does not guarantee ** that such changes have any effect (see Z80_NewSettings). ** a0 must point to the control structure. ** The return value in d0 is the same as for Z80_Coldstart. All other ** registers are automatically protected. ** ---------------------------------------------------------------------- ** About reallocating memory: ** ** 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 resume ** the emulation from the new addresses. ** The control structure can be moved whenever the emulator is not ** running, without doing anything other than passing the new address ** to Z80_Continue. Z80_PUB Z80_NewSettings ** 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. ** a0 must point to the control structure. ** The return value in d0 is nonzero if an error occurred, and zero ** otherwise. ** ------------------------------------------------------------------- Z80_PUB Z80_SetByte ;(a0,d0,d1) Z80_PUB Z80_SetWordLH ;(a0,d0,d1) Z80_PUB Z80_GetByte ;(a0,d0) Z80_PUB Z80_GetWordLH ;(a0,d0) Z80_PUB Z80_SetBlock ;(a0,d0,d1,d2) Z80_PUB Z80_ReadBlock ;(a0,a1,d0,d1) Z80_PUB Z80_WriteBlock ;(a0,a1,d0,d1) ** Routines to access the Z80 address space. They mirror any changes ** in the cache and handle the wraparound of addresses transparently. ** I recommend that they are used rathed than writing directly into ** the Z80 address space. ** 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_PUB Z80_SetMemFlag ;(a0,d0,d1,d2) ** Sets memory flags. Has no effect if the Z80_Flagmem field in the ** control structure is zero. ** a0 must point to the control structure. The Z80 address (word) is ** passed in d0 and the block size is an unsigned longword passed in d1. ** The flag value (byte) is passed in d2. Nothing is returned. For ranges ** of flag values, see the definition of memory write access control flags ** above. Z80_PUB Z80_GetMemFlag ;(a0,d0) ** Returns the memory control flag for an address. If the Z80_Flagmem ** field in the control structure is zero, a zero value is returned, ** signalling RAM. ** a0 must point to the control structure. The Z80 address (word) is ** passed in d0. The flag value is returned in (the whole of) d0, ** and has the range -128 to +127. ** ------------------------------------------------------------------- ** The requests could be called from hardware interrupts, keypresses, ** menus or whatever. They do not affect any registers (apart from CCR), ** and return nothing. ** a0 must contain a pointer to the control structure. Z80_PUB Z80_INTreq Z80_PUB Z80_NMIreq Z80_PUB Z80_RESETreq Z80_PUB Z80_EXITreq ** The detection time is currently not guaranteed to be anything. ** Hopefully, it is always finite. It shouldn't be more than a few ** instructions. ** ------------------------------------------------------------------- ** End of cross-references. ** ====================================================================== ENDC ;IFND Z80_INCLUDE