Skip to content

Commit

Permalink
emulator refactorization
Browse files Browse the repository at this point in the history
  • Loading branch information
noahw2021 authored Nov 27, 2023
2 parents 3124cf8 + db97a56 commit ed37b6c
Show file tree
Hide file tree
Showing 39 changed files with 858 additions and 715 deletions.
1 change: 1 addition & 0 deletions .testj
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
jk
102 changes: 61 additions & 41 deletions plasm2_emu/cpu/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -154,18 +167,18 @@ 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 {
WORD64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15;
WORD64 ip;
WORD64 sp;
union {
WORD64 flags;
WORD64 Flags;
struct {
BYTE GF : 1; // Greater flag
BYTE EF : 1; // Equal flag
Expand All @@ -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

Expand All @@ -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);
123 changes: 62 additions & 61 deletions plasm2_emu/cpu/cpu_clock.c
Original file line number Diff line number Diff line change
@@ -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;
}
22 changes: 11 additions & 11 deletions plasm2_emu/cpu/cpu_csm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Loading

0 comments on commit ed37b6c

Please sign in to comment.