created sicxe emulator project
This commit is contained in:
parent
cb38efe586
commit
3332b2971b
18 changed files with 1051 additions and 0 deletions
16
simulator_SIC_XE/include/device.h
Normal file
16
simulator_SIC_XE/include/device.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef DEVICE_H
|
||||
#define DEVICE_H
|
||||
|
||||
|
||||
class Device {
|
||||
public:
|
||||
Device();
|
||||
|
||||
bool test();
|
||||
virtual unsigned char read();
|
||||
virtual void write(unsigned char value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // DEVICE_H
|
||||
19
simulator_SIC_XE/include/file_device.h
Normal file
19
simulator_SIC_XE/include/file_device.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef FILE_DEVICE_H
|
||||
#define FILE_DEVICE_H
|
||||
|
||||
#include "device.h"
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
class FileDevice : public Device {
|
||||
public:
|
||||
explicit FileDevice(const std::string &filename);
|
||||
~FileDevice();
|
||||
unsigned char read() override;
|
||||
void write(unsigned char value) override;
|
||||
|
||||
private:
|
||||
std::fstream fileStream;
|
||||
};
|
||||
|
||||
#endif // FILE_DEVICE_H
|
||||
18
simulator_SIC_XE/include/input_device.h
Normal file
18
simulator_SIC_XE/include/input_device.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef INPUT_DEVICE_H
|
||||
#define INPUT_DEVICE_H
|
||||
|
||||
#include "device.h"
|
||||
#include <istream>
|
||||
|
||||
class InputDevice : public Device {
|
||||
public:
|
||||
explicit InputDevice(std::istream &in);
|
||||
~InputDevice();
|
||||
|
||||
unsigned char read();
|
||||
|
||||
private:
|
||||
std::istream &inStream;
|
||||
};
|
||||
|
||||
#endif // INPUT_DEVICE_H
|
||||
20
simulator_SIC_XE/include/instructions.h
Normal file
20
simulator_SIC_XE/include/instructions.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef INSTRUCTIONS_H
|
||||
#define INSTRUCTIONS_H
|
||||
|
||||
#include "opcode.h"
|
||||
|
||||
// Type 2 instruction handlers
|
||||
void addr_handler(Machine& m, int r1, int r2);
|
||||
void clear_handler(Machine& m, int r, int unused);
|
||||
void divr_handler(Machine& m, int r1, int r2);
|
||||
void mulr_handler(Machine& m, int r1, int r2);
|
||||
void rmo_handler(Machine& m, int r1, int r2);
|
||||
void shiftl_handler(Machine& m, int r1, int n);
|
||||
void shiftr_handler(Machine& m, int r1, int n);
|
||||
void subr_handler(Machine& m, int r1, int r2);
|
||||
void svc_handler(Machine& m, int n, int unused);
|
||||
void tixr_handler(Machine& m, int r1, int unused);
|
||||
|
||||
|
||||
|
||||
#endif // INSTRUCTIONS_H
|
||||
145
simulator_SIC_XE/include/machine.h
Normal file
145
simulator_SIC_XE/include/machine.h
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
#ifndef MACHINE_H
|
||||
#define MACHINE_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "device.h"
|
||||
#include "input_device.h"
|
||||
#include "output_device.h"
|
||||
#include "file_device.h"
|
||||
#include "opcode.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#define MEMORY_SIZE 65536
|
||||
#define NUM_DEVICES 256
|
||||
|
||||
|
||||
using std::string;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::cout;
|
||||
|
||||
|
||||
class Machine {
|
||||
public:
|
||||
Machine();
|
||||
~Machine();
|
||||
|
||||
// Accessor methods for registers
|
||||
int getA() const { return A; }
|
||||
void setA(int value) { A = value; }
|
||||
|
||||
int getB() const { return B; }
|
||||
void setB(int value) { B = value; }
|
||||
|
||||
int getX() const { return X; }
|
||||
void setX(int value) { X = value; }
|
||||
|
||||
int getL() const { return L; }
|
||||
void setL(int value) { L = value; }
|
||||
|
||||
int getS() const { return S; }
|
||||
void setS(int value) { S = value; }
|
||||
|
||||
int getT() const { return T; }
|
||||
void setT(int value) { T = value; }
|
||||
|
||||
int getPC() const { return PC; }
|
||||
void setPC(int value) { PC = value; }
|
||||
|
||||
int getSW() const { return SW; }
|
||||
void setSW(int value) { SW = value; }
|
||||
|
||||
double getF() const { return F; }
|
||||
void setF(double value) { F = value; }
|
||||
|
||||
int getReg(int regNum) const;
|
||||
void setReg(int regNum, int value);
|
||||
|
||||
// Memory access methods
|
||||
int getByte(int address);
|
||||
void setByte(int address, int value);
|
||||
|
||||
int getWord(int address);
|
||||
void setWord(int address, int value);
|
||||
|
||||
double getFloat(int address);
|
||||
void setFloat(int address, double value);
|
||||
|
||||
|
||||
// Device access methods
|
||||
Device& getDevice(int num);
|
||||
void setDevice(int num, std::shared_ptr<Device> device);
|
||||
// Set a file device at index `num` using the provided filename.
|
||||
void setFileDevice(int num, const std::string &filename);
|
||||
|
||||
|
||||
// Fetch and execute instructions
|
||||
int fetch();
|
||||
void execute();
|
||||
|
||||
bool execF1(int opcode);
|
||||
bool execF2(int opcode, int operand);
|
||||
bool execSICF3F4(int opcode, int ni, int operand);
|
||||
|
||||
// error handling methods
|
||||
void notImplemented(string mnemonic);
|
||||
void invalidOpcode(int opcode);
|
||||
void invalidAddressing();
|
||||
void divisionByZero(int opcode);
|
||||
void undefinedHandler(int opcode);
|
||||
|
||||
private:
|
||||
// registers
|
||||
int A, B, X, L, S, T, PC, SW;
|
||||
double F;
|
||||
|
||||
// memory
|
||||
unsigned char memory[MEMORY_SIZE];
|
||||
|
||||
// devices
|
||||
std::vector<std::shared_ptr<Device>> devices;
|
||||
// fallback device returned when device slot is empty/invalid
|
||||
Device fallbackDevice;
|
||||
};
|
||||
|
||||
// Convert integer to 24-bit signed SIC representation
|
||||
inline int toSIC24(int value) {
|
||||
value &= 0xFFFFFF;
|
||||
if (value & 0x800000) {
|
||||
value -= 0x1000000;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
inline int setCC(int sw, int cc) {
|
||||
sw &= ~CC_MASK;
|
||||
sw |= (cc & CC_MASK);
|
||||
return sw;
|
||||
}
|
||||
|
||||
inline int sic_comp(int a, int b, int sw) {
|
||||
int sa = toSIC24(a);
|
||||
int sb = toSIC24(b);
|
||||
|
||||
int cc;
|
||||
if (sa < sb) {
|
||||
cc = CC_LT;
|
||||
} else if (sa == sb) {
|
||||
cc = CC_EQ;
|
||||
} else {
|
||||
cc = CC_GT;
|
||||
}
|
||||
|
||||
return setCC(sw, cc);
|
||||
}
|
||||
|
||||
inline int getCC(int sw) {
|
||||
return sw & CC_MASK;
|
||||
}
|
||||
|
||||
|
||||
#endif // MACHINE_H
|
||||
100
simulator_SIC_XE/include/opcode.h
Normal file
100
simulator_SIC_XE/include/opcode.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
#ifndef OPCODE_H
|
||||
#define OPCODE_H
|
||||
|
||||
// ==============================
|
||||
// Opcode definitions (SIC/XE)
|
||||
// ==============================
|
||||
#define ADD 0x18
|
||||
#define ADDF 0x58
|
||||
#define ADDR 0x90
|
||||
#define AND 0x40
|
||||
#define CLEAR 0xB4
|
||||
#define COMP 0x28
|
||||
#define COMPF 0x88
|
||||
#define COMPR 0xA0
|
||||
#define DIV 0x24
|
||||
#define DIVF 0x64
|
||||
#define DIVR 0x9C
|
||||
#define FIX 0xC4
|
||||
#define FLOAT 0xC0
|
||||
#define HIO 0xF4
|
||||
#define J 0x3C
|
||||
#define JEQ 0x30
|
||||
#define JGT 0x34
|
||||
#define JLT 0x38
|
||||
#define JSUB 0x48
|
||||
#define LDA 0x00
|
||||
#define LDB 0x68
|
||||
#define LDCH 0x50
|
||||
#define LDF 0x70
|
||||
#define LDL 0x08
|
||||
#define LDS 0x6C
|
||||
#define LDT 0x74
|
||||
#define LDX 0x04
|
||||
#define LPS 0xD0
|
||||
#define MUL 0x20
|
||||
#define MULF 0x60
|
||||
#define MULR 0x98
|
||||
#define NORM 0xC8
|
||||
#define OR 0x44
|
||||
#define RD 0xD8
|
||||
#define RMO 0xAC
|
||||
#define RSUB 0x4C
|
||||
#define SHIFTL 0xA4
|
||||
#define SHIFTR 0xA8
|
||||
#define SIO 0xF0
|
||||
#define SSK 0xEC
|
||||
#define STA 0x0C
|
||||
#define STB 0x78
|
||||
#define STCH 0x54
|
||||
#define STF 0x80
|
||||
#define STI 0xD4
|
||||
#define STL 0x14
|
||||
#define STS 0x7C
|
||||
#define STSW 0xE8
|
||||
#define STT 0x84
|
||||
#define STX 0x10
|
||||
#define SUB 0x1C
|
||||
#define SUBF 0x5C
|
||||
#define SUBR 0x94
|
||||
#define SVC 0xB0
|
||||
#define TD 0xE0
|
||||
#define TIO 0xF8
|
||||
#define TIX 0x2C
|
||||
#define TIXR 0xB8
|
||||
#define WD 0xDC
|
||||
|
||||
|
||||
|
||||
// SW register condition codes
|
||||
constexpr int CC_LT = 0x0; // 00
|
||||
constexpr int CC_EQ = 0x1; // 01
|
||||
constexpr int CC_GT = 0x2; // 10
|
||||
constexpr int CC_MASK = 0x3; // mask for 2 bits
|
||||
|
||||
|
||||
|
||||
enum class InstructionType {
|
||||
TYPE1,
|
||||
TYPE2,
|
||||
TYPE3_4,
|
||||
INVALID
|
||||
};
|
||||
|
||||
class Machine; // forward
|
||||
|
||||
// Store raw function pointer (void*) to allow different handler signatures
|
||||
using RawHandler = void*;
|
||||
|
||||
struct InstructionInfo {
|
||||
const char* name;
|
||||
InstructionType type;
|
||||
RawHandler handler;
|
||||
};
|
||||
|
||||
extern InstructionInfo instructions[];
|
||||
|
||||
// Initialize the instruction table
|
||||
void loadInstructionSet();
|
||||
|
||||
#endif // OPCODE_H
|
||||
18
simulator_SIC_XE/include/output_device.h
Normal file
18
simulator_SIC_XE/include/output_device.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef OUTPUT_DEVICE_H
|
||||
#define OUTPUT_DEVICE_H
|
||||
|
||||
#include "device.h"
|
||||
#include <ostream>
|
||||
|
||||
class OutputDevice : public Device {
|
||||
public:
|
||||
explicit OutputDevice(std::ostream &out);
|
||||
~OutputDevice();
|
||||
|
||||
void write(unsigned char value) override;
|
||||
|
||||
private:
|
||||
std::ostream &outStream;
|
||||
};
|
||||
|
||||
#endif // OUTPUT_DEVICE_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue