1
0
mirror of synced 2025-04-18 23:24:01 +03:00

[*] UKNCBTL: Doxygen comments, other changes.

This commit is contained in:
nzeemin 2012-09-11 18:19:45 +00:00
parent a403c87b5f
commit c223c6a706
7 changed files with 2000 additions and 123 deletions

1846
Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@ -666,23 +666,19 @@ void Emulator_PrepareScreenRGB32(void* pImageBits, const DWORD* colors)
//TODO: 256 bytes * 4 - Floppy 1..4 path
//TODO: 256 bytes * 2 - Hard 1..2 path
void Emulator_SaveImage(LPCTSTR sFilePath)
BOOL Emulator_SaveImage(LPCTSTR sFilePath)
{
// Create file
FILE* fpFile = ::_tfsopen(sFilePath, _T("w+b"), _SH_DENYWR);
if (fpFile == NULL)
{
AlertWarning(_T("Failed to save image file."));
return;
}
return FALSE;
// Allocate memory
BYTE* pImage = (BYTE*) ::malloc(UKNCIMAGE_SIZE);
if (pImage == NULL)
{
AlertWarning(_T("Failed to save image file."));
::fclose(fpFile);
return;
return FALSE;
}
memset(pImage, 0, UKNCIMAGE_SIZE);
// Prepare header
@ -697,29 +693,31 @@ void Emulator_SaveImage(LPCTSTR sFilePath)
// Save image to the file
DWORD dwBytesWritten = ::fwrite(pImage, 1, UKNCIMAGE_SIZE, fpFile);
//TODO: Check if dwBytesWritten != UKNCIMAGE_SIZE
// Free memory, close file
::free(pImage);
::fclose(fpFile);
if (dwBytesWritten != UKNCIMAGE_SIZE)
return FALSE;
return TRUE;
}
void Emulator_LoadImage(LPCTSTR sFilePath)
BOOL Emulator_LoadImage(LPCTSTR sFilePath)
{
Emulator_Stop();
// Open file
FILE* fpFile = ::_tfsopen(sFilePath, _T("rb"), _SH_DENYWR);
if (fpFile == NULL)
{
AlertWarning(_T("Failed to load image file."));
return;
}
Emulator_Stop();
return FALSE;
// Read header
DWORD bufHeader[UKNCIMAGE_HEADER_SIZE / sizeof(DWORD)];
DWORD dwBytesRead = ::fread(bufHeader, 1, UKNCIMAGE_HEADER_SIZE, fpFile);
//TODO: Check if dwBytesRead != UKNCIMAGE_HEADER_SIZE
if (dwBytesRead != UKNCIMAGE_HEADER_SIZE)
{
::fclose(fpFile);
return FALSE;
}
//TODO: Check version and size
@ -728,14 +726,18 @@ void Emulator_LoadImage(LPCTSTR sFilePath)
if (pImage == NULL)
{
::fclose(fpFile);
AlertWarning(_T("Failed to load image file."));
return;
return FALSE;
}
// Read image
::fseek(fpFile, 0, SEEK_SET);
dwBytesRead = ::fread(pImage, 1, UKNCIMAGE_SIZE, fpFile);
//TODO: Check if dwBytesRead != UKNCIMAGE_SIZE
if (dwBytesRead != UKNCIMAGE_SIZE)
{
::free(pImage);
::fclose(fpFile);
return FALSE;
}
// Restore emulator state from the image
g_pBoard->LoadFromImage(pImage);
@ -746,7 +748,7 @@ void Emulator_LoadImage(LPCTSTR sFilePath)
::free(pImage);
::fclose(fpFile);
MainWindow_UpdateAllViews();
return TRUE;
}

View File

@ -54,8 +54,8 @@ BOOL Emulator_LoadROMCartridge(int slot, LPCTSTR sFilePath);
void Emulator_OnUpdate();
WORD Emulator_GetChangeRamStatus(int addrtype, WORD address);
void Emulator_SaveImage(LPCTSTR sFilePath);
void Emulator_LoadImage(LPCTSTR sFilePath);
BOOL Emulator_SaveImage(LPCTSTR sFilePath);
BOOL Emulator_LoadImage(LPCTSTR sFilePath);
//////////////////////////////////////////////////////////////////////

