mirror of
				https://github.com/RetroDECK/Supermodel.git
				synced 2025-04-10 19:15:14 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			328 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			328 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /**
 | |
|  ** Supermodel
 | |
|  ** A Sega Model 3 Arcade Emulator.
 | |
|  ** Copyright 2011 Bart Trzynadlowski, Nik Henson 
 | |
|  **
 | |
|  ** This file is part of Supermodel.
 | |
|  **
 | |
|  ** Supermodel is free software: you can redistribute it and/or modify it under
 | |
|  ** the terms of the GNU General Public License as published by the Free 
 | |
|  ** Software Foundation, either version 3 of the License, or (at your option)
 | |
|  ** any later version.
 | |
|  **
 | |
|  ** Supermodel is distributed in the hope that it will be useful, but WITHOUT
 | |
|  ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 | |
|  ** FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 | |
|  ** more details.
 | |
|  **
 | |
|  ** You should have received a copy of the GNU General Public License along
 | |
|  ** with Supermodel.  If not, see <http://www.gnu.org/licenses/>.
 | |
|  **/
 | |
|  
 | |
| /*
 | |
|  * DriveBoard.h
 | |
|  *
 | |
|  * Header for the CDriveBoard (force feedback emulation) class.
 | |
|  */
 | |
| 
 | |
| #ifndef INCLUDED_DRIVEBOARD_H
 | |
| #define INCLUDED_DRIVEBOARD_H
 | |
| 
 | |
| #include "Util/NewConfig.h"
 | |
| 
 | |
| /*
 | |
|  * CDriveBoard
 | |
|  */
 | |
| class CDriveBoard : public IBus
 | |
