diff --git a/plasm2_emu/cpu/cpu.h b/plasm2_emu/cpu/cpu.h index 6b37062..755683e 100644 --- a/plasm2_emu/cpu/cpu.h +++ b/plasm2_emu/cpu/cpu.h @@ -9,7 +9,7 @@ #include <time.h> // Current clock speed -#define BASE_CLOCK 1000 +#define BASE_CLOCK 41000000 #define PHYS_MEMSZ 10485760 // Critical System Malfunctions @@ -33,6 +33,15 @@ 5+: Operating system discretion */ +/* + Change this '1' to a '0' to remove the comparison of flags + to determine if clock speed should be regulated. This can save + a small amount of performance in the real world. + */ +#if 1 +#define CLOCK_SYSTEM_ACTIVE 1 +#endif + enum { // Generic Instructions __MOV = 0x00, // MOV 00 (R:04,04 __DEST) (R:04,04 ___SRC) 16 : Move Registers @@ -126,21 +135,25 @@ enum { __SIT = 0x96, // SIT 96 (R:04,08 IHNDLR) 16 : Set Interrupt Table }; -void cpu_init(void); -void cpu_shutdown(void); +void CpuInit(void); +void CpuShutdown(void); + +void CpuClock(void); -void cpu_clock(void); +#define NS_PER_S 1000000000 -typedef struct _cpuctx { +typedef struct _CPU_CTX { WORD64 ClocksPerSecond; - WORD64 SystemSeconds; - WORD64 SystemNanoSeconds; + WORD64 SystemTicks; + WORD64 SystemDeadTicks; + WORD64 NextTickNanoSecond; + WORD64 LastTrackedNanoSecond; time_t SystemBoot; // silly and quick 'timer' BYTE* PhysicalMemory; // PM usage good WORD64 PhysicalMemorySize; -}cpuctx_t; -extern cpuctx_t* cpuctx; +}CPU_CTX, *PCPU_CTX; +extern PCPU_CTX CpuCtx; #define Instruction(Name) void Name(void) #define ListInstruction(Name) [__##Name] = Name @@ -154,10 +167,10 @@ extern void(*Instructions[256])(void); typedef struct _PLASM2_CTX { union { union { - WORD64 rs_64[REGCOUNT_TOTAL]; + WORD64 Registers64[REGCOUNT_TOTAL]; struct { - WORD64 rs_gprs[REGCOUNT_GPRS]; - WORD64 rs_spec[REGCOUNT_SPEC]; + WORD64 GPRs[REGCOUNT_GPRS]; + WORD64 SystemRs[REGCOUNT_SPEC]; }; }; struct { @@ -165,7 +178,7 @@ typedef struct _PLASM2_CTX { WORD64 ip; WORD64 sp; union { - WORD64 flags; + WORD64 Flags; struct { BYTE GF : 1; // Greater flag BYTE EF : 1; // Equal flag @@ -185,41 +198,41 @@ typedef struct _PLASM2_CTX { }flags_s; }; union { - WORD64 security; + WORD64 SecurityRaw; struct { BYTE SecurityLevel : 5; WORD64 Reserved : 59; - }security_s; + }Security; }; struct { - WORD64 ps; // page start - WORD64 pe; // page end - WORD64 ral; // return address location, backup stack pointer - WORD64 it; // interrupt table - WORD64 vsp; // virtual trailing arm - WORD64 csm; // csm handler - WORD64 dvptr; // device map pointer - WORD64 spb; // stack pointer upper bound - WORD64 slb; // stack lower bound - WORD64 pml; // page max location - WORD64 nca; // next call address + WORD64 PageStart; // page start + WORD64 PageEnd; // page end + WORD64 ReturnAddressLocation; // return address location, backup stack pointer + WORD64 InterruptTable; // interrupt table + WORD64 VirtualStackPointer; // virtual trailing arm + WORD64 CSMHandler; // csm handler + WORD64 DeviceMap; // device map pointer + WORD64 StackPointerUpperBound; // stack pointer upper bound + WORD64 StackPointerLowerBound; // stack lower bound + WORD64 PageMaxLocation; // page max location + WORD64 NextCallAddress; // next call address - WORD64 reserved[1]; - }pti; + WORD64 Reserved[1]; + }ControlRegisters; }; }; }PLASM2_CTX, *PPLASM2_CTX; -extern PPLASM2_CTX i; +extern PPLASM2_CTX ECtx; -void cpui_csm_set(WORD64 Handler); -void cpui_csm_msg(BYTE Code, WORD64 AddtData); +void CpuCsmSetHandler(WORD64 Handler); +void CpuCsmSendMessage(BYTE Code, WORD64 AddtData); // addresses are physical -void cpui_inst_jmp(WORD64 Address); -void cpui_inst_cll(WORD64 Address); -void cpui_inst_ret(void); -void cpui_inst_int(BYTE Interrupt); -void cpui_inst_clr(void); +void CpuInstructionJMP(WORD64 Address); +void CpuInstructionCLL(WORD64 Address); +void CpuInstructionRET(void); +void CpuInstructionINT(BYTE Interrupt); +void CpuInstructionCLR(void); // cpu advanced functions @@ -231,8 +244,15 @@ timer, but cput_gettime will always return the time in MS. */ -WORD64 cput_gettime(void); // get current ms since system start -void cput_pwr_sleep(void); -void cput_pwr_shutdown(void); -void cput_pwr_restart(void); -void cput_pwr_awake(void); +WORD64 CpuTimerGetTime(void); // get current ms since system start +void CpuPowerSleep(void); +void CpuPowerShutdown(void); +void CpuPowerRestart(void); +void CpuPowerAwake(void); + +// advanced system timer + +WORD64 CpuTimerGetPreciseTimeNanoseconds(void); +WORD64 CpuTimerGetPreciseTimeMicroseconds(void); +WORD64 CpuTimerGetPreciseTimeMilliseconds(void); +WORD64 CpuTimerGetPreciseTimeSeconds(void); diff --git a/plasm2_emu/cpu/cpu_clock.c b/plasm2_emu/cpu/cpu_clock.c index 3d7f287..e1af3c5 100644 --- a/plasm2_emu/cpu/cpu_clock.c +++ b/plasm2_emu/cpu/cpu_clock.c @@ -1,61 +1,62 @@ -// -// cpu_clock.c -// plasm2_emu -// -// Created by Noah Wooten on 4/21/23. -// -#include "cpu.h" -#include "mmu/mmu.h" -#include "../decoder/decoder.h" -#include "../psin2/psin2.h" -#include "../emu.h" -#include <stdlib.h> -#include <string.h> -#include <time.h> - -void cpu_clock(void) { - - if ( - !i->flags_s.HF // Do not clock if we are halted - && !i->flags_s.NF // Skip this cycle, due to no-execute - ) { - time(&cpuctx->SystemSeconds); - } else { - if (i->flags_s.NF) { - i->flags_s.NF = 0; - int Psin2Id = Psin2iGetInstructionByOpcode(mmu_read1(i->ip)); - BYTE TotalRead = (Psin2iGetTotalSize(Psin2Id) / 8); - i->ip += TotalRead; - } - return; - } - - if (i->flags_s.VF && - i->flags_s.MF && - i->ip >= i->pti.pml - ) { - cpui_csm_msg(CSM_XPAGETOOSMALL, i->ip); - } - - BYTE ThisInstruction = mmu_read1(i->ip++); - if (EmuCtx->DebuggerEnabled) - DecoderGo(ThisInstruction); - - if (ThisInstruction == 0x00) { - if (mmu_read1(i->ip) == 0x00 && - mmu_read1(i->ip) == 0x00 - ) { - // we might be in a zero loop - FILE* Memout = fopen("memout.bin", "wb"); - fwrite(cpuctx->PhysicalMemory, cpuctx->PhysicalMemorySize, - 1, Memout); - fclose(Memout); - printf("[WARN]: CPU appears to be stuck.\n Continue?"); - SDL_Delay(500); - } - } - - Instructions[ThisInstruction](); - - return; -} +// +// cpu_clock.c +// plasm2_emu +// +// Created by Noah Wooten on 4/21/23. +// +#include "cpu.h" +#include "mmu/mmu.h" +#include "../decoder/decoder.h" +#include "../psin2/psin2.h" +#include "../emu.h" +#include <stdlib.h> +#include <string.h> +#include <time.h> + +void CpuClock(void) { + CpuCtx->LastTrackedNanoSecond = CpuTimerGetPreciseTimeNanoseconds(); + // Sadly somewhat messy. - nw 11/27/23 +#ifdef CLOCK_SYSTEM_ACTIVE + if (!(EmuCtx->Flags & EMUFLAG_NOCLOCK)) { + while (CpuCtx->NextTickNanoSecond > CpuCtx->LastTrackedNanoSecond) { +#if defined(__unix__) || defined(__MACH__) +#ifdef HAVE_NANOSLEEP + struct timespec NextClockTime, ThisTime; + NextClockTime.tv_sec = 0; + NextClockTime.tv_nsec = CpuCtx->NextTickNanoSecond - CpuCtx->LastTrackedNanoSecond; + nanosleep(&NextClockTime, &ThisTime); +#endif +#elif _WIN32 + /* @TODO : NtDelayExecution for nanosleep =D + This is a large CPU hole, that there doesn't seem to be a great solution to. + When I'm on my Windows desktop, I'll attempt to divide the NextClockTime nanoseconds + into 100ns chunks that a function such as NtDelayExecution can deal with. + - nw 11/27/23 + */ +#endif + CpuCtx->LastTrackedNanoSecond = CpuTimerGetPreciseTimeNanoseconds(); + } + + CpuCtx->NextTickNanoSecond = CpuCtx->LastTrackedNanoSecond + (NS_PER_S / (CpuCtx->ClocksPerSecond * 3)); + } +#endif + + CpuCtx->SystemTicks++; + + if (ECtx->flags_s.NF) { + ECtx->flags_s.NF = 0; + int Psin2Id = Psin2iGetInstructionByOpcode(MmuRead1(ECtx->ip)); + BYTE TotalToRead = (Psin2iGetTotalSize(Psin2Id) / 8); + ECtx->ip += TotalToRead; + return; + } + + + BYTE ThisInstruction = MmuRead1(ECtx->ip++); + if (EmuCtx->DebuggerEnabled) + DecoderGo(ThisInstruction); + + Instructions[ThisInstruction](); + + return; +} diff --git a/plasm2_emu/cpu/cpu_csm.c b/plasm2_emu/cpu/cpu_csm.c index 00fb278..056577c 100644 --- a/plasm2_emu/cpu/cpu_csm.c +++ b/plasm2_emu/cpu/cpu_csm.c @@ -9,21 +9,21 @@ #include <stdlib.h> #include <string.h> -void cpui_csm_set(WORD64 Handler) { - if (i->security_s.SecurityLevel < 2) - i->pti.csm = Handler; +void CpuCsmSetHandler(WORD64 Handler) { + if (ECtx->Security.SecurityLevel < 2) + ECtx->ControlRegisters.CSMHandler = Handler; else - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; return; } -void cpui_csm_msg(BYTE Code, WORD64 AddtData) { - if (i->security_s.SecurityLevel >= 3) - i->flags_s.XF = 1; +void CpuCsmSendMessage(BYTE Code, WORD64 AddtData) { + if (ECtx->Security.SecurityLevel >= 3) + ECtx->flags_s.XF = 1; for (int c = 0; c < REGCOUNT_SPEC; c++) - mmu_push(i->rs_spec[c]); - mmu_push(Code); - mmu_push(AddtData); - cpui_inst_cll(i->pti.csm); + MmuPush(ECtx->SystemRs[c]); + MmuPush(Code); + MmuPush(AddtData); + CpuInstructionCLL(ECtx->ControlRegisters.CSMHandler); return; } diff --git a/plasm2_emu/cpu/cpu_init.c b/plasm2_emu/cpu/cpu_init.c index 4c6b4dd..1316932 100644 --- a/plasm2_emu/cpu/cpu_init.c +++ b/plasm2_emu/cpu/cpu_init.c @@ -1,46 +1,46 @@ -// -// cpu_init.c -// plasm2_emu -// -// Created by Noah Wooten on 4/21/23. -// -#include "cpu.h" -#include "mmu/mmu.h" -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -cpuctx_t* cpuctx; - -// invalid opcode -void __cpui_invopc(void) { - i->flags_s.HF = 1; - printf("[ERR]: Invalid opcode presented. Continuing...\n"); - return; -} - -#pragma warning(disable: 6011 6387) - -void cpu_init(void) { - cpuctx = malloc(sizeof(cpuctx_t)); - memset(cpuctx, 0, sizeof(cpuctx_t)); - - time(&cpuctx->SystemBoot); - cpuctx->SystemSeconds = cpuctx->SystemBoot; - cpuctx->ClocksPerSecond = BASE_CLOCK; - - for (int i = 0; i < 256; i++) { - if (Instructions[i] == NULL) - Instructions[i] = __cpui_invopc; - } - - mmu_init(); - return; -} - -void cpu_shutdown(void) { - mmu_shutdown(); - - free(cpuctx); - return; -} +// +// cpu_init.c +// plasm2_emu +// +// Created by Noah Wooten on 4/21/23. +// +#include "cpu.h" +#include "mmu/mmu.h" +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +PCPU_CTX CpuCtx; + +// invalid opcode +void _CpuiInvalidOpcode(void) { + ECtx->flags_s.HF = 1; + printf("[ERR]: Invalid opcode presented. Continuing...\n"); + return; +} + +#pragma warning(disable: 6011 6387) + +void CpuInit(void) { + CpuCtx = malloc(sizeof(CPU_CTX)); + memset(CpuCtx, 0, sizeof(CPU_CTX)); + + CpuCtx->SystemTicks = 0; + CpuCtx->ClocksPerSecond = BASE_CLOCK; + CpuCtx->NextTickNanoSecond = 4096; + + for (int i = 0; i < 256; i++) { + if (Instructions[i] == NULL) + Instructions[i] = _CpuiInvalidOpcode; + } + + MmuInit(); + return; +} + +void CpuShutdown(void) { + MmuShutdown(); + + free(CpuCtx); + return; +} diff --git a/plasm2_emu/cpu/cpu_inst.c b/plasm2_emu/cpu/cpu_inst.c index 508e197..9cc347c 100644 --- a/plasm2_emu/cpu/cpu_inst.c +++ b/plasm2_emu/cpu/cpu_inst.c @@ -9,19 +9,19 @@ #include <stdlib.h> #include <string.h> -void cpui_inst_jmp(WORD64 Address) { - i->ip = Address; +void CpuInstructionJMP(WORD64 Address) { + ECtx->ip = Address; return; } -void cpui_inst_cll(WORD64 Address) { +void CpuInstructionCLL(WORD64 Address) { if (!Address) { - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; return; } - i->pti.ral = i->sp + 16; - mmu_push(i->ip); + ECtx->ControlRegisters.ReturnAddressLocation = ECtx->sp + 16; + MmuPush(ECtx->ip); union { WORD64 Raw; @@ -32,23 +32,23 @@ void cpui_inst_cll(WORD64 Address) { WORD16 Reserved; }; }SecurityPacket; - SecurityPacket.CallFlag = i->flags_s.CF; - i->flags_s.HF = 0; - SecurityPacket.Flags = (WORD32)i->flags; - SecurityPacket.SecurityLevel = i->security_s.SecurityLevel; - mmu_push(SecurityPacket.Raw); - i->flags_s.SF = 1; - i->flags_s.CF = 1; + SecurityPacket.CallFlag = ECtx->flags_s.CF; + ECtx->flags_s.HF = 0; + SecurityPacket.Flags = (WORD32)ECtx->Flags; + SecurityPacket.SecurityLevel = ECtx->Security.SecurityLevel; + MmuPush(SecurityPacket.Raw); + ECtx->flags_s.SF = 1; + ECtx->flags_s.CF = 1; - WORD64 PhysAdr = mmu_translate(Address, REASON_READ | REASON_EXEC, + WORD64 PhysAdr = MmuTranslate(Address, REASON_READ | REASON_EXEC, SIZE_WATCHDOG); - i->pti.nca = PhysAdr; + ECtx->ControlRegisters.NextCallAddress = PhysAdr; return; } -void cpui_inst_ret(void) { - if (!i->flags_s.CF) +void CpuInstructionRET(void) { + if (!ECtx->flags_s.CF) return; //i->sp = i->pti.ral; @@ -61,29 +61,29 @@ void cpui_inst_ret(void) { WORD16 Reserved; }; }SecurityPacket = { 0 }; - SecurityPacket.Raw = mmu_pop(); + SecurityPacket.Raw = MmuPop(); - i->ip = mmu_pop(); - i->flags = SecurityPacket.Flags; - i->security_s.SecurityLevel = SecurityPacket.SecurityLevel; - i->flags_s.CF = SecurityPacket.CallFlag; + ECtx->ip = MmuPop(); + ECtx->Flags = SecurityPacket.Flags; + ECtx->Security.SecurityLevel = SecurityPacket.SecurityLevel; + ECtx->flags_s.CF = SecurityPacket.CallFlag; return; } -void cpui_inst_int(BYTE Interrupt) { - WORD64* InterruptTable = (WORD64*)((BYTE*)cpuctx->PhysicalMemory + i->pti.it); // PM usage good (reason: pti.it is a secure register) +void CpuInstructionINT(BYTE Interrupt) { + WORD64* InterruptTable = (WORD64*)((BYTE*)CpuCtx->PhysicalMemory + ECtx->ControlRegisters.InterruptTable); // PM usage good (reason: pti.it is a secure register) WORD64 VirtualAddress = InterruptTable[Interrupt]; BYTE SecurityLevel = (BYTE)((VirtualAddress & 0xFF00000000000000LLU) >> 56LLU); - i->security_s.SecurityLevel = SecurityLevel; - WORD64 PhysicalAddress = mmu_translate(VirtualAddress & 0x00FFFFFFFFFFFFFF, REASON_EXEC | REASON_READ, SIZE_WATCHDOG); + ECtx->Security.SecurityLevel = SecurityLevel; + WORD64 PhysicalAddress = MmuTranslate(VirtualAddress & 0x00FFFFFFFFFFFFFF, REASON_EXEC | REASON_READ, SIZE_WATCHDOG); if (!PhysicalAddress) { - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; return; } - i->pti.ral = i->ip; - mmu_push(i->ip); + ECtx->ControlRegisters.ReturnAddressLocation = ECtx->ip; + MmuPush(ECtx->ip); union { WORD64 Raw; struct { @@ -93,24 +93,24 @@ void cpui_inst_int(BYTE Interrupt) { WORD16 Reserved; }; }SecurityPacket; - SecurityPacket.CallFlag = i->flags_s.CF; - SecurityPacket.Flags = (WORD32)i->flags; - SecurityPacket.SecurityLevel = i->security_s.SecurityLevel; - mmu_push(SecurityPacket.Raw); - i->flags_s.SF = 1; - i->ip = PhysicalAddress; + SecurityPacket.CallFlag = ECtx->flags_s.CF; + SecurityPacket.Flags = (WORD32)ECtx->Flags; + SecurityPacket.SecurityLevel = ECtx->Security.SecurityLevel; + MmuPush(SecurityPacket.Raw); + ECtx->flags_s.SF = 1; + ECtx->ip = PhysicalAddress; return; } -void cpui_inst_clr(void) { - WORD64 StackPointerBackup = i->sp; - i->sp = i->pti.ral; - WORD64 SecurityPacket = mmu_pop(); - WORD64 ReturnAddress = mmu_pop(); - ReturnAddress = i->ip; - mmu_push(ReturnAddress); - mmu_push(SecurityPacket); - i->sp = StackPointerBackup; - if (i->flags_s.CF) - i->ip = i->pti.nca; +void CpuInstructionCLR(void) { + WORD64 StackPointerBackup = ECtx->sp; + ECtx->sp = ECtx->ControlRegisters.ReturnAddressLocation; + WORD64 SecurityPacket = MmuPop(); + WORD64 ReturnAddress = MmuPop(); + ReturnAddress = ECtx->ip; + MmuPush(ReturnAddress); + MmuPush(SecurityPacket); + ECtx->sp = StackPointerBackup; + if (ECtx->flags_s.CF) + ECtx->ip = ECtx->ControlRegisters.NextCallAddress; } diff --git a/plasm2_emu/cpu/mmu/mmu.h b/plasm2_emu/cpu/mmu/mmu.h index 6e592c7..885434c 100644 --- a/plasm2_emu/cpu/mmu/mmu.h +++ b/plasm2_emu/cpu/mmu/mmu.h @@ -1,11 +1,11 @@ +// +// mmu.h +// plasm2_emu +// +// Created by Noah Wooten on 4/21/23. +// #pragma once #include "../../basetypes.h" -/* -mmu.h -plasm2 -plasm2_emu -(c) Noah Wooten 2023, All Rights Reserved -*/ #define REASON_EXEC 0x01 #define REASON_WRTE 0x02 @@ -14,29 +14,29 @@ plasm2_emu #define SIZE_WATCHDOG 0xAFFFFFFFFFFFFFFF // init -void mmu_init(void); -void mmu_shutdown(void); +void MmuInit(void); +void MmuShutdown(void); // i/o -BYTE mmu_read1(WORD64 Address); -WORD64 mmu_read8(WORD64 Address); -WORD64 mmu_readx(WORD64 Address, BYTE BytesToRead); -void mmu_put8(WORD64 Address, WORD64 Value); -void mmu_put4(WORD64 Address, WORD32 Value); -void mmu_put1(WORD64 Address, BYTE Value); +BYTE MmuRead1(WORD64 Address); +WORD64 MmuRead8(WORD64 Address); +WORD64 MmuReadX(WORD64 Address, BYTE BytesToRead); +void MmuPut8(WORD64 Address, WORD64 Value); +void MmuPut4(WORD64 Address, WORD32 Value); +void MmuPut1(WORD64 Address, BYTE Value); // virtual -WORD64 mmu_translate(WORD64 VirtualAddress, BYTE Reason, WORD64 MaxSize); -WORD64 mmu_createpage(WORD64 PhysicalAddress, WORD64 Size, BYTE Permissions); -void mmu_deletepage(WORD64 VirtualAddress); -void mmu_setptstart(WORD64 New); -void mmu_setptend(WORD64 New); +WORD64 MmuTranslate(WORD64 VirtualAddress, BYTE Reason, WORD64 MaxSize); +WORD64 MmuCreatePage(WORD64 PhysicalAddress, WORD64 Size, BYTE Permissions); +void MmuDeletePage(WORD64 VirtualAddress); +void MmuSetPageTableStart(WORD64 New); +void MmuSetPageTableEnd(WORD64 New); // stack -void mmu_push(WORD64 Value); -WORD64 mmu_pop(void); +void MmuPush(WORD64 Value); +WORD64 MmuPop(void); -typedef struct _mmuctx { +typedef struct _MMU_CTX { WORD64 MaxPageCount; WORD64 PageCount; struct { @@ -53,5 +53,5 @@ typedef struct _mmuctx { }; }; }*Pages; -}mmuctx_t; -extern mmuctx_t* mmuctx; +}MMU_CTX, *PMMU_CTX; +extern PMMU_CTX MmuCtx; diff --git a/plasm2_emu/cpu/mmu/mmu_init.c b/plasm2_emu/cpu/mmu/mmu_init.c index bbccb5f..b5669c2 100644 --- a/plasm2_emu/cpu/mmu/mmu_init.c +++ b/plasm2_emu/cpu/mmu/mmu_init.c @@ -1,33 +1,33 @@ -#include "../cpu.h" -#include "mmu.h" -#include <stdlib.h> -#include <string.h> -#include <time.h> -/* -mmu_init.c -plasm2 -plasm2_emu -(c) Noah Wooten 2023, All Rights Reserved -*/ - -mmuctx_t* mmuctx; - -#pragma warning(disable: 6387) - -void mmu_init(void) { - mmuctx = malloc(sizeof(mmuctx_t)); - memset(mmuctx, 0, sizeof(mmuctx_t)); - - cpuctx->PhysicalMemorySize = PHYS_MEMSZ; - cpuctx->PhysicalMemory = malloc(cpuctx->PhysicalMemorySize); // PM usage good (reason: internal use only) - memset(cpuctx->PhysicalMemory, 0, PHYS_MEMSZ); // PM usage good (reason: internal use only) - - i->sp = 0x3A0; - - return; -} - -void mmu_shutdown(void) { - free(cpuctx->PhysicalMemory); // PM usage good (reason: internal use only) - free(mmuctx); -} +// +// mmu_init.c +// plasm2_emu +// +// Created by Noah Wooten on 4/21/23. +// +#include "../cpu.h" +#include "mmu.h" +#include <stdlib.h> +#include <string.h> +#include <time.h> + +PMMU_CTX MmuCtx; + +#pragma warning(disable: 6387) + +void MmuInit(void) { + MmuCtx = malloc(sizeof(MMU_CTX)); + memset(MmuCtx, 0, sizeof(MMU_CTX)); + + CpuCtx->PhysicalMemorySize = PHYS_MEMSZ; + CpuCtx->PhysicalMemory = malloc(CpuCtx->PhysicalMemorySize); // PM usage good (reason: internal use only) + memset(CpuCtx->PhysicalMemory, 0, PHYS_MEMSZ); // PM usage good (reason: internal use only) + + ECtx->sp = 0x3A0; + + return; +} + +void MmuShutdown(void) { + free(CpuCtx->PhysicalMemory); // PM usage good (reason: internal use only) + free(MmuCtx); +} diff --git a/plasm2_emu/cpu/mmu/mmu_io.c b/plasm2_emu/cpu/mmu/mmu_io.c index 7379cdc..976e98d 100644 --- a/plasm2_emu/cpu/mmu/mmu_io.c +++ b/plasm2_emu/cpu/mmu/mmu_io.c @@ -1,59 +1,59 @@ +// +// mmu_io.c +// plasm2_emu +// +// Created by Noah Wooten on 4/21/23. +// #include "../cpu.h" #include "mmu.h" #include <stdlib.h> #include <string.h> -/* -mmu_init.c -plasm2 -plasm2_emu -(c) Noah Wooten 2023, All Rights Reserved -*/ -BYTE mmu_read1(WORD64 Address) { - BYTE* PhysicalMemory = (BYTE*)(cpuctx->PhysicalMemory); // PM usage good (reason: comes from trust) +BYTE MmuRead1(WORD64 Address) { + BYTE* PhysicalMemory = (BYTE*)(CpuCtx->PhysicalMemory); // PM usage good (reason: comes from trust) if (Address > PHYS_MEMSZ) - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; else return PhysicalMemory[Address]; return 0; } -WORD64 mmu_read8(WORD64 Address) { - return mmu_readx(Address, 8); +WORD64 MmuRead8(WORD64 Address) { + return MmuReadX(Address, 8); } -WORD64 mmu_readx(WORD64 Address, BYTE BytesToRead) { +WORD64 MmuReadX(WORD64 Address, BYTE BytesToRead) { union { WORD64 b; BYTE s[8]; }a = { 0 }; for (int i = 0; i < BytesToRead; i++) { - a.s[i] = mmu_read1(Address + i); + a.s[i] = MmuRead1(Address + i); } return a.b; } -void mmu_put8(WORD64 Address, WORD64 Value) { - BYTE* PhysicalBytes = (BYTE*)((BYTE*)cpuctx->PhysicalMemory + Address); // PM usage good (reason: comes from trust) +void MmuPut8(WORD64 Address, WORD64 Value) { + BYTE* PhysicalBytes = (BYTE*)((BYTE*)CpuCtx->PhysicalMemory + Address); // PM usage good (reason: comes from trust) WORD64* PhysicalWords = (WORD64*)PhysicalBytes; if (Address > PHYS_MEMSZ) - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; else PhysicalWords[0] = Value; return; } -void mmu_put1(WORD64 Address, BYTE Value) { - BYTE* PhysicalBytes = (BYTE*)((BYTE*)cpuctx->PhysicalMemory + Address); // PM usage good (reason: comes from trust) +void MmuPut1(WORD64 Address, BYTE Value) { + BYTE* PhysicalBytes = (BYTE*)((BYTE*)CpuCtx->PhysicalMemory + Address); // PM usage good (reason: comes from trust) if (Address > PHYS_MEMSZ) - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; else PhysicalBytes[0] = Value; return; } -void mmu_put4(WORD64 Address, WORD32 Value) { - WORD32* PhysicalBytes = (WORD32*)((BYTE*)cpuctx->PhysicalMemory + Address); // PM usage good (reason: comes from trust) +void MmuPut4(WORD64 Address, WORD32 Value) { + WORD32* PhysicalBytes = (WORD32*)((BYTE*)CpuCtx->PhysicalMemory + Address); // PM usage good (reason: comes from trust) if (Address > PHYS_MEMSZ) - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; else PhysicalBytes[0] = Value; return; diff --git a/plasm2_emu/cpu/mmu/mmu_stack.c b/plasm2_emu/cpu/mmu/mmu_stack.c index 103a0d6..525640c 100644 --- a/plasm2_emu/cpu/mmu/mmu_stack.c +++ b/plasm2_emu/cpu/mmu/mmu_stack.c @@ -12,23 +12,23 @@ #include <time.h> #include <stdio.h> -void mmu_push(WORD64 Value) { - while(InRange(i->sp, i->pti.ral, i->pti.ral + 16)) - i->sp += 1; - WORD64* Stack = (WORD64*)((BYTE*)cpuctx->PhysicalMemory + mmu_translate(i->sp, REASON_WRTE, 8)); // PM usage good: (reason: virtual memory) +void MmuPush(WORD64 Value) { + while(InRange(ECtx->sp, ECtx->ControlRegisters.ReturnAddressLocation, ECtx->ControlRegisters.ReturnAddressLocation + 16)) + ECtx->sp += 1; + WORD64* Stack = (WORD64*)((BYTE*)CpuCtx->PhysicalMemory + MmuTranslate(ECtx->sp, REASON_WRTE, 8)); // PM usage good: (reason: virtual memory) Stack[1] = Value; - if ((i->sp + 8) <= i->pti.spb) - i->sp += 8; + if ((ECtx->sp + 8) <= ECtx->ControlRegisters.StackPointerUpperBound) + ECtx->sp += 8; return; } -WORD64 mmu_pop(void) { - WORD64* Stack = (WORD64*)((BYTE*)cpuctx->PhysicalMemory + mmu_translate(i->sp, REASON_READ, 8)); // PM usage good: (reason: virtual memory) +WORD64 MmuPop(void) { + WORD64* Stack = (WORD64*)((BYTE*)CpuCtx->PhysicalMemory + MmuTranslate(ECtx->sp, REASON_READ, 8)); // PM usage good: (reason: virtual memory) WORD64 Return = Stack[0]; - if ((i->sp - 8) >= i->pti.slb) - i->sp -= 8; + if ((ECtx->sp - 8) >= ECtx->ControlRegisters.StackPointerLowerBound) + ECtx->sp -= 8; return Return; } diff --git a/plasm2_emu/cpu/mmu/mmu_virt.c b/plasm2_emu/cpu/mmu/mmu_virt.c index bb5dec9..5eb8978 100644 --- a/plasm2_emu/cpu/mmu/mmu_virt.c +++ b/plasm2_emu/cpu/mmu/mmu_virt.c @@ -6,32 +6,34 @@ // #include "../cpu.h" #include "mmu.h" +#include "../../emu.h" #include <stdlib.h> #include <string.h> #include <time.h> -WORD64 mmu_translate(WORD64 VirtualAddress, BYTE Reason, WORD64 MaxSize) { - if (i->flags_s.VF) { - for (int p = 0; p < mmuctx->PageCount; p++) { - if (InRange(VirtualAddress, mmuctx->Pages[p].Virtual, mmuctx->Pages[p].Virtual + mmuctx->Pages[p].Size)) { - if ((Reason & REASON_READ) && !mmuctx->Pages[p].Read) - return 0; - if ((Reason & REASON_WRTE) && !mmuctx->Pages[p].Write) - return 0; - if ((Reason & REASON_EXEC) && !mmuctx->Pages[p].Execute) - return 0; - if (MaxSize != SIZE_WATCHDOG) { - if (VirtualAddress + MaxSize >= (mmuctx->Pages[p].Virtual + mmuctx->Pages[p].Size)) - return 0; - } else { - if (VirtualAddress + MaxSize >= (mmuctx->Pages[p].Virtual + mmuctx->Pages[p].Size)) - return 0; - - i->flags_s.MF = 1; - i->pti.pml = VirtualAddress + MaxSize; +WORD64 MmuTranslate(WORD64 VirtualAddress, BYTE Reason, WORD64 MaxSize) { + if (ECtx->flags_s.VF) { + for (int p = 0; p < MmuCtx->PageCount; p++) { + if (InRange(VirtualAddress, MmuCtx->Pages[p].Virtual, MmuCtx->Pages[p].Virtual + MmuCtx->Pages[p].Size)) { + if (!(EmuCtx->Flags & EMUFLAG_NOSECURE)) { + if ((Reason & REASON_READ) && !MmuCtx->Pages[p].Read) + return 0; + if ((Reason & REASON_WRTE) && !MmuCtx->Pages[p].Write) + return 0; + if ((Reason & REASON_EXEC) && !MmuCtx->Pages[p].Execute) + return 0; + if (MaxSize != SIZE_WATCHDOG) { + if (VirtualAddress + MaxSize >= (MmuCtx->Pages[p].Virtual + MmuCtx->Pages[p].Size)) + return 0; + } else { + if (VirtualAddress + MaxSize >= (MmuCtx->Pages[p].Virtual + MmuCtx->Pages[p].Size)) + return 0; + } } + ECtx->flags_s.MF = 1; + ECtx->ControlRegisters.PageMaxLocation = VirtualAddress + MaxSize; - return mmuctx->Pages[p].Physical + (VirtualAddress - mmuctx->Pages[p].Virtual); + return MmuCtx->Pages[p].Physical + (VirtualAddress - MmuCtx->Pages[p].Virtual); } } return 0; diff --git a/plasm2_emu/cpu/mmu/pages/mmup_create.c b/plasm2_emu/cpu/mmu/pages/mmup_create.c index b490acb..7d2e9f3 100644 --- a/plasm2_emu/cpu/mmu/pages/mmup_create.c +++ b/plasm2_emu/cpu/mmu/pages/mmup_create.c @@ -1,26 +1,26 @@ +// +// mmup_create.c +// plasm2_emu +// +// Created by Noah Wooten on 4/21/23. +// #include "../../cpu.h" #include "../mmu.h" -/* -mmup_create.c -plasm2 -plasm2_emu -(c) Noah Wooten 2023, All Rights Reserved -*/ -WORD64 mmu_createpage(WORD64 PhysicalAddress, WORD64 Size, BYTE Permissions) { - if (mmuctx->PageCount + 1 > mmuctx->MaxPageCount) { - cpui_csm_msg(CSM_PTFAILNOTSIZE, mmuctx->PageCount + 1LLU); +WORD64 MmuCreatePage(WORD64 PhysicalAddress, WORD64 Size, BYTE Permissions) { + if (MmuCtx->PageCount + 1 > MmuCtx->MaxPageCount) { + CpuCsmSendMessage(CSM_PTFAILNOTSIZE, MmuCtx->PageCount + 1LLU); return 0; } - mmuctx->Pages[mmuctx->PageCount].Permissions = Permissions; - mmuctx->Pages[mmuctx->PageCount].Size = Size; - mmuctx->Pages[mmuctx->PageCount].Physical = PhysicalAddress; - mmuctx->Pages[mmuctx->PageCount].Virtual = i->pti.vsp; - mmuctx->Pages[mmuctx->PageCount].Active = 1; - i->pti.vsp += Size + 0x4200; + MmuCtx->Pages[MmuCtx->PageCount].Permissions = Permissions; + MmuCtx->Pages[MmuCtx->PageCount].Size = Size; + MmuCtx->Pages[MmuCtx->PageCount].Physical = PhysicalAddress; + MmuCtx->Pages[MmuCtx->PageCount].Virtual = ECtx->ControlRegisters.VirtualStackPointer; + MmuCtx->Pages[MmuCtx->PageCount].Active = 1; + ECtx->ControlRegisters.VirtualStackPointer += Size + 0x4200; - mmuctx->PageCount++; + MmuCtx->PageCount++; - return mmuctx->Pages[mmuctx->PageCount - 1].Virtual; + return MmuCtx->Pages[MmuCtx->PageCount - 1].Virtual; } diff --git a/plasm2_emu/cpu/mmu/pages/mmup_delete.c b/plasm2_emu/cpu/mmu/pages/mmup_delete.c index a04706e..aac59a3 100644 --- a/plasm2_emu/cpu/mmu/pages/mmup_delete.c +++ b/plasm2_emu/cpu/mmu/pages/mmup_delete.c @@ -1,16 +1,16 @@ +// +// mmup_delete.c +// plasm2_emu +// +// Created by Noah Wooten on 4/21/23. +// #include "../../cpu.h" #include "../mmu.h" -/* -mmup_delete.c -plasm2 -plasm2_emu -(c) Noah Wooten 2023, All Rights Reserved -*/ -void mmu_deletepage(WORD64 VirtualAddress) { - for (int c = 0; c < mmuctx->PageCount; c++) { - if (InRange(VirtualAddress, mmuctx->Pages[c].Virtual, mmuctx->Pages[c].Virtual + mmuctx->Pages[c].Size)) { - mmuctx->Pages[c].Active = 0; +void MmuDeletePage(WORD64 VirtualAddress) { + for (int c = 0; c < MmuCtx->PageCount; c++) { + if (InRange(VirtualAddress, MmuCtx->Pages[c].Virtual, MmuCtx->Pages[c].Virtual + MmuCtx->Pages[c].Size)) { + MmuCtx->Pages[c].Active = 0; break; } } diff --git a/plasm2_emu/cpu/mmu/pages/mmup_misc.c b/plasm2_emu/cpu/mmu/pages/mmup_misc.c index fb9a4df..6388345 100644 --- a/plasm2_emu/cpu/mmu/pages/mmup_misc.c +++ b/plasm2_emu/cpu/mmu/pages/mmup_misc.c @@ -1,22 +1,22 @@ +// +// mmup_misc.c +// plasm2_emu +// +// Created by Noah Wooten on 4/21/23. +// #include "../../cpu.h" #include "../mmu.h" -/* -mmup_misc.c -plasm2 -plasm2_emu -(c) Noah Wooten 2023, All Rights Reserved -*/ -void mmu_setptstart(WORD64 New) { - i->pti.ps = New; - mmuctx->Pages = (void*)((BYTE*)cpuctx->PhysicalMemory + i->pti.ps); // PM usage good: (reason: trusted instruction) - mmuctx->MaxPageCount = (i->pti.pe - i->pti.ps) / sizeof(mmuctx->Pages[0]); +void MmuSetPageTableStart(WORD64 New) { + ECtx->ControlRegisters.PageStart = New; + MmuCtx->Pages = (void*)((BYTE*)CpuCtx->PhysicalMemory + ECtx->ControlRegisters.PageStart); // PM usage good: (reason: trusted instruction) + MmuCtx->MaxPageCount = (ECtx->ControlRegisters.PageEnd - ECtx->ControlRegisters.PageStart) / sizeof(MmuCtx->Pages[0]); return; } -void mmu_setptend(WORD64 New) { - i->pti.pe = New; - mmuctx->Pages = (void*)((BYTE*)cpuctx->PhysicalMemory + i->pti.ps); // PM usage good: (reason: trusted instruction) - mmuctx->MaxPageCount = (i->pti.pe - i->pti.ps) / sizeof(mmuctx->Pages[0]); +void MmuSetPageTableEnd(WORD64 New) { + ECtx->ControlRegisters.PageEnd = New; + MmuCtx->Pages = (void*)((BYTE*)CpuCtx->PhysicalMemory + ECtx->ControlRegisters.PageStart); // PM usage good: (reason: trusted instruction) + MmuCtx->MaxPageCount = (ECtx->ControlRegisters.PageEnd - ECtx->ControlRegisters.PageStart) / sizeof(MmuCtx->Pages[0]); return; } diff --git a/plasm2_emu/cpu/ops/cops_arithmetic.c b/plasm2_emu/cpu/ops/cops_arithmetic.c index a86c23c..f9376fd 100644 --- a/plasm2_emu/cpu/ops/cops_arithmetic.c +++ b/plasm2_emu/cpu/ops/cops_arithmetic.c @@ -15,8 +15,8 @@ void ADD(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - i->rs_gprs[Inputs.Destination] += i->rs_gprs[Inputs.Source]; + Inputs.Input = MmuRead1(ECtx->ip++); + ECtx->GPRs[Inputs.Destination] += ECtx->GPRs[Inputs.Source]; return; } @@ -28,8 +28,8 @@ void SUB(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - i->rs_gprs[Inputs.Destination] -= i->rs_gprs[Inputs.Source]; + Inputs.Input = MmuRead1(ECtx->ip++); + ECtx->GPRs[Inputs.Destination] -= ECtx->GPRs[Inputs.Source]; return; } @@ -41,8 +41,8 @@ void MUL(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - i->rs_gprs[Inputs.Destination] *= i->rs_gprs[Inputs.Source]; + Inputs.Input = MmuRead1(ECtx->ip++); + ECtx->GPRs[Inputs.Destination] *= ECtx->GPRs[Inputs.Source]; return; } @@ -54,8 +54,8 @@ void DIV(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - i->rs_gprs[Inputs.Destination] /= i->rs_gprs[Inputs.Source]; + Inputs.Input = MmuRead1(ECtx->ip++); + ECtx->GPRs[Inputs.Destination] /= ECtx->GPRs[Inputs.Source]; return; } @@ -67,8 +67,8 @@ void MOD(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - i->rs_gprs[Inputs.Destination] %= i->rs_gprs[Inputs.Source]; + Inputs.Input = MmuRead1(ECtx->ip++); + ECtx->GPRs[Inputs.Destination] %= ECtx->GPRs[Inputs.Source]; return; } @@ -80,8 +80,8 @@ void INC(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - i->rs_gprs[Inputs.Source]++; + Inputs.Input = MmuRead1(ECtx->ip++); + ECtx->GPRs[Inputs.Source]++; return; } @@ -93,52 +93,52 @@ void DEC(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - i->rs_gprs[Inputs.Source]--; + Inputs.Input = MmuRead1(ECtx->ip++); + ECtx->GPRs[Inputs.Source]--; return; } void ADI(void) { - BYTE Input = mmu_read1(i->ip++) & 0xF; - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; + BYTE Input = MmuRead1(ECtx->ip++) & 0xF; + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; - i->rs_gprs[Input] += Immediate; + ECtx->GPRs[Input] += Immediate; return; } void SBI(void) { - BYTE Input = mmu_read1(i->ip++) & 0xF; - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; + BYTE Input = MmuRead1(ECtx->ip++) & 0xF; + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; - i->rs_gprs[Input] -= Immediate; + ECtx->GPRs[Input] -= Immediate; return; } void MLI(void) { - BYTE Input = mmu_read1(i->ip++) & 0xF; - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; + BYTE Input = MmuRead1(ECtx->ip++) & 0xF; + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; - i->rs_gprs[Input] *= Immediate; + ECtx->GPRs[Input] *= Immediate; return; } void DVI(void) { - BYTE Input = mmu_read1(i->ip++) & 0xF; - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; + BYTE Input = MmuRead1(ECtx->ip++) & 0xF; + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; - i->rs_gprs[Input] /= Immediate; + ECtx->GPRs[Input] /= Immediate; return; } void MDI(void) { - BYTE Input = mmu_read1(i->ip++) & 0xF; - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; + BYTE Input = MmuRead1(ECtx->ip++) & 0xF; + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; - i->rs_gprs[Input] %= Immediate; + ECtx->GPRs[Input] %= Immediate; return; } diff --git a/plasm2_emu/cpu/ops/cops_bitwise.c b/plasm2_emu/cpu/ops/cops_bitwise.c index 12aaf22..775853a 100644 --- a/plasm2_emu/cpu/ops/cops_bitwise.c +++ b/plasm2_emu/cpu/ops/cops_bitwise.c @@ -15,8 +15,8 @@ void AND(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - i->rs_gprs[Inputs.Destination] &= i->rs_gprs[Inputs.Source]; + Inputs.Input = MmuRead1(ECtx->ip++); + ECtx->GPRs[Inputs.Destination] &= ECtx->GPRs[Inputs.Source]; return; } @@ -28,8 +28,8 @@ void BOR(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - i->rs_gprs[Inputs.Destination] |= i->rs_gprs[Inputs.Source]; + Inputs.Input = MmuRead1(ECtx->ip++); + ECtx->GPRs[Inputs.Destination] |= ECtx->GPRs[Inputs.Source]; return; } @@ -41,8 +41,8 @@ void XOR(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - i->rs_gprs[Inputs.Destination] ^= i->rs_gprs[Inputs.Source]; + Inputs.Input = MmuRead1(ECtx->ip++); + ECtx->GPRs[Inputs.Destination] ^= ECtx->GPRs[Inputs.Source]; return; } @@ -54,8 +54,8 @@ void BSL(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - i->rs_gprs[Inputs.Destination] <<= i->rs_gprs[Inputs.Source]; + Inputs.Input = MmuRead1(ECtx->ip++); + ECtx->GPRs[Inputs.Destination] <<= ECtx->GPRs[Inputs.Source]; } void BSR(void) { @@ -66,8 +66,8 @@ void BSR(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - i->rs_gprs[Inputs.Destination] >>= i->rs_gprs[Inputs.Source]; + Inputs.Input = MmuRead1(ECtx->ip++); + ECtx->GPRs[Inputs.Destination] >>= ECtx->GPRs[Inputs.Source]; } void NOT(void) { @@ -78,50 +78,50 @@ void NOT(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - i->rs_gprs[Inputs.Destination] ^= 0xFFFFFFFFFFFFFFFF; + Inputs.Input = MmuRead1(ECtx->ip++); + ECtx->GPRs[Inputs.Destination] ^= 0xFFFFFFFFFFFFFFFF; } void ANI(void) { - BYTE Input = mmu_read1(i->ip++) & 0xF; - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; + BYTE Input = MmuRead1(ECtx->ip++) & 0xF; + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; - i->rs_gprs[Input] &= Immediate; + ECtx->GPRs[Input] &= Immediate; return; } void XOI(void) { - BYTE Input = mmu_read1(i->ip++) & 0xF; - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; + BYTE Input = MmuRead1(ECtx->ip++) & 0xF; + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; - i->rs_gprs[Input] ^= Immediate; + ECtx->GPRs[Input] ^= Immediate; return; } void ORI(void) { - BYTE Input = mmu_read1(i->ip++) & 0xF; - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; + BYTE Input = MmuRead1(ECtx->ip++) & 0xF; + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; - i->rs_gprs[Input] |= Immediate; + ECtx->GPRs[Input] |= Immediate; return; } void BLI(void) { - BYTE Input = mmu_read1(i->ip++) & 0xF; - BYTE Immediate = mmu_read1(i->ip++); + BYTE Input = MmuRead1(ECtx->ip++) & 0xF; + BYTE Immediate = MmuRead1(ECtx->ip++); - i->rs_gprs[Input] <<= Immediate; + ECtx->GPRs[Input] <<= Immediate; return; } void BRI(void) { - BYTE Input = mmu_read1(i->ip++) & 0xF; - BYTE Immediate = mmu_read1(i->ip++); + BYTE Input = MmuRead1(ECtx->ip++) & 0xF; + BYTE Immediate = MmuRead1(ECtx->ip++); - i->rs_gprs[Input] >>= Immediate; + ECtx->GPRs[Input] >>= Immediate; return; } diff --git a/plasm2_emu/cpu/ops/cops_devices.c b/plasm2_emu/cpu/ops/cops_devices.c index 82b5c72..388d51e 100644 --- a/plasm2_emu/cpu/ops/cops_devices.c +++ b/plasm2_emu/cpu/ops/cops_devices.c @@ -9,9 +9,9 @@ #include "../../devices/devices.h" void DSQ(void) { - BYTE Register = mmu_read1(i->ip++) & 0xF; - WORD64 Status = DevicesiStatusQuery((WORD32)i->rs_gprs[Register] & 0xFFFFFFFF); - mmu_push(Status); + BYTE Register = MmuRead1(ECtx->ip++) & 0xF; + WORD64 Status = DevicesiStatusQuery((WORD32)ECtx->GPRs[Register] & 0xFFFFFFFF); + MmuPush(Status); return; } @@ -23,8 +23,8 @@ void DSC(void) { BYTE Device : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - DevicesiSendCommand((WORD32)i->rs_gprs[Inputs.Device], i->rs_gprs[Inputs.Command]); + Inputs.Input = MmuRead1(ECtx->ip++); + DevicesiSendCommand((WORD32)ECtx->GPRs[Inputs.Device], ECtx->GPRs[Inputs.Command]); return; } @@ -36,8 +36,8 @@ void DSD(void) { BYTE Device : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - DevicesiSendData((WORD32)i->rs_gprs[Inputs.Device], i->rs_gprs[Inputs.Data]); + Inputs.Input = MmuRead1(ECtx->ip++); + DevicesiSendData((WORD32)ECtx->GPRs[Inputs.Device], ECtx->GPRs[Inputs.Data]); return; } @@ -49,31 +49,31 @@ void DGD(void) { BYTE Device : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - i->rs_gprs[Inputs.Destination] = DevicesiGetData((WORD32)i->rs_gprs[Inputs.Device]); + Inputs.Input = MmuRead1(ECtx->ip++); + ECtx->GPRs[Inputs.Destination] = DevicesiGetData((WORD32)ECtx->GPRs[Inputs.Device]); return; } void DRS(void) { - WORD64 Device = i->rs_gprs[mmu_read1(i->ip++) & 0xF]; + WORD64 Device = ECtx->GPRs[MmuRead1(ECtx->ip++) & 0xF]; DevicesiReset((WORD32)Device); return; } void DPE(void) { - WORD64 Device = i->rs_gprs[mmu_read1(i->ip++) & 0xF]; + WORD64 Device = ECtx->GPRs[MmuRead1(ECtx->ip++) & 0xF]; DevicesiOn((WORD32)Device); return; } void DPD(void) { - WORD64 Device = i->rs_gprs[mmu_read1(i->ip++) & 0xF]; + WORD64 Device = ECtx->GPRs[MmuRead1(ECtx->ip++) & 0xF]; DevicesiOff((WORD32)Device); return; } void DGC(void) { - BYTE Register = mmu_read1(i->ip++) & 0xF; - i->rs_gprs[Register] = DevicesiDevCount(); + BYTE Register = MmuRead1(ECtx->ip++) & 0xF; + ECtx->GPRs[Register] = DevicesiDevCount(); return; } diff --git a/plasm2_emu/cpu/ops/cops_general.c b/plasm2_emu/cpu/ops/cops_general.c index 28ee82a..a803444 100644 --- a/plasm2_emu/cpu/ops/cops_general.c +++ b/plasm2_emu/cpu/ops/cops_general.c @@ -15,86 +15,86 @@ void MOV(void) { BYTE Dest : 4; }; }Input; - Input.Byte = mmu_read1(i->ip++); - i->rs_gprs[Input.Dest] = i->rs_gprs[Input.Source]; + Input.Byte = MmuRead1(ECtx->ip++); + ECtx->GPRs[Input.Dest] = ECtx->GPRs[Input.Source]; return; } void LDI(void) { - BYTE Destination = mmu_read1(i->ip++) & 0xF; - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; - i->rs_gprs[Destination] = Immediate; + BYTE Destination = MmuRead1(ECtx->ip++) & 0xF; + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; + ECtx->GPRs[Destination] = Immediate; return; } void JMP(void) { - BYTE Address = mmu_read1(i->ip++) & 0xF; - WORD64 PhysicalAddress = mmu_translate(i->rs_gprs[Address], REASON_READ | REASON_EXEC, SIZE_WATCHDOG); + BYTE Address = MmuRead1(ECtx->ip++) & 0xF; + WORD64 PhysicalAddress = MmuTranslate(ECtx->GPRs[Address], REASON_READ | REASON_EXEC, SIZE_WATCHDOG); if (PhysicalAddress) - cpui_inst_jmp(PhysicalAddress); + CpuInstructionJMP(PhysicalAddress); else - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; return; } void NXC(void) { - i->flags_s.NF = 0; + ECtx->flags_s.NF = 0; return; } void NXE(void) { - i->flags_s.NF = !i->flags_s.EF; + ECtx->flags_s.NF = !ECtx->flags_s.EF; return; } void NXZ(void) { - i->flags_s.NF = !i->flags_s.ZF; + ECtx->flags_s.NF = !ECtx->flags_s.ZF; return; } void NXG(void) { - i->flags_s.NF = !i->flags_s.GF; + ECtx->flags_s.NF = !ECtx->flags_s.GF; return; } void NXL(void) { - i->flags_s.NF = !i->flags_s.LF; + ECtx->flags_s.NF = !ECtx->flags_s.LF; return; } void CLL(void) { - BYTE Register = mmu_read1(i->ip++) & 0xF; - WORD64 Address = i->rs_gprs[Register]; - WORD64 PhysicalAddress = mmu_translate(Address, REASON_EXEC | REASON_READ, SIZE_WATCHDOG); + BYTE Register = MmuRead1(ECtx->ip++) & 0xF; + WORD64 Address = ECtx->GPRs[Register]; + WORD64 PhysicalAddress = MmuTranslate(Address, REASON_EXEC | REASON_READ, SIZE_WATCHDOG); if (PhysicalAddress) - cpui_inst_cll(PhysicalAddress); + CpuInstructionCLL(PhysicalAddress); else - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; return; } void RET(void) { - cpui_inst_ret(); + CpuInstructionRET(); } void IMR(void) { - WORD16 ReturnValue = (WORD16)mmu_readx(i->ip, 2); - i->ip += 2; - i->r0 = ReturnValue; + WORD16 ReturnValue = (WORD16)MmuReadX(ECtx->ip, 2); + ECtx->ip += 2; + ECtx->r0 = ReturnValue; RET(); // reuse return; } void SHF(void) { - i->flags_s.HF = 1; + ECtx->flags_s.HF = 1; return; } void CMP(void) { // __CMP = 0x0C, // CMP 0C (R:04,04 ___OP1) (R:04,04 ___OP2) 16 : Compare - i->flags_s.EF = 0; - i->flags_s.GF = 0; - i->flags_s.LF = 0; + ECtx->flags_s.EF = 0; + ECtx->flags_s.GF = 0; + ECtx->flags_s.LF = 0; union { BYTE Byte; @@ -103,59 +103,59 @@ void CMP(void) { // __CMP = 0x0C, // CMP 0C (R:04,04 ___OP1) (R:04,04 ___OP2) 16 BYTE r1 : 4; }; }Input; - Input.Byte = mmu_read1(i->ip++); - - if (i->rs_gprs[Input.r1] > i->rs_gprs[Input.r2]) - i->flags_s.GF = 1; - if (i->rs_gprs[Input.r1] == i->rs_gprs[Input.r2]) - i->flags_s.EF = 1; - if (i->rs_gprs[Input.r1] < i->rs_gprs[Input.r2]) - i->flags_s.LF = 1; + Input.Byte = MmuRead1(ECtx->ip++); + + if (ECtx->GPRs[Input.r1] > ECtx->GPRs[Input.r2]) + ECtx->flags_s.GF = 1; + if (ECtx->GPRs[Input.r1] == ECtx->GPRs[Input.r2]) + ECtx->flags_s.EF = 1; + if (ECtx->GPRs[Input.r1] < ECtx->GPRs[Input.r2]) + ECtx->flags_s.LF = 1; return; } void JMI(void) { - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; - WORD64 Translated = mmu_translate(Immediate, REASON_READ | REASON_EXEC, SIZE_WATCHDOG); + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; + WORD64 Translated = MmuTranslate(Immediate, REASON_READ | REASON_EXEC, SIZE_WATCHDOG); if (Translated) - cpui_inst_jmp(Translated); + CpuInstructionJMP(Translated); else - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; return; } void CLI(void) { - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; - WORD64 Translated = mmu_translate(Immediate, REASON_READ | REASON_EXEC, SIZE_WATCHDOG); + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; + WORD64 Translated = MmuTranslate(Immediate, REASON_READ | REASON_EXEC, SIZE_WATCHDOG); if (Translated) - cpui_inst_cll(Translated); + CpuInstructionCLL(Translated); else - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; return; } void CMI(void) { - i->flags_s.EF = 0; - i->flags_s.GF = 0; - i->flags_s.LF = 0; + ECtx->flags_s.EF = 0; + ECtx->flags_s.GF = 0; + ECtx->flags_s.LF = 0; - BYTE Register = mmu_read1(i->ip++) & 0xF; - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; + BYTE Register = MmuRead1(ECtx->ip++) & 0xF; + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; - if (i->rs_gprs[Register] > Immediate) - i->flags_s.GF = 1; - if (i->rs_gprs[Register] < Immediate) - i->flags_s.LF = 1; - if (i->rs_gprs[Register] == Immediate) - i->flags_s.EF = 1; + if (ECtx->GPRs[Register] > Immediate) + ECtx->flags_s.GF = 1; + if (ECtx->GPRs[Register] < Immediate) + ECtx->flags_s.LF = 1; + if (ECtx->GPRs[Register] == Immediate) + ECtx->flags_s.EF = 1; return; } void CLR(void) { - return cpui_inst_clr(); + return CpuInstructionCLR(); } diff --git a/plasm2_emu/cpu/ops/cops_interrupts.c b/plasm2_emu/cpu/ops/cops_interrupts.c index fd56756..fc3aa8e 100644 --- a/plasm2_emu/cpu/ops/cops_interrupts.c +++ b/plasm2_emu/cpu/ops/cops_interrupts.c @@ -8,8 +8,8 @@ #include "../mmu/mmu.h" void INT(void) { - BYTE Interrupt = i->rs_gprs[mmu_read1(i->ip++) & 0xF] & 0xFF; - cpui_inst_int(Interrupt); + BYTE Interrupt = ECtx->GPRs[MmuRead1(ECtx->ip++) & 0xF] & 0xFF; + CpuInstructionINT(Interrupt); return; } @@ -21,32 +21,32 @@ void HND(void) { BYTE Interrupt : 4; }; }Input; - Input.Byte = mmu_read1(i->ip++); - BYTE SecurityLevel = (BYTE)mmu_pop(); - if (!i->flags_s.TF) { - i->flags_s.XF = 1; + Input.Byte = MmuRead1(ECtx->ip++); + BYTE SecurityLevel = (BYTE)MmuPop(); + if (!ECtx->flags_s.TF) { + ECtx->flags_s.XF = 1; return; } - if (SecurityLevel < i->security_s.SecurityLevel) { - i->flags_s.XF = 1; + if (SecurityLevel < ECtx->Security.SecurityLevel) { + ECtx->flags_s.XF = 1; return; } - WORD64 VirtualAddress = i->rs_gprs[Input.Handler]; + WORD64 VirtualAddress = ECtx->GPRs[Input.Handler]; VirtualAddress &= 0x00FFFFFFFFFFFFFF; VirtualAddress |= ((WORD64)SecurityLevel) << 56; - mmu_put8(i->pti.it + ((WORD64)Input.Interrupt * 8), VirtualAddress); + MmuPut8(ECtx->ControlRegisters.InterruptTable + ((WORD64)Input.Interrupt * 8), VirtualAddress); return; } void IRT(void) { - if (i->sp != i->pti.ral) { - i->flags_s.XF = 1; - if (i->flags_s.AF) { - cpui_csm_msg(CSM_IMPROPERSTACK, i->sp - i->pti.ral); + if (ECtx->sp != ECtx->ControlRegisters.ReturnAddressLocation) { + ECtx->flags_s.XF = 1; + if (ECtx->flags_s.AF) { + CpuCsmSendMessage(CSM_IMPROPERSTACK, ECtx->sp - ECtx->ControlRegisters.ReturnAddressLocation); return; } } - i->sp = i->pti.ral; + ECtx->sp = ECtx->ControlRegisters.ReturnAddressLocation; union { WORD64 Raw; struct { @@ -56,36 +56,36 @@ void IRT(void) { WORD16 Reserved; }; }SecurityPacket; - SecurityPacket.Raw = mmu_pop(); - i->flags = SecurityPacket.Flags; - i->security_s.SecurityLevel = SecurityPacket.SecurityLevel; - i->flags_s.CF = SecurityPacket.CallFlag; - i->ip = mmu_pop(); + SecurityPacket.Raw = MmuPop(); + ECtx->Flags = SecurityPacket.Flags; + ECtx->Security.SecurityLevel = SecurityPacket.SecurityLevel; + ECtx->flags_s.CF = SecurityPacket.CallFlag; + ECtx->ip = MmuPop(); return; } void ENI(void) { - i->flags_s.IF = 1; + ECtx->flags_s.IF = 1; return; } void DSI(void) { - i->flags_s.IF = 0; + ECtx->flags_s.IF = 0; return; } void SMH(void) { - BYTE Register = mmu_read1(i->ip++) & 0xF; - if (i->security_s.SecurityLevel == 0) - cpui_csm_set(i->rs_gprs[Register]); + BYTE Register = MmuRead1(ECtx->ip++) & 0xF; + if (ECtx->Security.SecurityLevel == 0) + CpuCsmSetHandler(ECtx->GPRs[Register]); else - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; return; } void SIT(void) { - WORD64 PhysicalAddress = i->rs_gprs[mmu_read1(i->ip++) & 0xF]; - if (i->security_s.SecurityLevel < 2) - i->pti.it = PhysicalAddress; + WORD64 PhysicalAddress = ECtx->GPRs[MmuRead1(ECtx->ip++) & 0xF]; + if (ECtx->Security.SecurityLevel < 2) + ECtx->ControlRegisters.InterruptTable = PhysicalAddress; return; } diff --git a/plasm2_emu/cpu/ops/cops_memory.c b/plasm2_emu/cpu/ops/cops_memory.c index eff13a2..cd5fc21 100644 --- a/plasm2_emu/cpu/ops/cops_memory.c +++ b/plasm2_emu/cpu/ops/cops_memory.c @@ -15,13 +15,13 @@ void LDW(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - WORD64 VirtualAddress = mmu_translate(i->rs_gprs[Inputs.Address], REASON_READ, 8); + Inputs.Input = MmuRead1(ECtx->ip++); + WORD64 VirtualAddress = MmuTranslate(ECtx->GPRs[Inputs.Address], REASON_READ, 8); if (!VirtualAddress) { - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; return; } - i->rs_gprs[Inputs.Destination] = mmu_read8(VirtualAddress); + ECtx->GPRs[Inputs.Destination] = MmuRead8(VirtualAddress); return; } @@ -33,13 +33,13 @@ void LDB(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - WORD64 VirtualAddress = mmu_translate(i->rs_gprs[Inputs.Address], REASON_READ, 1); + Inputs.Input = MmuRead1(ECtx->ip++); + WORD64 VirtualAddress = MmuTranslate(ECtx->GPRs[Inputs.Address], REASON_READ, 1); if (!VirtualAddress) { - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; return; } - i->rs_gprs[Inputs.Destination] = mmu_read1(VirtualAddress); + ECtx->GPRs[Inputs.Destination] = MmuRead1(VirtualAddress); return; } @@ -51,13 +51,13 @@ void STW(void) { BYTE Address : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - WORD64 VirtualAddress = mmu_translate(i->rs_gprs[Inputs.Address], REASON_WRTE, 8); + Inputs.Input = MmuRead1(ECtx->ip++); + WORD64 VirtualAddress = MmuTranslate(ECtx->GPRs[Inputs.Address], REASON_WRTE, 8); if (!VirtualAddress) { - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; return; } - mmu_put8(VirtualAddress, i->rs_gprs[Inputs.Register]); + MmuPut8(VirtualAddress, ECtx->GPRs[Inputs.Register]); return; } @@ -69,47 +69,47 @@ void STB(void) { BYTE Address : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - WORD64 VirtualAddress = mmu_translate(i->rs_gprs[Inputs.Address], REASON_WRTE, 1); + Inputs.Input = MmuRead1(ECtx->ip++); + WORD64 VirtualAddress = MmuTranslate(ECtx->GPRs[Inputs.Address], REASON_WRTE, 1); if (!VirtualAddress) { - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; return; } - mmu_put1(VirtualAddress, (BYTE)i->rs_gprs[Inputs.Register]); + MmuPut1(VirtualAddress, (BYTE)ECtx->GPRs[Inputs.Register]); return; } void PSH(void) { - BYTE Register = mmu_read1(i->ip++) & 0xF; - mmu_push(i->rs_gprs[Register]); + BYTE Register = MmuRead1(ECtx->ip++) & 0xF; + MmuPush(ECtx->GPRs[Register]); return; } void POP(void) { - BYTE Register = mmu_read1(i->ip++) & 0xF; - i->rs_gprs[Register] = mmu_pop(); + BYTE Register = MmuRead1(ECtx->ip++) & 0xF; + ECtx->GPRs[Register] = MmuPop(); return; } void PSR(void) { for (int c = 0; c < 16; c++) - mmu_push(i->rs_gprs[c]); + MmuPush(ECtx->GPRs[c]); return; } void POR(void) { for (int c = 0; c < 16; c++) - i->rs_gprs[c] = mmu_pop(); + ECtx->GPRs[c] = MmuPop(); return; } void VME(void) { - i->flags_s.VF = 1; + ECtx->flags_s.VF = 1; return; } void VMD(void) { - i->flags_s.VF = 0; + ECtx->flags_s.VF = 0; return; } @@ -121,90 +121,90 @@ void VPC(void) { BYTE PhysicalAddress : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - if (!i->flags_s.VF) + Inputs.Input = MmuRead1(ECtx->ip++); + if (!ECtx->flags_s.VF) return; - if (i->flags_s.AF) { - if (i->security_s.SecurityLevel > 1) + if (ECtx->flags_s.AF) { + if (ECtx->Security.SecurityLevel > 1) return; } - WORD64 VirtualAddr = mmu_createpage(i->rs_gprs[Inputs.PhysicalAddress], i->rs_gprs[Inputs.Size], i->r0 & (REASON_EXEC | REASON_READ | REASON_WRTE)); - mmu_push(VirtualAddr); + WORD64 VirtualAddr = MmuCreatePage(ECtx->GPRs[Inputs.PhysicalAddress], ECtx->GPRs[Inputs.Size], ECtx->r0 & (REASON_EXEC | REASON_READ | REASON_WRTE)); + MmuPush(VirtualAddr); return; } void VPD(void) { - BYTE Register = mmu_read1(i->ip++) & 0xF; - if (!i->flags_s.VF) + BYTE Register = MmuRead1(ECtx->ip++) & 0xF; + if (!ECtx->flags_s.VF) return; - if (i->flags_s.AF) { - if (i->security_s.SecurityLevel > 1) + if (ECtx->flags_s.AF) { + if (ECtx->Security.SecurityLevel > 1) return; } - mmu_deletepage(i->rs_gprs[Register]); + MmuDeletePage(ECtx->GPRs[Register]); return; } void VSI(void) { - i->security_s.SecurityLevel++; + ECtx->Security.SecurityLevel++; return; } void VSD(void) { - if (!i->flags_s.AF) - i->security_s.SecurityLevel--; + if (!ECtx->flags_s.AF) + ECtx->Security.SecurityLevel--; return; } void SPS(void) { - BYTE Register = mmu_read1(i->ip++) & 0xF; - i->sp = i->rs_gprs[Register]; + BYTE Register = MmuRead1(ECtx->ip++) & 0xF; + ECtx->sp = ECtx->GPRs[Register]; return; } void SPG(void) { - BYTE Register = mmu_read1(i->ip++) & 0xF; - i->rs_gprs[Register] = i->sp; + BYTE Register = MmuRead1(ECtx->ip++) & 0xF; + ECtx->GPRs[Register] = ECtx->sp; return; } void VSS(void) { - BYTE Register = mmu_read1(i->ip++) & 0xF; - if (i->flags_s.AF) { - if (i->security_s.SecurityLevel > 1) + BYTE Register = MmuRead1(ECtx->ip++) & 0xF; + if (ECtx->flags_s.AF) { + if (ECtx->Security.SecurityLevel > 1) return; } - mmu_setptstart(i->rs_gprs[Register]); + MmuSetPageTableStart(ECtx->GPRs[Register]); return; } void VES(void) { - BYTE Register = mmu_read1(i->ip++) & 0xF; - if (i->flags_s.AF) { - if (i->security_s.SecurityLevel > 1) + BYTE Register = MmuRead1(ECtx->ip++) & 0xF; + if (ECtx->flags_s.AF) { + if (ECtx->Security.SecurityLevel > 1) return; } - mmu_setptend(i->rs_gprs[Register]); + MmuSetPageTableEnd(ECtx->GPRs[Register]); return; } void LWS(void) { - BYTE Register = mmu_read1(i->ip++) & 0x0F; - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; + BYTE Register = MmuRead1(ECtx->ip++) & 0x0F; + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; - WORD64 Virtual = mmu_translate(Immediate, REASON_READ, 8); - i->rs_gprs[Register] = mmu_read8(Virtual); + WORD64 Virtual = MmuTranslate(Immediate, REASON_READ, 8); + ECtx->GPRs[Register] = MmuRead8(Virtual); return; } void SWS(void) { - BYTE Register = mmu_read1(i->ip++) & 0x0F; - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; + BYTE Register = MmuRead1(ECtx->ip++) & 0x0F; + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; - WORD64 Virtual = mmu_translate(Immediate, REASON_READ, 8); - mmu_put8(Virtual, i->rs_gprs[Register]); + WORD64 Virtual = MmuTranslate(Immediate, REASON_READ, 8); + MmuPut8(Virtual, ECtx->GPRs[Register]); return; } @@ -217,13 +217,13 @@ void LDH(void) { BYTE Destination : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - WORD64 VirtualAddress = mmu_translate(i->rs_gprs[Inputs.Address], REASON_READ, 4); + Inputs.Input = MmuRead1(ECtx->ip++); + WORD64 VirtualAddress = MmuTranslate(ECtx->GPRs[Inputs.Address], REASON_READ, 4); if (!VirtualAddress) { - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; return; } - i->rs_gprs[Inputs.Destination] = mmu_readx(VirtualAddress, 4); + ECtx->GPRs[Inputs.Destination] = MmuReadX(VirtualAddress, 4); return; } @@ -235,25 +235,25 @@ void STH(void) { BYTE Address : 4; }; }Inputs; - Inputs.Input = mmu_read1(i->ip++); - WORD64 VirtualAddress = mmu_translate(i->rs_gprs[Inputs.Address], REASON_WRTE, 8); + Inputs.Input = MmuRead1(ECtx->ip++); + WORD64 VirtualAddress = MmuTranslate(ECtx->GPRs[Inputs.Address], REASON_WRTE, 8); if (!VirtualAddress) { - i->flags_s.XF = 1; + ECtx->flags_s.XF = 1; return; } - mmu_put4(VirtualAddress, (WORD32)i->rs_gprs[Inputs.Register]); + MmuPut4(VirtualAddress, (WORD32)ECtx->GPRs[Inputs.Register]); return; } void PSI(void) { - WORD64 Immediate = mmu_read8(i->ip); - i->ip += 8; - mmu_push(Immediate); + WORD64 Immediate = MmuRead8(ECtx->ip); + ECtx->ip += 8; + MmuPush(Immediate); return; } void PPW(void) { - mmu_pop(); + MmuPop(); return; } diff --git a/plasm2_emu/cpu/xcc/xcc_systemtime.c b/plasm2_emu/cpu/xcc/xcc_systemtime.c new file mode 100644 index 0000000..f6d8a16 --- /dev/null +++ b/plasm2_emu/cpu/xcc/xcc_systemtime.c @@ -0,0 +1,58 @@ +// +// xcc_systemtime.c +// plasm2_emu +// +// Created by Noah Wooten on 11/27/23. +// + +#include "../cpu.h" +#include <time.h> + +#ifdef _WIN32 +#include <windows.h> +#endif + +#ifdef __MACH__ +#include <mach/clock.h> +#include <mach/mach.h> +#endif + +WORD64 CpuTimerGetPreciseTimeNanoseconds(void) { +#ifdef _WIN32 + WORD64 Return; + QueryPerformanceCounter(&Return); + CpuCtx->LastTrackedNanoSecond = Return; + return Return; +#elif __MACH__ + clock_serv_t ClockService; + mach_timespec_t Timer; + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &ClockService); + clock_get_time(ClockService, &Timer); + mach_port_deallocate(mach_task_self(), ClockService); + WORD64 Seconds = Timer.tv_sec; + Seconds *= NS_PER_S; + Seconds += Timer.tv_nsec; + return Seconds; +#elif __unix__ + struct timespec TimeSpec; + clock_gettime(CLOCK_REALTIME, &TimeSpec); + + WORD64 RealNSeconds = NS_PER_S * TimeSpec.tv_secs; + RealNSeconds += TImeSpec.tv_nsecs; + return RealNSeconds; +#else +#errror "No high precision timer implementation!" +#endif +} + +WORD64 CpuTimerGetPreciseTimeMicroseconds(void) { + return CpuTimerGetPreciseTimeNanoseconds() / 1000; +} + +WORD64 CpuTimerGetPreciseTimeMilliseconds(void) { + return CpuTimerGetPreciseTimeMicroseconds() / 1000; +} + +WORD64 CpuTimerGetPreciseTimeSeconds(void) { + return CpuTimerGetPreciseTimeMilliseconds() / 1000; +} diff --git a/plasm2_emu/cpu/xcc/xcc_timer.c b/plasm2_emu/cpu/xcc/xcc_timer.c index 9b8f3ef..b235c44 100644 --- a/plasm2_emu/cpu/xcc/xcc_timer.c +++ b/plasm2_emu/cpu/xcc/xcc_timer.c @@ -6,6 +6,6 @@ // #include "../cpu.h" -WORD64 cput_gettime(void) { - return (cpuctx->SystemSeconds - cpuctx->SystemBoot) & 0x0FFFFFFFFFFFFFFF; +WORD64 CpuTimerGetTime(void) { + return (CpuCtx->SystemTicks - CpuCtx->SystemBoot) & 0x0FFFFFFFFFFFFFFF; } diff --git a/plasm2_emu/decoder/decoder_debug.c b/plasm2_emu/decoder/decoder_debug.c index a41ef3b..9968952 100644 --- a/plasm2_emu/decoder/decoder_debug.c +++ b/plasm2_emu/decoder/decoder_debug.c @@ -8,6 +8,7 @@ #include "../cpu/cpu.h" #include "../cpu/mmu/mmu.h" #include "../psin2/psin2.h" +#include "../emu.h" #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -15,19 +16,22 @@ #pragma warning(disable: 6011 6387) // no it couldnt BYTE DecoderRead1(void) { - BYTE Return = mmu_read1(DcCtx->SpeculativePointer); + BYTE Return = MmuRead1(DcCtx->SpeculativePointer); DcCtx->SpeculativePointer += 1; return Return; } WORD64 DecoderReadX(BYTE HowMuch) { - WORD64 Returns = mmu_readx(DcCtx->SpeculativePointer, HowMuch); + WORD64 Returns = MmuReadX(DcCtx->SpeculativePointer, HowMuch); DcCtx->SpeculativePointer += HowMuch; return Returns; } void DecoderGo(BYTE Instruction) { - int Psin2Id = Psin2iGetInstructionByOpcode(Instruction); + if (EmuCtx->Flags & EMUFLAG_NODEBUG) + return; + + int Psin2Id = Psin2iGetInstructionByOpcode(Instruction); /* if debugger is disabled, the cpu does no opcode checking by default (yet) as of 7/21/23. this may be implemented in the future, but for now there will @@ -40,7 +44,7 @@ void DecoderGo(BYTE Instruction) { but not crash the emulator. */ - DcCtx->SpeculativePointer = i->ip; + DcCtx->SpeculativePointer = ECtx->ip; _bool TwoArgsOneByte = TRUE; _bool IsOperandRegister[2] = { FALSE, FALSE }; @@ -116,7 +120,7 @@ void DecoderGo(BYTE Instruction) { CPart[0] = '\0'; if (Written) strcat(CPart, ", "); - sprintf(CPart, "%sr%llu=0x%016llX", CPart, OperandValues[c], i->rs_gprs[OperandValues[c]]); + sprintf(CPart, "%sr%llu=0x%016llX", CPart, OperandValues[c], ECtx->GPRs[OperandValues[c]]); strcat(Ctx, CPart); Written++; @@ -126,7 +130,7 @@ void DecoderGo(BYTE Instruction) { if (Written) strcat(Ctx, ", "); - sprintf(CPart, "ip=0x%llX, sp=0x%llX", i->ip, i->sp); + sprintf(CPart, "ip=0x%llX, sp=0x%llX", ECtx->ip, ECtx->sp); strcat(Ctx, CPart); DecoderPrint(Ctx); diff --git a/plasm2_emu/decoder/decoder_print.c b/plasm2_emu/decoder/decoder_print.c index 6b9f069..f8daafd 100644 --- a/plasm2_emu/decoder/decoder_print.c +++ b/plasm2_emu/decoder/decoder_print.c @@ -12,6 +12,9 @@ #include <string.h> void DecoderPrint(const char* Format) { + if (EmuCtx->Flags & EMUFLAG_NOPRINT) + return; + printf("[DBG]: "); int i = 0; diff --git a/plasm2_emu/devices/devices_init.c b/plasm2_emu/devices/devices_init.c index 264a42e..a548dbb 100644 --- a/plasm2_emu/devices/devices_init.c +++ b/plasm2_emu/devices/devices_init.c @@ -25,7 +25,7 @@ void DevicesInit(void) { memset(DevicesCtx, 0, sizeof(DEVICES_CTX)); DevicesCtx->DeviceCount = 0; - DevicesCtx->Devices = (void*)cpuctx->PhysicalMemory; // PM usage good: (reason: internal usage only) + DevicesCtx->Devices = (void*)CpuCtx->PhysicalMemory; // PM usage good: (reason: internal usage only) ShouldStartVideo = TRUE; while (!VideoStarted) @@ -34,8 +34,14 @@ void DevicesInit(void) { KbInit(); FdiskInit(); } + +extern _bool VideoStopped; +extern _bool ShouldStopVideo; + void DevicesShutdown(void) { KbShutdown(); - VideoShutdown(); + ShouldStopVideo = TRUE; + while (!VideoStopped) + SDL_Delay(10); return; } diff --git a/plasm2_emu/devices/fdisk/fdisk_init.c b/plasm2_emu/devices/fdisk/fdisk_init.c index 8a27368..6761c92 100644 --- a/plasm2_emu/devices/fdisk/fdisk_init.c +++ b/plasm2_emu/devices/fdisk/fdisk_init.c @@ -93,7 +93,7 @@ void FdiskClock(void) { int OldestPair = 0; WORD64 OldestChunk = 0xFFFFFFFFFFFFFFFF; for (int i = 0; i < FdiskCtx->DriveCount; i++) { - if (FdiskCtx->Drives[i].NextChunkScan > cput_gettime()) + if (FdiskCtx->Drives[i].NextChunkScan > CpuTimerGetTime()) continue; for (int c = 0; c < 4; c++) { if (FdiskCtx->Drives[i].LoadedChunkCpuTick[c] < OldestChunk) { diff --git a/plasm2_emu/devices/fdisk/fdisk_native.c b/plasm2_emu/devices/fdisk/fdisk_native.c index 652f7ad..2c23e96 100644 --- a/plasm2_emu/devices/fdisk/fdisk_native.c +++ b/plasm2_emu/devices/fdisk/fdisk_native.c @@ -80,7 +80,7 @@ WORD64 FdiskiDriveRead(int DriveId) { if (InRange(FdiskCtx->Drives[DriveId].CurrentFilePointer, FdiskCtx->Drives[DriveId].LoadedChunkBaseAddr[i], FdiskCtx->Drives[DriveId].LoadedChunkBaseAddr[i] + FdiskCtx->Drives[DriveId].LoadedChunkSize[i])) { BYTE* AsBytes = ((BYTE*)FdiskCtx->Drives[DriveId].CurrentLoadedChunks[i] + (FdiskCtx->Drives[DriveId].CurrentFilePointer - FdiskCtx->Drives[DriveId].LoadedChunkBaseAddr[i])); WORD64* AsU64 = (WORD64*)AsBytes; - FdiskCtx->Drives[DriveId].LoadedChunkCpuTick[i] = cput_gettime(); + FdiskCtx->Drives[DriveId].LoadedChunkCpuTick[i] = CpuTimerGetTime(); if (!FdiskCtx->Drives[DriveId].SkipInc && !FdiskCtx->Drives[DriveId].DisableInc) { FdiskCtx->Drives[DriveId].CurrentFilePointer += 0x8; } @@ -97,7 +97,7 @@ WORD64 FdiskiDriveRead(int DriveId) { free(FdiskCtx->Drives[DriveId].CurrentLoadedChunks[NewChunkId]); FdiskCtx->Drives[DriveId].LoadedChunkBaseAddr[NewChunkId] = FdiskCtx->Drives[DriveId].CurrentFilePointer - (FDISK_CACHE_CHUNK / 2 ); FdiskCtx->Drives[DriveId].LoadedChunkSize[NewChunkId] = FDISK_CACHE_CHUNK; - FdiskCtx->Drives[DriveId].LoadedChunkCpuTick[NewChunkId] = cput_gettime(); + FdiskCtx->Drives[DriveId].LoadedChunkCpuTick[NewChunkId] = CpuTimerGetTime(); FdiskCtx->Drives[DriveId].CurrentLoadedChunks[NewChunkId] = malloc(FDISK_CACHE_CHUNK); pfseek(FdiskCtx->Drives[DriveId].DrivePhysicalPointer, FdiskCtx->Drives[DriveId].LoadedChunkBaseAddr[NewChunkId], SEEK_SET); fread(FdiskCtx->Drives[DriveId].CurrentLoadedChunks[NewChunkId], FDISK_CACHE_CHUNK, 1, FdiskCtx->Drives[DriveId].DrivePhysicalPointer); @@ -125,7 +125,7 @@ void FdiskiDriveWrite(int DriveId, WORD64 Data) { if (InRange(FdiskCtx->Drives[DriveId].CurrentFilePointer, FdiskCtx->Drives[DriveId].LoadedChunkBaseAddr[i], FdiskCtx->Drives[DriveId].LoadedChunkBaseAddr[i] + FdiskCtx->Drives[DriveId].LoadedChunkSize[i])) { BYTE* AsBytes = ((BYTE*)FdiskCtx->Drives[DriveId].CurrentLoadedChunks[i] + (FdiskCtx->Drives[DriveId].CurrentFilePointer - FdiskCtx->Drives[DriveId].LoadedChunkBaseAddr[i])); WORD64* AsU64 = (WORD64*)AsBytes; - FdiskCtx->Drives[DriveId].LoadedChunkCpuTick[i] = cput_gettime(); + FdiskCtx->Drives[DriveId].LoadedChunkCpuTick[i] = CpuTimerGetTime(); AsU64[0] = Data; if (!FdiskCtx->Drives[DriveId].SkipInc && !FdiskCtx->Drives[DriveId].DisableInc) { FdiskCtx->Drives[DriveId].CurrentFilePointer += 0x8; @@ -141,7 +141,7 @@ void FdiskiDriveWrite(int DriveId, WORD64 Data) { free(FdiskCtx->Drives[DriveId].CurrentLoadedChunks[NewChunkId]); FdiskCtx->Drives[DriveId].LoadedChunkBaseAddr[NewChunkId] = FdiskCtx->Drives[DriveId].CurrentFilePointer - (FDISK_CACHE_CHUNK / 2); FdiskCtx->Drives[DriveId].LoadedChunkSize[NewChunkId] = FDISK_CACHE_CHUNK; - FdiskCtx->Drives[DriveId].LoadedChunkCpuTick[NewChunkId] = cput_gettime(); + FdiskCtx->Drives[DriveId].LoadedChunkCpuTick[NewChunkId] = CpuTimerGetTime(); FdiskCtx->Drives[DriveId].CurrentLoadedChunks[NewChunkId] = malloc(FDISK_CACHE_CHUNK); pfseek(FdiskCtx->Drives[DriveId].DrivePhysicalPointer, FdiskCtx->Drives[DriveId].LoadedChunkBaseAddr[NewChunkId], SEEK_SET); fread(FdiskCtx->Drives[DriveId].CurrentLoadedChunks[NewChunkId], FDISK_CACHE_CHUNK, 1, FdiskCtx->Drives[DriveId].DrivePhysicalPointer); @@ -176,8 +176,8 @@ void FdiskiGetDriveVendorString(int DriveId, WORD64 Pointer) { if (!FdiskCtx->Drives[DriveId].IsDriveAwake) return; - WORD64 RPointer = mmu_translate(Pointer, REASON_WRTE, 16); - BYTE* TPointer = ((BYTE*)cpuctx->PhysicalMemory + RPointer); + WORD64 RPointer = MmuTranslate(Pointer, REASON_WRTE, 16); + BYTE* TPointer = ((BYTE*)CpuCtx->PhysicalMemory + RPointer); memcpy(TPointer, FdiskCtx->Drives[DriveId].DeviceVendor, 16); return; @@ -213,7 +213,7 @@ void FdiskiFarSeek(int DriveId, WORD64 SpecPos) { free(FdiskCtx->Drives[DriveId].CurrentLoadedChunks[NewChunkId]); FdiskCtx->Drives[DriveId].LoadedChunkBaseAddr[NewChunkId] = FdiskCtx->Drives[DriveId].SpeculativeSeek - (FDISK_CACHE_CHUNK / 2); FdiskCtx->Drives[DriveId].LoadedChunkSize[NewChunkId] = FDISK_CACHE_CHUNK; - FdiskCtx->Drives[DriveId].LoadedChunkCpuTick[NewChunkId] = cput_gettime(); + FdiskCtx->Drives[DriveId].LoadedChunkCpuTick[NewChunkId] = CpuTimerGetTime(); FdiskCtx->Drives[DriveId].CurrentLoadedChunks[NewChunkId] = malloc(FDISK_CACHE_CHUNK); pfseek(FdiskCtx->Drives[DriveId].DrivePhysicalPointer, FdiskCtx->Drives[DriveId].LoadedChunkBaseAddr[NewChunkId], SEEK_SET); fread(FdiskCtx->Drives[DriveId].CurrentLoadedChunks[NewChunkId], FDISK_CACHE_CHUNK, 1, FdiskCtx->Drives[DriveId].DrivePhysicalPointer); @@ -265,7 +265,7 @@ WORD64 FdiskiDriveReadStack(int DriveId) { return 0; WORD64 CFPBackup = FdiskCtx->Drives[DriveId].CurrentFilePointer; - FdiskCtx->Drives[DriveId].CurrentFilePointer = mmu_pop(); + FdiskCtx->Drives[DriveId].CurrentFilePointer = MmuPop(); WORD64 Return = FdiskiDriveRead(DriveId); FdiskCtx->Drives[DriveId].CurrentFilePointer = CFPBackup; return Return; @@ -278,7 +278,7 @@ void FdiskiDriveWriteStack(int DriveId, WORD64 Data) { return; WORD64 CFPBackup = FdiskCtx->Drives[DriveId].CurrentFilePointer; - FdiskCtx->Drives[DriveId].CurrentFilePointer = mmu_pop(); + FdiskCtx->Drives[DriveId].CurrentFilePointer = MmuPop(); FdiskiDriveWrite(DriveId, Data); FdiskCtx->Drives[DriveId].CurrentFilePointer = CFPBackup; diff --git a/plasm2_emu/devices/kb/kb_init.c b/plasm2_emu/devices/kb/kb_init.c index 1d8e8c4..401351f 100644 --- a/plasm2_emu/devices/kb/kb_init.c +++ b/plasm2_emu/devices/kb/kb_init.c @@ -18,13 +18,13 @@ PKB_CTX KbCtx; void KbClock(void) { if (KbCtx->NotifyUp) { - mmu_push(KbCtx->NotifyUp); - cpui_inst_int(KbCtx->KeyUp); + MmuPush(KbCtx->NotifyUp); + CpuInstructionINT(KbCtx->KeyUp); KbCtx->NotifyUp = 0; } if (KbCtx->NotifyDown) { - mmu_push(KbCtx->NotifyDown); - cpui_inst_int(KbCtx->KeyDown); + MmuPush(KbCtx->NotifyDown); + CpuInstructionINT(KbCtx->KeyDown); KbCtx->NotifyDown = 0; } diff --git a/plasm2_emu/devices/kb/kb_native.c b/plasm2_emu/devices/kb/kb_native.c index 1bd38ac..2fffc68 100644 --- a/plasm2_emu/devices/kb/kb_native.c +++ b/plasm2_emu/devices/kb/kb_native.c @@ -21,7 +21,7 @@ void KbiSetKeyUpInterrupt(WORD64 Interrupt) { } WORD64 KbiGetKeyMapPointer(void) { - return mmu_translate(0x23F0, REASON_READ, 256); + return MmuTranslate(0x23F0, REASON_READ, 256); } void KbiiMarkKeyState(BYTE Keycode, BYTE Status) { diff --git a/plasm2_emu/devices/sdbg/sdbg_init.c b/plasm2_emu/devices/sdbg/sdbg_init.c index 2f244be..84e0902 100644 --- a/plasm2_emu/devices/sdbg/sdbg_init.c +++ b/plasm2_emu/devices/sdbg/sdbg_init.c @@ -31,7 +31,7 @@ void SdbgShutdown(void) { } void SdbgClock(void) { - if (sdbgctx->LastSend > cput_gettime()) { + if (sdbgctx->LastSend > CpuTimerGetTime()) { if (sdbgctx->ReadyOut) { printf("%s", sdbgctx->CollectionBufferOut); sdbgctx->ReadyOut = 0; diff --git a/plasm2_emu/devices/sdbg/sdbg_natives.c b/plasm2_emu/devices/sdbg/sdbg_natives.c index 13545f1..01c3195 100644 --- a/plasm2_emu/devices/sdbg/sdbg_natives.c +++ b/plasm2_emu/devices/sdbg/sdbg_natives.c @@ -12,8 +12,8 @@ void SdbgSend(void) { memset(sdbgctx->CollectionBufferOut, 0, 256); - BYTE* RealPointer = (BYTE*)cpuctx->PhysicalMemory + mmu_translate(sdbgctx->VirtualPointer, REASON_READ, sdbgctx->VirtualSize); - if (RealPointer == cpuctx->PhysicalMemory) { // failed + BYTE* RealPointer = (BYTE*)CpuCtx->PhysicalMemory + MmuTranslate(sdbgctx->VirtualPointer, REASON_READ, sdbgctx->VirtualSize); + if (RealPointer == CpuCtx->PhysicalMemory) { // failed sdbgctx->Active = 1; return; } diff --git a/plasm2_emu/devices/video/video_handlers.c b/plasm2_emu/devices/video/video_handlers.c index 2bcb7b9..115f79e 100644 --- a/plasm2_emu/devices/video/video_handlers.c +++ b/plasm2_emu/devices/video/video_handlers.c @@ -61,19 +61,19 @@ WORD64 VideoSendData(WORD32 Device, WORD64 Data) { VideoiSetTextBuffer(Data); break; case 0x02: - Color = (WORD32)mmu_pop(); + Color = (WORD32)MmuPop(); VideoiDrawLine((WORD16)GET16_HIHI(Data), (WORD16)GET16_HILO(Data), (WORD16)GET16_LOHI(Data), (WORD16)GET16_LOLO(Data), Color); break; case 0x03: - Color = (WORD32)mmu_pop(); + Color = (WORD32)MmuPop(); VideoiDrawRect((WORD16)GET16_HIHI(Data), (WORD16)GET16_HILO(Data), (WORD16)GET16_LOHI(Data), (WORD16)GET16_LOLO(Data), Color); break; case 0x04: - Color = (WORD32)mmu_pop(); + Color = (WORD32)MmuPop(); VideoiDrawFill((WORD16)GET16_HIHI(Data), (WORD16)GET16_HILO(Data), (WORD16)GET16_LOHI(Data), (WORD16)GET16_LOLO(Data), Color); break; case 0x05: - Ptr = mmu_pop(); // aka pointer here + Ptr = MmuPop(); // aka pointer here VideoiCopyRect((WORD16)GET16_HIHI(Data), (WORD16)GET16_HILO(Data), (WORD16)GET16_LOHI(Data), (WORD16)GET16_LOLO(Data), Ptr); break; case 0x06: // wip @@ -94,12 +94,12 @@ WORD64 VideoReset(WORD32 Device, WORD64 NullArg) { } WORD64 VideoOff(WORD32 Device, WORD64 NullArg) { - if (i->security_s.SecurityLevel < 2) + if (ECtx->Security.SecurityLevel < 2) VideoShutdown(); return 0; } WORD64 VideoOn(WORD32 Device, WORD64 NullArg) { - if (i->security_s.SecurityLevel < 2) + if (ECtx->Security.SecurityLevel < 2) VideoInit(); return 0; } diff --git a/plasm2_emu/devices/video/video_init.c b/plasm2_emu/devices/video/video_init.c index de6a6a5..0b91f07 100644 --- a/plasm2_emu/devices/video/video_init.c +++ b/plasm2_emu/devices/video/video_init.c @@ -18,6 +18,8 @@ BYTE PauseDrawing; PVIDEO_CTX VideoCtx; SDL_Thread* LoopThread; _bool VideoStarted; +extern _bool ShouldStopVideo; +extern _bool VideoStopped; #pragma warning(disable: 6011 6387) @@ -52,6 +54,11 @@ void VideoLoop(void) { VideoStarted = 1; while (!Quit) { + if (ShouldStopVideo) { + VideoShutdown(); + VideoStopped = TRUE; + } + while (SDL_PollEvent(&Event)) { if (PauseDrawing) break; diff --git a/plasm2_emu/devices/video/video_native.c b/plasm2_emu/devices/video/video_native.c index 671ae17..89a89fe 100644 --- a/plasm2_emu/devices/video/video_native.c +++ b/plasm2_emu/devices/video/video_native.c @@ -24,48 +24,48 @@ extern BYTE PauseDrawing; #define A(x) (Uint8)((WORD32)(x & 0x000000FF) >> 0) WORD64 VideoiGetTextBuffer(void) { - return 0; // deprecated + return 0; // deprecated } void VideoiSetTextBuffer(WORD64 NewOffset) { - return; // deprecated + return; // deprecated } void VideoiDrawLine(WORD16 x1, WORD16 y1, WORD16 x2, WORD16 y2, WORD32 color) { - PauseDrawing = 1; - SDL_SetRenderDrawColor(Renderer, R(color), G(color), B(color), A(color)); - SDL_RenderDrawLine(Renderer, x1, y1, x2, y2); - PauseDrawing = 0; + PauseDrawing = 1; + SDL_SetRenderDrawColor(Renderer, R(color), G(color), B(color), A(color)); + SDL_RenderDrawLine(Renderer, x1, y1, x2, y2); + PauseDrawing = 0; - return; + return; } void VideoiDrawRect(WORD16 x, WORD16 y, WORD16 w, WORD16 h, WORD32 color) { - PauseDrawing = 1; - SDL_SetRenderDrawColor(Renderer, R(color), G(color), B(color), A(color)); - SDL_Rect DestRect; - DestRect.x = x; - DestRect.y = y; - DestRect.h = h; - DestRect.w = w; - SDL_RenderDrawRect(Renderer, &DestRect); - PauseDrawing = 0; - - return; + PauseDrawing = 1; + SDL_SetRenderDrawColor(Renderer, R(color), G(color), B(color), A(color)); + SDL_Rect DestRect; + DestRect.x = x; + DestRect.y = y; + DestRect.h = h; + DestRect.w = w; + SDL_RenderDrawRect(Renderer, &DestRect); + PauseDrawing = 0; + + return; } void VideoiDrawFill(WORD16 x, WORD16 y, WORD16 w, WORD16 h, WORD32 color) { - PauseDrawing = 1; - SDL_SetRenderDrawColor(Renderer, R(color), G(color), B(color), A(color)); - SDL_Rect DestRect; - DestRect.x = x; - DestRect.y = y; - DestRect.h = h; - DestRect.w = w; - SDL_RenderFillRect(Renderer, &DestRect); - PauseDrawing = 0; - - return; + PauseDrawing = 1; + SDL_SetRenderDrawColor(Renderer, R(color), G(color), B(color), A(color)); + SDL_Rect DestRect; + DestRect.x = x; + DestRect.y = y; + DestRect.h = h; + DestRect.w = w; + SDL_RenderFillRect(Renderer, &DestRect); + PauseDrawing = 0; + + return; } #define RMASK 0x000000FF @@ -74,36 +74,36 @@ void VideoiDrawFill(WORD16 x, WORD16 y, WORD16 w, WORD16 h, WORD32 color) { #define AMASK 0xFF000000 void VideoiCopyRect(WORD16 x, WORD16 y, WORD16 w, WORD16 h, WORD64 ptr) { - PauseDrawing = 1; - WORD64 VAdr = mmu_translate(ptr, REASON_READ, w * h * 4); - if (!VAdr) { - cpui_csm_msg(CSM_PAGETOOSMALL, ptr); - } + PauseDrawing = 1; + WORD64 VAdr = MmuTranslate(ptr, REASON_READ, w * h * 4); + if (!VAdr) { + CpuCsmSendMessage(CSM_PAGETOOSMALL, ptr); + } #ifdef _WIN32 - SDL_Surface* Surface = SDL_CreateRGBSurfaceFrom((cpuctx->PhysicalMemory + VAdr), w, h, 32 * w, 32, RMASK, GMASK, BMASK, AMASK); + SDL_Surface* Surface = SDL_CreateRGBSurfaceFrom((CpuCtx->PhysicalMemory + VAdr), w, h, 32 * w, 32, RMASK, GMASK, BMASK, AMASK); #else - SDL_Surface* Surface = SDL_CreateRGBSurfaceFrom((cpuctx->PhysicalMemory + VAdr), w, h, 32, 32, RMASK, GMASK, BMASK, AMASK); + SDL_Surface* Surface = SDL_CreateRGBSurfaceFrom((CpuCtx->PhysicalMemory + VAdr), w, h, 32, 32, RMASK, GMASK, BMASK, AMASK); #endif SDL_Texture* TargetTexture = SDL_CreateTextureFromSurface(Renderer, Surface); - SDL_FreeSurface(Surface); - SDL_Rect DestRect = { x, y, w, h }; - SDL_RenderCopy(Renderer, TargetTexture, NULL, &DestRect); - SDL_DestroyTexture(TargetTexture); - PauseDrawing = 0; + SDL_FreeSurface(Surface); + SDL_Rect DestRect = { x, y, w, h }; + SDL_RenderCopy(Renderer, TargetTexture, NULL, &DestRect); + SDL_DestroyTexture(TargetTexture); + PauseDrawing = 0; - return; + return; } WORD64 VideoiGetWidthHeight(void) { - return (VideoCtx->w << 16) | (VideoCtx->h); + return (VideoCtx->w << 16) | (VideoCtx->h); } void VideoiSuggestSize(WORD16 w, WORD16 h) { - if (!VideoCtx->SizeLocked) { - VideoCtx->w = w; - VideoCtx->h = h; - SDL_SetWindowSize(Window, w, h); - } + if (!VideoCtx->SizeLocked) { + VideoCtx->w = w; + VideoCtx->h = h; + SDL_SetWindowSize(Window, w, h); + } - return; + return; } diff --git a/plasm2_emu/emu.h b/plasm2_emu/emu.h index b80c904..95ceb54 100644 --- a/plasm2_emu/emu.h +++ b/plasm2_emu/emu.h @@ -15,6 +15,11 @@ there may be problems that the CPU cannot handle. */ +#define EMUFLAG_NOPRINT 0x0001 +#define EMUFLAG_NODEBUG 0x0002 +#define EMUFLAG_NOCLOCK 0x0004 +#define EMUFLAG_NOSECURE 0x0008 + void EmuInit(void); void EmuShutdown(void); @@ -23,8 +28,6 @@ void EmuRegisterFatal(const char* Reason); _bool EmuCheckClock(char* ThePtr); // query if its time to stop -typedef struct _EMU_PRINTF_EVENT *PEMU_PRINTF_EVENT; - typedef struct _EMU_CTX { _bool RequiresHalt; char LastReason[256]; @@ -32,6 +35,8 @@ typedef struct _EMU_CTX { _bool DebuggerEnabled; void* VideoMutex; + + WORD64 Flags; }EMU_CTX, *PEMU_CTX; void* EmutexCreate(void); diff --git a/plasm2_emu/main.c b/plasm2_emu/main.c index c6de13c..a56a04a 100644 --- a/plasm2_emu/main.c +++ b/plasm2_emu/main.c @@ -34,32 +34,35 @@ Starting physical memory map: int __t_argc; char** __t_argv; -PPLASM2_CTX i; +PPLASM2_CTX ECtx; -typedef struct _appargs { +typedef struct _APP_ARGS { char** argv; int argc; -}appargs_t; -int __nonvideo_main(appargs_t*); +}APP_ARGS, *PAPP_ARGS; +int PlasmEmuNonVideoMain(PAPP_ARGS); #include <SDL.h> _bool ShouldStartVideo; +_bool ShouldStopVideo; +_bool VideoStopped; int main(int argc, char** argv) { ShouldStartVideo = FALSE; + ShouldStopVideo = FALSE; - appargs_t* Args = malloc(sizeof(appargs_t)); + PAPP_ARGS Args = malloc(sizeof(APP_ARGS)); Args->argc = argc; Args->argv = argv; - SDL_CreateThread(__nonvideo_main, "Plasm2MainThread", Args); + SDL_CreateThread(PlasmEmuNonVideoMain, "Plasm2MainThread", Args); while (!ShouldStartVideo) SDL_Delay(100); VideoInit(); } -int __nonvideo_main(appargs_t* Args) { +int PlasmEmuNonVideoMain(PAPP_ARGS Args) { int argc = Args->argc; char** argv = Args->argv; @@ -87,6 +90,10 @@ int __nonvideo_main(appargs_t* Args) { printf("Misc Switches: (General Function Only)\n\n"); printf("%s -d | --debug : Enables disassembler / debugger mode.\n", argv[0]); printf("%s -h | --help : Shows this screen.\n", argv[0]); + printf("%s --no-debug : Prevents the debugger from activating.\n", argv[0]); + printf("%s --no-print : Allows the debugger to activate, but without printing.\n", argv[0]); + printf("%s --no-clock : Disables the clock speed regulation system. Drastically increases performance.\n", argv[0]); + printf("%s --no-secure : Disables virtual memory security.\n", argv[0]); printf("\nBy default, PLASM2Emu accepts a properly formed 'bios.bin'.\n"); return 0; @@ -107,18 +114,34 @@ int __nonvideo_main(appargs_t* Args) { ToolsMain(); return 0; } + + if (strstr(argv[i], "--no-debug")) { + EmuCtx->Flags |= EMUFLAG_NODEBUG; + } + + if (strstr(argv[i], "--no-print")) { + EmuCtx->Flags |= EMUFLAG_NOPRINT; + } + + if (strstr(argv[i], "--no-clock")) { + EmuCtx->Flags |= EMUFLAG_NOCLOCK; + } + + if (strstr(argv[i], "--no-secure")) { + EmuCtx->Flags |= EMUFLAG_NOSECURE; + } } - i = malloc(sizeof(PLASM2_CTX)); - memset(i, 0, sizeof(*i)); + ECtx = malloc(sizeof(PLASM2_CTX)); + memset(ECtx, 0, sizeof(*ECtx)); - cpu_init(); + CpuInit(); - i->pti.dvptr = 0x0000; - i->ip = 0x03A0; - i->pti.slb = 0x24F0; - i->pti.spb = 0x25F0; - i->sp = 0x24F0; + ECtx->ControlRegisters.DeviceMap = 0x0000; + ECtx->ip = 0x03A0; + ECtx->ControlRegisters.StackPointerLowerBound = 0x24F0; + ECtx->ControlRegisters.StackPointerUpperBound = 0x25F0; + ECtx->sp = 0x24F0; FILE* Bios = fopen("bios.bin", "rb"); if (!Bios) { @@ -132,7 +155,7 @@ int __nonvideo_main(appargs_t* Args) { BiosLength = 4906; fseek(Bios, 0, SEEK_SET); - fread((BYTE*)cpuctx->PhysicalMemory + 0x3A0, BiosLength, 1, Bios); // read the bios into ram + fread((BYTE*)CpuCtx->PhysicalMemory + 0x3A0, BiosLength, 1, Bios); // read the bios into ram DevicesInit(); DevicesCollect();// PM usage good (reason: comes from trust) @@ -152,9 +175,7 @@ int __nonvideo_main(appargs_t* Args) { char TheHaltReason[256]; - time_t Startup, Startdown; - Startup = time(NULL); - WORD64 ClockCnt = 0; + WORD64 PreMs = CpuTimerGetPreciseTimeMilliseconds(); while (1) { if (EmuCheckClock(TheHaltReason)) { @@ -165,42 +186,48 @@ int __nonvideo_main(appargs_t* Args) { KbClock(); VideoClock(); - cpu_clock(); - ClockCnt++; + CpuClock(); - if (i->flags_s.HF && !i->flags_s.IF) + if (ECtx->flags_s.HF && !ECtx->flags_s.IF) break; } - - time(&Startdown); + + WORD64 PostMs = CpuTimerGetPreciseTimeMilliseconds(); if (EmuCtx->DebuggerEnabled) DecoderShutdown(); VideoClock(); - printf("Debug Shutdown Interrupt.\n"); - + FILE* MemOut = fopen("memout.bin", "wb"); if (MemOut) { - fwrite(cpuctx->PhysicalMemory, cpuctx->PhysicalMemorySize, 1, MemOut); + fwrite(CpuCtx->PhysicalMemory, CpuCtx->PhysicalMemorySize, 1, MemOut); fclose(MemOut); } - fgetc(stdin); + //fgetc(stdin); + WORD64 SystemTickBackup = CpuCtx->SystemTicks; DevicesShutdown(); - cpu_shutdown(); + CpuShutdown(); EmuShutdown(); printf("CPU Halted.\n"); - - printf("Total Clocks: %llu\n", ClockCnt); - time_t Diff = (Startdown - Startup) + 1; - printf("Total Time: %ldm %lds\n", Diff / 60, Diff % 60); - printf("Clocks Per Sec: %llu\n", (ClockCnt) / (Diff)); - - //fclose(a); - free(i); + free(ECtx); + + WORD64 MsDifference = PostMs - PreMs; + WORD64 SDifference = MsDifference / 1000; + MsDifference %= 1000; + + printf("Completed execution of %llu instructions in %llus, %llums.\n", + SystemTickBackup, SDifference, MsDifference); + + long double PreciseFloatingTime = SDifference + (MsDifference / 1000.0); + long double PreciseFloatingInstructions = SystemTickBackup; + long double PreciseClockSpeed = PreciseFloatingInstructions / PreciseFloatingTime; + WORD64 ImpreciseClockSpeed = (WORD64)PreciseClockSpeed; + + printf("Average Clock Speed: %llu Hz", ImpreciseClockSpeed); return 0; } diff --git a/plasm2_emu/plasm2_emu.xcodeproj/project.pbxproj b/plasm2_emu/plasm2_emu.xcodeproj/project.pbxproj index b2af0b3..7e9cea8 100644 --- a/plasm2_emu/plasm2_emu.xcodeproj/project.pbxproj +++ b/plasm2_emu/plasm2_emu.xcodeproj/project.pbxproj @@ -51,6 +51,7 @@ 8C6C48EF2B09677E00B73C87 /* devices_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6C48EB2B09677E00B73C87 /* devices_init.c */; }; 8C6C48F02B09677E00B73C87 /* devices_collect.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6C48EC2B09677E00B73C87 /* devices_collect.c */; }; 8C6C48F12B09677E00B73C87 /* devices_handlers.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6C48ED2B09677E00B73C87 /* devices_handlers.c */; }; + 8CBC12712B14F94A00890ABD /* xcc_systemtime.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CBC12702B14F94A00890ABD /* xcc_systemtime.c */; }; 8CEEB0752B095C520026004C /* libSDL2-2.0.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CEEB0742B095C520026004C /* libSDL2-2.0.0.dylib */; }; 8CEEB08C2B095F140026004C /* emu.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CEEB0882B095F140026004C /* emu.c */; }; 8CEEB08D2B095F140026004C /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CEEB08A2B095F140026004C /* main.c */; }; @@ -127,6 +128,7 @@ 8C6C48EC2B09677E00B73C87 /* devices_collect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = devices_collect.c; sourceTree = "<group>"; }; 8C6C48ED2B09677E00B73C87 /* devices_handlers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = devices_handlers.c; sourceTree = "<group>"; }; 8C6C48EE2B09677E00B73C87 /* devices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = devices.h; sourceTree = "<group>"; }; + 8CBC12702B14F94A00890ABD /* xcc_systemtime.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = xcc_systemtime.c; sourceTree = "<group>"; }; 8CEEAFD92B0954F50026004C /* plasm2_emu */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = plasm2_emu; sourceTree = BUILT_PRODUCTS_DIR; }; 8CEEB0742B095C520026004C /* libSDL2-2.0.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libSDL2-2.0.0.dylib"; path = "../../../../../../opt/homebrew/Cellar/sdl2/2.28.5/lib/libSDL2-2.0.0.dylib"; sourceTree = "<group>"; }; 8CEEB0882B095F140026004C /* emu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = emu.c; sourceTree = "<group>"; }; @@ -340,6 +342,7 @@ isa = PBXGroup; children = ( 8C6C48882B09600300B73C87 /* xcc_timer.c */, + 8CBC12702B14F94A00890ABD /* xcc_systemtime.c */, ); path = xcc; sourceTree = "<group>"; @@ -451,6 +454,7 @@ 8CEEB0962B095F420026004C /* cpu_init.c in Sources */, 8C6C48CA2B0966D400B73C87 /* kb_handlers.c in Sources */, 8C6C489C2B09602200B73C87 /* mmu_virt.c in Sources */, + 8CBC12712B14F94A00890ABD /* xcc_systemtime.c in Sources */, 8CEEB08C2B095F140026004C /* emu.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/plasm2_emu/plasm2_emu.xcodeproj/xcshareddata/xcschemes/plasm2_emu.xcscheme b/plasm2_emu/plasm2_emu.xcodeproj/xcshareddata/xcschemes/plasm2_emu.xcscheme index 8463431..982df5e 100644 --- a/plasm2_emu/plasm2_emu.xcodeproj/xcshareddata/xcschemes/plasm2_emu.xcscheme +++ b/plasm2_emu/plasm2_emu.xcodeproj/xcshareddata/xcschemes/plasm2_emu.xcscheme @@ -56,6 +56,10 @@ argument = "--debug" isEnabled = "NO"> </CommandLineArgument> + <CommandLineArgument + argument = "--no-clock" + isEnabled = "NO"> + </CommandLineArgument> </CommandLineArguments> </LaunchAction> <ProfileAction