View File

@ -983,7 +983,12 @@ void MainWindow_DoFileLoadState()
bufFileName);
if (! okResult) return;
Emulator_LoadImage(bufFileName);
if (!Emulator_LoadImage(bufFileName))
{
AlertWarning(_T("Failed to load image file."));
}
MainWindow_UpdateAllViews();
}
void MainWindow_DoFileSaveState()
@ -996,7 +1001,10 @@ void MainWindow_DoFileSaveState()
bufFileName);
if (! okResult) return;
Emulator_SaveImage(bufFileName);
if (!Emulator_SaveImage(bufFileName))
{
AlertWarning(_T("Failed to save image file."));
}
}
void MainWindow_DoFileScreenshot()

View File

@ -90,7 +90,8 @@ class CHardDrive;
//////////////////////////////////////////////////////////////////////
class CMotherboard // UKNC computer
/// \brief UKNC computer
class CMotherboard
{
public: // Construct / destruct
@ -98,22 +99,22 @@ public: // Construct / destruct
~CMotherboard();
protected: // Devices
CProcessor* m_pCPU; // CPU device
CProcessor* m_pPPU; // PPU device
CMemoryController* m_pFirstMemCtl; // CPU memory control
CMemoryController* m_pSecondMemCtl; // PPU memory control
CFloppyController* m_pFloppyCtl; // FDD control
CHardDrive* m_pHardDrives[2]; // HDD control
CProcessor* m_pCPU; ///< CPU device
CProcessor* m_pPPU; ///< PPU device
CMemoryController* m_pFirstMemCtl; ///< CPU memory control
CMemoryController* m_pSecondMemCtl; ///< PPU memory control
CFloppyController* m_pFloppyCtl; ///< FDD control
CHardDrive* m_pHardDrives[2]; ///< HDD control
public: // Getting devices
CProcessor* GetCPU() { return m_pCPU; }
CProcessor* GetPPU() { return m_pPPU; }
CMemoryController* GetCPUMemoryController() { return m_pFirstMemCtl; }
CMemoryController* GetPPUMemoryController() { return m_pSecondMemCtl; }
CProcessor* GetCPU() { return m_pCPU; } ///< Getter for m_pCPU
CProcessor* GetPPU() { return m_pPPU; } ///< Getter for m_pPPU
CMemoryController* GetCPUMemoryController() { return m_pFirstMemCtl; } ///< Get CPU memory controller
CMemoryController* GetPPUMemoryController() { return m_pSecondMemCtl; } ///< Get PPU memory controller
protected: // Memory
BYTE* m_pRAM[3]; // RAM, three planes, 64 KB each
BYTE* m_pROM; // System ROM, 32 KB
BYTE* m_pROMCart[2]; // ROM cartridges #1 and #2, 24 KB each
BYTE* m_pRAM[3]; ///< RAM, three planes, 64 KB each
BYTE* m_pROM; ///< System ROM, 32 KB
BYTE* m_pROMCart[2]; ///< ROM cartridges #1 and #2, 24 KB each
public: // Memory access
WORD GetRAMWord(int plan, WORD offset);
BYTE GetRAMByte(int plan, WORD offset);
@ -124,9 +125,9 @@ public: // Memory access
WORD GetROMCartWord(int cartno, WORD offset);
BYTE GetROMCartByte(int cartno, WORD offset);
public: // Debug
void DebugTicks(); // One Debug PPU tick -- use for debug step or debug breakpoint
void SetCPUBreakpoint(WORD bp) { m_CPUbp = bp; } // Set CPU breakpoint
void SetPPUBreakpoint(WORD bp) { m_PPUbp = bp; } // Set PPU breakpoint
void DebugTicks(); ///< One Debug PPU tick -- use for debug step or debug breakpoint
void SetCPUBreakpoint(WORD bp) { m_CPUbp = bp; } ///< Set CPU breakpoint
void SetPPUBreakpoint(WORD bp) { m_PPUbp = bp; } ///< Set PPU breakpoint
chan_stc GetChannelStruct(unsigned char cpu,unsigned char chan, unsigned char tx)
{//cpu==1 ,ppu==0; tx==1, rx==0
if(cpu)
@ -146,21 +147,21 @@ public: // Debug
}
public: // System control
void Reset(); // Reset computer
void LoadROM(const BYTE* pBuffer); // Load 32 KB ROM image from the biffer
void LoadROMCartridge(int cartno, const BYTE* pBuffer); // Load 24 KB ROM cartridge image
void LoadRAM(int plan, const BYTE* pBuffer); // Load 32 KB RAM image from the biffer
void Tick8000(); // Tick 8.00 MHz
void Tick6250(); // Tick 6.25 MHz
void Tick50(); // Tick 50 Hz - goes to CPU/PPU EVNT line
void TimerTick(); // Timer Tick, 2uS -- dividers are within timer routine
void ResetFloppy(); // INIT signal for FDD
WORD GetTimerValue(); // returns current timer value
WORD GetTimerValueView() { return m_timer; } // Returns current timer value for debugger
WORD GetTimerReload(); // returns timer reload value
WORD GetTimerReloadView() { return m_timerreload; } // Returns timer reload value for debugger
WORD GetTimerState(); // returns timer state
WORD GetTimerStateView() { return m_timerflags; } // Returns timer state for debugger
void Reset(); ///< Reset computer
void LoadROM(const BYTE* pBuffer); ///< Load 32 KB ROM image from the biffer
void LoadROMCartridge(int cartno, const BYTE* pBuffer); ///< Load 24 KB ROM cartridge image
void LoadRAM(int plan, const BYTE* pBuffer); ///< Load 32 KB RAM image from the biffer
void Tick8000(); ///< Tick 8.00 MHz
void Tick6250(); ///< Tick 6.25 MHz
void Tick50(); ///< Tick 50 Hz - goes to CPU/PPU EVNT line
void TimerTick(); ///< Timer Tick, 2uS -- dividers are within timer routine
void ResetFloppy(); ///< INIT signal for FDD
WORD GetTimerValue(); ///< Returns current timer value
WORD GetTimerValueView() { return m_timer; } ///< Returns current timer value for debugger
WORD GetTimerReload(); ///< Returns timer reload value
WORD GetTimerReloadView() { return m_timerreload; } ///< Returns timer reload value for debugger
WORD GetTimerState(); ///< Returns timer state
WORD GetTimerStateView() { return m_timerflags; } ///< Returns timer state for debugger
void ChanWriteByCPU(BYTE chan, BYTE data);
void ChanWriteByPPU(BYTE chan, BYTE data);
@ -181,39 +182,55 @@ public: // System control
//void FloppyDebug(BYTE val);
void SetTimerReload(WORD val); //sets timer reload value
void SetTimerState(WORD val); //sets timer state
void ExecuteCPU(); // Execute one CPU instruction
void ExecutePPU(); // Execute one PPU instruction
BOOL SystemFrame(); // Do one frame -- use for normal run
void KeyboardEvent(BYTE scancode, BOOL okPressed); // Key pressed or released
void SetTimerReload(WORD val); ///< Sets timer reload value
void SetTimerState(WORD val); ///< Sets timer state
void ExecuteCPU(); ///< Execute one CPU instruction
void ExecutePPU(); ///< Execute one PPU instruction
BOOL SystemFrame(); ///< Do one frame -- use for normal run
void KeyboardEvent(BYTE scancode, BOOL okPressed); ///< Key pressed or released
WORD GetKeyboardRegister(void);
WORD GetScannedKey() {return m_scanned_key; }
/// \brief Attach floppy image to the slot -- insert the disk.
BOOL AttachFloppyImage(int slot, LPCTSTR sFileName);
/// \brief Empty the floppy slot -- remove the disk.
void DetachFloppyImage(int slot);
/// \brief Check if the floppy attached.
BOOL IsFloppyImageAttached(int slot) const;
/// \brief Check if the attached floppy image is read-only.
BOOL IsFloppyReadOnly(int slot) const;
/// \brief Check if the floppy drive engine rotates the disks.
BOOL IsFloppyEngineOn() const;
WORD GetFloppyState();
WORD GetFloppyData();
void SetFloppyState(WORD val);
void SetFloppyData(WORD val);
/// \brief Check if ROM cartridge image assigned to the cartridge slot.
BOOL IsROMCartridgeLoaded(int cartno) const;
/// \brief Empty the ROM cartridge slot.
void UnloadROMCartridge(int cartno);
/// \brief Attach hard drive image to the slot.
BOOL AttachHardImage(int slot, LPCTSTR sFileName);
/// \brief Empty hard drive slot.
void DetachHardImage(int slot);
/// \brief Check if the hard drive attached.
BOOL IsHardImageAttached(int slot) const;
/// \brief Check if the attached hard drive image is read-only.
BOOL IsHardImageReadOnly(int slot) const;
WORD GetHardPortWord(int slot, WORD port); // To use from CSecondMemoryController only
void SetHardPortWord(int slot, WORD port, WORD data); // To use from CSecondMemoryController only
WORD GetHardPortWord(int slot, WORD port); ///< To use from CSecondMemoryController only
void SetHardPortWord(int slot, WORD port, WORD data); ///< To use from CSecondMemoryController only
/// \brief Assign tape read callback function.
void SetTapeReadCallback(TAPEREADCALLBACK callback, int sampleRate);
/// \brief Assign write read callback function.
void SetTapeWriteCallback(TAPEWRITECALLBACK callback, int sampleRate);
/// \brief Assign sound output callback function.
void SetSoundGenCallback(SOUNDGENCALLBACK callback);
/// \brief Assign serial port input/output callback functions.
void SetSerialCallbacks(SERIALINCALLBACK incallback, SERIALOUTCALLBACK outcallback);
/// \brief Assign parallel port output callback function.
void SetParallelOutCallback(PARALLELOUTCALLBACK outcallback);
public: // Saving/loading emulator status
@ -229,8 +246,8 @@ private: // Timing
int m_cputicks;
unsigned int m_lineticks;
private:
WORD m_CPUbp;
WORD m_PPUbp;
WORD m_CPUbp; ///< CPU breakpoint, 177777 if not set
WORD m_PPUbp; ///< PPU breakpoint, 177777 if not set
WORD m_timer;
WORD m_timerreload;

View File

@ -297,7 +297,7 @@ BOOL CProcessor::InterruptProcessing ()
{
WORD intrVector = 0xFFFF;
BOOL currMode = ((m_psw & 0400) != 0); // Current processor mode: TRUE = HALT mode, FALSE = USER mode
BOOL intrMode; // TRUE = HALT mode interrupt, FALSE = USER mode interrupt
BOOL intrMode = FALSE; // TRUE = HALT mode interrupt, FALSE = USER mode interrupt
if (m_stepmode)
m_stepmode = FALSE;
@ -1931,7 +1931,7 @@ void CProcessor::ExecuteASH () // ASH
if (dst & 0100000) new_psw |= PSW_C; else new_psw &= ~PSW_C;
dst <<= 1;
if ((dst<0) != ((new_psw & PSW_C)!=0)) new_psw |= PSW_V;
m_internalTick+=ASH_S_TIMING;
m_internalTick = m_internalTick + ASH_S_TIMING;
}
}
else
@ -1940,7 +1940,7 @@ void CProcessor::ExecuteASH () // ASH
{
if (dst & 1) new_psw |= PSW_C; else new_psw &= ~PSW_C;
dst >>= 1;
m_internalTick+=ASH_S_TIMING;
m_internalTick = m_internalTick + ASH_S_TIMING;
}
}
@ -1972,7 +1972,7 @@ void CProcessor::ExecuteASHC () // ASHC
if (dst & 0x80000000L) new_psw |= PSW_C; else new_psw &= ~PSW_C;
dst <<= 1;
if ((dst<0) != ((new_psw & PSW_C)!=0)) new_psw |= PSW_V;
m_internalTick+=ASHC_S_TIMING;
m_internalTick = m_internalTick + ASHC_S_TIMING;
}
}
else
@ -1981,7 +1981,7 @@ void CProcessor::ExecuteASHC () // ASHC
{
if (dst & 1) new_psw |= PSW_C; else new_psw &= ~PSW_C;
dst >>= 1;
m_internalTick+=ASHC_S_TIMING;
m_internalTick = m_internalTick + ASHC_S_TIMING;
}
}

