8acec1b95d
Do not pollute the global namespace by defining byte, sbyte, and word.
218 lines
7.3 KiB
C
218 lines
7.3 KiB
C
/* Copyright (c) 2008, 2017 Stephen Checkoway
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
*/
|
|
|
|
/*! \file
|
|
*
|
|
* Create and run a z80 processor instance.
|
|
* \author Stephen Checkoway
|
|
* \version 0.1
|
|
* \date 2008, 2017
|
|
*/
|
|
#ifndef ZEL_Z80_H
|
|
#define ZEL_Z80_H
|
|
|
|
#include <stdint.h>
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#else
|
|
#include <stdbool.h>
|
|
#endif
|
|
|
|
/*! Opaque type representing a z80 processor. */
|
|
typedef struct Z80_t *Z80;
|
|
|
|
/* NOTE: Changing the order of these requires changing z80_instructions.h! */
|
|
/*! 16 bit paired z80 registers. The registers ending in P are the
|
|
* primed registers.
|
|
*/
|
|
enum
|
|
{
|
|
REG_BC, //!< z80 register bc.
|
|
REG_DE, //!< z80 register de.
|
|
REG_HL, //!< z80 register hl.
|
|
REG_AF, //!< z80 register af.
|
|
REG_IX, //!< z80 register ix.
|
|
REG_IY, //!< z80 register iy.
|
|
REG_PC, //!< z80 register pc.
|
|
REG_SP, //!< z80 register sp.
|
|
REG_BCP, //!< z80 register bc'.
|
|
REG_DEP, //!< z80 register de'.
|
|
REG_HLP, //!< z80 register hl'.
|
|
REG_AFP, //!< z80 register af'.
|
|
REG_IR, //!< z80 register ir.
|
|
NUM_REG, //!< Number of 16 bit z80 paired registers.
|
|
};
|
|
|
|
/*! Enumerated value describing the control flow of the processor.
|
|
* \sa Z80FunctionBlock
|
|
*/
|
|
typedef enum
|
|
{
|
|
CF_CALL, //!< Call instruction.
|
|
CF_JUMP, //!< Jump instruction.
|
|
CF_RETURN, //!< Return instruction.
|
|
CF_RETURN_I, //!< Return from interrupt instruction.
|
|
CF_RETURN_N, //!< Return from nonmaskable interrupt instruction.
|
|
CF_RESTART, //!< Restart instruction.
|
|
CF_INTERRUPT, //!< Maskable interrupt.
|
|
CF_NMI, //!< Nonmaskable interrupt.
|
|
CF_HALT, //!< Halt instruction.
|
|
} ControlFlowType;
|
|
|
|
/*! A block of callbacks used by Z80_New() to control how the
|
|
* z80 interracts with its peripherials.
|
|
* \headerfile z80.h zel/z80.h
|
|
*/
|
|
typedef struct
|
|
{
|
|
/*! Read a byte of memory.
|
|
* \param addr The address to read.
|
|
* \param inst True if the z80 is reading instructions.
|
|
* \param cpu The \c Z80 instance making the read call.
|
|
* \return The byte from memory.
|
|
*/
|
|
uint8_t (*ReadMem)(uint16_t addr, bool inst, Z80 cpu);
|
|
/*! Write a byte of memory.
|
|
* \param addr The address to write.
|
|
* \param val The byte to write.
|
|
* \param cpu The \c Z80 instance making the write call.
|
|
*/
|
|
void (*WriteMem)(uint16_t addr, uint8_t val, Z80 cpu);
|
|
/*! Read the interrupt data.
|
|
* \param n Read the \a n th byte of data.
|
|
* \param cpu The \c Z80 instance making the read call.
|
|
*/
|
|
uint8_t (*ReadInterruptData)(uint16_t n, Z80 cpu);
|
|
/*! Read a byte from an I/O port.
|
|
* \param addr The contents of the address bus during the
|
|
* request. The low 8 bits specify the port.
|
|
* \param cpu The \c Z80 instance making the read call.
|
|
* \return The byte from the I/O port.
|
|
*/
|
|
uint8_t (*ReadIO)(uint16_t addr, Z80 cpu);
|
|
/*! Write a byte from an I/O port.
|
|
* \param addr The contents of the address bus during the
|
|
* request. The low 8 bits specify the port.
|
|
* \param val The byte to write.
|
|
* \param cpu The \c Z80 instance making the read call.
|
|
*/
|
|
void (*WriteIO)(uint16_t addr, uint8_t val, Z80 cpu);
|
|
/*! Notify the peripherials that a return from interrupt
|
|
* instruction has occured.
|
|
* \param cpu The \c Z80 instance performing the notification.
|
|
*/
|
|
void (*InterruptComplete)(Z80 cpu);
|
|
/*! Optional notification of control flow. This can be set to
|
|
* \c NULL if notification is not desired.
|
|
* \param pc The address of the current instruction.
|
|
* \param target The target address of the instruction. For
|
|
* example, the jump target.
|
|
* \param type The type of control flow.
|
|
* \param cpu The \c Z80 instance performing the notification.
|
|
*/
|
|
void (*ControlFlow)(uint16_t pc, uint16_t target, ControlFlowType type, Z80 cpu);
|
|
} Z80FunctionBlock;
|
|
|
|
/*! Create a new \c Z80 instance using the callbacks specified in \a blk.
|
|
* \param blk A pointer to a block of callbacks. Only
|
|
* Z80FunctionBlock.ControlFlow() may be \c NULL.
|
|
* \return The new \c Z80 instance.
|
|
*/
|
|
Z80 Z80_New( const Z80FunctionBlock *blk );
|
|
|
|
/*! Frees the memory associated with \a cpu.
|
|
* \param cpu The \c Z80 instance to free.
|
|
*/
|
|
void Z80_Free( Z80 cpu );
|
|
|
|
/*! Perform a single step of the processor cpu.
|
|
* \param outPC If non\c NULL, \a *outPC is set to the program counter after
|
|
* the current instruction is executed.
|
|
* \param cpu The \c Z80 instance to step.
|
|
* \return The number of clock ticks that have elapsed while executing
|
|
* the instruction.
|
|
*/
|
|
int Z80_Step( uint16_t *outPC, Z80 cpu );
|
|
|
|
/*! Check if \a cpu has halted.
|
|
* \param cpu The \c Z80 instance.
|
|
* \return \c true if \a cpu has halted.
|
|
*/
|
|
bool Z80_HasHalted( Z80 cpu );
|
|
|
|
/*! Get a 16 bit paired register.
|
|
* \param reg The register to get.
|
|
* \param cpu The \c Z80 instance.
|
|
* \return The contents of the register specified by \a reg.
|
|
*/
|
|
uint16_t Z80_GetReg( int reg, Z80 cpu );
|
|
|
|
/*! Set a 16 bit paired register.
|
|
* \param reg The register to set.
|
|
* \param value The value to assign to the register.
|
|
* \param cpu The \c Z80 instance.
|
|
*/
|
|
void Z80_SetReg( int reg, uint16_t value, Z80 cpu );
|
|
|
|
/*! Disassemble the z80 instruction pointed to by \a address into \a buffer.
|
|
* \param address The address of the beginning the instruction.
|
|
* \param buffer A pointer to at least 25 bytes of storage. If buffer
|
|
* is \c NULL, then the instruction is not disassembled and only the
|
|
* length is returned.
|
|
* \param cpu The \c Z80 instance. The Z80FunctionBlock.ReadMem()
|
|
* function will be called to read the instructions.
|
|
* \return The length of the instruction in bytes.
|
|
*/
|
|
int Z80_Disassemble( uint16_t address, char *buffer, Z80 cpu );
|
|
|
|
/*! Simulate the NMI pin going active. This causes the z80 to jump to
|
|
* the nmi handler.
|
|
* \param cpu The Z80 instance.
|
|
*/
|
|
void Z80_RaiseNMI( Z80 cpu );
|
|
|
|
/*! Simulate the interrupt pin going active. If interrupts are not
|
|
* disabled, then the z80 handles the interrupt according to the
|
|
* interrupt mode.
|
|
* \param cpu The Z80 instance.
|
|
*/
|
|
void Z80_RaiseInterrupt( Z80 cpu );
|
|
|
|
/*! Cause the z80 to reissue the I/O instruction. This only has an
|
|
* effect when called during the Z80FunctionBlock.ReadIO() or
|
|
* Z80FunctionBlock.WriteIO() callbacks. It is to enable debugging by
|
|
* breaking on I/O.
|
|
* \param cpu The \c Z80 instance.
|
|
*/
|
|
void Z80_RestartIO( Z80 cpu );
|
|
|
|
/*! Clear the halt condition. Causes the processor to continue
|
|
* fetching instructions rather than performing NOPs.
|
|
* \param cpu The \c Z80 instance.
|
|
*/
|
|
void Z80_ClearHalt( Z80 cpu );
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|