//1// Copyright (c) 2004 K. Wilkins2//3// This software is provided 'as-is', without any express or implied warranty.4// In no event will the authors be held liable for any damages arising from5// the use of this software.6//7// Permission is granted to anyone to use this software for any purpose,8// including commercial applications, and to alter it and redistribute it9// freely, subject to the following restrictions:10//11// 1. The origin of this software must not be misrepresented; you must not12// claim that you wrote the original software. If you use this software13// in a product, an acknowledgment in the product documentation would be14// appreciated but is not required.15//16// 2. Altered source versions must be plainly marked as such, and must not17// be misrepresented as being the original software.18//19// 3. This notice may not be removed or altered from any source distribution.20//2122//////////////////////////////////////////////////////////////////////////////23// Handy - An Atari Lynx Emulator //24// Copyright (c) 1996,1997 //25// K. Wilkins //26//////////////////////////////////////////////////////////////////////////////27// System object header file //28//////////////////////////////////////////////////////////////////////////////29// //30// This header file provides the interface definition and inline code for //31// the system object, this object if what binds together all of the Handy //32// hardware enmulation objects, its the glue that holds the system together //33// //34// K. Wilkins //35// August 1997 //36// //37//////////////////////////////////////////////////////////////////////////////38// Revision History: //39// ----------------- //40// //41// 01Aug1997 KW Document header added & class documented. //42// //43//////////////////////////////////////////////////////////////////////////////4445#ifndef SYSTEM_H46#define SYSTEM_H4748#include "machine.h"4950#include <string>5152#define HANDY_SYSTEM_FREQ 1600000053#define HANDY_TIMER_FREQ 205455#define HANDY_FILETYPE_LNX 056#define HANDY_FILETYPE_HOMEBREW 157#define HANDY_FILETYPE_SNAPSHOT 258#define HANDY_FILETYPE_ILLEGAL 35960#define HANDY_SCREEN_WIDTH 16061#define HANDY_SCREEN_HEIGHT 10262//63// Define the global variable list64//6566/*67#ifdef SYSTEM_CPP68uint32 gSuzieDoneTime = 0;69uint32 gSystemCycleCount=0;70uint32 gNextTimerEvent=0;71uint32 gCPUBootAddress=0;72uint32 gSystemIRQ=FALSE;73uint32 gSystemNMI=FALSE;74uint32 gSystemCPUSleep=FALSE;75uint32 gSystemHalt=FALSE;76#else77extern uint32 gSystemCycleCount;78extern uint32 gSuzieDoneTime;79extern uint32 gNextTimerEvent;80extern uint32 gCPUBootAddress;81extern uint32 gSystemIRQ;82extern uint32 gSystemNMI;83extern uint32 gSystemCPUSleep;84extern uint32 gSystemHalt;85#endif86*/8788//89// Define the interfaces before we start pulling in the classes90// as many classes look for articles from the interfaces to91// allow compilation9293#include "sysbase.h"9495class CSystem;9697//98// Now pull in the parts that build the system99//100#include "lynxbase.h"101#include "ram.h"102#include "rom.h"103#include "memmap.h"104#include "cart.h"105#include "susie.h"106#include "mikie.h"107#include "c65c02.h"108109#define TOP_START 0xfc00110#define TOP_MASK 0x03ff111#define TOP_SIZE 0x400112#define SYSTEM_SIZE 65536113114class CSystem : public CSystemBase115{116public:117CSystem(const uint8 *, uint32, const uint8*, uint32, int, int, bool) MDFN_COLD;118~CSystem() MDFN_COLD;119120public:121void Reset() MDFN_COLD;122123inline void Update(uint32 targetclock)124{125// Only update if there is a predicted timer event126if(gSystemCycleCount >= gNextTimerEvent)127{128mMikie->Update();129}130131// Step the processor through 1 instruction132mCpu->Update();133134// If the CPU is asleep then skip to the next timer event135if(gSystemCPUSleep)136{137gSystemCycleCount = std::min(gNextTimerEvent, targetclock);138}139}140141void Blit(const uint32 *src);142143bool Advance(int buttons, uint32 *vbuff, int16 *sbuff, int &sbuffsize);144bool GetSaveRamPtr(int &size, uint8 *&data) { return mCart->GetSaveRamPtr(size, data); }145void GetReadOnlyCartPtrs(int &s0, uint8 *&p0, int &s1, uint8 *&p1) { mCart->GetReadOnlyPtrs(s0, p0, s1, p1); }146147//148// We MUST have separate CPU & RAM peek & poke handlers as all CPU accesses must149// go thru the address generator at $FFF9150//151// BUT, Mikie video refresh & Susie see the whole system as RAM152//153// Complete and utter wankers, its taken me 1 week to find the 2 lines154// in all the documentation that mention this fact, the mother of all155// bugs has been found and FIXED.......156157// CPU158inline void Poke_CPU(uint32 addr, uint8 data) { mMemoryHandlers[addr]->Poke(addr,data);};159inline uint8 Peek_CPU(uint32 addr) { return mMemoryHandlers[addr]->Peek(addr);};160inline void PokeW_CPU(uint32 addr,uint16 data) { mMemoryHandlers[addr]->Poke(addr,data&0xff);addr++;mMemoryHandlers[addr]->Poke(addr,data>>8);};161inline uint16 PeekW_CPU(uint32 addr) {return ((mMemoryHandlers[addr]->Peek(addr))+(mMemoryHandlers[addr]->Peek(addr+1)<<8));};162163// RAM164inline void Poke_RAM(uint32 addr, uint8 data) { mRam->Poke(addr,data);};165inline uint8 Peek_RAM(uint32 addr) { return mRam->Peek(addr);};166inline void PokeW_RAM(uint32 addr,uint16 data) { mRam->Poke(addr,data&0xff);addr++;mRam->Poke(addr,data>>8);};167inline uint16 PeekW_RAM(uint32 addr) {return ((mRam->Peek(addr))+(mRam->Peek(addr+1)<<8));};168169// High level cart access for debug etc170inline void Poke_CART(uint32 addr, uint8 data) {mCart->Poke(addr,data);};171inline uint8 Peek_CART(uint32 addr) {return mCart->Peek(addr);};172inline void CartBank(EMMODE bank) {mCart->BankSelect(bank);};173inline uint32 CartSize() {return mCart->ObjectSize();};174175// Low level cart access for Suzy, Mikey176inline void Poke_CARTB0(uint8 data) {mCart->Poke0(data);};177inline void Poke_CARTB1(uint8 data) {mCart->Poke1(data);};178inline uint8 Peek_CARTB0() {return mCart->Peek0();}179inline uint8 Peek_CARTB1() {return mCart->Peek1();}180inline void CartAddressStrobe(bool strobe) {mCart->CartAddressStrobe(strobe);};181inline void CartAddressData(bool data) {mCart->CartAddressData(data);};182183// Low level CPU access184void SetRegs(C6502_REGS ®s) {mCpu->SetRegs(regs);};185void GetRegs(C6502_REGS ®s) {mCpu->GetRegs(regs);};186187// Mikey system interfacing188void ComLynxCable(int status) { mMikie->ComLynxCable(status); };189void ComLynxRxData(int data) { mMikie->ComLynxRxData(data); };190void ComLynxTxCallback(void (*function)(int data,uint32 objref),uint32 objref) { mMikie->ComLynxTxCallback(function,objref); };191192// Suzy system interfacing193uint32 PaintSprites() {return mSusie->PaintSprites();};194195// Miscellaneous196void SetButtonData(uint32 data);197// uint32 GetButtonData() {return mSusie->GetButtonData();};198uint8* GetRamPointer() {return mRam->GetRamPointer();};199200public:201CLynxBase *mMemoryHandlers[SYSTEM_SIZE];202CCart *mCart;203CRom *mRom;204CMemMap *mMemMap;205CRam *mRam;206C65C02 *mCpu;207CMikie *mMikie;208CSusie *mSusie;209210// old globals211uint32 gSuzieDoneTime;212uint32 gSystemCycleCount;213uint32 gNextTimerEvent;214uint32 gSystemIRQ;215uint32 gSystemNMI;216uint32 gSystemCPUSleep;217uint32 gSystemHalt; // this is set in various places, but never tested, anywhere?218219// frame overflow detection220int frameoverflow;221// rotation of the device222int rotate;223// video dest224uint32 *videobuffer;225226template<bool isReader>void SyncState(NewState *ns);227};228229#endif230231232