| {
 | |
| public:
 | |
|   /*
 | |
|    * IsAttached(void):
 | |
|    *
 | |
|    * Returns:
 | |
|    *    True if the drive board is "attached" and should be emulated,
 | |
|    *    otherwise false.
 | |
|    */
 | |
|   bool IsAttached(void);
 | |
| 
 | |
|   /*
 | |
|    * IsSimulated(void):
 | |
|    *
 | |
|    * Returns:
 | |
|    *    True if the drive board is being simulated rather than actually
 | |
|    *    emulated, otherwise false.
 | |
|    */
 | |
|   bool IsSimulated(void);
 | |
| 
 | |
|   /*
 | |
|    * GetDIPSwitches(dip1, dip2):
 | |
|    *
 | |
|    * Reads the two sets of DIP switches on the drive board.
 | |
|    *
 | |
|    * Parameters:
 | |
|    *    dip1  Reference of variable to store DIP switch 1 to.
 | |
|    *    dip2  DIP switch 2.
 | |
|    */
 | |
|   void GetDIPSwitches(UINT8 &dip1, UINT8 &dip2);
 | |
| 
 | |
|   /*
 | |
|    * SetDIPSwitches(dip1, dip2):
 | |
|    *
 | |
|    * Sets the DIP switches.
 | |
|    *
 | |
|    * Parameters:
 | |
|    *    dip1  DIP switch 1 value.
 | |
|    *    dip2  DIP switch 2 value.
 | |
|    */
 | |
|   void SetDIPSwitches(UINT8 dip1, UINT8 dip2);
 | |
| 
 | |
|   /*
 | |
|    * GetSteeringStrength(void):
 | |
|    *
 | |
|    * Returns:
 | |
|    *    Strength of the steering based on drive board DIP switches (1-8).
 | |
|    */
 | |
|   unsigned GetSteeringStrength(void);
 | |
| 
 | |
|   /*
 | |
|    * SetSteeringStrength(steeringStrength):
 | |
|    *
 | |
|    * Sets the steering strength (modifies the DIP switch setting).
 | |
|    *
 | |
|    * Parameters:
 | |
|    *    steeringStrength  A value ranging from 1 to 8.
 | |
|    */
 | |
|   void SetSteeringStrength(unsigned steeringStrength);
 | |
| 
 | |
|   /*
 | |
|    * Get7SegDisplays(seg1Digit1, seg1Digit2, seg2Digit1, seg2Digit2):
 | |
|    *
 | |
|    * Reads the 7-segment displays.
 | |
|    *
 | |
|    * Parameters:
 | |
|    *    seg1Digit1  Reference of variable to store digit 1 of the first 7-
 | |
|    *          segment display to.
 | |
|    *    seg1Digit2  First display, second digit.
 | |
|    *    seg2Digit1  Second display, first digit.
 | |
|    *    seg2Digit2  Second display, second digit.
 | |
|    */
 | |
|   void Get7SegDisplays(UINT8 &seg1Digit, UINT8 &seg1Digit2, UINT8 &seg2Digit1, UINT8 &seg2Digit2);
 | |
| 
 | |
|   /*
 | |
|    * GetZ80(void):
 | |
|    *
 | |
|    * Returns:
 | |
|    *    The Z80 object.
 | |
|    */
 | |
|   CZ80 *GetZ80(void);
 | |
| 
 | |
|   /*
 | |
|    * SaveState(SaveState):
 | |
|    *
 | |
|    * Saves the drive board state.
 | |
|    *
 | |
|    * Parameters:
 | |
|    *    SaveState Block file to save state information to.
 | |
|    */
 | |
|   void SaveState(CBlockFile *SaveState);
 | |
| 
 | |
|   /*
 | |
|    * LoadState(SaveState):
 | |
|    *
 | |
|    * Restores the drive board state.
 | |
|    *
 | |
|    * Parameters:
 | |
|    *    SaveState Block file to load save state information from.
 | |
|    */
 | |
|   void LoadState(CBlockFile *SaveState);
 | |
| 
 | |
|   /*
 | |
|    * Init(romPtr):
 | |
|    *
 | |
|    * Initializes (and "attaches") the drive board. This should be called
 | |
|    * before other members.
 | |
|    *
 | |
|    * Parameters:
 | |
|    *    romPtr    Pointer to the drive board ROM (Z80 program). If this
 | |
|    *          is NULL, then the drive board will not be emulated.
 | |
|    *
 | |
|    * Returns:
 | |
|    *    FAIL if the drive board could not be initialized (prints own error
 | |
|    *    message), otherwise OKAY. If the drive board is not attached
 | |
|    *    because no ROM was passed to it, no error is generated and the
 | |
|    *    drive board is silently disabled (detached).
 | |
|    */
 | |
|   bool Init(const UINT8 *romPtr);
 | |
| 
 | |
|   /*
 | |
|    * AttachInputs(InputsPtr, gameInputFlags):
 | |
|    *
 | |
|    * Attaches inputs to the drive board (for access to the steering wheel 
 | |
|    * position).
 | |
|    *
 | |
|    * Parameters:
 | |
|    *    inputs      Pointer to the input object.
 | |
|    *    gameInputFlags  The current game's input flags.
 | |
|    */
 | |
|   void AttachInputs(CInputs *inputs, unsigned gameInputFlags);
 | |
| 
 | |
|   void AttachOutputs(COutputs *outputs);
 | |
| 
 | |
|   /*
 | |
|    * Reset(void):
 | |
|    *
 | |
|    * Resets the drive board.
 | |
|    */
 | |
|   void Reset(void);
 | |
| 
 | |
|   /*
 | |
|    * Read():
 | |
|    *
 | |
|    * Reads data from the drive board.
 | |
|    *
 | |
|    * Returns:
 | |
|    *    Data read.
 | |
|    */
 | |
|   UINT8 Read(void);
 | |
| 
 | |
|   /*
 | |
|    * Write(data):
 | |
|    *
 | |
|    * Writes data to the drive board.
 | |
|    *
 | |
|    * Parameters:
 | |
|    *    data  Data to send.
 | |
|    */
 | |
|   void Write(UINT8 data);
 | |
| 
 | |
|   /*
 | |
|    * RunFrame(void):
 | |
|    *
 | |
|    * Emulates a single frame's worth of time on the drive board.
 | |
|    */
 | |
|   void RunFrame(void);
 | |
| 
 | |
|   /*
 | |
|    * CDriveBoard(config):
 | |
|    * ~CDriveBoard():
 | |
|    *
 | |
|    * Constructor and destructor. Memory is freed by destructor.
 | |
|    *
 | |
|    * Paramters:
 | |
|    *    config  Run-time configuration. The reference should be held because
 | |
|    *            this changes at run-time.
 | |
|    */
 | |
|   CDriveBoard(const Util::Config::Node &config);
 | |
|   ~CDriveBoard(void);
 | |
| 
 | |
|   /*
 | |
|    * Read8(addr):
 | |
|    * IORead8(portNum):
 | |
|    *
 | |
|    * Methods for reading from Z80's memory and IO space. Required by CBus.
 | |
|    *
 | |
|    * Parameters:
 | |
|    *    addr    Address in memory (0-0xFFFF).
 | |
|    *    portNum   Port address (0-255).
 | |
|    *
 | |
|    * Returns:
 | |
|    *    A byte of data from the address or port.
 | |
|    */
 | |
|   UINT8 Read8(UINT32 addr);
 | |
|   UINT8 IORead8(UINT32 portNum);
 | |
|   
 | |
|   /*
 | |
|    * Write8(addr, data):
 | |
|    * IORead8(portNum, data):
 | |
|    *
 | |
|    * Methods for writing to Z80's memory and IO space. Required by CBus.
 | |
|    *
 | |
|    * Parameters:
 | |
|    *    addr    Address in memory (0-0xFFFF).
 | |
|    *    portNum   Port address (0-255).
 | |
|    *    data    Byte to write.
 | |
|    */
 | |
|   void Write8(UINT32 addr, UINT8 data);
 | |
|   void IOWrite8(UINT32 portNum, UINT8 data);
 | |
|   
 | |
| private:
 | |
|   const Util::Config::Node &m_config;
 | |
|   bool m_attached;    // True if drive board is attached
 | |
|   bool m_tmpDisabled;     // True if temporarily disabled by loading an incompatible save state
 | |
|   bool m_simulated;       // True if drive board should be simulated rather than emulated
 | |
| 
 | |
|   UINT8 m_dip1;       // Value of DIP switch 1
 | |
|   UINT8 m_dip2;         // Value of DIP switch 2
 | |
| 
 | |
|   const UINT8* m_rom;     // 32k ROM 
 | |
|   UINT8* m_ram;           // 8k RAM
 | |
| 
 | |
|   CZ80 m_z80;             // Z80 CPU @ 4MHz
 | |
| 
 | |
|   CInputs *m_inputs;      
 | |
|   unsigned m_inputFlags;
 | |
| 
 | |
|   COutputs *m_outputs;
 | |
|   
 | |
|   // Emulation state
 | |
|   bool m_initialized;     // True if drive board has finished initialization
 | |
|   bool m_allowInterrupts; // True if drive board has enabled NMI interrupts
 | |
| 
 | |
|   UINT8 m_seg1Digit1;   // Current value of left digit on 7-segment display 1
 | |
|   UINT8 m_seg1Digit2;   // Current value of right digit on 7-segment display 1
 | |
|   UINT8 m_seg2Digit1;   // Current value of left digit on 7-segment display 2
 | |
|   UINT8 m_seg2Digit2;     // Current value of right digit on 7-segment display 2
 | |
| 
 | |
|   UINT8 m_dataSent;       // Last command sent by main board
 | |
|   UINT8 m_dataReceived;   // Data to send back to main board
 | |
| 
 | |
|   UINT16 m_adcPortRead;   // ADC port currently reading from
 | |
|   UINT8 m_adcPortBit;     // Bit number currently reading on ADC port
 | |
| 
 | |
|   UINT8 m_port42Out;      // Last value sent to Z80 I/O port 42 (encoder motor data)
 | |
|   UINT8 m_port46Out;      // Last value sent to Z80 I/O port 46 (encoder motor control)
 | |
| 
 | |
|   UINT8 m_prev42Out;      // Previous value sent to Z80 I/O port 42
 | |
|   UINT8 m_prev46Out;      // Previous value sent to Z80 I/O port 46
 | |
| 
 | |
|   UINT8 m_uncenterVal1;   // First part of pending uncenter command
 | |
|   UINT8 m_uncenterVal2;   // Second part of pending uncenter command
 | |
| 
 | |
|   // Simulation state
 | |
|   UINT8 m_initState;
 | |
|   UINT8 m_statusFlags;
 | |
|   UINT8 m_boardMode;
 | |
|   UINT8 m_readMode;
 | |
|   UINT8 m_wheelCenter;
 | |
|   UINT8 m_cockpitCenter;
 | |
|   UINT8 m_echoVal;
 | |
| 
 | |
|   // Feedback state
 | |
|   INT8 m_lastConstForce;  // Last constant force command sent
 | |
|   UINT8 m_lastSelfCenter; // Last self center command sent
 | |
|   UINT8 m_lastFriction;   // Last friction command sent
 | |
|   UINT8 m_lastVibrate;    // Last vibrate command sent
 | |
| 
 | |
|   UINT8 SimulateRead(void);
 | |
| 
 | |
|   void SimulateWrite(UINT8 data);
 | |
| 
 | |
|   void SimulateFrame(void);
 | |
| 
 | |
|   void EmulateFrame(void);
 | |
| 
 | |
|   void ProcessEncoderCmd(void);
 | |
| 
 | |
|   void SendStopAll(void);
 | |
| 
 | |
|   void SendConstantForce(INT8 val);
 | |
| 
 | |
|   void SendSelfCenter(UINT8 val);
 | |
| 
 | |
|   void SendFriction(UINT8 val);
 | |
| 
 | |
|   void SendVibrate(UINT8 val);
 | |
| };
 | |
| 
 | |
| #endif  // INCLUDED_DRIVEBOARD_H
 | 