View File

@ -21,68 +21,70 @@ class CMemoryController;
//////////////////////////////////////////////////////////////////////
class CProcessor // KM1801VM2 processor
/// \brief KM1801VM2 processor
class CProcessor
{
public: // Constructor / initialization
CProcessor(LPCTSTR name);
/// \brief Link the processor and memory controller.
void AttachMemoryController(CMemoryController* ctl) { m_pMemoryController = ctl; }
void SetHALTPin(BOOL value);
void SetDCLOPin(BOOL value);
void SetACLOPin(BOOL value);
void MemoryError();
/// \brief Get the processor name, assigned in the constructor.
LPCTSTR GetName() const { return m_name; }
public:
static void Init(); // Initialize static tables
static void Done(); // Release memory used for static tables
static void Init(); ///< Initialize static tables
static void Done(); ///< Release memory used for static tables
protected: // Statics
typedef void ( CProcessor::*ExecuteMethodRef )();
static ExecuteMethodRef* m_pExecuteMethodMap;
static void RegisterMethodRef(WORD start, WORD end, CProcessor::ExecuteMethodRef methodref);
protected: // Processor state
TCHAR m_name[5]; // Processor name (DO NOT use it inside the processor code!!!)
WORD m_internalTick; // How many ticks waiting to the end of current instruction
WORD m_psw; // Processor Status Word (PSW)
WORD m_R[8]; // Registers (R0..R5, R6=SP, R7=PC)
BOOL m_okStopped; // "Processor stopped" flag
WORD m_savepc; // CPC register
WORD m_savepsw; // CPSW register
BOOL m_stepmode; // Read TRUE if it's step mode
BOOL m_buserror; // Read TRUE if occured bus error for implementing double bus error if needed
BOOL m_haltpin; // HALT pin
BOOL m_DCLOpin; // DCLO pin
BOOL m_ACLOpin; // ACLO pin
BOOL m_waitmode; // WAIT
TCHAR m_name[5]; ///< Processor name (DO NOT use it inside the processor code!!!)
WORD m_internalTick; ///< How many ticks waiting to the end of current instruction
WORD m_psw; ///< Processor Status Word (PSW)
WORD m_R[8]; ///< Registers (R0..R5, R6=SP, R7=PC)
BOOL m_okStopped; ///< "Processor stopped" flag
WORD m_savepc; ///< CPC register
WORD m_savepsw; ///< CPSW register
BOOL m_stepmode; ///< Read TRUE if it's step mode
BOOL m_buserror; ///< Read TRUE if occured bus error for implementing double bus error if needed
BOOL m_haltpin; ///< HALT pin
BOOL m_DCLOpin; ///< DCLO pin
BOOL m_ACLOpin; ///< ACLO pin
BOOL m_waitmode; ///< WAIT
protected: // Current instruction processing
WORD m_instruction; // Curent instruction
int m_regsrc; // Source register number
int m_methsrc; // Source address mode
WORD m_addrsrc; // Source address
int m_regdest; // Destination register number
int m_methdest; // Destination address mode
WORD m_addrdest; // Destination address
WORD m_instruction; ///< Curent instruction
int m_regsrc; ///< Source register number
int m_methsrc; ///< Source address mode
WORD m_addrsrc; ///< Source address
int m_regdest; ///< Destination register number
int m_methdest; ///< Destination address mode
WORD m_addrdest; ///< Destination address
protected: // Interrupt processing
BOOL m_STRTrq; // Start interrupt pending
BOOL m_RPLYrq; // Hangup interrupt pending
BOOL m_ILLGrq; // Illegal instruction interrupt pending
BOOL m_RSVDrq; // Reserved instruction interrupt pending
BOOL m_TBITrq; // T-bit interrupt pending
BOOL m_ACLOrq; // Power down interrupt pending
BOOL m_HALTrq; // HALT command or HALT signal
BOOL m_EVNTrq; // Timer event interrupt pending
BOOL m_FIS_rq; // FIS command interrupt pending
BOOL m_BPT_rq; // BPT command interrupt pending
BOOL m_IOT_rq; // IOT command interrupt pending
BOOL m_EMT_rq; // EMT command interrupt pending
BOOL m_TRAPrq; // TRAP command interrupt pending
WORD m_virq[16]; // VIRQ vector
BOOL m_ACLOreset; // Power fail interrupt request reset
BOOL m_EVNTreset; // EVNT interrupt request reset;
int m_VIRQreset; // VIRQ request reset for given device
BOOL m_STRTrq; ///< Start interrupt pending
BOOL m_RPLYrq; ///< Hangup interrupt pending
BOOL m_ILLGrq; ///< Illegal instruction interrupt pending
BOOL m_RSVDrq; ///< Reserved instruction interrupt pending
BOOL m_TBITrq; ///< T-bit interrupt pending
BOOL m_ACLOrq; ///< Power down interrupt pending
BOOL m_HALTrq; ///< HALT command or HALT signal
BOOL m_EVNTrq; ///< Timer event interrupt pending
BOOL m_FIS_rq; ///< FIS command interrupt pending
BOOL m_BPT_rq; ///< BPT command interrupt pending
BOOL m_IOT_rq; ///< IOT command interrupt pending
BOOL m_EMT_rq; ///< EMT command interrupt pending
BOOL m_TRAPrq; ///< TRAP command interrupt pending
WORD m_virq[16]; ///< VIRQ vector
BOOL m_ACLOreset; ///< Power fail interrupt request reset
BOOL m_EVNTreset; ///< EVNT interrupt request reset;
int m_VIRQreset; ///< VIRQ request reset for given device
protected:
CMemoryController* m_pMemoryController;
@ -90,9 +92,10 @@ public:
CMemoryController* GetMemoryController() { return m_pMemoryController; }
public: // Register control
WORD GetPSW() const { return m_psw; }
WORD GetPSW() const { return m_psw; } ///< Get the processor status word register value
WORD GetCPSW() const { return m_savepsw; }
BYTE GetLPSW() const { return LOBYTE(m_psw); }
/// \brief Set the processor status word register value
void SetPSW(WORD word)
{
m_psw = word & 0777;
@ -104,7 +107,8 @@ public: // Register control
m_psw = (m_psw & 0xFF00) | (WORD)byte;
if ((m_psw & 0600) != 0600) m_savepsw = m_psw;
}
WORD GetReg(int regno) const { return m_R[regno]; }
WORD GetReg(int regno) const { return m_R[regno]; } ///< Get register value
/// \brief Set register value
void SetReg(int regno, WORD word)
{
m_R[regno] = word;
@ -140,18 +144,18 @@ public: // PSW bits control
WORD GetHALT() const { return (m_psw & PSW_HALT) != 0; }
public: // Processor state
// "Processor stopped" flag
/// \brief "Processor stopped" flag
BOOL IsStopped() const { return m_okStopped; }
// HALT flag (TRUE - HALT mode, FALSE - USER mode)
/// \brief HALT flag (TRUE - HALT mode, FALSE - USER mode)
BOOL IsHaltMode() const
{
return ((m_psw & 0400) != 0);
}
public: // Processor control
void TickEVNT(); // EVNT signal
void InterruptVIRQ(int que, WORD interrupt); // External interrupt via VIRQ signal
void TickEVNT(); ///< EVNT signal
void InterruptVIRQ(int que, WORD interrupt); ///< External interrupt via VIRQ signal
WORD GetVIRQ(int que);
void Execute(); // Execute one instruction - for debugger only
void Execute(); ///< Execute one instruction - for debugger only
BOOL InterruptProcessing();
void CommandExecution();
@ -160,8 +164,8 @@ public: // Saving/loading emulator status (pImage addresses up to 32 bytes)
void LoadFromImage(const BYTE* pImage);
protected: // Implementation
void FetchInstruction(); // Read next instruction
void TranslateInstruction(); // Execute the instruction
void FetchInstruction(); ///< Read next instruction
void TranslateInstruction(); ///< Execute the instruction
protected: // Implementation - memory access
WORD GetWordExec(WORD address) { return m_pMemoryController->GetWordExec(address, IsHaltMode()); }
WORD GetWord(WORD address) { return m_pMemoryController->GetWord(address, IsHaltMode()); }