├── .gitignore ├── .vscode └── settings.json ├── CMakeLists.txt └── src ├── CMakeLists.txt ├── dev ├── bus │ ├── axp │ │ ├── 21174.cpp │ │ ├── 21174.h │ │ ├── 21272.cpp │ │ ├── 21272.h │ │ └── 21274.h │ ├── comm │ │ └── dec │ │ │ ├── console.cpp │ │ │ └── cty.h │ ├── pci │ │ ├── pci.cpp │ │ └── pci.h │ └── uqio │ │ └── uqio.h ├── chip │ ├── dec │ │ ├── cmctl.cpp │ │ ├── cmctl.h │ │ ├── cqbic.cpp │ │ ├── cqbic.h │ │ ├── cssc.cpp │ │ └── cssc.h │ ├── flash.cpp │ ├── flash.h │ ├── nvmem.cpp │ └── nvmem.h ├── cpu │ ├── alpha │ │ ├── axp.cpp │ │ ├── axp.h │ │ ├── axp21264_ipr.h │ │ ├── axp_arith.h │ │ ├── axp_branch.h │ │ ├── axp_bwx.h │ │ ├── axp_fpbr.h │ │ ├── axp_fpmem.h │ │ ├── axp_fpoper.h │ │ ├── axp_logical.h │ │ ├── axp_mem.cpp │ │ ├── axp_mem.h │ │ ├── axp_misc.h │ │ ├── axp_mmu.h │ │ ├── axp_pal.h │ │ ├── axp_tb.cpp │ │ ├── debug.cpp │ │ ├── debug.h │ │ ├── ev4.cpp │ │ ├── ev4.h │ │ ├── ev4_pal.cpp │ │ ├── ev5.cpp │ │ ├── ev5.h │ │ ├── ev5_defs.h │ │ ├── ev5_ipr.h │ │ ├── ev5_pal.cpp │ │ ├── ev6.cpp │ │ ├── ev6.h │ │ ├── ev6_ipr.cpp │ │ ├── ev6_ipr.h │ │ ├── ev6_pal.cpp │ │ ├── execute.cpp │ │ ├── fw.h │ │ ├── load.cpp │ │ ├── opcode.h │ │ ├── opcodes.cpp │ │ └── opcodes.h │ ├── i8080 │ │ ├── debug.cpp │ │ ├── execute.cpp │ │ ├── i8080.cpp │ │ ├── i8080.h │ │ ├── i8080dbg.h │ │ └── i8080op.h │ ├── m6500 │ │ ├── debug.h │ │ ├── m6502.cpp │ │ ├── m6502.h │ │ └── m6502op.h │ ├── mcs48 │ │ ├── debug.cpp │ │ ├── execute.cpp │ │ ├── load.cpp │ │ ├── mcs48.cpp │ │ ├── mcs48.h │ │ └── opcodes.cpp │ ├── pdp10 │ │ ├── execute.cpp │ │ ├── kx10.h │ │ ├── memory.cpp │ │ ├── opcode.cpp │ │ ├── opcode.h │ │ ├── pdp10.cpp │ │ └── pdp10.h │ ├── pdp11 │ │ ├── models.cpp │ │ ├── models.h │ │ ├── opcodes.cpp │ │ ├── pdp11.cpp │ │ ├── pdp11.h │ │ └── pdp11_defs.h │ ├── upd7810 │ │ ├── debug.cpp │ │ ├── execute.cpp │ │ ├── load.cpp │ │ ├── opcodes.cpp │ │ ├── upd7810.cpp │ │ └── upd7810.h │ └── vax │ │ ├── debug.cpp │ │ ├── old │ │ ├── cis.cpp │ │ ├── cvax.cpp │ │ ├── cvax.h │ │ ├── disasm.cpp │ │ ├── execute.cpp │ │ ├── fpu.cpp │ │ ├── fpu.h │ │ ├── ka780.cpp │ │ ├── ka780.h │ │ ├── mem.cpp │ │ ├── mmu.h │ │ ├── mtpr.h │ │ ├── nvax.h │ │ ├── opcodes.cpp │ │ ├── opcodes.h │ │ ├── v11.cpp │ │ ├── v11.h │ │ ├── vax.cpp │ │ └── vax.h │ │ ├── opcodes.cpp │ │ ├── opcodes.h │ │ ├── vax.cpp │ │ └── vax.h └── video │ └── dec │ ├── vt100.cpp │ └── vt100.h ├── emu ├── command.cpp ├── command.h ├── console.cpp ├── console.h ├── core.h ├── debug.cpp ├── debug.h ├── debugger │ ├── debugger.cpp │ ├── debugger.h │ ├── device.cpp │ ├── device.h │ ├── symbols.cpp │ └── symbols.h ├── delegate.cpp ├── delegate.h ├── devcall.cpp ├── devcall.h ├── devfinder.cpp ├── devfinder.h ├── device.cpp ├── device.h ├── devproc.cpp ├── devproc.h ├── devsys.cpp ├── devsys.h ├── dibus.cpp ├── dibus.h ├── didebug.cpp ├── didebug.h ├── diexec.cpp ├── diexec.h ├── distate.cpp ├── distate.h ├── divideo.cpp ├── divideo.h ├── driver.h ├── engine.cpp ├── engine.h ├── fileio.cpp ├── fileio.h ├── list.h ├── machine.cpp ├── machine.h ├── map.new │ └── map.h ├── map │ ├── access.cpp │ ├── addrmap.cpp │ ├── addrmap.h │ ├── busmgr.cpp │ ├── he.h │ ├── hea.h │ ├── hedp.cpp │ ├── hedp.h │ ├── hedr.h │ ├── hedr0.cpp │ ├── hedr1.cpp │ ├── hedr2.cpp │ ├── hedr3.cpp │ ├── hedr4.cpp │ ├── hedr5.cpp │ ├── hedr6.cpp │ ├── hedr7.cpp │ ├── hedri.h │ ├── hedw.h │ ├── hedw0.cpp │ ├── hedw1.cpp │ ├── hedw2.cpp │ ├── hedw3.cpp │ ├── hedw4.cpp │ ├── hedw5.cpp │ ├── hedw6.cpp │ ├── hedw7.cpp │ ├── hedwi.h │ ├── hem.cpp │ ├── hem.h │ ├── hep.h │ ├── heun.cpp │ ├── heun.h │ ├── map.cpp │ ├── map.h │ ├── rom.h │ ├── romentry.h │ └── space.cpp ├── romloader.cpp ├── romloader.h ├── scheduler.cpp ├── scheduler.h ├── screen.cpp ├── screen.h ├── sysconfig.cpp ├── sysconfig.h ├── syslist.cpp ├── syslist.h ├── systems.cpp ├── templates.h ├── video.cpp ├── video.h └── xtal.h ├── lib └── util │ ├── bitmap.cpp │ ├── bitmap.h │ ├── color.cpp │ ├── color.h │ ├── time.cpp │ └── time.h ├── main └── main.cpp ├── merged ├── formats │ ├── dec │ │ ├── image.cpp │ │ └── word10.h │ └── int36.h └── osd │ ├── ether.cpp │ ├── ether.h │ ├── main.cpp │ ├── osdfile.h │ ├── posixfile.cpp │ ├── posixfile.h │ ├── socket.h │ ├── telnet.cpp │ └── telnet.h ├── osd ├── osdcore.cpp ├── osdcore.h └── sdl │ ├── sdlmain.cpp │ └── sdlmain.h ├── printers └── epson │ ├── externs.h │ ├── mx.cpp │ └── mx.h ├── system └── dec │ ├── axp │ ├── alphapc.cpp │ ├── alphapc.h │ ├── externs.h │ ├── tsunami.cpp │ └── tsunami.h │ └── vax │ ├── externs.h │ ├── ka650.cpp │ ├── ka650.h │ ├── ka655.cpp │ └── ka655.h ├── terminals └── dec │ ├── externs.h │ ├── vt100.cpp │ └── vt100.h └── tools └── dump.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | .cproject 2 | .project 3 | .settings 4 | /data/ 5 | /build/ 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools" 3 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.21) 2 | 3 | set (CMAKE_CXX_STANDARD 20) 4 | set (CMAKE_CXX_STANDARD_REQUIRED YES) 5 | 6 | project(mse) 7 | 8 | find_package(SDL2 REQUIRED) 9 | find_package(fmt REQUIRED) 10 | find_package(LibLZMA REQUIRED) 11 | 12 | include_directories(src) 13 | 14 | add_subdirectory(src) 15 | -------------------------------------------------------------------------------- /src/dev/bus/axp/21174.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 21174.cpp - AXP 21174 logic chipset package 3 | * 4 | * Created on: Feb 19, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "dev/bus/axp/21174.h" 10 | -------------------------------------------------------------------------------- /src/dev/bus/axp/21274.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 21274.h - 21274 Typhoon logic chipset package 3 | * 4 | * Created on: Feb 19, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | -------------------------------------------------------------------------------- /src/dev/bus/comm/dec/console.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * console.cpp 3 | * 4 | * Created on: May 7, 2018 5 | * Author: Timothy Stark 6 | */ 7 | 8 | #include "emu/emucore.h" 9 | #include "dev/comm/dec/cty.h" 10 | #include "dev/cpu/vax/mtpr.h" 11 | 12 | using namespace dec; 13 | 14 | ctyDevice::ctyDevice() 15 | { 16 | } 17 | 18 | ctyDevice::~ctyDevice() 19 | { 20 | } 21 | 22 | //ctyDevice *ctyDevice::create(sysDevice *sdev, std::string devName) 23 | //{ 24 | // ctyDevice *dev = new ctyDevice(); 25 | // 26 | // if (dev == nullptr) 27 | // return nullptr; 28 | // 29 | // dev->devName = devName; 30 | // dev->devType = "CTY"; 31 | //// dev->devDesc = model->desc; 32 | //// dev->driver = model->driver; 33 | // 34 | // // Assign system device for I/O access 35 | // dev->setSystemDevice(sdev); 36 | // 37 | // // Initialize console device 38 | //// dev->reset(); 39 | // 40 | // // Add CPU device to system device 41 | //// sdev->addConsoleDevice(dev); 42 | // 43 | // return dev; 44 | //} 45 | 46 | uint16_t ctyDevice::read16(uint32_t ioAddr) 47 | { 48 | switch (ioAddr) { 49 | case IPR_nRXCS: 50 | case IPR_nRXDB: 51 | case IPR_nTXCS: 52 | case IPR_nTXDB: 53 | break; 54 | } 55 | 56 | // Return as default zero 57 | return 0; 58 | } 59 | 60 | void ctyDevice::write16(uint32_t ioAddr, uint16_t data) 61 | { 62 | switch (ioAddr) { 63 | case IPR_nRXCS: 64 | case IPR_nRXDB: 65 | case IPR_nTXCS: 66 | case IPR_nTXDB: 67 | break; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/dev/bus/comm/dec/cty.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cty.h 3 | * 4 | * Created on: May 4, 2018 5 | * Author: fswor 6 | */ 7 | 8 | #pragma once 9 | 10 | // RXCS - Console Receive Control and Status Register 11 | #define RXCS_ACT 0x0800 // (R) Receive Active 12 | #define RXCS_RDY 0x0080 // (R) Ready/Done 13 | #define RXCS_IE 0x0040 // (R/W) Interrupt Enable 14 | 15 | #define RXCS_RW (RXCS_IE) 16 | 17 | // RXDB - Console Receive Data Buffer 18 | #define RXDB_ERR 0x8000 // (R) Error 19 | #define RXDB_OVR 0x4000 // (R) Overrun 20 | #define RXDB_FRM 0x2000 // (R) Frame Error 21 | #define RXDB_BRK 0x1000 // (R) Receive Break 22 | #define RXDB_CHAR 0x00FF // (R) Data Buffer 23 | 24 | // TXCS - Console Transmit Control and Status Register 25 | #define TXCS_RDY 0x0080 // (R) Ready 26 | #define TXCS_IE 0x0040 // (R/W) Interrupt Enable 27 | #define TXCS_MAINT 0x0004 // (R/W) Maintenance Mode 28 | #define TXCS_BRK 0x0001 // (R/W) Transmit Break 29 | 30 | #define TXCS_RW (TXCS_IE|TXCS_MAINT|TXCS_BRK) 31 | 32 | // TXDB - Console Transmit Data Buffer 33 | #define TXDB_CHAR 0x00FF // (W) Data Buffer 34 | #define TXDB_SEL 0x0F00 // (W) Mode Selection 35 | 36 | 37 | namespace dec { 38 | class ctyDevice /* : public device_t */ 39 | { 40 | public: 41 | ctyDevice(); 42 | ~ctyDevice(); 43 | 44 | // static ctyDevice *create(sysDevice *sdev, std::string devName); 45 | 46 | uint16_t read16(uint32_t ioAddr); 47 | void write16(uint32_t ioAddr, uint16_t data); 48 | 49 | }; 50 | } 51 | -------------------------------------------------------------------------------- /src/dev/bus/pci/pci.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * pci.cpp - Intel PCI bus interface package 3 | * 4 | * Created on: Jan 28, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "dev/bus/pci/pci.h" 10 | -------------------------------------------------------------------------------- /src/dev/bus/pci/pci.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pci.h - PCI device bus 3 | * 4 | * Created on: Jan 28, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | 11 | class pci_busDevice : public Device 12 | { 13 | public: 14 | pci_busDevice() = default; 15 | ~pci_busDevice() = default; 16 | 17 | private: 18 | }; 19 | -------------------------------------------------------------------------------- /src/dev/chip/dec/cmctl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * cmctl.cpp - CVAX Memory Controller 3 | * 4 | * Created on: Mar 8, 2019 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/emucore.h" 9 | #include "dev/chip/dec/vax/cmctl.h" 10 | 11 | DEFINE_DEVICE_TYPE(CMCTL, cmctl_device, "CMCTL", "CVAX Memory Controller") 12 | 13 | #ifdef DEBUG 14 | static const char *cmNames[] = 15 | { 16 | "CMCNF00", "CMCNF01", "CMCNF02", "CMCNF03", 17 | "CMCNF04", "CMCNF05", "CMCNF06", "CMCNF07", 18 | "CMCNF08", "CMCNF09", "CMCNF10", "CMCNF11", 19 | "CMCNF12", "CMCNF13", "CMCNF14", "CMCNF15", 20 | "CMERR", "CMCSR", "CMSIZE", 21 | }; 22 | #endif /* DEBUG */ 23 | 24 | cmctl_device::cmctl_device(const system_config &config, tag_t *tag, device_t *owner, uint64_t clock) 25 | : device_t(config, CMCTL, tag, owner, clock) 26 | { 27 | } 28 | 29 | cmctl_device::~cmctl_device() 30 | { 31 | } 32 | 33 | void cmctl_device::devStart() 34 | { 35 | } 36 | 37 | //void cmctl_device::devStop() 38 | //{ 39 | //} 40 | // 41 | //void cmctl_device::devReset() 42 | //{ 43 | //} 44 | 45 | uint32_t cmctl_device::read(offs_t offset, int acc) 46 | { 47 | return cmReg[offset]; 48 | } 49 | 50 | void cmctl_device::write(offs_t offset, uint32_t data, int acc) 51 | { 52 | // if (acc < LN_LONG) { 53 | // uint32_t sc = (offset & ALIGN_LONG) << 3; 54 | // uint32_t mask = ((acc == LN_WORD) ? W_MASK : B_MASK) << sc; 55 | // ndata = ((data << sc) & mask) | (sscReg[offset] & ~mask); 56 | // } else 57 | // ndata = data; 58 | data <<= (offset & ALIGN_LONG) << 3; 59 | 60 | switch (offset) { 61 | case CM_nCNF00: case CM_nCNF01: case CM_nCNF02: case CM_nCNF03: 62 | case CM_nCNF04: case CM_nCNF05: case CM_nCNF06: case CM_nCNF07: 63 | case CM_nCNF08: case CM_nCNF09: case CM_nCNF10: case CM_nCNF11: 64 | case CM_nCNF12: case CM_nCNF13: case CM_nCNF14: case CM_nCNF15: 65 | if (data & CMCNF_SRQ) { 66 | 67 | } 68 | cmReg[offset] = (data & CMCNF_RW) | (cmReg[offset] & ~CMCNF_RW); 69 | break; 70 | 71 | case CM_nERR: 72 | cmReg[offset] &= ~(data & CMERR_W1C); 73 | break; 74 | 75 | case CM_nCSR: 76 | cmReg[offset] = data & CMCSR_RW; 77 | break; 78 | 79 | case CM_nMSZ: 80 | break; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/dev/chip/dec/cmctl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cmctl.h - CVAX Memory Controller 3 | * 4 | * Created on: Jan 6, 2019 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | // CMCTL - Memory Controller Registers 11 | //#define CM_BASE (REG_BASE + 0x100) // CMCTL Base Address 12 | ////#define CM_NREGS 18 // Number of Registers 13 | //#define CM_NREGS 19 // Number of Registers 14 | //#define CM_SIZE (CM_NREGS << 2) // Total Bytes 15 | //#define CM_END (CM_BASE + CM_SIZE) // End of CMCTL Registers 16 | //#define CM_REG(rn) cmReg[rn] 17 | 18 | #define CM_nCNF00 0 // CMCTL Configuration 0 19 | #define CM_nCNF01 1 // CMCTL Configuration 1 20 | #define CM_nCNF02 2 // CMCTL Configuration 2 21 | #define CM_nCNF03 3 // CMCTL Configuration 3 22 | #define CM_nCNF04 4 // CMCTL Configuration 4 23 | #define CM_nCNF05 5 // CMCTL Configuration 5 24 | #define CM_nCNF06 6 // CMCTL Configuration 6 25 | #define CM_nCNF07 7 // CMCTL Configuration 7 26 | #define CM_nCNF08 8 // CMCTL Configuration 8 27 | #define CM_nCNF09 9 // CMCTL Configuration 9 28 | #define CM_nCNF10 10 // CMCTL Configuration 10 29 | #define CM_nCNF11 11 // CMCTL Configuration 11 30 | #define CM_nCNF12 12 // CMCTL Configuration 12 31 | #define CM_nCNF13 13 // CMCTL Configuration 13 32 | #define CM_nCNF14 14 // CMCTL Configuration 14 33 | #define CM_nCNF15 15 // CMCTL Configuration 15 34 | #define CM_nERR 16 // CMCTL Error Register 35 | #define CM_nCSR 17 // CMCTL Control/Status Register 36 | #define CM_nMSZ 18 // CMCTL Memory Size 37 | 38 | #define CM_ERR CM_REG(CM_nERR) 39 | #define CM_CSR CM_REG(CM_nCSR) 40 | #define CM_MSZ CM_REG(CM_nMSZ) 41 | 42 | // CMCTL Configuration Register 43 | #define CMCNF_VLD 0x80000000 // Address Valid 44 | #define CMCNF_BA 0x1FF00000 // Base Address 45 | #define CMCNF_LOCK 0x00000040 // Lock 46 | #define CMCNF_SRQ 0x00000020 // Signature Request 47 | #define CMCNF_SIG 0x0000001F // Signature 48 | 49 | #define CMCNF_RW (CMCNF_VLD|CMCNF_BA) 50 | #define CMCNF_MASK (CMCNF_RW|CMCNF_SIG) 51 | 52 | #define MEM_BANK (1u << 22) // Bank Size 53 | #define MEM_SIG 0x17 // ECC, 4 x 4 MB 54 | 55 | // CMCTL Error Register 56 | #define CMERR_RDS 0x80000000 // Uncorrected Error 57 | #define CMERR_FRQ 0x40000000 // 2nd RDS 58 | #define CMERR_CRD 0x20000000 // CRD Error 59 | #define CMERR_PAG 0x1FFFFC00 // Page Address 60 | #define CMERR_DMA 0x00000100 // DMA Error 61 | #define CMERR_BUS 0x00000080 // Bus Error 62 | #define CMERR_SYN 0x0000007F // Syndrome 63 | 64 | #define CMERR_W1C (CMERR_RDS|CMERR_FRQ|CMERR_CRD|CMERR_DMA|CMERR_BUS) 65 | 66 | // CMCTL Control/Status Register 67 | #define CMCSR_PMI 0x00002000 // PMI Speed 68 | #define CMCSR_CRD 0x00001000 // Enable CRD Interrupt 69 | #define CMCSR_FRF 0x00000800 // Force Reference 70 | #define CMCSR_DET 0x00000400 // Dis Error 71 | #define CMCSR_FDT 0x00000200 // Fast Diagnostic 72 | #define CMCSR_DCM 0x00000080 // Diagnostic Mode 73 | #define CMCSR_SYN 0x0000007F // Syndrome 74 | 75 | #define CMCSR_RW (CMCSR_PMI|CMCSR_CRD|CMCSR_DET|CMCSR_FDT|CMCSR_DCM|CMCSR_SYN) 76 | 77 | class cmctl_device : public device_t 78 | { 79 | public: 80 | cmctl_device(const system_config &config, tag_t *tag, device_t *owner, uint64_t clock); 81 | ~cmctl_device(); 82 | 83 | virtual void devStart() override; 84 | // virtual void devStop() override; 85 | // virtual void devReset() override; 86 | 87 | uint32_t read(offs_t offset, int acc); 88 | void write(offs_t offset, uint32_t data, int acc); 89 | 90 | private: 91 | uint32_t cmReg[32]; 92 | }; 93 | 94 | DECLARE_DEVICE_TYPE(CMCTL, cmctl_device) 95 | -------------------------------------------------------------------------------- /src/dev/chip/dec/cqbic.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * cqbic.cpp - CVAX Qbus Interface Chip 3 | * 4 | * Created on: Mar 8, 2019 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/emucore.h" 9 | #include "dev/chip/dec/vax/cqbic.h" 10 | 11 | #ifdef DEBUG 12 | static const char *bicNames[] = \ 13 | { "SCR", "DSER", "MEAR", "SEAR", "MBR" }; 14 | #endif /* DEBUG */ 15 | 16 | DEFINE_DEVICE_TYPE(CQBIC, cqbic_device, "CQBIC", "CVAX Qbus Interface Chip") 17 | 18 | cqbic_device::cqbic_device(const system_config &config, tag_t *tag, device_t *owner, uint64_t clock) 19 | : device_t(config, CQBIC, tag, owner, clock) 20 | { 21 | } 22 | 23 | cqbic_device::~cqbic_device() 24 | { 25 | } 26 | 27 | void cqbic_device::devStart() 28 | { 29 | } 30 | 31 | //void cqbic_device::devStop() 32 | //{ 33 | //} 34 | // 35 | //void cqbic_device::devReset() 36 | //{ 37 | //} 38 | 39 | uint32_t cqbic_device::read(offs_t offset, int acc) 40 | { 41 | return cqReg[offset]; 42 | } 43 | 44 | void cqbic_device::write(offs_t offset, uint32_t data, int acc) 45 | { 46 | uint32_t ndata; 47 | 48 | if (acc < LN_LONG) { 49 | uint32_t sc = (offset & ALIGN_LONG) << 3; 50 | uint32_t mask = ((acc == LN_WORD) ? MSK_WORD : MSK_BYTE) << sc; 51 | ndata = ((data << sc) & mask) | (cqReg[offset] & ~mask); 52 | } else 53 | ndata = data; 54 | 55 | switch (offset) { 56 | case CQ_nSCR: 57 | cqReg[offset] = (ndata & SCR_RW) | (cqReg[offset] & ~SCR_RW) | SCR_PWROK; 58 | break; 59 | 60 | case CQ_nDSER: 61 | cqReg[offset] &= ~ndata; 62 | break; 63 | 64 | case CQ_nMEAR: 65 | case CQ_nSEAR: 66 | break; 67 | 68 | case CQ_nMBR: 69 | cqReg[offset] = ndata & MBR_ADDR; 70 | break; 71 | } 72 | } 73 | 74 | uint32_t cqbic_device::read_map(offs_t offset, int acc) 75 | { 76 | // return mapReg[offset]; 77 | return 0; 78 | } 79 | 80 | void cqbic_device::write_map(offs_t offset, uint32_t data, int acc) 81 | { 82 | } 83 | 84 | uint32_t cqbic_device::read_mem(offs_t offset, int acc) 85 | { 86 | // return mapReg[offset]; 87 | return 0; 88 | } 89 | 90 | void cqbic_device::write_mem(offs_t offset, uint32_t data, int acc) 91 | { 92 | } 93 | 94 | uint16_t cqbic_device::read_io(offs_t offset, int acc) 95 | { 96 | // return mapReg[offset]; 97 | return 0; 98 | } 99 | 100 | void cqbic_device::write_io(offs_t offset, uint16_t data, int acc) 101 | { 102 | } 103 | 104 | uint16_t cqbic_device::read_ipc(offs_t offset, int acc) 105 | { 106 | // return mapReg[offset]; 107 | return 0; 108 | } 109 | 110 | void cqbic_device::write_ipc(offs_t offset, uint16_t data, int acc) 111 | { 112 | } 113 | -------------------------------------------------------------------------------- /src/dev/chip/dec/cssc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * cssc.cpp - CVAX System Support Chip 3 | * 4 | * Created on: Mar 8, 2019 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/emucore.h" 9 | #include "dev/chip/dec/vax/cssc.h" 10 | 11 | #ifdef DEBUG 12 | static const char *sscNames[] = 13 | { 14 | "BASE", NULL, NULL, NULL, /* 00-03 */ 15 | "CR", NULL, NULL, NULL, /* 04-07 */ 16 | "BTO", NULL, NULL, NULL, /* 08-0B */ 17 | "DLEDR", NULL, NULL, NULL, /* 0C-0F */ 18 | NULL, NULL, NULL, NULL, /* 10-13 */ 19 | NULL, NULL, NULL, NULL, /* 14-17 */ 20 | NULL, NULL, NULL, "TODR", /* 18-1B */ 21 | "CSRS", "CSRD", "CSTS", "CSTD", /* 1C-1F */ 22 | "RXCS", "RXDB", "TXCS", "TXDB", /* 20-23 */ 23 | NULL, NULL, NULL, NULL, /* 24-27 */ 24 | NULL, NULL, NULL, NULL, /* 28-2B */ 25 | NULL, NULL, NULL, NULL, /* 2C-2F */ 26 | NULL, NULL, NULL, NULL, /* 30-33 */ 27 | NULL, NULL, NULL, NULL, /* 34-37 */ 28 | NULL, NULL, NULL, NULL, /* 38-3B */ 29 | NULL, NULL, NULL, NULL, /* 3C-3F */ 30 | "TCR0", "TIR0", "TNIR0", "TIVR0", /* 40-43 */ 31 | "TCR1", "TIR1", "TNIR1", "TIVR1", /* 44-47 */ 32 | NULL, NULL, NULL, NULL, /* 48-4B */ 33 | "AD0MAT", "AD0MSK", NULL, NULL, /* 4C-4F */ 34 | "AD1MAT", "AD1MSK", NULL, NULL, /* 50-53 */ 35 | }; 36 | #endif /* DEBUG */ 37 | 38 | DEFINE_DEVICE_TYPE(CSSC, cssc_device, "CSSC", "CVAX System Support Chip") 39 | 40 | cssc_device::cssc_device(const system_config &config, tag_t *tag, device_t *owner, uint64_t clock) 41 | : device_t(config, CSSC, tag, owner, clock) 42 | { 43 | } 44 | 45 | cssc_device::~cssc_device() 46 | { 47 | } 48 | 49 | void cssc_device::devStart() 50 | { 51 | } 52 | 53 | //void cssc_device::devStop() 54 | //{ 55 | //} 56 | // 57 | //void cssc_device::devReset() 58 | //{ 59 | //} 60 | 61 | uint32_t cssc_device::read(offs_t offset, int acc) 62 | { 63 | uint32_t data; 64 | 65 | switch (offset) { 66 | case SSC_nTIR0: 67 | data = 0; 68 | break; 69 | case SSC_nTIR1: 70 | data = 0; 71 | break; 72 | default: 73 | data = sscReg[offset]; 74 | break; 75 | } 76 | 77 | return data; 78 | } 79 | 80 | void cssc_device::write(offs_t offset, uint32_t data, int acc) 81 | { 82 | uint32_t ndata; 83 | 84 | if (acc < LN_LONG) { 85 | uint32_t sc = (offset & ALIGN_LONG) << 3; 86 | uint32_t mask = ((acc == LN_WORD) ? MSK_WORD : MSK_BYTE) << sc; 87 | ndata = ((data << sc) & mask) | (sscReg[offset] & ~mask); 88 | } else 89 | ndata = data; 90 | 91 | switch (offset) { 92 | case SSC_nBASE: 93 | sscReg[offset] = (ndata & BASE_ADDR) | BASE_MBO; 94 | break; 95 | 96 | case SSC_nCR: 97 | sscReg[offset] &= (ndata & CNF_W1C); 98 | sscReg[offset] = (ndata & CNF_RW) | (sscReg[offset] & ~CNF_RW); 99 | break; 100 | 101 | case SSC_nBTO: 102 | sscReg[offset] &= (ndata & BTO_W1C); 103 | sscReg[offset] = (ndata & BTO_RW) | (sscReg[offset] & ~BTO_RW); 104 | break; 105 | 106 | case SSC_nDLEDR: 107 | sscReg[offset] = ndata & LED_MASK; 108 | break; 109 | 110 | case SSC_nTCR0: 111 | break; 112 | case SSC_nTNIR0: 113 | sscReg[offset] = ndata; 114 | break; 115 | case SSC_nTIVR0: 116 | sscReg[offset] = ndata & TIVR_VEC; 117 | break; 118 | 119 | case SSC_nTCR1: 120 | break; 121 | case SSC_nTNIR1: 122 | sscReg[offset] = ndata; 123 | break; 124 | case SSC_nTIVR1: 125 | sscReg[offset] = ndata & TIVR_VEC; 126 | break; 127 | 128 | case SSC_nAD0MAT: 129 | case SSC_nAD0MSK: 130 | case SSC_nAD1MAT: 131 | case SSC_nAD1MSK: 132 | sscReg[offset] = ndata & ADS_MASK; 133 | break; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/dev/chip/flash.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * flash.cpp - Flash memory device package 3 | * 4 | * Created on: Feb 17, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "dev/chip/flash.h" 10 | 11 | flash_memDevice::flash_memDevice(const SystemConfig &config, const DeviceType &type, 12 | cstag_t &tagName, Device *owner, uint64_t clock) 13 | : Device(config, type, tagName, owner, clock), 14 | nvmInterface(this, "flash") 15 | { 16 | 17 | } 18 | 19 | flash_memDevice::~flash_memDevice() 20 | { 21 | // Save contents 22 | } 23 | -------------------------------------------------------------------------------- /src/dev/chip/flash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * flash.h - Flash memory device package 3 | * 4 | * Created on: Feb 17, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "dev/chip/nvmem.h" 11 | 12 | class flash_memDevice : public Device, public nvmInterface 13 | { 14 | public: 15 | flash_memDevice(const SystemConfig &config, const DeviceType &type, 16 | cstag_t &tagName, Device *owner, uint64_t clock); 17 | ~flash_memDevice(); 18 | }; 19 | -------------------------------------------------------------------------------- /src/dev/chip/nvmem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * nvmem.cpp - Non-volatile memory interface package 3 | * 4 | * Created on: Feb 17, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "dev/chip/nvmem.h" 10 | 11 | nvmInterface::nvmInterface(Device *owner, ctag_t *name) 12 | : DeviceInterface(owner, (name != nullptr) ? name : "nvmem") 13 | { 14 | 15 | } 16 | 17 | nvmInterface::~nvmInterface() 18 | { 19 | // Save contents 20 | } 21 | -------------------------------------------------------------------------------- /src/dev/chip/nvmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * nvmem.h - Non-volatile memory interface package 3 | * 4 | * Created on: Feb 17, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | class nvmInterface : public DeviceInterface 11 | { 12 | public: 13 | nvmInterface(Device *owner, ctag_t *name = nullptr); 14 | ~nvmInterface(); 15 | 16 | // void reset(); 17 | // void load(fs::path &fname); 18 | // void save(fs::path &fname); 19 | // 20 | //protected: 21 | // virtual void nvmSetDefault() = 0; 22 | // virtual void nvmLoad(fs::path &fname) { load(fname); } 23 | // virtual void nvmSave(fs::path &fname) { save(fname); } 24 | // 25 | //protected: 26 | // vector data; 27 | }; 28 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/axp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * alpha.cpp - DEC Alpha CPU Processor package 3 | * 4 | * Created on: Nov 20, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/sysconfig.h" 10 | #include "dev/cpu/alpha/axp.h" 11 | 12 | alpha_cpuDevice::alpha_cpuDevice(const SystemConfig &config, const DeviceType &type, 13 | const string &tagName, Device *owner, uint64_t clock, int aWidth) 14 | : cpuDevice(config, type, tagName, owner, clock), 15 | mapProgramConfig("program", LittleEndian, 64, 16, 8, aWidth, 16, 0) 16 | { 17 | // Initialize opcode table for disassembler 18 | initOpcodeTable(); 19 | } 20 | 21 | mapConfigList alpha_cpuDevice::getAddressConfigList() const 22 | { 23 | return mapConfigList { 24 | { aspace::asProgram, &mapProgramConfig } 25 | }; 26 | } 27 | 28 | void alpha_cpuDevice::startDevice() 29 | { 30 | 31 | getAddressSpace(AS_PROGRAM)->setMemorySpecific(mapProgram); 32 | 33 | } -------------------------------------------------------------------------------- /src/dev/cpu/alpha/axp21264_ipr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * axp21264_ipr.h - Alpha 21264 - IPR registers 3 | * 4 | * Created on: Feb 6, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | // I_CTL - Ibox Control register 11 | // 12 | // Chip ID field following values: 13 | // 14 | // 3 = 21264 pass 2.3 15 | // 5 = 21264 pass 2.5 16 | 17 | struct iCtl_t 18 | { 19 | uint64_t spce:1; // System performance counter enable 20 | uint64_t ic_en:2; // ICache set enable 21 | uint64_t spe:3; // Super page mode enable 22 | uint64_t sde:2; // PALshadow register enable 23 | uint64_t sbe:2; // Stream buffer enable 24 | uint64_t bpMode:2; // Brach prediction mode selection 25 | uint64_t hwe:1; // Allow PAL reserved opcodes in kernel 26 | uint64_t sl_xmit:1; // Cause SROM to advance to next bit 27 | uint64_t sl_rcv:1; 28 | uint64_t va48:1; // Enable 48-bit addresses (45 otherwise) 29 | uint64_t vaForm32:1; // Address formatting on read of IVA_FORM 30 | uint64_t single_issue_h:1; // Force instruction issue from bottom of queues 31 | uint64_t pct0_en:1; // Enable performance counter #0 32 | uint64_t pct1_en:1; // Enable performance counter #1 33 | uint64_t call_pal_r23:1; // Use PALshadow register R23, instead of R27 34 | uint64_t mchk_en:1; // Machine check enable 35 | uint64_t tb_mb_en:1; // Insert MB on TB fills (1 = multiprocessors) 36 | uint64_t bist_fail:1; // Indicates status of BIST (1 = pass / 0 = fail) 37 | uint64_t chip_id:6; // Chip revision ID 38 | uint64_t vptb:18; // Virtual page table base 39 | uint64_t sext_vptb:16; // Sign extension of VPTB 40 | }; 41 | 42 | #define READ_ICTL(dest) \ 43 | { union { uint64_t tmp1; iCtl_t tmp2; } src = { .tmp2 = ev6.ictl }; dest = src.tmp1; } 44 | 45 | #define WRITE_ICTL(src) \ 46 | { union { uint64_t tmp1; iCtl_t tmp2; } dest = { .tmp1 = src }; ev6.ictl = dest.tmp2; } 47 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/axp_arith.h: -------------------------------------------------------------------------------- 1 | /* 2 | * axp_arith.h - Alpha CPU processor - arithmetic instructions 3 | * 4 | * Created on: Nov 21, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | // Addition instructions 11 | #define DOPC_ADDL RCV = SXTL(RAV + RBVL) 12 | #define DOPC_S4ADDL RCV = SXTL((RAV * 4) + RBVL) 13 | #define DOPC_S8ADDL RCV = SXTL((RAV * 8) + RBVL) 14 | 15 | #define DOPC_ADDQ RCV = RAV + RBVL 16 | #define DOPC_S4ADDQ RCV = (RAV * 4) + RBVL 17 | #define DOPC_S8ADDQ RCV = (RAV * 8) + RBVL 18 | 19 | // Subtract instructions 20 | #define DOPC_SUBL RCV = SXTL(RAV - RBVL) 21 | #define DOPC_S4SUBL RCV = SXTL((RAV * 4) - RBVL) 22 | #define DOPC_S8SUBL RCV = SXTL((RAV * 8) - RBVL) 23 | 24 | #define DOPC_SUBQ RCV = RAV - RBVL 25 | #define DOPC_S4SUBQ RCV = (RAV * 4) - RBVL 26 | #define DOPC_S8SUBQ RCV = (RAV * 8) - RBVL 27 | 28 | // Multiply instructions 29 | #define DOPC_MULL RCV = SXTL(SXTL(RAV) * SXTL(RBVL)) 30 | #define DOPC_MULQ RCV = RAV * RBVL 31 | 32 | // Comparison instructions 33 | #define DOPC_CMPEQ RCV = (RAV == RBVL) ? 1 : 0 34 | #define DOPC_CMPULT RCV = (ZXTQ(RAV) < ZXTQ(RBVL)) ? 1 : 0 35 | #define DOPC_CMPULE RCV = (ZXTQ(RAV) <= ZXTQ(RBVL)) ? 1 : 0 36 | #define DOPC_CMPLT RCV = (SXTQ(RAV) < SXTQ(RBVL)) ? 1 : 0 37 | #define DOPC_CMPLE RCV = (SXTQ(RAV) <= SXTQ(RBVL)) ? 1 : 0 38 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/axp_branch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * axp_branch.h - Alpha CPU Processor - branch/control instructions 3 | * 4 | * Created on: Nov 21, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | // branch condition instructions 11 | #define DOPC_BEQ if (SXTQ(RAV) == 0) addPC(DISP21 << 2) 12 | #define DOPC_BGE if (SXTQ(RAV) >= 0) addPC(DISP21 << 2) 13 | #define DOPC_BGT if (SXTQ(RAV) > 0) addPC(DISP21 << 2) 14 | #define DOPC_BLE if (SXTQ(RAV) <= 0) addPC(DISP21 << 2) 15 | #define DOPC_BLT if (SXTQ(RAV) < 0) addPC(DISP21 << 2) 16 | #define DOPC_BNE if (SXTQ(RAV) != 0) addPC(DISP21 << 2) 17 | 18 | // branch set/clear instructions 19 | #define DOPC_BLBC if ((RAV & 1) == 0) addPC(DISP21 << 2) 20 | #define DOPC_BLBS if ((RAV & 1) == 1) addPC(DISP21 << 2) 21 | 22 | // branch instructions 23 | #define DOPC_BSR DOPC_BR 24 | #define DOPC_BR \ 25 | { \ 26 | RAV = state.pcAddr & ~0x03LL; \ 27 | addPC(DISP21 << 2); \ 28 | } 29 | 30 | 31 | // JMP, JSR, RET and JSR_COROUTINE are the same 32 | // instructions with different prediction bits 33 | #define DOPC_JSR DOPC_JMP 34 | #define DOPC_RET DOPC_JMP 35 | #define DOPC_JMP \ 36 | { \ 37 | uint64_t temp = RBV & ~0x03LL; \ 38 | RAV = state.pcAddr & ~0x03LL; \ 39 | setPC(temp | (state.pcAddr & 0x03LL)); \ 40 | } 41 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/axp_bwx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * axp_bwx.h 3 | * 4 | * Created on: Jan 19, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #define DOPC_EXTBL RCV = (RAV >> ((RBVL & 7) * 8)) & MSKQ_BYTE 9 | #define DOPC_EXTWL RCV = (RAV >> ((RBVL & 7) * 8)) & MSKQ_WORD 10 | #define DOPC_EXTLL RCV = (RAV >> ((RBVL & 7) * 8)) & MSKQ_LONG 11 | #define DOPC_EXTQL RCV = RAV >> ((RBVL & 7) * 8) 12 | #define DOPC_EXTWH RCV = (RAV << ((64 - ((RBVL & 7) * 8)) & 63)) & MSKQ_WORD 13 | #define DOPC_EXTLH RCV = (RAV << ((64 - ((RBVL & 7) * 8)) & 63)) & MSKQ_LONG 14 | #define DOPC_EXTQH RCV = (RAV << ((64 - ((RBVL & 7) * 8)) & 63)) & MSKQ_QUAD 15 | 16 | #define DOPC_INSBL RCV = (RAV & MSKQ_BYTE) << ((RBVL & 7) * 8) 17 | #define DOPC_INSWL RCV = (RAV & MSKQ_WORD) << ((RBVL & 7) * 8) 18 | #define DOPC_INSLL RCV = (RAV & MSKQ_LONG) << ((RBVL & 7) * 8) 19 | #define DOPC_INSQL RCV = RAV << ((RBVL & 7) * 8) 20 | #define DOPC_INSWH RCV = (RBVL & 7) ? ((RAV & MSKQ_WORD) >> ((64 - ((RBVL & 7) * 8)) & 63)) : 0 21 | #define DOPC_INSLH RCV = (RBVL & 7) ? ((RAV & MSKQ_LONG) >> ((64 - ((RBVL & 7) * 8)) & 63)) : 0 22 | #define DOPC_INSQH RCV = (RBVL & 7) ? ((RAV & MSKQ_QUAD) >> ((64 - ((RBVL & 7) * 8)) & 63)) : 0 23 | 24 | #define DOPC_MSKBL RCV = RAV & ~(MSKQ_BYTE << (RBVL & 7) * 8) 25 | #define DOPC_MSKWL RCV = RAV & ~(MSKQ_WORD << (RBVL & 7) * 8) 26 | #define DOPC_MSKLL RCV = RAV & ~(MSKQ_LONG << (RBVL & 7) * 8) 27 | #define DOPC_MSKQL RCV = RAV & ~(MSKQ_QUAD << (RBVL & 7) * 8) 28 | #define DOPC_MSKWH RCV = (RBVL & 7) ? (RAV & ~(MSKQ_WORD >> ((64 - ((RBVL & 7) * 8)) & 63))) : RAV 29 | #define DOPC_MSKLH RCV = (RBVL & 7) ? (RAV & ~(MSKQ_LONG >> ((64 - ((RBVL & 7) * 8)) & 63))) : RAV 30 | #define DOPC_MSKQH RCV = (RBVL & 7) ? (RAV & ~(MSKQ_QUAD >> ((64 - ((RBVL & 7) * 8)) & 63))) : RAV 31 | 32 | #define DOPC_SEXTB RCV = SXTB(RBVL) 33 | #define DOPC_SEXTW RCV = SXTW(RBVL) 34 | 35 | #define DOPC_ZAP \ 36 | RCV = RAV & \ 37 | (((RBVL & 1) ? 0 : 0x00000000000000FFULL) | \ 38 | ((RBVL & 2) ? 0 : 0x000000000000FF00ULL) | \ 39 | ((RBVL & 4) ? 0 : 0x0000000000FF0000ULL) | \ 40 | ((RBVL & 8) ? 0 : 0x00000000FF000000ULL) | \ 41 | ((RBVL & 16) ? 0 : 0x000000FF00000000ULL) | \ 42 | ((RBVL & 32) ? 0 : 0x0000FF0000000000ULL) | \ 43 | ((RBVL & 64) ? 0 : 0x00FF000000000000ULL) | \ 44 | ((RBVL & 128) ? 0 : 0xFF00000000000000ULL)) 45 | 46 | #define DOPC_ZAPNOT \ 47 | RCV = RAV & \ 48 | (((RBVL & 1) ? 0x00000000000000FFULL : 0) | \ 49 | ((RBVL & 2) ? 0x000000000000FF00ULL : 0) | \ 50 | ((RBVL & 4) ? 0x0000000000FF0000ULL : 0) | \ 51 | ((RBVL & 8) ? 0x00000000FF000000ULL : 0) | \ 52 | ((RBVL & 16) ? 0x000000FF00000000ULL : 0) | \ 53 | ((RBVL & 32) ? 0x0000FF0000000000ULL : 0) | \ 54 | ((RBVL & 64) ? 0x00FF000000000000ULL : 0) | \ 55 | ((RBVL & 128) ? 0xFF00000000000000ULL : 0)) 56 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/axp_fpbr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * axp_fpbranch.h - branch instructions (floating) 3 | * 4 | * Created on: Feb 9, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #define FPR_SIGN 0x8000000000000000ull 11 | 12 | #define DOPC_FBEQ FPSTART; if ((FAV & ~FPR_SIGN) == 0) addPC(DISP21 << 2) 13 | #define DOPC_FBNE FPSTART; if ((FAV & ~FPR_SIGN) != 0) addPC(DISP21 << 2) 14 | #define DOPC_FBLT FPSTART; if (FAV > FPR_SIGN) addPC(DISP21 << 2) 15 | #define DOPC_FBLE FPSTART; if ((FAV & FPR_SIGN) || (FAV == 0)) addPC(DISP21 << 2) 16 | #define DOPC_FBGT FPSTART; if ((FAV & FPR_SIGN) && (FAV != 0)) addPC(DISP21 << 2) 17 | #define DOPC_FBGE FPSTART; if (FAV <= FPR_SIGN) addPC(DISP21 << 2) 18 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/axp_fpmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * axp_fpmem.h - FP memory instructions 3 | * 4 | * Created on: Feb 9, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #define DOPC_LDF FPSTART; if (FA != 31) FAV = readv32(RBV + SXTW(DISP16)) 11 | #define DOPC_LDG FPSTART; if (FA != 31) FAV = readv64(RBV + SXTW(DISP16)) 12 | #define DOPC_LDS FPSTART; if (FA != 31) FAV = readv32(RBV + SXTW(DISP16)) 13 | #define DOPC_LDT FPSTART; if (FA != 31) FAV = readv64(RBV + SXTW(DISP16)) 14 | 15 | #define DOPC_STF FPSTART; if (FA != 31) writev32(RBV + SXTW(DISP16), FAV) 16 | #define DOPC_STG FPSTART; if (FA != 31) writev64(RBV + SXTW(DISP16), FAV) 17 | #define DOPC_STS FPSTART; if (FA != 31) writev32(RBV + SXTW(DISP16), FAV) 18 | #define DOPC_STT FPSTART; if (FA != 31) writev64(RBV + SXTW(DISP16), FAV) 19 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/axp_fpoper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * axp_fpoper.h - Operate instructions (floating) 3 | * 4 | * Created on: Feb 9, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #define DOPC_MF_FPCR FPSTART; FAV = state.fpcr; 11 | 12 | #define DOPC_MT_FPCR \ 13 | FPSTART; \ 14 | state.fpcr = FAV & 0x7FFF800000000000ull; \ 15 | if (state.fpcr & 0x3F00000000000000ull) \ 16 | state.fpcr |= 0x8000000000000000ull; 17 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/axp_logical.h: -------------------------------------------------------------------------------- 1 | /* 2 | * axp_logical.h - logical instructions 3 | * 4 | * Created on: Jan 19, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #define DOPC_AND RCV = RAV & RBVL 9 | #define DOPC_EQV RCV = RAV ^ ~RBVL 10 | #define DOPC_ORNOT RCV = RAV | ~ RBVL 11 | #define DOPC_XOR RCV = RAV ^ RBVL 12 | 13 | #define DOPC_BIC RCV = RAV & ~RBVL 14 | #define DOPC_BIS RCV = RAV | RBVL 15 | 16 | #define DOPC_CMOVEQ if (SXTQ(RAV) == 0) RCV = RBVL 17 | #define DOPC_CMOVGE if (SXTQ(RAV) >= 0) RCV = RBVL 18 | #define DOPC_CMOVGT if (SXTQ(RAV) > 0) RCV = RBVL 19 | #define DOPC_CMOVLBC if ((RAV & 1) == 0) RCV = RBVL 20 | #define DOPC_CMOVLBS if ((RAV & 1) == 1) RCV = RBVL 21 | #define DOPC_CMOVLE if (SXTQ(RAV) <= 0) RCV = RBVL 22 | #define DOPC_CMOVLT if (SXTQ(RAV) < 0) RCV = RBVL 23 | #define DOPC_CMOVNE if (SXTQ(RAV) != 0) RCV = RBVL 24 | 25 | #define DOPC_SLL RCV = RAV << (RBVL & 0x3F) 26 | #define DOPC_SRL RCV = RAV >> (RBVL & 0x3F) 27 | #define DOPC_SRA RCV = SXTQ(RAV) >> (RBVL & 0x3F) 28 | 29 | //#define DOPC_SRA \ 30 | // RCV = (RBVL & 0x3F) \ 31 | // ? ((RAV >> (RCV & 0x3F)) \ 32 | // | ((RAV >> 63) ? (MSK_QUAD << (64 - (RBVL & 63))) : 0)) \ 33 | // : RAV 34 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/axp_mem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * axp_memory.h - Alpha CPU Processor - memory instructions 3 | * 4 | * Created on: Nov 21, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | // load address instructions 11 | #define DOPC_LDA RAV = RBV + SXTW(DISP16) 12 | #define DOPC_LDAH RAV = RBV + SXTL(DISP16 << 16) 13 | 14 | // load instructions 15 | #define DOPC_LDBU RAV = readv8(RBV + SXTW(DISP16)) 16 | #define DOPC_LDWU RAV = readv16(RBV + SXTW(DISP16)) 17 | #define DOPC_LDL RAV = readv32(RBV + SXTW(DISP16)) 18 | #define DOPC_LDL_L RAV = readv32(RBV + SXTW(DISP16)) 19 | #define DOPC_LDQ RAV = readv64(RBV + SXTW(DISP16)) 20 | #define DOPC_LDQ_L RAV = readv64(RBV + SXTW(DISP16)) 21 | #define DOPC_LDQ_U RAV = readv64((RBV + SXTW(DISP16)) & ~0x07LL) 22 | 23 | // store instructions 24 | #define DOPC_STB writev8(RBV + SXTW(DISP16), RAV) 25 | #define DOPC_STW writev16(RBV + SXTW(DISP16), RAV) 26 | #define DOPC_STL writev32(RBV + SXTW(DISP16), RAV) 27 | #define DOPC_STL_C writev32(RBV + SXTW(DISP16), RAV) 28 | #define DOPC_STQ writev64(RBV + SXTW(DISP16), RAV) 29 | #define DOPC_STQ_C writev64(RBV + SXTW(DISP16), RAV) 30 | #define DOPC_STQ_U writev64((RBV + SXTW(DISP16)) & ~0x07LL, RAV) 31 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/axp_misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * axp_misc.h 3 | * 4 | * Created on: Jan 25, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #define DOPC_IMPLVER RAV = getArchType(); 11 | #define DOPC_AMASK RAV = RBVL & ~getArchFlags(); 12 | 13 | #define DOPC_RPCC RAV = (uint64_t(state.ccOffset) << 32) | uint64_t(state.cc); 14 | 15 | #define DOPC_RC_ RAV = bIntrFlag ? 1 : 0; bIntrFlag = false; 16 | #define DOPC_RS RAV = bIntrFlag ? 1 : 0; bIntrFlag = true; 17 | 18 | // Do nothing at this time until multi-processing are supported 19 | #define DOPC_MB 20 | #define DOPC_WMB 21 | #define DOPC_TRAPB 22 | #define DOPC_EXCB 23 | #define DOPC_FETCH 24 | #define DOPC_FETCH_M 25 | #define DOPC_ECB 26 | #define DOPC_WH64 27 | #define DOPC_WH64EN 28 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/axp_mmu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * axp_mmu.h - Alpha series - memory management 3 | * 4 | * Created on: Feb 11, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #define SPE0_MASK 0x0000FFFF'C0000000LL // Virtual Address <47:30> 11 | #define SPE0_MATCH 0x0000FFF8'00000000LL // Address match <47:31> 12 | #define SPE0_MAP 0x00000000'3FFFFFFFLL // Map address <29:0> 13 | 14 | #define SPE1_MASK 0x0000FE00'00000000LL // Virtual address <47:41> 15 | #define SPE1_MATCH 0x0000FC00'00000000LL // Address match <47:42> 16 | #define SPE1_MAP 0x000001FF'FFFFFFFFLL // Map address <40:0> 17 | #define SPE1_TEST 0x00000100'00000000LL // Test address <40> 18 | #define SPE1_ADD 0x00000E00'00000000LL // Add address <43:41> 19 | 20 | #define SPE2_MASK 0x0000C000'00000000LL // Virtual address <47:46> 21 | #define SPE2_MATCH 0x00008000'00000000LL // Address match <47> 22 | #define SPE2_MAP 0x00000FFF'00000000LL // Map address <43:0> 23 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/axp_tb.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * axp_tlb.cpp - TLB - Translation buffers 3 | * 4 | * Created on: Feb 10, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "dev/cpu/alpha/axp.h" 10 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/ev4.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ev5.h - 21164 series - EV5 architecture 3 | * 4 | * Created on: Feb 6, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "dev/cpu/alpha/axp.h" 11 | 12 | //#include "dev/cpu/alpha/ev5_defs.h" 13 | //#include "dev/cpu/alpha/ev5_ipr.h" 14 | 15 | #define CPUID_AXP21064 16 | 17 | class dec21064_cpuDevice : public alpha_cpuDevice 18 | { 19 | public: 20 | dec21064_cpuDevice(const SystemConfig &config, cstag_t &tagName, Device *owner, uint64_t clock); 21 | ~dec21064_cpuDevice() = default; 22 | 23 | void preset() override; // EV5-specific processor reset 24 | int abort(int why); // Aborting with internal exception codes 25 | void enterException(int excCode); 26 | 27 | int translate(uint64_t vAddr, uint64_t &pAddr, bool &asmb, int accFlags); 28 | 29 | // Virtual PAL hardware instruction calls 30 | void call_pal(uint32_t opWord) override; // PAL00 instruction 31 | void hw_mfpr(uint32_t opWord) override; // PAL19 instruction 32 | void hw_mtpr(uint32_t opWord) override; // PAL1D instruction 33 | void hw_ld(uint32_t opWord) override; // PAL1B instruction 34 | void hw_st(uint32_t opWord) override; // PAL1F instruction 35 | void hw_ret(uint32_t opWord) override; // PAL1E instruction 36 | 37 | private: 38 | // Internal Processor Registers 39 | // struct ev5state 40 | // { 41 | // uint64_t icsr = ICSR_MBO; 42 | // uint64_t mcsr = 0; 43 | // 44 | // uint64_t dc_test = 0; 45 | // uint64_t dc_mode = 0; 46 | // uint64_t maf_mode = 0; 47 | // 48 | // uint64_t PALtemp[24]; // PALtemp registers 49 | // } ev5; 50 | 51 | }; 52 | 53 | DECLARE_DEVICE_TYPE(dec21064, dec21064_cpuDevice); 54 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/ev5.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ev5.h - 21164 series - EV5 architecture 3 | * 4 | * Created on: Feb 6, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "dev/cpu/alpha/axp.h" 11 | 12 | #include "dev/cpu/alpha/ev5_defs.h" 13 | #include "dev/cpu/alpha/ev5_ipr.h" 14 | 15 | #define CPUID_AXP21164 16 | 17 | class dec21164_cpuDevice : public alpha_cpuDevice 18 | { 19 | public: 20 | dec21164_cpuDevice(const SystemConfig &config, cstag_t &tagName, Device *owner, uint64_t clock); 21 | ~dec21164_cpuDevice() = default; 22 | 23 | void preset() override; // EV5-specific processor reset 24 | int abort(int why); // Aborting with internal exception codes 25 | void enterException(int excCode) override; 26 | 27 | int translate(uint64_t vAddr, uint64_t &pAddr, bool &asmb, int accFlags); 28 | 29 | // Virtual PAL hardware instruction calls 30 | void call_pal(uint32_t opWord) override; // PAL00 instruction 31 | void hw_mfpr(uint32_t opWord) override; // PAL19 instruction 32 | void hw_mtpr(uint32_t opWord) override; // PAL1D instruction 33 | void hw_ld(uint32_t opWord) override; // PAL1B instruction 34 | void hw_st(uint32_t opWord) override; // PAL1F instruction 35 | void hw_ret(uint32_t opWord) override; // PAL1E instruction 36 | 37 | private: 38 | // Internal Processor Registers 39 | struct ev5state 40 | { 41 | uint64_t icsr = ICSR_MBO; 42 | uint64_t mcsr = 0; 43 | 44 | uint64_t dc_test = 0; 45 | uint64_t dc_mode = 0; 46 | uint64_t maf_mode = 0; 47 | 48 | uint64_t PALtemp[24]; // PALtemp registers 49 | } ev5; 50 | 51 | }; 52 | 53 | DECLARE_DEVICE_TYPE(dec21164, dec21164_cpuDevice); 54 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/ev5_ipr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ev5_ipr.h - 21164 series - EV5 IPR registers 3 | * 4 | * Created on: Feb 6, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #define IPR_ISR 0x100 // (R) 11 | #define IPR_ITB_TAG 0x101 // (W) Istream Translation Buffer Tag Register 12 | #define IPR_ITB_PTE 0x102 // (R/W) Instruction Translation Buffer Page Table Entry Register 13 | #define IPR_ITB_ASN 0x103 // (R/W) Instruction Translation Buffer Address Space Number Register 14 | #define IPR_ITB_PTE_TEMP 0x104 // (R) 15 | #define IPR_ITB_IA 0x105 // (W) 16 | #define IPR_ITB_IAP 0x106 // (W) 17 | #define IPR_ITB_IS 0x107 // (W) 18 | #define IPR_SIRR 0x108 // (R/W) 19 | #define IPR_ASTRR 0x109 // (R/W) 20 | #define IPR_ASTER 0x10A // (R/W) 21 | #define IPR_EXC_ADDR 0x10B // (R/W) 22 | #define IPR_EXC_SUM 0x10C // (R/W0C) 23 | #define IPR_EXC_MASK 0x10D // (R) 24 | #define IPR_PAL_BASE 0x10E // (R/W) 25 | #define IPR_ICM 0x10F // (R/W) 26 | #define IPR_IPLR 0x110 // (R/W) 27 | #define IPR_INTID 0x111 // (R) 28 | #define IPR_IFAULT_VA_FORM 0x112 // (R) 29 | #define IPR_IVPTBR 0x113 // (R/W) 30 | #define IPR_HWINT_CLR 0x115 // (W) 31 | #define IPR_SL_XMIT 0x116 // (W) 32 | #define IPR_SL_RCV 0x117 // (R) 33 | #define IPR_ICSR 0x118 // (R/W) 34 | #define IPR_IC_FLUSH_CTL 0x119 // (W) 35 | #define IPR_IC_PERR_STAT 0x11A // (R/W1C) 36 | #define IPR_PMCTR 0x11C // (R/W) 37 | 38 | #define IPR_PALtemp0 0x140 // (R/W) 39 | #define IPR_PALtemp1 0x141 // (R/W) 40 | #define IPR_PALtemp2 0x142 // (R/W) 41 | #define IPR_PALtemp3 0x143 // (R/W) 42 | #define IPR_PALtemp4 0x144 // (R/W) 43 | #define IPR_PALtemp5 0x145 // (R/W) 44 | #define IPR_PALtemp6 0x146 // (R/W) 45 | #define IPR_PALtemp7 0x147 // (R/W) 46 | #define IPR_PALtemp8 0x148 // (R/W) 47 | #define IPR_PALtemp9 0x149 // (R/W) 48 | #define IPR_PALtemp10 0x14A // (R/W) 49 | #define IPR_PALtemp11 0x14B // (R/W) 50 | #define IPR_PALtemp12 0x14C // (R/W) 51 | #define IPR_PALtemp13 0x14D // (R/W) 52 | #define IPR_PALtemp14 0x14E // (R/W) 53 | #define IPR_PALtemp15 0x14F // (R/W) 54 | #define IPR_PALtemp16 0x150 // (R/W) 55 | #define IPR_PALtemp17 0x151 // (R/W) 56 | #define IPR_PALtemp18 0x152 // (R/W) 57 | #define IPR_PALtemp19 0x153 // (R/W) 58 | #define IPR_PALtemp20 0x154 // (R/W) 59 | #define IPR_PALtemp21 0x155 // (R/W) 60 | #define IPR_PALtemp22 0x156 // (R/W) 61 | #define IPR_PALtemp23 0x157 // (R/W) 62 | 63 | #define IPR_DTB_ASN 0x200 // (W) 64 | #define IPR_DTB_CM 0x201 // (W) 65 | #define IPR_DTB_TAG 0x202 // (W) 66 | #define IPR_DTB_PTE 0x203 // (R/W) 67 | #define IPR_DTB_PTE_TEMP 0x204 // (R) 68 | #define IPR_MM_STAT 0x205 // (R) 69 | #define IPR_VA 0x206 // (R) 70 | #define IPR_VA_FORM 0x207 // (R) 71 | #define IPR_MVPTBR 0x208 // (W) 72 | #define IPR_DTB_IAP 0x209 // (W) 73 | #define IPR_DTB_IA 0x20A // (W) 74 | #define IPR_DTB_IS 0x20B // (W) 75 | #define IPR_ALT_MODE 0x20C // (W) 76 | #define IPR_CC 0x20D // (W) 77 | #define IPR_CC_CTL 0x20E // (W) 78 | #define IPR_MCSR 0x20F // (R/W) 79 | #define IPR_DC_FLUSH 0x210 // (W) 80 | #define IPR_DC_PERR_STAT 0x212 // (R/W1C) 81 | #define IPR_DC_TEST_CTL 0x213 // (R/W) 82 | #define IPR_DC_TEST_TAG 0x214 // (R/W) 83 | #define IPR_DC_TEST_TAG_TEMP 0x215 // (R/W) 84 | #define IPR_DC_MODE 0x216 // (R/W) 85 | #define IPR_MAF_MODE 0x217 // (R/W) 86 | 87 | 88 | #define PAL_BASE_MASK 0x000000FFFFFFC000ull 89 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/ev6.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ev6.h - DEC 21264 Alpha Processor series 3 | * 4 | * Created on: Nov 22, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #define CPUID_21264CB // 21264 EV68 11 | 12 | #include "dev/cpu/alpha/axp.h" 13 | 14 | class dec21264_cpuDevice : public alpha_cpuDevice 15 | { 16 | public: 17 | dec21264_cpuDevice(const SystemConfig &config, cstag_t &tagName, Device *owner, uint64_t clock); 18 | ~dec21264_cpuDevice() = default; 19 | 20 | void preset() override; // individual processor reset 21 | int abort(int why); // Aborting with internal exception codes 22 | void enterException(int excCode) override; 23 | 24 | int translate(uint64_t vAddr, uint64_t &pAddr, bool &asmb, int accFlags); 25 | 26 | // Virtual PAL hardware instruction calls 27 | void call_pal(uint32_t opWord) override; // PAL00 instruction 28 | void hw_mfpr(uint32_t opWord) override; // PAL19 instruction 29 | void hw_mtpr(uint32_t opWord) override; // PAL1D instruction 30 | void hw_ld(uint32_t opWord) override; // PAL1B instruction 31 | void hw_st(uint32_t opWord) override; // PAL1F instruction 32 | void hw_ret(uint32_t opWord) override; // PAL1E instruction 33 | 34 | // void run(); 35 | 36 | private: 37 | // Internal processor registers 38 | struct ev6state 39 | { 40 | iCtl_t ictl; 41 | } ev6; 42 | }; 43 | 44 | DECLARE_DEVICE_TYPE(dec21264, dec21264_cpuDevice) 45 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/ev6_ipr.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * axp21264_ipr.cpp 3 | * 4 | * Created on: Feb 6, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | 10 | static ctag_t *iprNames[] = 11 | { 12 | "ITB_TAG", "ITB_PTE", "ITB_IAP", "ITB_IA", 13 | "ITB_IS", "", "EXC_ADDR", "IVA_FORM", 14 | "", "CM", "IER", "IER_CM", 15 | "SIRR", "ISUM", "HW_INT_CLR", "EXC_SUM", 16 | "PAL_BASE", "I_CTL", "IC_FLUSH_ASM", "IC_FLUSH", 17 | "PCTR_CTL", "CLR_MAP", "I_STAT", "SLEEP", 18 | "", "", "", "", 19 | "", "", "", "", 20 | "DTB_TAG0", "DTB_PTE0", "", "", 21 | "DTB_IS0", "DTB_ASN0", "DTB_ALTMODE", "MM_STAT", 22 | "M_CTL", "DC_CTL", "DC_STAT", "C_DATA", 23 | "C_SHFT", "", "", "", 24 | "", "", "", "", 25 | "", "", "", "", 26 | "", "", "", "", 27 | "", "", "", "" 28 | 29 | "PCXT0", "PCXT0_ASN", 30 | "PCXT0_ASTER", "PCXT0_ASTER_ASN", 31 | "PCXT0_ASTRR", "PCXT0_ASTRR_ASN", 32 | "PCXT0_ASTRR_ASTER", "PCXT0_ASTRR_ASTER_ASN", 33 | "PCXT0_PPCE", "PCXT0_PPCE_ASN", 34 | "PCXT0_PPCE_ASTER", "PCXT0_PPCE_ASTER_ASN", 35 | "PCXT0_PPCE_ASTRR", "PCXT0_PPCE_ASTRR_ASN", 36 | "PCXT0_PPCE_ASTRR_ASTER", "PCXT0_PPCE_ASTRR_ASTER_ASN", 37 | "PCXT0_FPE", "PCXT0_FPE_ASN", 38 | "PCXT0_FPE_ASTER", "PCXT0_FPE_ASTER_ASN", 39 | "PCXT0_FPE_ASTRR", "PCXT0_FPE_ASTRR_ASN", 40 | "PCXT0_FPE_ASTRR_ASTER", "PCXT0_FPE_ASTRR_ASTER_ASN", 41 | "PCXT0_FPE_PPCE", "PCXT0_FPE_PPCE_ASN", 42 | "PCXT0_FPE_PPCE_ASTER", "PCXT0_FPE_PPCE_ASTER_ASN", 43 | "PCXT0_FPE_PPCE_ASTRR", "PCXT0_FPE_PPCE_ASTRR_ASN", 44 | "PCXT0_FPE_PPCE_ASTRR_ASTER", "PCXT0_FPE_PPCE_ASTRR_ASTER_ASN", 45 | 46 | "PCXT1", "PCXT1_ASN", 47 | "PCXT1_ASTER", "PCXT1_ASTER_ASN", 48 | "PCXT1_ASTRR", "PCXT1_ASTRR_ASN", 49 | "PCXT1_ASTRR_ASTER", "PCXT1_ASTRR_ASTER_ASN", 50 | "PCXT1_PPCE", "PCXT1_PPCE_ASN", 51 | "PCXT1_PPCE_ASTER", "PCXT1_PPCE_ASTER_ASN", 52 | "PCXT1_PPCE_ASTRR", "PCXT1_PPCE_ASTRR_ASN", 53 | "PCXT1_PPCE_ASTRR_ASTER", "PCXT1_PPCE_ASTRR_ASTER_ASN", 54 | "PCXT1_FPE", "PCXT1_FPE_ASN", 55 | "PCXT1_FPE_ASTER", "PCXT1_FPE_ASTER_ASN", 56 | "PCXT1_FPE_ASTRR", "PCXT1_FPE_ASTRR_ASN", 57 | "PCXT1_FPE_ASTRR_ASTER", "PCXT1_FPE_ASTRR_ASTER_ASN", 58 | "PCXT1_FPE_PPCE", "PCXT1_FPE_PPCE_ASN", 59 | "PCXT1_FPE_PPCE_ASTER", "PCXT1_FPE_PPCE_ASTER_ASN", 60 | "PCXT1_FPE_PPCE_ASTRR", "PCXT1_FPE_PPCE_ASTRR_ASN", 61 | "PCXT1_FPE_PPCE_ASTRR_ASTER", "PCXT1_FPE_PPCE_ASTRR_ASTER_ASN" 62 | 63 | }; 64 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/ev6_ipr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ev6_ipr.h - 21264 series - EV6 internal processor registers 3 | * 4 | * Created on: Feb 6, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #define ICTL_BP_MODE_FALL 0x2 // 1x, where 'x' is not relevant 11 | #define ICTL_BP_MODE_DYN 0x0 // 0x, where 'x' is relevant 12 | #define ICTL_BP_MODE_LOCAL 0x1 // Local history prediction 13 | #define ICTL_BP_MODE_CHOICE 0x0 // Choice selected prediction 14 | 15 | #define ICTL_SDE_ENABLE 0x2 // bit 0 does not affect 21264 operation 16 | 17 | #define PAL_BASE_MASK 0x00000FFFFFFF8000ull 18 | 19 | 20 | // IPR index definitions 21 | 22 | #define IPR_ITB_TAG 0x00 23 | #define IPR_ITB_PTE 0x01 24 | #define IPR_ITB_IAP 0x02 25 | #define IPR_ITB_IA 0x03 26 | #define IPR_ITB_IS 0x04 27 | 28 | #define IPR_EXC_ADDR 0x06 29 | #define IPR_IVA_FORM 0x07 30 | 31 | #define IPR_CM 0x09 32 | #define IPR_IER 0x0A 33 | #define IPR_IER_CM 0x0B 34 | #define IPR_SIRR 0x0C 35 | #define IPR_ISUM 0x0D 36 | #define IPR_HW_INT_CLR 0x0E 37 | #define IPR_EXC_SUM 0x0F 38 | #define IPR_PAL_BASE 0x10 39 | #define IPR_I_CTL 0x11 40 | #define IPR_IC_FLUSH_ASM 0x12 41 | #define IPR_IC_FLUSH 0x13 42 | #define IPR_PCTR_CTL 0x14 43 | #define IPR_CLR_MAP 0x15 44 | #define IPR_I_STAT 0x16 45 | #define IPR_SLEEP 0x17 46 | 47 | #define IPR_DTB_IA 0xA3 48 | #define IPR_DTB_IAP 0xA2 49 | #define IPR_DTB_IS0 0x24 50 | #define IPR_DTB_IS1 0xA4 51 | #define IPR_DTB_TAG0 0x20 52 | #define IPR_DTB_TAG1 0xA0 53 | #define IPR_DTB_PTE0 0x21 54 | #define IPR_DTB_PTE1 0xA1 55 | #define IPR_DTB_ASN0 0x25 56 | #define IPR_DTB_ASN1 0xA5 57 | #define IPR_DTB_ALTMODE 0x26 58 | 59 | #define IPR_MM_STAT 0x27 60 | #define IPR_M_CTL 0x28 61 | #define IPR_DC_CTL 0x29 62 | #define IPR_DC_STAT 0x2A 63 | #define IPR_C_DATA 0x2B 64 | #define IPR_C_SHFT 0x2C 65 | 66 | #define IPR_PCXT0 0x40 67 | #define IPR_PCXT1 0x60 68 | 69 | #define PCXT_ASN 70 | #define PCXT_ASTER 71 | #define PCXT_ASTRR 72 | #define PCXT_PPCE 73 | #define PCXT_FPE 74 | 75 | // Ebox IPR registers 76 | #define IPR_CC 0xC0 77 | #define IPR_CC_CTL 0xC1 78 | #define IPR_VA 0xC2 79 | #define IPR_VA_FORM 0xC3 80 | #define IPR_VA_CTL 0xC4 81 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/fw.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fw.h - firmware loader package 3 | * 4 | * Created on: Feb 6, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | struct romHeader 11 | { 12 | uint32_t magic1; // Validation Pattern (5A5AC3C3) 13 | uint32_t magic2; // Inverse Validation Pattern (A5A53C3C) 14 | uint32_t hdrSize; // Header Size (in bytes) 15 | uint32_t imgChkSum; // Image Checksum 16 | uint32_t imgSize; // Image Size; 17 | uint32_t flgDecmp; // Decompression Flag 18 | uint32_t dstAddrLow; // Destination Address (Low) 19 | uint32_t dstAddrHigh; // Destination Address (High) 20 | uint8_t hdrRevision; // Revision Header 21 | uint8_t idRom; // Firmware ID 22 | uint8_t hdrExtRev; // External Revision Header 23 | uint8_t rsvd; // Reserved 24 | uint32_t romSize; // Flash ROM Image Size 25 | uint32_t idOptFwLow; // Optional Firmware ID (Low) 26 | uint32_t idOptFwHigh; // Optional Firmware ID (High) 27 | uint32_t romOffset; // ROM Offset 28 | uint32_t hdrChkSum; // Header Checksum 29 | }; 30 | 31 | // Pattern validation for ROM header 32 | #define ROM_MAGIC1 0x5A5AC3C3 33 | #define ROM_MAGIC2 0xA5A53C3C 34 | 35 | // Firmware ID 36 | #define FWID_DBM 0 // Debug Monitor 37 | #define FWID_WNT 1 // Windows NT ARC 38 | #define FWID_SRM 2 // Alpha SRM Console 39 | #define FWID_FSB 6 // Fail-safe Booter 40 | #define FWID_MILO 7 // Linux Miniloader 41 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/load.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * load.cpp - loading executable files 3 | * 4 | * Created on: Jan 22, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "dev/cpu/alpha/axp.h" 10 | #include "dev/cpu/alpha/fw.h" 11 | 12 | bool alpha_cpuDevice::load(ifstream &fin, offs_t off) 13 | { 14 | uint8_t blkData[512]; 15 | offs_t soff = off; 16 | 17 | romHeader romHdr; 18 | uint64_t romSize; 19 | 20 | // assert(mapProgram != nullptr); 21 | 22 | if (off == 0) 23 | { 24 | // Check if it contains LFU image 25 | fin.seekg(0, ios_base::beg); 26 | fin.read((char *)blkData, sizeof(blkData)); 27 | 28 | // Check if file is LFU image 29 | if (!memcmp((char *)&blkData[4], "LFU ", 4)) { 30 | // strip first LFU block as not needed. 31 | fin.seekg(0x240, ios_base::beg); 32 | 33 | // Reserve first 9 MB memory space uncompressed 34 | // firmware space and loading image at starting at 35 | // address 90.0000 36 | soff = off = 0x900000; 37 | } 38 | else if ((*(uint32_t *)&blkData[0] == ROM_MAGIC1) && 39 | (*(uint32_t *)&blkData[4] == ROM_MAGIC2)) 40 | { 41 | fin.seekg(0, ios_base::beg); 42 | fin.read((char *)&romHdr, sizeof(romHdr)); 43 | // if ((romHdr.magic1 == ROM_MAGIC1) && 44 | // (romHdr.magic2 == ROM_MAGIC2)) 45 | soff = off = romHdr.dstAddrLow; 46 | romSize = romHdr.romSize; 47 | fmt::printf("%s: Loading firmware image at %X (%d bytes)\n", 48 | getDeviceName(), off, romSize); 49 | } 50 | else 51 | { 52 | fmt::printf("%s: Not executable firmware image - aborted.\n", getDeviceName()); 53 | return false; 54 | } 55 | } 56 | 57 | while (!fin.eof()) 58 | { 59 | fin.read((char *)blkData, sizeof(blkData)); 60 | mapProgram.writeBlock(off, blkData, fin.gcount()); 61 | off += fin.gcount(); 62 | } 63 | fin.close(); 64 | 65 | fmt::printf("%s: Loaded %s into %llX-%llX (length: %d bytes)\n", 66 | getDeviceName(), "LFU" /* fname */, soff, off, off - soff); 67 | 68 | // Set starting PC and PAL address 69 | setPCAddress(soff|1); 70 | setPALAddress(soff); 71 | 72 | return true; 73 | } 74 | 75 | 76 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/opcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * opcode.h - Alpha CPU Processor (Opcode) package 3 | * 4 | * Created on: Nov 20, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | //#define OPC_nPAL 0x00 9 | //#define OPC_nLDA 0x08 10 | //#define OPC_nLDAH 0x09 11 | //#define OPC_nLDBU 0x0A 12 | //#define OPC_nLDQ_U 0x0B 13 | //#define OPC_nLDWU 0x0C 14 | //#define OPC_nSTW 0x0D 15 | //#define OPC_nSTB 0x0E 16 | //#define OPC_nSTQ_U 0x0F 17 | //#define OPC_nIALU 0x10 // ALU Operate instruction 18 | //#define OPC_nILOG 0x11 19 | //#define OPC_nISHFT 0x12 20 | //#define OPC_nIMUL 0x13 21 | //#define OPC_nIFLT 0x14 22 | //#define OPC_nVAX 0x15 23 | //#define OPC_nIEEE 0x16 24 | //#define OPC_nFP 0x17 25 | //#define OPC_nMISC 0x18 26 | //#define OPC_nPAL19 0x19 27 | //#define OPC_nJMP 0x1A 28 | //#define OPC_nPAL1B 0x1B 29 | //#define OPC_nFLTI 0x1C 30 | //#define OPC_nPAL1D 0x1D 31 | //#define OPC_nPAL1E 0x1E 32 | //#define OPC_nPAL1F 0x1F 33 | //#define OPC_nLDF 0x20 34 | //#define OPC_nLOG 0x21 35 | //#define OPC_nLDS 0x22 36 | //#define OPC_nLDT 0x23 37 | //#define OPC_nSTF 0x24 38 | //#define OPC_nSTG 0x25 39 | //#define OPC_nSTS 0x26 40 | //#define OPC_nSTT 0x27 41 | //#define OPC_nLDL 0x28 42 | //#define OPC_nLDQ 0x29 43 | //#define OPC_nLDL_L 0x2A 44 | //#define OPC_nLDQ_L 0x2B 45 | //#define OPC_nSTL 0x2C 46 | //#define OPC_nSTQ 0x2D 47 | //#define OPC_nSTL_C 0x2E 48 | //#define OPC_nSTQ_C 0x2F 49 | //#define OPC_nBR 0x30 50 | //#define OPC_nFBEQ 0x31 51 | //#define OPC_nFBLT 0x32 52 | //#define OPC_nFBLE 0x33 53 | //#define OPC_nBSR 0x34 54 | //#define OPC_nFBNE 0x35 55 | //#define OPC_nFBGE 0x36 56 | //#define OPC_nFBGT 0x37 57 | //#define OPC_nBLBC 0x38 58 | //#define OPC_nBEQ 0x39 59 | //#define OPC_nBLT 0x3A 60 | //#define OPC_nBLE 0x3B 61 | //#define OPC_nBLBS 0x3C 62 | //#define OPC_nBNE 0x3D 63 | //#define OPC_nBGE 0x3E 64 | //#define OPC_nBGT 0x3F 65 | 66 | enum opCodes { 67 | OPC_PAL = 0, OPC_01, OPC_02, OPC_03, 68 | OPC_04, OPC_05, OPC_06, OPC_07, 69 | OPC_LDA, OPC_LDAH, OPC_LDBU, OPC_LDQ_U, 70 | OPC_LDWU, OPC_STW, OPC_STB, OPC_STQ_U, 71 | OPC_INTA, OPC_INTL, OPC_INTS, OPC_INTM, 72 | OPC_ITFP, OPC_FLTV, OPC_FLTI, OPC_FLTL, 73 | OPC_MISC, OPC_HW_MFPR, OPC_JSR, OPC_HW_LD, 74 | OPC_FPTI, OPC_HW_MTPR, OPC_RET, OPC_HW_ST, 75 | OPC_LDF, OPC_LDG, OPC_LDS, OPC_LDT, 76 | OPC_STF, OPC_STG, OPC_STS, OPC_STT, 77 | OPC_LDL, OPC_LDQ, OPC_LDL_L, OPC_LDQ_L, 78 | OPC_STL, OPC_STQ, OPC_STL_C, OPC_STQ_C, 79 | OPC_BR, OPC_FBEQ, OPC_FBLT, OPC_FBLE, 80 | OPC_BSR, OPC_FBNE, OPC_FBGE, OPC_FBGT, 81 | OPC_BLBC, OPC_BEQ, OPC_BLT, OPC_BLE, 82 | OPC_BLBS, OPC_BNE, OPC_BGE, OPC_BGT 83 | }; 84 | -------------------------------------------------------------------------------- /src/dev/cpu/alpha/opcodes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * opcodes.h 3 | * 4 | * Created on: Jan 17, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | //// Opcode field types 9 | //#define OPT_PAL 0 // PALcode instructions 10 | //#define OPT_BRA 1 // Branch instructions 11 | //#define OPT_MEM 2 // Memory instructions 12 | //#define OPT_IOP 3 // Operate instructions (integer) 13 | //#define OPT_FOP 4 // Floating instructions 14 | // 15 | //// Operand modes 16 | //#define OPR_PAL 0x0200 // PALcode number 17 | //#define OPR_MJP 0x0100 // Jump displacement 18 | //#define OPR_MDP 0x0080 // Memory displacement 19 | //#define OPR_BDP 0x0040 // Branch displacement 20 | //#define OPR_IDX 0x0020 // Register B - index 21 | //#define OPR_LIT 0x0010 // 8-bit literal 22 | //#define OPR_RC 0x0004 // Register C 23 | //#define OPR_RB 0x0002 // Register B 24 | //#define OPR_RA 0X0001 // Register A 25 | //#define OPR_NONE 0x0000 // Hardware PALcode 26 | // 27 | //#define OP_PAL (OPT_PAL|OPR_PAL) 28 | //#define OP_BRA (OPT_BRA|OPR_RA|OPR_BDP) 29 | //#define OP_MJP (OPT_MEM|OPR_RA|OPR_RB|OPR_MJP) 30 | //#define OP_MFC (OPT_MEM|OPR_RA|OPR_RB) 31 | //#define OP_MFC1 (OPT_MEM) 32 | //#define OP_MEM (OPT_MEM|OPR_RA|OPR_RB|OPR_MDP) 33 | //#define OP_IPR (OPT_MEM|OPR_RA|OPR_MDP) // OPR_IPR 34 | //#define OP_IOP (OPT_IOP|OPR_RA|OPR_RB|OPR_RC) 35 | //#define OP_FOP (OPT_FOP|OPR_RA|OPR_RB|OPR_RC) 36 | -------------------------------------------------------------------------------- /src/dev/cpu/i8080/i8080op.h: -------------------------------------------------------------------------------- 1 | /* 2 | * i8080op.h - Intel 8080/8085 processor - opcodes 3 | * 4 | * Created on: Sep 6, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | 9 | #define DO_NOP // Do nothing 10 | 11 | #define DO_LDAX REG_A = readMem(REGW(opCode)); 12 | #define DO_LDA REG_A = readMem(tval); 13 | #define DO_LHLD REG_HL = readMem(tval) | (readMem(tval+1) << 8); 14 | #define DO_LXI REGW(opCode) = tval; 15 | 16 | #define DO_STAX writeMem(REGW(opCode), REG_A); 17 | #define DO_STA writeMem(tval, REG_A); 18 | #define DO_SHLD writeMem(tval, REG_HL); writeMem(tval+1, REG_HL >> 8); 19 | 20 | #define DO_MOV REGB(opCode) = REGA(opCode); 21 | #define DO_MOVMr writeMem(REG_HL, REGA(opCode)); 22 | #define DO_MOVrM REGB(opCode) = readMem(REG_HL); 23 | #define DO_MVI REGB(opCode) = tval; 24 | #define DO_MVIM writeMem(REG_HL, tval); 25 | 26 | #define DO_INR REGB(opCode) = opINR(REGB(opCode)); 27 | #define DO_DCR REGB(opCode) = opDCR(REGB(opCode)); 28 | #define DO_INRM writeMem(REG_HL, opINR(readMem(REG_HL))); 29 | #define DO_DCRM writeMem(REG_HL, opDCR(readMem(REG_HL))); 30 | #define DO_INX REGW(opCode)++; 31 | #define DO_DCX REGW(opCode)--; 32 | 33 | // if (is8085()) 34 | // { 35 | // afReg.sb.l &= ~SR_VF; 36 | // if (bcReg.sw == 0x0000) 37 | // afReg.ub.l |= SR_VF; 38 | // } 39 | 40 | #define DO_RLC \ 41 | REG_A = (REG_A << 1) | (REG_A >> 7); \ 42 | REG_F = (REG_F & ~SR_CF) | (REG_A & SR_CF); 43 | 44 | #define DO_RRC \ 45 | REG_F = (REG_F & ~SR_CF) | (REG_A & SR_CF); \ 46 | REG_A = (REG_A >> 1) | (REG_A << 7); 47 | 48 | #define DO_RAL \ 49 | cFlag = REG_A & SR_CF; \ 50 | REG_F = (REG_F & ~SR_CF) | ((REG_A >> 7) & SR_CF); \ 51 | REG_A = (REG_A << 1) | cFlag; 52 | 53 | #define DO_RAR \ 54 | cFlag = (REG_A & SR_CF) << 7; \ 55 | REG_F = (REG_F & ~SR_CF) | (REG_A & SR_CF); \ 56 | REG_A = (REG_A >> 1) | cFlag; 57 | 58 | #define DO_DAD opDAD(REGW(opCode)); 59 | 60 | #define DO_ADD opADD(REGA(opCode)); 61 | #define DO_ADC opADC(REGA(opCode)); 62 | #define DO_SUB opSUB(REGA(opCode)); 63 | #define DO_SBB opSBB(REGA(opCode)); 64 | #define DO_ANA opANA(REGA(opCode)); 65 | #define DO_XRA opXRA(REGA(opCode)); 66 | #define DO_ORA opORA(REGA(opCode)); 67 | #define DO_CMP opCMP(REGA(opCode)); 68 | 69 | #define DO_ADDM opADD(readMem(REG_HL)); 70 | #define DO_ADCM opADC(readMem(REG_HL)); 71 | #define DO_SUBM opSUB(readMem(REG_HL)); 72 | #define DO_SBBM opSBB(readMem(REG_HL)); 73 | #define DO_ANAM opANA(readMem(REG_HL)); 74 | #define DO_XRAM opXRA(readMem(REG_HL)); 75 | #define DO_ORAM opORA(readMem(REG_HL)); 76 | #define DO_CMPM opCMP(readMem(REG_HL)); 77 | 78 | #define DO_ADI opADD(tval); 79 | #define DO_ACI opADC(tval); 80 | #define DO_SUI opSUB(tval); 81 | #define DO_SBI opSBB(tval); 82 | #define DO_ANI opANA(tval); 83 | #define DO_XRI opXRA(tval); 84 | #define DO_ORI opORA(tval); 85 | #define DO_CPI opCMP(tval); 86 | 87 | 88 | #define DO_STC REG_F |= SR_CF; 89 | #define DO_CMC REG_F ^= SR_CF; 90 | #define DO_CMA REG_A ^= 0xFF; 91 | 92 | // if (is8085()) 93 | // afReg.ub.l |= SR_HF|SR_VF; 94 | 95 | #define DO_RST opRST(REGBn(opCode)); 96 | #define DO_HLT 97 | #define DO_EI enableInterrupts(true); 98 | #define DO_DI enableInterrupts(false); -------------------------------------------------------------------------------- /src/dev/cpu/m6500/debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * debug.h - MOS 65xx processor - debugging/tracing 3 | * 4 | * Created on: Sep 6, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #define ONTRACE if(dbg.checkAnyFlags(DBG_TRACE)) 9 | 10 | #define PRE_IMPL(opcode) \ 11 | { \ 12 | dbg.log("%04X %-3s\n", pcReg.uw, opcode); \ 13 | } 14 | 15 | #define POST_IMPL 16 | 17 | 18 | 19 | #define OP_EXEC(opcode, format) \ 20 | ONTRACE PRE_##format(opcode); \ 21 | DO_##opcode; \ 22 | POST_##format; 23 | 24 | #define OP_FUNC(opcode, call, format) \ 25 | ONTRACE PRE_##format(opcode); \ 26 | call(); \ 27 | POST_##format; 28 | -------------------------------------------------------------------------------- /src/dev/cpu/m6500/m6502.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * m6500.cpp - MOS 6500 processor emulation package 3 | * 4 | * Created on: Feb 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "dev/cpu/m6500/m6502.h" 10 | #include "dev/cpu/m6500/m6502op.h" 11 | 12 | m6502_cpuDevice::m6502_cpuDevice(const SystemConfig &config, const DeviceType &type, 13 | const string &tagName, Device *owner, uint64_t clock, int addrWidth) 14 | : cpuDevice(config, type, tagName, owner, clock), 15 | mapProgramConfig("program", LittleEndian, 8, 16, 8, addrWidth, 16, 0) 16 | { 17 | // Initialize opcode table for disassembler 18 | // initOpcodeTable(); 19 | } 20 | 21 | mapConfigList m6502_cpuDevice::getAddressConfigList() const 22 | { 23 | return mapConfigList { 24 | { aspace::asProgram, &mapProgramConfig }, 25 | }; 26 | } 27 | 28 | DEFINE_DEVICE_TYPE(m6502, m6502_cpuDevice, "m6502", "MOS 6502") 29 | 30 | // MOS 6502 processor (with 16-bit addressing) 31 | m6502_cpuDevice::m6502_cpuDevice(const SystemConfig &config, 32 | const string &tagName, Device *owner, uint64_t clock) 33 | : m6502_cpuDevice(config, m6502, tagName, owner, clock, 16) 34 | { 35 | } 36 | 37 | // // MOS 6504 processor (with 13-bit addressing) 38 | // m6504_cpuDevice::m6504_cpuDevice(const SystemConfig &config, 39 | // const string &tagName, Device *owner, uint64_t clock) 40 | // : m6502_cpuDevice(config, m6502, tagName, owner, clock, 13) 41 | // { 42 | // } 43 | 44 | void m6502_cpuDevice::reset() 45 | { 46 | // Clear all CPU registers 47 | aReg = 0; 48 | xReg = 0; 49 | yReg = 0; 50 | pReg = 0; 51 | spReg.uw = 0x0100; 52 | pcReg = 0; 53 | 54 | } 55 | 56 | void m6502_cpuDevice::startDevice() 57 | { 58 | 59 | // Register CPU registers 60 | addState(m6502_A, "A", aReg); 61 | addState(m6502_X, "X", xReg); 62 | addState(m6502_Y, "Y", yReg); 63 | addState(m6502_P, "P", pReg); 64 | addState(m6502_S, "SP", spReg.uw); 65 | addState(m6502_PC, "PC", pcReg); 66 | 67 | getAddressSpace(AS_PROGRAM)->setMemorySpecific(mapProgram); 68 | } 69 | 70 | 71 | void m6502_cpuDevice::step(Console *user) 72 | { 73 | 74 | } 75 | 76 | void m6502_cpuDevice::run() 77 | { 78 | 79 | } 80 | 81 | void m6502_cpuDevice::execute() 82 | { 83 | 84 | uint8_t opCode = mapProgram.read8(pcReg, this); 85 | 86 | switch (opCode) 87 | { 88 | case 0x00: // BRK instruction 89 | DO_OPC(BRK, IMP); 90 | break; 91 | 92 | case 0x18: // CLC instruction 93 | DO_OPC(CLC, IMP); 94 | break; 95 | 96 | case 0xD8: // CLD instruction 97 | DO_OPC(CLD, IMP); 98 | break; 99 | 100 | case 0x58: // CLI instruction 101 | DO_OPC(CLI, IMP); 102 | break; 103 | 104 | case 0xB8: // CLV instruction 105 | DO_OPC(CLV, IMP); 106 | break; 107 | 108 | case 0x38: // SEC instruction 109 | DO_OPC(SEC, IMP); 110 | break; 111 | 112 | case 0xF8: // SED instruction 113 | DO_OPC(SED, IMP); 114 | break; 115 | 116 | case 0x78: // SEI instruction 117 | DO_OPC(SEI, IMP); 118 | break; 119 | 120 | case 0xAA: // TAX instruction 121 | DO_OPC(TAX, IMP); 122 | break; 123 | 124 | case 0xA8: // TAY instruction 125 | DO_OPC(TAY, IMP); 126 | break; 127 | 128 | case 0xBA: // TSX instruction 129 | DO_OPC(TSX, IMP); 130 | break; 131 | 132 | case 0x8A: // TXA instruction 133 | DO_OPC(TXA, IMP); 134 | break; 135 | 136 | case 0x9A: // TXS instruction 137 | DO_OPC(TXS, IMP); 138 | break; 139 | 140 | case 0x98: // TYA instruction 141 | DO_OPC(TYA, IMP); 142 | break; 143 | } 144 | } -------------------------------------------------------------------------------- /src/dev/cpu/m6500/m6502.h: -------------------------------------------------------------------------------- 1 | /* 2 | * m6500.h - MOS 6500 processor emulation package 3 | * 4 | * Created on: Feb 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/devproc.h" 11 | 12 | #define PSW_N 0x80 // negative bit 13 | #define PSW_V 0x40 // overflow bit 14 | #define PSW_B 0x10 // break bit 15 | #define PSW_D 0x08 // decinal bit 16 | #define PSW_I 0x04 // 17 | #define PSW_Z 0x02 // zero bit 18 | #define PSW_C 0x01 // carry bit 19 | 20 | #define DO_OPC(opCode, opType) 21 | 22 | class m6502_cpuDevice : public cpuDevice 23 | { 24 | public: 25 | m6502_cpuDevice(const SystemConfig &config, const string &tagName, Device *owner, uint64_t clock); 26 | virtual ~m6502_cpuDevice() = default; 27 | 28 | enum registerState 29 | { 30 | m6502_A, m6502_X, m6502_Y, m6502_P, 31 | m6502_S, m6502_PC, m6502_IR 32 | }; 33 | 34 | mapConfigList getAddressConfigList() const; 35 | 36 | void step(Console *user) override; 37 | 38 | void run(); 39 | void execute(); 40 | void reset(); 41 | 42 | void startDevice(); 43 | 44 | protected: 45 | m6502_cpuDevice(const SystemConfig &config, const DeviceType &type, 46 | const string &tagName, Device *owner, uint64_t clock, int addrWidth); 47 | 48 | inline void incSP() { spReg.ub.l++; } 49 | inline void decSP() { spReg.ub.l--; } 50 | 51 | inline void setNZ(int8_t val) 52 | { 53 | pReg &= ~(PSW_N|PSW_Z); 54 | if (val == 0) 55 | pReg |= PSW_Z; 56 | if (val < 0) 57 | pReg |= PSW_N; 58 | } 59 | 60 | // 6502 opcode function calls 61 | 62 | protected: 63 | uint8_t aReg; // A register (accumlator) 64 | uint8_t xReg; // X register (X index) 65 | uint8_t yReg; // Y register (Y index) 66 | uint8_t pReg; // P register (status) 67 | pair16_t spReg; // S register (stack - always 0100-01FF) 68 | uint16_t pcReg; // PC register 69 | 70 | mapAddressConfig mapProgramConfig; 71 | 72 | aspace::MemoryAccess<16, 0, 0, LittleEndian>::specific mapProgram; 73 | }; 74 | -------------------------------------------------------------------------------- /src/dev/cpu/m6500/m6502op.h: -------------------------------------------------------------------------------- 1 | /* 2 | * m6500.h - MOS 65xx processor - opcodes 3 | * 4 | * Created on: Sep 3, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | 11 | #define DOPC_ADC 12 | #define DOPC_AND 13 | #define DOPC_ASL 14 | #define DOPC_BIT 15 | 16 | // Branch instructions 17 | #define DOPC_BPL 18 | #define DOPC_BMI 19 | #define DOPC_BVC 20 | #define DOPC_BVS 21 | #define DOPC_BCC 22 | #define DOPC_BNE 23 | #define DOPC_BEQ 24 | 25 | #define DOPC_CLC pReg &= ~PSW_C; 26 | #define DOPC_CLD pReg &= ~PSW_D; 27 | #define DOPC_CLI pReg &= ~PSW_I; 28 | #define DOPC_CLV pReg &= ~PSW_V; 29 | #define DOPC_CMP 30 | #define DOPC_CPX 31 | #define DOPC_CPY 32 | #define DOPC_DEC 33 | #define DOPC_DEX 34 | #define DOPC_DEY 35 | #define DOPC_EOR 36 | #define DOPC_INC 37 | #define DOPC_INX 38 | #define DOPC_INY 39 | #define DOPC_JMP 40 | #define DOPC_JSR 41 | #define DOPC_LDA 42 | #define DOPC_LDX 43 | #define DOPC_LDY 44 | #define DOPC_LSR 45 | #define DOPC_NOP 46 | #define DOPC_ORA 47 | #define DOPC_PHA 48 | #define DOPC_PHP 49 | #define DOPC_PLA 50 | #define DOPC_PLP 51 | #define DOPC_ROL 52 | #define DOPC_ROR 53 | #define DOPC_RTI 54 | #define DOPC_RTS 55 | #define DOPC_SBC 56 | #define DOPC_SEC pReg |= PSW_C; 57 | #define DOPC_SED pReg |= PSW_D; 58 | #define DOPC_SEI pReg |= PSW_I; 59 | #define DOPC_STA 60 | #define DOPC_STX 61 | #define DOPC_STY 62 | #define DOPC_TAX xReg = aReg; setNZ(xReg); 63 | #define DOPC_TAY yReg = aReg; setNZ(yReg); 64 | #define DOPC_TSX xReg = spReg.ub.l; 65 | #define DOPC_TXA aReg = xReg; setNZ(aReg); 66 | #define DOPC_TXS spReg.ub.l = xReg; 67 | #define DOPC_TYA aReg = yReg; setNZ(aReg); 68 | 69 | 70 | #define DO_OPC(opCode, opType) 71 | -------------------------------------------------------------------------------- /src/dev/cpu/mcs48/load.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * load.cpp - loading executable files 3 | * 4 | * Created on: Mar 26, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "dev/cpu/mcs48/mcs48.h" 10 | 11 | bool mcs48_cpuDevice::load(ifstream &fin, offs_t off) 12 | { 13 | uint8_t blkData[512]; 14 | offs_t soff = off; 15 | 16 | // assert(mapProgram != nullptr); 17 | 18 | // if (off == 0) 19 | // { 20 | // // Check if it contains LFU image 21 | // fin.seekg(0, ios_base::beg); 22 | // fin.read((char *)blkData, sizeof(blkData)); 23 | // 24 | // // Check if file is LFU image 25 | // if (!memcmp((char *)&blkData[4], "LFU ", 4)) { 26 | // // strip first LFU block as not needed. 27 | // fin.seekg(0x240, ios_base::beg); 28 | // 29 | // // Reserve first 9 MB memory space uncompressed 30 | // // firmware space and loading image at starting at 31 | // // address 90.0000 32 | // soff = off = 0x900000; 33 | // } 34 | // else if ((*(uint32_t *)&blkData[0] == ROM_MAGIC1) && 35 | // (*(uint32_t *)&blkData[4] == ROM_MAGIC2)) 36 | // { 37 | // fin.seekg(0, ios_base::beg); 38 | // fin.read((char *)&romHdr, sizeof(romHdr)); 39 | //// if ((romHdr.magic1 == ROM_MAGIC1) && 40 | //// (romHdr.magic2 == ROM_MAGIC2)) 41 | // soff = off = romHdr.dstAddrLow; 42 | // romSize = romHdr.romSize; 43 | // fmt::printf("%s: Loading firmware image at %X (%d bytes)\n", 44 | // getDeviceName(), off, romSize); 45 | // } 46 | // else 47 | // { 48 | // fmt::printf("%s: Not executable firmware image - aborted.\n", getDeviceName()); 49 | // return false; 50 | // } 51 | // } 52 | 53 | while (!fin.eof()) 54 | { 55 | fin.read((char *)blkData, sizeof(blkData)); 56 | mapProgram.writeBlock(off, blkData, fin.gcount()); 57 | off += fin.gcount(); 58 | } 59 | fin.close(); 60 | 61 | fmt::printf("%s: Loaded %s into %llX-%llX (length: %d bytes)\n", 62 | getDeviceName(), "LFU" /* fname */, soff, off, off - soff); 63 | 64 | // Set starting PC and PAL address 65 | setPCAddress(soff); 66 | 67 | return true; 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/dev/cpu/pdp10/memory.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * memory.cpp - PDP-10 family processors - memory access package 3 | * 4 | * Created on: Oct 28, 2019 5 | * Author: Tim Stark 6 | * 7 | */ 8 | 9 | #include "emu/emucore.h" 10 | #include "dev/cpu/pdp10/kx10.h" 11 | 12 | int pdp10_cpu_base::readp() 13 | { 14 | if (abReg < AC_NREGS) { 15 | mbReg = curReg[abReg]; 16 | return 0; 17 | } else { 18 | if (abReg >= memSize) { 19 | nxmFlag = true; 20 | return 1; 21 | } 22 | mbReg = mem[abReg]; 23 | } 24 | return 0; 25 | } 26 | 27 | int pdp10_cpu_base::writep() 28 | { 29 | if (abReg < AC_NREGS) { 30 | curReg[abReg] = mbReg; 31 | return 0; 32 | } else { 33 | if (abReg >= memSize) { 34 | nxmFlag = true; 35 | return 1; 36 | } 37 | mem[abReg] = mbReg; 38 | } 39 | return 0; 40 | } 41 | 42 | int pdp10_cpu_base::readv(uint32_t ctx, uint32_t flags) 43 | { 44 | if (abReg < AC_NREGS) { 45 | mbReg = curReg[abReg]; 46 | return 0; 47 | } else { 48 | if (abReg >= memSize) { 49 | nxmFlag = true; 50 | return 1; 51 | } 52 | mbReg = mem[abReg]; 53 | } 54 | return 0; 55 | } 56 | 57 | int pdp10_cpu_base::writev(uint32_t ctx, uint32_t flags) 58 | { 59 | if (abReg < AC_NREGS) { 60 | curReg[abReg] = mbReg; 61 | return 0; 62 | } else { 63 | if (abReg >= memSize) { 64 | nxmFlag = true; 65 | return 1; 66 | } 67 | mem[abReg] = mbReg; 68 | } 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /src/dev/cpu/pdp10/pdp10.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * pdp10.cpp - DEC PDP-10 processor emulation package 3 | * 4 | * Created on: Feb 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "dev/cpu/pdp10/pdp10.h" 10 | 11 | -------------------------------------------------------------------------------- /src/dev/cpu/pdp10/pdp10.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pdp10.h - DEC PDP-10 processor emulation package 3 | * 4 | * Created on: Feb 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/devproc.h" 11 | 12 | class pdp10_cpuDevice : public cpuDevice 13 | { 14 | 15 | }; 16 | -------------------------------------------------------------------------------- /src/dev/cpu/pdp11/models.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * models.cpp 3 | * 4 | * Created on: Apr 22, 2017 5 | * Author: Tim Stark 6 | */ 7 | 8 | #if 0 9 | p11mask_t p11_cpuMasks[] = 10 | { 11 | // PSW MMR0 MMR3 PAR PDR 12 | { PSW_1103, 0, 0, 0, 0 }, // PDP-11/03 13 | { PSW_1104, 0, 0, 0, 0 }, // PDP-11/04 14 | { PSW_1105, 0, 0, 0, 0 }, // PDP-11/05 15 | { PSW_1120, 0, 0, 0, 0 }, // PDP-11/20 16 | { PSW_1134, MM0_1134, 0000000, PAR_1134, PDR_1134 }, // PDP-11/34 17 | { PSW_1140, MM0_1140, 0000000, PAR_1140, PDR_1140 }, // PDP-11/40 18 | { PSW_1144, MM0_1144, MM3_1144, PAR_1144, PDR_1144 }, // PDP-11/44 19 | { PSW_1145, MM0_1145, MM3_1145, PAR_1145, PDR_1145 }, // PDP-11/45 20 | { PSW_1160, MM0_1160, 0000000, PAR_1160, PDR_1160 }, // PDP-11/60 21 | { PSW_1170, MM0_1170, MM3_1170, PAR_1170, PDR_1170 }, // PDP-11/70 22 | 23 | { PSW_F11, MM0_F11, MM3_F11, PAR_F11, PDR_F11 }, // PDP-11/23 24 | { PSW_F11, MM0_F11, MM3_F11, PAR_F11, PDR_F11 }, // PDP-11/23+ 25 | { PSW_F11, MM0_F11, MM3_F11, PAR_F11, PDR_F11 }, // PDP-11/24 26 | 27 | { PSW_J11, MM0_J11, MM3_J11, PAR_J11, PDR_J11 }, // PDP-11/53 28 | { PSW_J11, MM0_J11, MM3_J11, PAR_J11, PDR_J11 }, // PDP-11/73A 29 | { PSW_J11, MM0_J11, MM3_J11, PAR_J11, PDR_J11 }, // PDP-11/73B 30 | { PSW_J11, MM0_J11, MM3_J11, PAR_J11, PDR_J11 }, // PDP-11/83 31 | { PSW_J11, MM0_J11, MM3_J11, PAR_J11, PDR_J11 }, // PDP-11/84 32 | { PSW_J11, MM0_J11, MM3_J11, PAR_J11, PDR_J11 }, // PDP-11/93 33 | { PSW_J11, MM0_J11, MM3_J11, PAR_J11, PDR_J11 }, // PDP-11/94 34 | }; 35 | #endif 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/dev/cpu/pdp11/pdp11.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * pdp11.cpp - DEC PDP-11 processor emulation package 3 | * 4 | * Created on: Feb 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "dev/cpu/pdp11/pdp11.h" 10 | 11 | -------------------------------------------------------------------------------- /src/dev/cpu/pdp11/pdp11.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pdp11.h - DEC PDP-11 processor emulation package 3 | * 4 | * Created on: Feb 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/devproc.h" 11 | #include "dev/cpu/pdp11/pdp11_defs.h" 12 | 13 | class pdp11_cpuDevice : public cpuDevice 14 | { 15 | 16 | }; 17 | -------------------------------------------------------------------------------- /src/dev/cpu/upd7810/debug.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * debug.cpp - NEC uPD7810 series - debugging routines 3 | * 4 | * Created on: Mar 29, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/didebug.h" 10 | #include "dev/cpu/upd7810/upd7810.h" 11 | 12 | string upd7810_cpuDevice::getStringAddress(offs_t addr) 13 | { 14 | string strAddr; 15 | 16 | // Display 16-bit address 17 | strAddr = fmt::sprintf("%04X", addr & 0xFFFF); 18 | 19 | return strAddr; 20 | } 21 | 22 | int upd7810_cpuDevice::list(Console *cty, offs_t vAddr) 23 | { 24 | using namespace aspace; 25 | 26 | return 0; 27 | } 28 | 29 | void upd7810_cpuDevice::initOpcodeTable() 30 | { 31 | } 32 | -------------------------------------------------------------------------------- /src/dev/cpu/upd7810/execute.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * execute.cpp - NEC uPD7810 series - execute routines 3 | * 4 | * Created on: Mar 29, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "dev/cpu/upd7810/upd7810.h" 10 | 11 | void upd7810_cpuDevice::init() 12 | { 13 | // Reset all memory configurations 14 | // mapProgram = getAddressSpace(AS_PROGRAM); 15 | // mapData = getAddressSpace(AS_DATA); 16 | // mapPort = getAddressSpace(AS_IOPORT); 17 | } 18 | 19 | void upd7810_cpuDevice::setPCAddress(offs_t addr) 20 | { 21 | // pcAddr = addr; 22 | } 23 | 24 | 25 | void upd7810_cpuDevice::step(Console *user) 26 | { 27 | // // Save current log flags and 28 | // // enable console output 29 | // uint32_t flags = dbg.getLogFlags(); 30 | // dbg.setLogFlags(LOG_CONSOLE); 31 | // 32 | // // Execute one instruction as single step 33 | // log = user; 34 | // execute(); 35 | // 36 | // // Restore log flags 37 | // dbg.loadLogFlags(flags); 38 | } 39 | 40 | void upd7810_cpuDevice::run() 41 | { 42 | // // Start execution state 43 | // pState = execRunning; 44 | // 45 | // try { 46 | // while(pState == execRunning) 47 | // { 48 | // execute(); 49 | // } 50 | // dbg.flushAll(); 51 | // } 52 | // 53 | // catch (...) 54 | // { 55 | // // Flush all remaining buffers 56 | // dbg.flushAll(); 57 | // } 58 | // 59 | // // Stop execution state 60 | // pState = execStopped; 61 | } 62 | 63 | void upd7810_cpuDevice::execute() 64 | { 65 | } 66 | -------------------------------------------------------------------------------- /src/dev/cpu/upd7810/load.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * load.cpp - loading executable files 3 | * 4 | * Created on: Mar 29, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "dev/cpu/upd7810/upd7810.h" 10 | 11 | bool upd7810_cpuDevice::load(ifstream &fin, offs_t off) 12 | { 13 | uint8_t blkData[512]; 14 | offs_t soff = off; 15 | 16 | assert(mapProgram != nullptr); 17 | 18 | // if (off == 0) 19 | // { 20 | // // Check if it contains LFU image 21 | // fin.seekg(0, ios_base::beg); 22 | // fin.read((char *)blkData, sizeof(blkData)); 23 | // 24 | // // Check if file is LFU image 25 | // if (!memcmp((char *)&blkData[4], "LFU ", 4)) { 26 | // // strip first LFU block as not needed. 27 | // fin.seekg(0x240, ios_base::beg); 28 | // 29 | // // Reserve first 9 MB memory space uncompressed 30 | // // firmware space and loading image at starting at 31 | // // address 90.0000 32 | // soff = off = 0x900000; 33 | // } 34 | // else if ((*(uint32_t *)&blkData[0] == ROM_MAGIC1) && 35 | // (*(uint32_t *)&blkData[4] == ROM_MAGIC2)) 36 | // { 37 | // fin.seekg(0, ios_base::beg); 38 | // fin.read((char *)&romHdr, sizeof(romHdr)); 39 | //// if ((romHdr.magic1 == ROM_MAGIC1) && 40 | //// (romHdr.magic2 == ROM_MAGIC2)) 41 | // soff = off = romHdr.dstAddrLow; 42 | // romSize = romHdr.romSize; 43 | // fmt::printf("%s: Loading firmware image at %X (%d bytes)\n", 44 | // getDeviceName(), off, romSize); 45 | // } 46 | // else 47 | // { 48 | // fmt::printf("%s: Not executable firmware image - aborted.\n", getDeviceName()); 49 | // return false; 50 | // } 51 | // } 52 | 53 | while (!fin.eof()) 54 | { 55 | fin.read((char *)blkData, sizeof(blkData)); 56 | mapProgram->writeBlock(off, blkData, fin.gcount()); 57 | off += fin.gcount(); 58 | } 59 | fin.close(); 60 | 61 | fmt::printf("%s: Loaded %s into %llX-%llX (length: %d bytes)\n", 62 | getDeviceName(), "LFU" /* fname */, soff, off, off - soff); 63 | 64 | // Set starting PC and PAL address 65 | setPCAddress(soff); 66 | 67 | return true; 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/dev/cpu/upd7810/opcodes.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * opcodes.cpp - NEC uPD7810 series - instruction table 3 | * 4 | * Created on: Mar 29, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/dev/cpu/upd7810/upd7810.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * upd7810.cpp - NEC uPD7810 series emulation package 3 | * 4 | * Created on: Mar 29, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/map/addrmap.h" 10 | #include "emu/map/map.h" 11 | #include "emu/device.h" 12 | #include "emu/sysconfig.h" 13 | 14 | #include "dev/cpu/upd7810/upd7810.h" 15 | 16 | using namespace aspace; 17 | 18 | upd7810_cpuDevice::upd7810_cpuDevice(const SystemConfig &config, const DeviceType &type, 19 | const string &tagName, Device *owner, uint64_t clock) 20 | : cpuDevice(config, type, tagName, owner, clock), 21 | mapProgramConfig("program", LittleEndian, 8, 16, 8, 16, 16, 0) 22 | { 23 | // Initialize opcode table for disassembler 24 | // initOpcodeTable(); 25 | } 26 | 27 | mapConfigList upd7810_cpuDevice::getAddressConfigList() const 28 | { 29 | return mapConfigList { 30 | { aspace::asProgram, &mapProgramConfig }, 31 | }; 32 | } 33 | 34 | 35 | // ************************************************************** 36 | 37 | DEFINE_DEVICE_TYPE(upd7810, upd7810_cpuDevice, "upd7810", "NEC uPD7810") 38 | 39 | upd7810_cpuDevice::upd7810_cpuDevice(const SystemConfig &config, 40 | const string &tagName, Device *owner, uint64_t clock) 41 | : upd7810_cpuDevice(config, upd7810, tagName, owner, clock) 42 | { 43 | // Initialize opcode table for disassembler 44 | // initOpcodeTable(); 45 | } 46 | -------------------------------------------------------------------------------- /src/dev/cpu/upd7810/upd7810.h: -------------------------------------------------------------------------------- 1 | /* 2 | * upd7810.h - NEC uPD7810 series emulation package 3 | * 4 | * Created on: Mar 29, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/devproc.h" 11 | 12 | #define chargeCycles(cycle) 13 | 14 | struct upd7810op_t 15 | { 16 | cchar_t *opName; 17 | cchar_t *opReg; 18 | uint8_t opType; 19 | uint8_t opCode; 20 | uint8_t opMask; 21 | }; 22 | 23 | class upd7810_cpuDevice : public cpuDevice 24 | { 25 | protected: 26 | upd7810_cpuDevice(const SystemConfig &config, const DeviceType &type, 27 | const string &tagName, Device *owner, uint64_t clock); 28 | 29 | public: 30 | upd7810_cpuDevice(const SystemConfig &config, const string &tagName, Device *owner, uint64_t clock); 31 | virtual ~upd7810_cpuDevice() = default; 32 | 33 | // Virtual function calls from execution interface 34 | void step(Console *user) override; 35 | void setPCAddress(offs_t addr) override; 36 | bool load(ifstream &fin, offs_t off) override; 37 | 38 | void devReset() override { init(); } 39 | 40 | void initOpcodeTable(); 41 | 42 | void init(); 43 | void execute(); 44 | void run(); 45 | 46 | mapConfigList getAddressConfigList() const; 47 | 48 | // Debugging tools 49 | string getStringAddress(offs_t addr); 50 | int list(Console *cty, offs_t vAddr) override; 51 | 52 | protected: 53 | pair16_t pcAddr; 54 | pair16_t spReg; 55 | 56 | pair16_t eaReg; // Extended accumulator register 57 | pair16_t bcReg; // B/C register 8/16-bit 58 | pair16_t deReg; // D/E register 8/16-bit 59 | pair16_t hlReg; // H/L register 8/16-bit 60 | 61 | mapAddressConfig mapProgramConfig; 62 | 63 | mapAddressSpace *mapProgram = nullptr; 64 | 65 | // static mcs48op_t opTable[]; 66 | }; 67 | 68 | 69 | //class i8035_cpuDevice : public mcs48_cpuDevice 70 | //{ 71 | //public: 72 | // i8035_cpuDevice(const SystemConfig &config, const string &tagName, Device *owner, uint64_t clock); 73 | // virtual ~i8035_cpuDevice() = default; 74 | // 75 | //}; 76 | 77 | DECLARE_DEVICE_TYPE(upd7810, upd7810_cpuDevice); 78 | -------------------------------------------------------------------------------- /src/dev/cpu/vax/old/cvax.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cvax.h 3 | * 4 | * Created on: Mar 12, 2017 5 | * Author: Timothy Stark 6 | * 7 | * CVAX 78034 processor emulation 8 | * 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "dev/cpu/vax/vax.h" 14 | 15 | // CVAX System ID register definition 16 | // 17 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 18 | // | 10 | Reserved | uCode rev | 19 | // +-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-+ 20 | // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 21 | // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 22 | 23 | #define SID_ID (10 << 24) 24 | #define SID_UCODE 6 25 | 26 | #define SRM_START 0x20040000 27 | 28 | // Internal Processor Registers 29 | // TODR - Time of Day Register 30 | #define TODR_BASE (1u << 28) 31 | #define TODR_SEC 100 32 | 33 | // ICCS - Interval Count Control Status Register 34 | #define ICCS_IE 0x0040 // Interrupt Enable 35 | #define ICCS_WMASK (ICCS_IE) // Writable Mask 36 | #define ICCS_SECOND 100 // Ticks Each Second 37 | #define ICCS_IPL UQ_BR6 // Interrupt Level BR6 38 | #define ICCS_VEC SCB_TIMER // System Vector 39 | #define ICCS_PRIO 255 // Device Priority 40 | 41 | // CONPC/CONPSL Register 42 | #define CON_PWRUP (HALT_PWRON << 8) // Power Up State 43 | 44 | // CADR (IPR 37) - Cache Disable Register 45 | #define CADR_S1E 0x0040 // Set 1 Cache Enable 46 | #define CADR_ISE 0x0020 // I-Stream Cache Enable 47 | #define CADR_DSE 0x0010 // D-Stream Cache Enable 48 | #define CADR_MBO 0x000C // Unused - Always On. 49 | #define CADR_WW 0x0002 // Write Wrong Priority 50 | #define CADR_DIA 0x0001 // Diagnostic Mode 51 | #define CADR_RW 0x00F3 // Read/Write Access Mask 52 | 53 | // MSER (IPR 39) - Memory System Error Register 54 | #define MSER_HM 0x0080 // Hit/Miss 55 | #define MSER_DSL 0x0040 // DAL Parity Error 56 | #define MSER_MCD 0x0020 // Machine Check DAL Parity Error 57 | #define MSER_MCC 0x0010 // Machine Check Cache Parity Error 58 | #define MSER_DAT 0x0002 // Data Parity Error 59 | #define MSER_TAG 0x0001 // Tag Parity Error 60 | 61 | // CONPSL (IPR 42) - Saved PSL Register 62 | #define CONPSL_MASK 0xFFFF00FF // Processor Status Mask 63 | #define CONPSL_MAPEN 0x00008000 // MAPEN<0> Bit 64 | #define CONPSL_INVALID 0x00004000 // Invalid Bit 65 | #define CONPSL_RESTART 0x00003F00 // Restart Code 66 | 67 | // Machine Check Codes 68 | #define MCHK_TBM_P0 0x03 // PPTE in P0 region 69 | #define MCHK_TBM_P1 0x06 // PPTE in P1 region 70 | #define MCHK_MO_P0 0x07 // PPTE in P0 region 71 | #define MCHK_M0_P1 0x08 // PPTE in P1 region 72 | #define MCHK_INTIPL 0x09 // Invalid Interrupt Request 73 | #define MCHK_READ 0x80 // Read Reference Check 74 | #define MCHK_WRITE 0x82 // Write Reference Check 75 | 76 | class cvax_cpu : public vax_cpu_base 77 | { 78 | public: 79 | cvax_cpu(const system_config &config, tag_t *tag, device_t *owner, uint64_t clock); 80 | ~cvax_cpu(); 81 | 82 | // void reset(); 83 | // int boot(); 84 | 85 | void devReset() override; 86 | 87 | // static cvax_cpu *create(sysDevice *sdev, std::string devName); 88 | 89 | protected: 90 | // Instructions 91 | void mfpr(); 92 | void mtpr(); 93 | 94 | void halt(uint32_t code); 95 | void check(uint32_t code); 96 | }; 97 | 98 | DECLARE_DEVICE_TYPE(CVAX, cvax_cpu) 99 | -------------------------------------------------------------------------------- /src/dev/cpu/vax/old/ka780.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ka780.cpp 3 | * 4 | * Created on: Mar 12, 2017 5 | * Author: Timothy Stark 6 | * 7 | * KA780/KA785 CPU series 8 | * 9 | */ 10 | 11 | #include "emu/emucore.h" 12 | #include "dev/cpu/vax/mtpr.h" 13 | #include "dev/cpu/vax/vax.h" 14 | #include "dev/cpu/vax/fpu.h" 15 | #include "dev/cpu/vax/ka780.h" 16 | 17 | #include "dev/cpu/vax/opcodes.h" 18 | 19 | DEFINE_DEVICE_TYPE(KA780, ka780_cpu, "KA780", "VAX-11/780") 20 | 21 | ka780_cpu::ka780_cpu(const system_config &config, tag_t *tag, device_t *owner, uint64_t clock) 22 | : vax_cpu_base(config, KA780, tag, owner, clock, 32, 30) 23 | { 24 | } 25 | 26 | ka780_cpu::~ka780_cpu() 27 | { 28 | } 29 | 30 | void ka780_cpu::reset() 31 | { 32 | // Initialize SID register 33 | ipReg[IPR_nSID] = (SID_ID|SID_ECO|SID_PLANT); 34 | // Set specific serial number 35 | ipReg[IPR_nSID] |= SID_SN; 36 | } 37 | 38 | void ka780_cpu::mfpr() 39 | { 40 | } 41 | 42 | void ka780_cpu::mtpr() 43 | { 44 | } 45 | 46 | //#define CPU_KA780 47 | //#define CPU_CLASS ka780_cpu 48 | //#include "dev/cpu/vax/executes.h" 49 | -------------------------------------------------------------------------------- /src/dev/cpu/vax/old/ka780.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ka780.h 3 | * 4 | * Created on: Mar 12, 2017 5 | * Author: Timothy Stark 6 | * 7 | * VAX-11/780 series system 8 | * 9 | */ 10 | 11 | #pragma once 12 | 13 | // System ID register definition 14 | // 15 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 16 | // | 1 |T| ECO Level |Plant| Serial Number | 17 | // +-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-+ 18 | // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 19 | // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 20 | // 21 | // T = 0 if VAX-11/780 22 | // 1 if VAX-11/785 23 | 24 | #define SID_ID (1 << 24) 25 | #define SID_785 (1u << 23) 26 | #define SID_ECO (0u << 15) 27 | #define SID_PLANT (0u << 12) 28 | 29 | // KA780 SID Serial Number 30 | #define SID_SN 1 31 | #define SID_SN_MASK ((1u << 12) - 1) 32 | 33 | class ka780_cpu : public vax_cpu_base 34 | { 35 | public: 36 | ka780_cpu(const system_config &config, tag_t *tag, device_t *owner, uint64_t clock); 37 | ~ka780_cpu(); 38 | 39 | void reset(); 40 | // int boot(); 41 | 42 | protected: 43 | void mfpr(); 44 | void mtpr(); 45 | }; 46 | 47 | DECLARE_DEVICE_TYPE(KA780, ka780_cpu) 48 | -------------------------------------------------------------------------------- /src/dev/cpu/vax/old/mmu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mmu.h 3 | * 4 | * Created on: Apr 14, 2017 5 | * Author: Timothy Stark 6 | * 7 | * Memory Management Unit 8 | * 9 | */ 10 | 11 | #pragma once 12 | 13 | // Virtual address regions 14 | #define VA_ADDR_P0 (0u << 30) // 00000000 - 3FFFFFFF 15 | #define VA_ADDR_P1 (1u << 30) // 40000000 - 7FFFFFFF 16 | #define VA_ADDR_S0 (1u << 31) // 80000000 - FFFFFFFF 17 | 18 | // Page offset (each page holds 512 bytes) 19 | #define PAG_WIDTH 9 20 | #define PAG_SIZE (1u << PAG_WIDTH) 21 | #define PAG_MASK (PAG_SIZE - 1) 22 | 23 | // Virtual Page Number (VPN) 24 | #define VPN_WIDTH (31u - PAG_WIDTH) 25 | #define VPN_SIZE (1u << VPN_WIDTH) 26 | #define VPN_POS PAG_WIDTH 27 | #define VPN_MASK (VPN_SIZE - 1) 28 | #define VA_VPN ((VPN_MASK << VPN_POS) & paMask) 29 | 30 | // Translation Buffer Index 31 | #define TBI_WIDTH 12 32 | #define TBI_SIZE (1u << TBI_WIDTH) 33 | #define TBI_MASK (TBI_SIZE - 1) 34 | #define TLB_SIZE TBI_SIZE 35 | 36 | // Virtual Address Field Extractions 37 | #define VA_GETBASE(va) ((va) & ~PAG_MASK) 38 | #define VA_GETOFF(va) ((va) & PAG_MASK) 39 | #define VA_GETVPN(va) (((va) >> VPN_POS) & VPN_MASK) 40 | #define VA_GETTBI(vpn) ((vpn) & TBI_MASK) 41 | 42 | // Page Table Entry 43 | #define PTE_V 0x80000000 // Valid Bit 44 | #define PTE_PROT 0x78000000 // Protection Code 45 | #define PTE_M 0x04000000 // Modified Bit 46 | #define PTE_OWN 0x01800000 // Ownership 47 | #define PTE_GLOBAL 0x00400000 // Global Page Table Entry 48 | #define PTE_PFN 0x0001FFFF // Page Frame Number 49 | 50 | #define PTE_M_PROT 0xF // Protection Code Mask 51 | #define PTE_M_OWN 0x3 // Owner Mode Mask 52 | #define PTE_M_PFN 0x1FFFF // Page Frame Number Mask 53 | 54 | #define PTE_P_PROT 27 // Position of Protection Code 55 | #define PTE_P_OWN 23 // Position of Ownership Mode 56 | #define PTE_P_PFN 0 // Position of Page Frame Number 57 | 58 | #define PTE_GETACC(pte) (((pte) >> PTE_P_PROT) & PTE_M_PROT) 59 | 60 | // Translation Buffer Entry 61 | // 62 | // | | Access Bits | 63 | // | | | Write | Read | 64 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 65 | // | Physical Frame Number |M|U|S|E|K|U|S|E|K| 66 | // +-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-+ 67 | // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 68 | // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 69 | 70 | #define TLB_N_ACC 4 71 | #define TLB_M_ACC ((1u << TLB_N_ACC) - 1) 72 | #define TLB_P_RDACC 0 73 | #define TLB_P_WRACC TLB_N_ACC 74 | #define TLN_P_M (TLB_N_ACC * 2) 75 | #define TLB_RDACC (TLB_M_ACC << TLB_P_RDACC) 76 | #define TLB_WRACC (TLB_M_ACC << TLB_P_WRACC) 77 | #define TLB_M (1u << (TLB_N_ACC * 2)) 78 | 79 | #define TLB_N_PFN (32u - PAG_WIDTH) 80 | #define TLB_M_PFN ((1u << TLB_N_PFN) - 1) 81 | #define TLB_PFN (TLB_M_PFN << PAG_WIDTH) 82 | 83 | #define MM_WRITE 4 // Write Access 84 | #define MM_EMASK 3 // Mask Against Probe 85 | 86 | #define MM_ACV 0 // Access-Control Violation 87 | #define MM_LNV 1 // Length Not Valid 88 | #define MM_PACV 2 // PTE Access-Control Violation (11/780 only) 89 | #define MM_PLNV 3 // PTE Length Not Valid 90 | #define MM_TNV 4 // Translation Not Valid 91 | #define MM_PTNV 6 // PTE Translation Not Valid 92 | #define MM_OK 7 // Successful Translation 93 | 94 | #define MM_FAIL -1 // Check Memory Access Failure 95 | -------------------------------------------------------------------------------- /src/dev/cpu/vax/old/nvax.h: -------------------------------------------------------------------------------- 1 | /* 2 | * nvax.h 3 | * 4 | * Created on: Jun 1, 2017 5 | * Author: Timothy Stark 6 | * 7 | * NVAX emulation 8 | * 9 | */ 10 | 11 | #pragma once 12 | 13 | -------------------------------------------------------------------------------- /src/dev/cpu/vax/old/v11.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * v11.cpp 3 | * 4 | * Created on: Mar 12, 2017 5 | * Author: Timothy Stark 6 | * 7 | * V-11 (Scorpio) processor emulation 8 | */ 9 | 10 | 11 | #include "emu/emucore.h" 12 | #include "dev/cpu/vax/mtpr.h" 13 | #include "dev/cpu/vax/v11.h" 14 | #include "dev/cpu/vax/fpu.h" 15 | #include "dev/cpu/vax/opcodes.h" 16 | 17 | DEFINE_DEVICE_TYPE(V11, v11_cpu, "V11", "V11") 18 | 19 | v11_cpu::v11_cpu(const system_config &config, tag_t *tag, device_t *owner, uint64_t clock) 20 | : vax_cpu_base(config, V11, tag, owner, clock, 32, 30) 21 | { 22 | } 23 | 24 | v11_cpu::~v11_cpu() 25 | { 26 | } 27 | 28 | void v11_cpu::reset() 29 | { 30 | // Initialize SID register 31 | ipReg[IPR_nSID] = (SID_ID|SID_CPUREV|SID_PATREV|SID_MBO|SID_UCODE); 32 | } 33 | 34 | void v11_cpu::mfpr() 35 | { 36 | } 37 | 38 | void v11_cpu::mtpr() 39 | { 40 | } 41 | 42 | //#define CPU_V11 43 | //#define CPU_CLASS v11_cpu 44 | //#include "dev/cpu/vax/executes.h" 45 | -------------------------------------------------------------------------------- /src/dev/cpu/vax/old/v11.h: -------------------------------------------------------------------------------- 1 | /* 2 | * v11.h 3 | * 4 | * Created on: Mar 12, 2017 5 | * Author: Timothy Stark 6 | * 7 | * V-11 (Scorpio) processor emulation 8 | * 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "dev/cpu/vax/vax.h" 14 | 15 | // System ID register definition 16 | // 17 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 18 | // | 5 |T|CPU rev| Patch rev |1| uCode rev | 19 | // +-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-^-+-+-+-+ 20 | // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 21 | // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 22 | // 23 | // T = 0 if VAX 8200/8300 24 | // 1 if VAX 8250/8350 25 | 26 | #define SID_ID (5 << 24) 27 | #define SID_8x50 (1u << 23) 28 | #define SID_CPUREV (0u << 19) 29 | #define SID_PATREV (0u << 9) 30 | #define SID_MBO (1u << 8) 31 | #define SID_UCODE 0 32 | 33 | // KA780 SID Serial Number 34 | #define SID_SN 1 35 | #define SID_SN_MASK ((1u << 12) - 1) 36 | 37 | class v11_cpu : public vax_cpu_base 38 | { 39 | public: 40 | v11_cpu(const system_config &config, tag_t *tag, device_t *owner, uint64_t clock); 41 | ~v11_cpu(); 42 | 43 | void reset(); 44 | // int boot(); 45 | 46 | protected: 47 | void mfpr(); 48 | void mtpr(); 49 | }; 50 | 51 | DECLARE_DEVICE_TYPE(V11, v11_cpu) 52 | -------------------------------------------------------------------------------- /src/dev/cpu/vax/vax.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * vax.cpp - DEC VAX processor emulation package 3 | * 4 | * Created on: Feb 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "dev/cpu/vax/vax.h" 10 | 11 | vax_cpuDevice::vax_cpuDevice(const SystemConfig &config, const DeviceType &type, 12 | const string &tagName, Device *owner, uint64_t clock, int aWidth) 13 | : cpuDevice(config, type, tagName, owner, clock), 14 | mapProgramConfig("program", LittleEndian, 32, 16, 8, aWidth, 16, 0) 15 | { 16 | // Initialize opcode table for disassembler 17 | // initOpcodeTable(); 18 | } 19 | 20 | void vax_cpuDevice::startDevice() 21 | { 22 | { 23 | addState(VAX_R0, "R0", state.gpReg[0].l); 24 | addState(VAX_R1, "R1", state.gpReg[1].l); 25 | addState(VAX_R2, "R2", state.gpReg[2].l); 26 | addState(VAX_R3, "R3", state.gpReg[3].l); 27 | addState(VAX_R4, "R4", state.gpReg[4].l); 28 | addState(VAX_R5, "R5", state.gpReg[5].l); 29 | addState(VAX_R6, "R6", state.gpReg[6].l); 30 | addState(VAX_R7, "R7", state.gpReg[7].l); 31 | addState(VAX_R8, "R8", state.gpReg[8].l); 32 | addState(VAX_R9, "R9", state.gpReg[9].l); 33 | addState(VAX_R10, "R10", state.gpReg[10].l); 34 | addState(VAX_R11, "R11", state.gpReg[11].l); 35 | addState(VAX_R12, "R12", state.gpReg[12].l); 36 | addState(VAX_R13, "R13", state.gpReg[13].l); 37 | addState(VAX_R14, "R14", state.gpReg[14].l); 38 | addState(VAX_R15, "R15", state.gpReg[15].l); 39 | 40 | addState(VAX_AP, "AP", state.gpReg[12].l); 41 | addState(VAX_FP, "FP", state.gpReg[13].l); 42 | addState(VAX_SP, "SP", state.gpReg[14].l); 43 | addState(VAX_PC, "PC", state.gpReg[15].l); 44 | 45 | } 46 | 47 | getAddressSpace(AS_PROGRAM)->setMemorySpecific(mapProgram); 48 | } -------------------------------------------------------------------------------- /src/dev/cpu/vax/vax.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vax.h - DEC VAX processor emulation package 3 | * 4 | * Created on: Feb 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/devproc.h" 11 | 12 | // Number of registers 13 | #define CPU_nGREGS 16 14 | #define CPU_nOREGS 20 15 | #define CPU_nPREGS 256 16 | #define CPU_nNREGS 16 17 | #define CPU_nOPCTBL 1024 18 | 19 | // Register List 20 | #define REG_nR0 0 21 | #define REG_nR1 1 22 | #define REG_nR2 2 23 | #define REG_nR3 3 24 | #define REG_nR4 4 25 | #define REG_nR5 5 26 | #define REG_nR6 6 27 | #define REG_nR7 7 28 | #define REG_nR8 8 29 | #define REG_nR9 9 30 | #define REG_nR10 10 31 | #define REG_nR11 11 32 | #define REG_nR12 12 33 | #define REG_nR13 13 34 | #define REG_nR14 14 35 | #define REG_nR15 15 36 | 37 | #define REG_nAP REG_nR12 // Argument Pointer 38 | #define REG_nFP REG_nR13 // Frame Pointer 39 | #define REG_nSP REG_nR14 // Stack Pointer 40 | #define REG_nPC REG_nR15 // Program Counter 41 | 42 | #define REG_R0 gpReg[REG_nR0].l 43 | #define REG_R1 gpReg[REG_nR1].l 44 | #define REG_R2 gpReg[REG_nR2].l 45 | #define REG_R3 gpReg[REG_nR3].l 46 | #define REG_R4 gpReg[REG_nR4].l 47 | #define REG_R5 gpReg[REG_nR5].l 48 | #define REG_R6 gpReg[REG_nR6].l 49 | #define REG_R7 gpReg[REG_nR7].l 50 | #define REG_R8 gpReg[REG_nR8].l 51 | #define REG_R9 gpReg[REG_nR9].l 52 | #define REG_R10 gpReg[REG_nR10].l 53 | #define REG_R11 gpReg[REG_nR11].l 54 | #define REG_R12 gpReg[REG_nR12].l 55 | #define REG_R13 gpReg[REG_nR13].l 56 | #define REG_R14 gpReg[REG_nR14].l 57 | #define REG_R15 gpReg[REG_nR15].l 58 | 59 | #define REG_AP gpReg[REG_nAP].l 60 | #define REG_FP gpReg[REG_nFP].l 61 | #define REG_SP gpReg[REG_nSP].l 62 | #define REG_PC gpReg[REG_nPC].l 63 | 64 | // Register definition 65 | #define CPU_REGUB(rn) ZXTB(gpReg[rn].b) 66 | #define CPU_REGUW(rn) ZXTW(gpReg[rn].w) 67 | #define CPU_REGUL(rn) ZXTL(gpReg[rn].l) 68 | #define CPU_REGSB(rn) SXTB(gpReg[rn].b) 69 | #define CPU_REGSW(rn) SXTW(gpReg[rn].w) 70 | #define CPU_REGSL(rn) SXTL(gpReg[rn].l) 71 | 72 | // Processor flags 73 | #define CPU_INIE 0x80000000 // Interrupt/exception in progress 74 | 75 | class vax_cpuDevice : public cpuDevice 76 | { 77 | public: 78 | enum stateRegisters 79 | { 80 | VAX_R0, VAX_R1, VAX_R2, VAX_R3, 81 | VAX_R4, VAX_R5, VAX_R6, VAX_R7, 82 | VAX_R8, VAX_R9, VAX_R10, VAX_R11, 83 | VAX_R12, VAX_R13, VAX_R14, VAX_R15, 84 | VAX_AP, VAX_FP, VAX_SP, VAX_PC 85 | }; 86 | 87 | vax_cpuDevice(const SystemConfig &config, const DeviceType &type, 88 | const string &tagName, Device *owner, uint64_t clock, int aWidth); 89 | virtual ~vax_cpuDevice() = default; 90 | 91 | void startDevice() override; 92 | 93 | protected: 94 | struct 95 | { 96 | scale32_t gpReg[CPU_nGREGS]; // General registers 97 | uint32_t ipReg[CPU_nPREGS]; // Processor registers 98 | uint32_t opReg[CPU_nOREGS]; // Operand registers 99 | int32_t rqReg[CPU_nOREGS]; // Recovery registers 100 | uint32_t paReg[CPU_nNREGS]; // Parameter registers 101 | 102 | uint32_t psReg; // Processor status register 103 | uint32_t ccReg; // Condition Codes 104 | uint32_t accMode; // Access Mode 105 | 106 | uint32_t opCode; // Current opcode 107 | uint32_t opCount; // Number of operand registers 108 | uint32_t rqCount; // Number of recovery registers 109 | uint32_t paCount; // Number of parameter registers 110 | 111 | uint32_t flags; // Processor flags 112 | 113 | } state; 114 | 115 | mapAddressConfig mapProgramConfig; 116 | 117 | aspace::MemoryAccess<30, 2, 0, LittleEndian>::specific mapProgram; 118 | }; 119 | -------------------------------------------------------------------------------- /src/dev/video/dec/vt100.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * vt100.h - DEC VT100 terminal - DC011/DC012 video controller 3 | * 4 | * Created on: Sep 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/screen.h" 10 | #include "dev/video/dec/vt100.h" 11 | 12 | using namespace emu::video; 13 | 14 | DEFINE_DEVICE_TYPE(VT100_VIDEO, vt100_videoDevice, "VT100_Video", "VT100 video controller"); 15 | 16 | vt100_videoDevice::vt100_videoDevice(const SystemConfig &config, const DeviceType &type, 17 | const string &tagName, Device *owner, uint64_t clock) 18 | : Device(config, type, tagName, owner, clock), 19 | romCharData(*this, nullptr), 20 | readRAMData(*this), 21 | diVideo(this) 22 | { 23 | 24 | } 25 | 26 | vt100_videoDevice::vt100_videoDevice(const SystemConfig &config, cstag_t &tagName, Device *owner, uint64_t clock) 27 | : vt100_videoDevice(config, VT100_VIDEO, tagName, owner, clock) 28 | { 29 | 30 | } 31 | 32 | void vt100_videoDevice::resolveDeviceObjects() 33 | { 34 | readRAMData.resolveSafe(0); 35 | } 36 | 37 | void vt100_videoDevice::write8_dc011(offs_t off, uint8_t data) 38 | { 39 | 40 | } 41 | 42 | void vt100_videoDevice::write8_dc012(offs_t off, uint8_t data) 43 | { 44 | 45 | } 46 | 47 | void vt100_videoDevice::write8_brightness(offs_t off, uint8_t data) 48 | { 49 | 50 | } 51 | 52 | void vt100_videoDevice::displayCharacter() 53 | { 54 | 55 | } 56 | 57 | void vt100_videoDevice::updateVideo(bitmap16_t &bitmap, const rect_t &clip) 58 | { 59 | 60 | } -------------------------------------------------------------------------------- /src/dev/video/dec/vt100.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vt100.h - DEC VT100 terminal - DC011/DC012 video controller 3 | * 4 | * Created on: Aug 22, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/divideo.h" 11 | 12 | namespace emu::video 13 | { 14 | class vt100_videoDevice : public Device, public diVideo 15 | { 16 | public: 17 | vt100_videoDevice(const SystemConfig &config, cstag_t &tagName, Device *owner, uint64_t clock); 18 | 19 | void setCharData(ctag_t *name) { romCharData.setObjectName(name); } 20 | 21 | auto getReadRAMDataCallback() { return readRAMData.bind(); } 22 | 23 | void resolveDeviceObjects() override; 24 | 25 | // I/O access function calls 26 | void write8_dc011(offs_t off, uint8_t data); 27 | void write8_dc012(offs_t off, uint8_t data); 28 | void write8_brightness(offs_t off, uint8_t data); 29 | 30 | void updateVideo(bitmap16_t &bitmap, const rect_t &clip); 31 | 32 | protected: 33 | vt100_videoDevice(const SystemConfig &config, const DeviceType &type, 34 | const string &tagName, Device *owner, uint64_t clock); 35 | 36 | read8cb_t readRAMData; 37 | 38 | void displayCharacter(); 39 | 40 | RequiredRegionPointer romCharData; 41 | }; 42 | } 43 | 44 | DECLARE_DEVICE_TYPE(VT100_VIDEO, emu::video::vt100_videoDevice); 45 | 46 | using vt100video_t = emu::video::vt100_videoDevice; -------------------------------------------------------------------------------- /src/emu/command.h: -------------------------------------------------------------------------------- 1 | /* 2 | * command.h - command handler package 3 | * 4 | * Created on: Jul 5, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | class Console; 11 | class Machine; 12 | class Device; 13 | 14 | enum CommandStatus 15 | { 16 | cmdOk = 0, 17 | cmdNotFound, 18 | cmdError, 19 | cmdShutdown 20 | }; 21 | 22 | class args_t 23 | { 24 | public: 25 | args_t() = default; 26 | ~args_t() = default; 27 | 28 | using args = vector; 29 | 30 | inline void clear() { count = 0; index = 0; params.clear(); } 31 | inline bool empty() { return (count == 0); } 32 | inline int size() { return count; } 33 | inline void next() { index++; } 34 | 35 | inline string operator [](int idx) { return (idx < count) ? params[idx] : ""; } 36 | inline void add(string arg) { params.push_back(arg); count++; } 37 | inline string current() { return (index < count) ? params[index] : ""; } 38 | 39 | inline string getNext() { string arg = current(); next(); return arg; } 40 | 41 | private: 42 | int count = 0; 43 | int index = 0; 44 | args params; 45 | }; 46 | 47 | typedef CommandStatus (*cmdFunc_t)(Console *, args_t &); 48 | typedef CommandStatus (*cmdDevice_t)(Console *, Machine *, Device *, args_t &); 49 | 50 | struct command_t 51 | { 52 | const char *name; 53 | cmdFunc_t func; 54 | command_t *ext; 55 | }; 56 | 57 | struct devCommand_t 58 | { 59 | const char *name; 60 | cmdDevice_t func; 61 | }; 62 | 63 | class CommandHandler { 64 | friend class Console; 65 | 66 | public: 67 | 68 | CommandHandler() = default; 69 | ~CommandHandler() = default; 70 | 71 | CommandStatus execute(Console *cty, string cmdLine); 72 | 73 | private: 74 | int split(const string &cmdLine, args_t &args); 75 | 76 | private: 77 | static command_t mseCommands[]; 78 | static command_t mseListCommands[]; 79 | static command_t mseSetCommands[]; 80 | static command_t mseShowCommands[]; 81 | 82 | command_t *lastCommand = nullptr; 83 | Device *lastDevice = nullptr; 84 | offs_t lastAddress = 0; 85 | }; 86 | -------------------------------------------------------------------------------- /src/emu/console.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * console.cpp 3 | * 4 | * Created on: Jul 5, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/console.h" 10 | 11 | // Command Handler 12 | 13 | int CommandHandler::split(const string &cmdLine, args_t &args) 14 | { 15 | istringstream line(cmdLine); 16 | 17 | while (line) { 18 | string word; 19 | 20 | line >> word; 21 | if (!word.empty()) 22 | args.add(word); 23 | } 24 | 25 | return args.size(); 26 | } 27 | 28 | CommandStatus CommandHandler::execute(Console *cty, string cmdLine) 29 | { 30 | command_t *cmdList; 31 | args_t args; 32 | 33 | // Split command line into words 34 | args.clear(); 35 | split(cmdLine, args); 36 | if (args.empty()) { 37 | // Check if repeating command for continuing 38 | if (lastCommand != nullptr) 39 | lastCommand->func(cty, args); 40 | return cmdOk; 41 | } 42 | 43 | cmdList = mseCommands; 44 | for (int idx = 0; cmdList[idx].name; idx++) { 45 | if (cmdList[idx].name == args.current()) { 46 | args.next(); 47 | 48 | command_t *optList = cmdList[idx].ext; 49 | if (optList != nullptr) 50 | { 51 | for (int idx2 = 0; optList[idx2].name; idx2++) { 52 | if (optList[idx2].name == args.current()) { 53 | args.next(); 54 | assert(optList[idx2].func != nullptr); 55 | return optList[idx2].func(cty, args); 56 | } 57 | } 58 | } 59 | 60 | if (cmdList[idx].func != nullptr) { 61 | lastCommand = &cmdList[idx]; 62 | return cmdList[idx].func(cty, args); 63 | } 64 | 65 | // cout << fmt::sprintf("Usage: %s <%s%s%s> [arguments...]\n", args[0], 66 | // cmdList[idx].func != nullptr ? "device" : "", 67 | // (cmdList[idx].func != nullptr && cmdList[idx].ext != nullptr) ? "|" : "", 68 | // cmdList[idx].ext != nullptr ? "options" : ""); 69 | } 70 | } 71 | 72 | // Command not found 73 | return cmdNotFound; 74 | } 75 | 76 | // Console handler 77 | 78 | void Console::script(fs::path fname) 79 | { 80 | // fmt::printf("Script: %s\n", fname); 81 | 82 | string cmdLine; 83 | int noLine = 0; 84 | 85 | CommandStatus st = cmdOk; 86 | 87 | try { 88 | ifstream fin(fname); 89 | while (!fin.eof()) 90 | { 91 | getline(fin, cmdLine); 92 | noLine++; 93 | 94 | fmt::printf("/// %04d: %s\n", noLine, cmdLine); 95 | 96 | // Check comment character first 97 | if (cmdLine[0] == '#' || cmdLine[0] == ';') 98 | continue; 99 | 100 | st = cmd.execute(this, cmdLine); 101 | if (st == cmdShutdown) 102 | break; 103 | if (st == cmdNotFound) 104 | { 105 | cout << fmt::sprintf("*** Invalid command: %s\n", cmdLine) << flush; 106 | st = cmdOk; 107 | } 108 | } 109 | 110 | fin.close(); 111 | } 112 | 113 | catch (system_error &e) 114 | { 115 | // cerr << fmt::sprintf("%s: file error: %s\n", fname, e.code().message()); 116 | cout << flush; 117 | } 118 | } 119 | 120 | void Console::prompt() 121 | { 122 | string cmdLine; 123 | CommandStatus st = cmdOk; 124 | 125 | while(st == cmdOk) 126 | { 127 | 128 | cout << fmt::sprintf("MSE> ") << flush; 129 | 130 | getline(cin, cmdLine); 131 | 132 | st = cmd.execute(this, cmdLine); 133 | if (st == cmdShutdown) 134 | break; 135 | if (st == cmdNotFound) 136 | { 137 | cout << fmt::sprintf("*** Invalid command: %s\n", cmdLine) << flush; 138 | st = cmdOk; 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/emu/console.h: -------------------------------------------------------------------------------- 1 | /* 2 | * console.h 3 | * 4 | * Created on: Jul 5, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/command.h" 11 | #include "emu/engine.h" 12 | 13 | class Console 14 | { 15 | public: 16 | Console() : engine(this) {} 17 | ~Console() = default; 18 | 19 | void script(fs::path fname); 20 | void prompt(); 21 | 22 | inline void setLastAddress(Device *device, offs_t addr) { cmd.lastDevice = device; cmd.lastAddress = addr; } 23 | inline offs_t getLastAddress(Device *&device) { device = cmd.lastDevice; return cmd.lastAddress; } 24 | 25 | inline void print(cstag_t &message) { cout << message << flush; } 26 | 27 | template 28 | void printf(cstag_t &format, Args ... args) 29 | { 30 | fmt::printf(format, forward(args) ...); 31 | } 32 | 33 | public: 34 | SystemEngine engine; 35 | 36 | private: 37 | // SystemEngine engine; 38 | CommandHandler cmd; 39 | }; 40 | -------------------------------------------------------------------------------- /src/emu/debug.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * debug.cpp 3 | * 4 | * Created on: Jan 20, 2021 5 | * Author: Tim STark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/debug.h" 10 | 11 | LogFile::~LogFile() 12 | { 13 | // Close all logging files 14 | close(-1); 15 | } 16 | 17 | bool LogFile::open(fs::path fname, int slot) 18 | { 19 | if (slot < 0 || slot >= LOG_NFILES) 20 | return false; 21 | 22 | // Check if old log files is still opened 23 | if (fout[slot].is_open()) 24 | { 25 | fout[slot] << "------ End of logging ------" << endl << flush; 26 | fout[slot].close(); 27 | } 28 | 29 | // Open new log file at appending mode 30 | fout[slot].open(fname, ios::app); 31 | fout[slot] << "------ Start of logging ------" << endl << flush; 32 | 33 | logFlags |= (1u << slot); 34 | 35 | return false; 36 | } 37 | 38 | void LogFile::close(int slot) 39 | { 40 | if (slot < 0) 41 | { 42 | // For any negative value, flush remaining buffers 43 | // and close all logging files 44 | logFlags = 0; 45 | for (int idx = 0; idx < LOG_NFILES; idx++) 46 | { 47 | if (fout[idx].is_open()) 48 | { 49 | fout[slot] << "------ End of logging ------" << endl << flush; 50 | fout[idx].close(); 51 | } 52 | } 53 | } 54 | else if (slot < LOG_NFILES) 55 | { 56 | logFlags &= ~(1u << slot); 57 | if (fout[slot].is_open()) 58 | { 59 | fout[slot] << "------ End of logging ------" << endl << flush; 60 | fout[slot].close(); 61 | } 62 | } 63 | } 64 | 65 | void LogFile::setConsole(Console *user) 66 | { 67 | cty = user; 68 | if (cty != nullptr) 69 | logFlags |= LOG_CONSOLE; 70 | else 71 | logFlags &= ~LOG_CONSOLE; 72 | } 73 | 74 | void LogFile::flushAll() 75 | { 76 | // Flush all remaining buffers 77 | for (int idx = 0; idx < LOG_NFILES; idx++) 78 | if (logFlags & (1u << idx)) 79 | fout[idx] << flush; 80 | // if (logFlags & LOG_CONSOLE && cty != nullptr) 81 | } 82 | 83 | void LogFile::out(const uint32_t flags, cstag_t &message) 84 | { 85 | if ((logFlags & (flags & (LOG_ALLFILES|LOG_CONSOLE))) == 0) 86 | return; 87 | 88 | // Record message into some logging files 89 | for (int idx = 0; idx < LOG_NFILES; idx++) 90 | { 91 | if (logFlags & (flags & (1u << idx))) 92 | { 93 | fout[idx] << message; 94 | if (logFlags & LOG_FLUSH) 95 | fout[idx] << flush; 96 | } 97 | } 98 | 99 | // Print message on operator's terminal 100 | if (logFlags & (flags & LOG_CONSOLE)) 101 | { 102 | assert(cty != nullptr); 103 | cty->print(message); 104 | } 105 | } 106 | 107 | // ********************************************************* 108 | 109 | void Debug::setLogFlag(int slot, bool enable) 110 | { 111 | uint32_t flags = 0; 112 | 113 | if (slot >= 0 && slot < LOG_NFILES) 114 | flags = 1u << slot; 115 | else if (slot == LOG_CTYSLOT) 116 | flags = LOG_CONSOLE; 117 | else if (slot == LOG_ALLSLOTS) 118 | flags = LOG_ALLFILES; 119 | 120 | if (enable == true) 121 | logFlags |= flags; 122 | else 123 | logFlags &= ~flags; 124 | } 125 | 126 | dbgOption Debug::dbgList[2] = 127 | { 128 | { "trace", DBG_TRACE }, 129 | { "all", DBG_ALL } 130 | }; 131 | 132 | bool Debug::setOptionFlag(cstag_t &option, bool enable) 133 | { 134 | uint64_t flags = 0; 135 | 136 | for (auto &dbg : dbgList) 137 | if (option == dbg.dbgName) 138 | flags = dbg.dbgFlag; 139 | 140 | if (enable == true) 141 | dbgFlags |= flags; 142 | else 143 | dbgFlags &= ~flags; 144 | 145 | return flags ? true : false; 146 | } 147 | -------------------------------------------------------------------------------- /src/emu/debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * debug.h 3 | * 4 | * Created on: Jan 20, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #define DBG_NONE 0x00000000 // All log flags off 11 | #define DBG_ALL 0xFFFFFFFF // All log flags 12 | 13 | // Debug flags 14 | #define DBG_TRACE 0x80000000 // Tracing execution 15 | #define DBG_OPERAND 0x40000000 // Operand activity 16 | #define DBG_IOREGS 0x20000000 // I/O register activity 17 | #define DBG_IODATA 0x10000000 // I/O data activity 18 | #define DBG_EXCEPTION 0x08000000 // Interrupt/Exception activity 19 | 20 | #define LOG_NFILES 8 21 | 22 | // Log flags 23 | #define LOG_CONSOLE 0x80000000 // Console output 24 | #define LOG_FLUSH 0x40000000 // Flushing buffers 25 | #define LOG_ALLFILES 0x000000FF 26 | #define LOG_FILE8 0x00000080 27 | #define LOG_FILE7 0x00000040 28 | #define LOG_FILE6 0x00000020 29 | #define LOG_FILE5 0x00000010 30 | #define LOG_FILE4 0x00000008 31 | #define LOG_FILE3 0x00000004 32 | #define LOG_FILE2 0x00000002 33 | #define LOG_FILE1 0x00000001 34 | 35 | // Enable/disable log slots 36 | #define LOG_CTYSLOT -1 37 | #define LOG_ALLSLOTS -2 38 | 39 | class Console; 40 | 41 | class LogFile 42 | { 43 | public: 44 | LogFile() = default; 45 | ~LogFile(); 46 | 47 | void setConsole(Console *user); 48 | void out(uint32_t flags, cstag_t &message); 49 | void flushAll(); 50 | 51 | template 52 | void log(uint32_t flags, string format, Args... args) 53 | { 54 | string msg = fmt::sprintf(format, args...); 55 | out(flags, msg); 56 | } 57 | 58 | bool open(fs::path fname, int slot); 59 | void close(int slot); 60 | 61 | private: 62 | uint32_t logFlags = 0; 63 | Console *cty = nullptr; 64 | ofstream fout[LOG_NFILES]; 65 | }; 66 | 67 | class Debug 68 | { 69 | public: 70 | struct DebugOption 71 | { 72 | cstag_t dbgName; 73 | uint64_t dbgFlag; 74 | }; 75 | 76 | Debug() = default; 77 | ~Debug() = default; 78 | 79 | void setLogFlag(int slot, bool enable); 80 | bool setOptionFlag(cstag_t &option, bool enable); 81 | 82 | inline void setLogFile(LogFile *log) { logFile = log; } 83 | 84 | inline void setLogFlags(uint32_t flags) { logFlags |= flags; } 85 | inline void clearLogFlags(uint32_t flags) { logFlags &= ~flags; } 86 | inline void loadLogFlags(uint32_t flags) { logFlags = flags; } 87 | inline uint32_t getLogFlags() { return logFlags; } 88 | 89 | inline bool checkAnyFlags(uint64_t flags) { return (dbgFlags & flags); } 90 | inline bool checkAllFlags(uint64_t flags) { return (dbgFlags & flags) == flags; } 91 | inline void setDebugFlags(uint64_t flags) { dbgFlags |= flags; } 92 | inline void clearDebugFlags(uint64_t flags) { dbgFlags &= ~flags; } 93 | inline void loadDebugFlags(uint64_t flags) { dbgFlags = flags; } 94 | inline uint64_t getDebugFlags() { return dbgFlags; } 95 | 96 | inline void flushAll() { assert(logFile != nullptr); logFile->flushAll(); } 97 | 98 | template 99 | void log(string format, Args... args) 100 | { 101 | string out = fmt::sprintf(format, args...); 102 | 103 | assert(logFile != nullptr); 104 | logFile->out(logFlags, out); 105 | } 106 | 107 | template 108 | void logf(uint32_t flags, string format, Args... args) 109 | { 110 | string out = fmt::sprintf(format, args...); 111 | 112 | assert(logFile != nullptr); 113 | logFile->out(logFlags | flags, out); 114 | } 115 | 116 | private: 117 | uint64_t dbgFlags = 0; 118 | uint32_t logFlags = 0; 119 | 120 | LogFile *logFile = nullptr; 121 | Console *user = nullptr; 122 | 123 | static DebugOption dbgList[2]; 124 | }; 125 | 126 | using dbgOption = Debug::DebugOption; 127 | -------------------------------------------------------------------------------- /src/emu/debugger/debugger.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * debugger.cpp - main debugger package 3 | * 4 | * Created on: Sep 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/debugger/debugger.h" 10 | 11 | using namespace emu::debug; 12 | 13 | Debugger::Debugger() 14 | { 15 | 16 | } 17 | 18 | Debugger::~Debugger() 19 | { 20 | 21 | } -------------------------------------------------------------------------------- /src/emu/debugger/debugger.h: -------------------------------------------------------------------------------- 1 | /* 2 | * debugger.h - main debugger package 3 | * 4 | * Created on: Sep 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | namespace emu::debug 11 | { 12 | class Debugger 13 | { 14 | public: 15 | Debugger(); 16 | ~Debugger(); 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /src/emu/debugger/device.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * device.cpp - debugger package for CPU processors 3 | * 4 | * Created on: Sep 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/dibus.h" 10 | #include "emu/diexec.h" 11 | #include "emu/distate.h" 12 | #include "emu/didebug.h" 13 | #include "emu/debugger/symbols.h" 14 | #include "emu/debugger/device.h" 15 | 16 | using namespace emu::debug; 17 | 18 | DeviceDebugger::DeviceDebugger(Device *device) 19 | : symTable(device->getMachine(), device) 20 | { 21 | 22 | // Get interfaces from device 23 | device->hasInterface(devMemory); 24 | device->hasInterface(devExecute); 25 | device->hasInterface(devState); 26 | device->hasInterface(devDebug); 27 | 28 | if (devState != nullptr) 29 | { 30 | // Add all device state registers to symbol table 31 | for (const auto entry : devState->getStateEntries()) 32 | { 33 | using namespace std::placeholders; 34 | 35 | symTable.add(entry->getSymbol().c_str(), 36 | std::bind(&DeviceStateEntry::getValue, entry), 37 | entry->isWritable() ? std::bind(&DeviceStateEntry::setValue, entry, _1) : setFunc(nullptr), 38 | entry->getFormat()); 39 | } 40 | } 41 | } 42 | 43 | DeviceDebugger::~DeviceDebugger() 44 | { 45 | 46 | } 47 | 48 | void DeviceDebugger::hookInstruction(offs_t pcAddr) 49 | { 50 | 51 | } -------------------------------------------------------------------------------- /src/emu/debugger/device.h: -------------------------------------------------------------------------------- 1 | /* 2 | * device.h - debugger package for CPU processors 3 | * 4 | * Created on: Sep 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/debugger/symbols.h" 11 | 12 | class diExternalBus; 13 | class diExecute; 14 | class diState; 15 | class diDebug; 16 | 17 | namespace emu::debug 18 | { 19 | class DeviceDebugger 20 | { 21 | public: 22 | DeviceDebugger(Device *device); 23 | ~DeviceDebugger(); 24 | 25 | // hook function calls from device 26 | void hookInstruction(offs_t pcAddr); 27 | 28 | private: 29 | SymbolTable symTable; 30 | 31 | diExternalBus *devMemory = nullptr; 32 | diExecute *devExecute = nullptr; 33 | diState *devState = nullptr; 34 | diDebug *devDebug = nullptr; 35 | }; 36 | } 37 | 38 | using debug_t = emu::debug::DeviceDebugger; -------------------------------------------------------------------------------- /src/emu/debugger/symbols.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * symbols.cpp - debugger package - symbol tables 3 | * 4 | * Created on: Sep 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/debugger/symbols.h" 10 | 11 | using namespace emu::debug; 12 | 13 | SymbolEntry::SymbolEntry(SymbolTable &table, ctag_t *name, cstag_t &format) 14 | : table(table), name(name), format(format) 15 | { 16 | 17 | } 18 | 19 | IntegerSymbolEntry::IntegerSymbolEntry(SymbolTable &table, ctag_t *name, 20 | getFunc getter, setFunc setter, cstag_t &format) 21 | : SymbolEntry(table, name, format), 22 | getter(std::move(getter)), 23 | setter(std::move(setter)), 24 | value(0) 25 | { 26 | } 27 | 28 | IntegerSymbolEntry::IntegerSymbolEntry(SymbolTable &table, ctag_t *name, uint64_t cval) 29 | : SymbolEntry(table, name, ""), 30 | getter([this] () { return value; }), 31 | setter(nullptr), 32 | value(cval) 33 | { 34 | } 35 | 36 | SymbolTable::SymbolTable(const Machine *system, Device *device) 37 | : system(*system), device(device) 38 | { 39 | 40 | } 41 | 42 | void SymbolTable::add(ctag_t *name, getFunc getter, setFunc setter, cstag_t &format) 43 | { 44 | // Replace that symbol entry with new one. 45 | symList.erase(name); 46 | symList.emplace(name, IntegerSymbolEntry(*this, name, getter, setter, format)); 47 | } -------------------------------------------------------------------------------- /src/emu/debugger/symbols.h: -------------------------------------------------------------------------------- 1 | /* 2 | * symbols.h - debugger - symbols table 3 | * 4 | * Created on: Sep 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | 11 | namespace emu::debug 12 | { 13 | class SymbolTable; 14 | 15 | typedef std::function getFunc; 16 | typedef std::function setFunc; 17 | 18 | class SymbolEntry 19 | { 20 | public: 21 | SymbolEntry(SymbolTable &table, ctag_t *name, cstag_t &format); 22 | virtual ~SymbolEntry() = default; 23 | 24 | protected: 25 | SymbolTable &table; 26 | cstag_t name; 27 | cstag_t format; 28 | }; 29 | 30 | class IntegerSymbolEntry : public SymbolEntry 31 | { 32 | public: 33 | IntegerSymbolEntry(SymbolTable &table, ctag_t *name, getFunc getter, setFunc setter, cstag_t &format); 34 | IntegerSymbolEntry(SymbolTable &table, ctag_t *name, uint64_t cval); 35 | 36 | uint64_t getValue() const { return getter(); } 37 | void setValue(uint64_t val) { if (setter != nullptr) setter(val); } 38 | 39 | private: 40 | getFunc getter = nullptr; 41 | setFunc setter = nullptr; 42 | uint64_t value = 0; 43 | }; 44 | 45 | class SymbolTable 46 | { 47 | public: 48 | SymbolTable(const Machine *system, Device *device = nullptr); 49 | ~SymbolTable() = default; 50 | 51 | void add(ctag_t *name, getFunc getter, setFunc setter = nullptr, cstag_t &format = ""); 52 | 53 | private: 54 | const Machine &system; 55 | Device *device = nullptr; 56 | 57 | SymbolTable *parent = nullptr; 58 | 59 | std::unordered_map symList; 60 | }; 61 | } -------------------------------------------------------------------------------- /src/emu/delegate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * delegate.cpp 3 | * 4 | * Created on: Jul 5, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/delegate.h" 10 | 11 | -------------------------------------------------------------------------------- /src/emu/devcall.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * devcall.cpp - device callback delegate package 3 | * 4 | * Created on: Oct 20, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/devcall.h" 10 | 11 | template class cbRead_t; 12 | template class cbRead_t; 13 | template class cbRead_t; 14 | template class cbRead_t; 15 | 16 | template class cbWrite_t; 17 | template class cbWrite_t; 18 | template class cbWrite_t; 19 | template class cbWrite_t; 20 | 21 | -------------------------------------------------------------------------------- /src/emu/devfinder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * devfinder.h - device/memory finder package 3 | * 4 | * Created on: Oct 19, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/devfinder.h" 10 | 11 | 12 | ObjectFinder::ObjectFinder(Device &owner, ctag_t *name) 13 | : base(owner), objName(name) 14 | { 15 | owner.registerObject(this); 16 | } 17 | 18 | void ObjectFinder::setObjectName(ctag_t *name) 19 | { 20 | assert(!isResolved); 21 | 22 | objName = name; 23 | } 24 | 25 | void *ObjectFinder::findMemoryRegion(uint8_t width, size_t &size, bool required) const 26 | { 27 | mapMemoryRegion *region = base.findMemoryRegion(objName); 28 | 29 | if (region == nullptr) 30 | { 31 | size = 0; 32 | return nullptr; 33 | } 34 | 35 | // fmt::printf("%s: %s width=%d region=%d\n", base.getDeviceName(), objName, width, region != nullptr); 36 | 37 | // if (region->getBitWidth() != width) 38 | // { 39 | // // if (required) 40 | // size = 0; 41 | // return nullptr; 42 | // } 43 | 44 | // memory region had been found.. all done. 45 | size = region->getSize() / width; 46 | return region->getBase(); 47 | } 48 | 49 | void *ObjectFinder::findMemoryShared(uint8_t width, size_t &size, bool required) const 50 | { 51 | mapMemoryShare *share = base.findMemoryShare(objName); 52 | 53 | if (share == nullptr) 54 | { 55 | size = 0; 56 | return nullptr; 57 | } 58 | 59 | // fmt::printf("%s: %s width=%d shared=%d\n", base.getDeviceName(), objName, width, share != nullptr); 60 | 61 | // if (share->getBitWidth() != width) 62 | // { 63 | // // if (required) 64 | // size = 0; 65 | // return nullptr; 66 | // } 67 | 68 | // memory region had been found.. all done. 69 | size = share->getBytes() / width; 70 | return share->getData(); 71 | } 72 | 73 | bool ObjectFinder::validate(bool found, bool required, ctag_t *name) 74 | { 75 | if (required && objName == nullptr) 76 | { 77 | fmt::printf("%s: %s (unknown object name) is not defined as required\n", 78 | base.getDeviceName(), name); 79 | return false; 80 | } 81 | else if (found) 82 | { 83 | fmt::printf("%s: %s %s '%s' now found and linked\n", 84 | base.getDeviceName(), required ? "required" : "optional", name, objName); 85 | return true; 86 | } 87 | else 88 | { 89 | if (required) 90 | fmt::printf("%s: required %s '%s' not found\n", base.getDeviceName(), name, objName); 91 | else if (objName != nullptr) 92 | fmt::printf("%s: optional %s '%s' not found\n", base.getDeviceName(), name, objName); 93 | return !required; 94 | } 95 | } 96 | 97 | // ********************************************************************************* 98 | 99 | template 100 | MemoryRegionFinder::MemoryRegionFinder(Device &owner, ctag_t *objName) 101 | : ObjectFinderCommon(owner, objName) 102 | { 103 | } 104 | 105 | template 106 | bool MemoryRegionFinder::find() 107 | { 108 | assert(!this->isResolved); 109 | 110 | this->object = this->base.findMemoryRegion(this->objName); 111 | this->isResolved = true; 112 | 113 | return this->validate("region memory"); 114 | } -------------------------------------------------------------------------------- /src/emu/devproc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * devproc.cpp - Processor (CPU) Device package 3 | * 4 | * Created on: Nov 19, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/devproc.h" 10 | 11 | cpuDevice::cpuDevice(const SystemConfig &config, const DeviceType &type, 12 | const string &tagName, Device *owner, uint64_t clock) 13 | : Device(config, type, tagName, owner, clock), 14 | diExecute(this), 15 | diExternalBus(this, "system"), 16 | diState(this), 17 | diDebug(this) 18 | { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/emu/devproc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * devproc.h - Processor (CPU) Device package 3 | * 4 | * Created on: Nov 19, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/diexec.h" 11 | #include "emu/dibus.h" 12 | #include "emu/distate.h" 13 | #include "emu/didebug.h" 14 | 15 | class cpuDevice 16 | : public Device, 17 | public diExecute, 18 | public diExternalBus, 19 | public diState, 20 | public diDebug 21 | { 22 | protected: 23 | cpuDevice(const SystemConfig &config, const DeviceType &type, 24 | const string &tagName, Device *owner, uint64_t clock); 25 | 26 | public: 27 | virtual ~cpuDevice() = default; 28 | 29 | void setProcessorID(int id) { cpuid = id; } 30 | int getProcessorID() const { return cpuid; } 31 | 32 | private: 33 | int cpuid = 0; 34 | }; 35 | 36 | -------------------------------------------------------------------------------- /src/emu/devsys.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * devsys.cpp - system device package 3 | * 4 | * Created on: Jul 14, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/dibus.h" 10 | #include "emu/devsys.h" 11 | 12 | sysDevice::sysDevice(const SystemConfig &config, const DeviceType &type, cstag_t &tagName, uint64_t clock) 13 | : Device(config, type, tagName, nullptr, clock), 14 | driver(config.getSystemDriver()) 15 | { 16 | 17 | } 18 | 19 | void sysDevice::devConfigure(SystemConfig &config) 20 | { 21 | assert(&config == &getSystemConfig()); 22 | 23 | // system-specific initialization 24 | driver.configure(config, *this); 25 | } 26 | -------------------------------------------------------------------------------- /src/emu/devsys.h: -------------------------------------------------------------------------------- 1 | /* 2 | * devsys.h - system device package 3 | * 4 | * Created on: Jul 14, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/map/map.h" 11 | 12 | class sysDevice : public Device 13 | { 14 | public: 15 | sysDevice(const SystemConfig &config, const DeviceType &type, cstag_t &tagName, uint64_t clock); 16 | 17 | inline void setExternalBusManager(aspace::BusManager *bus) { busManager = bus; } 18 | 19 | // Virtual device function calls 20 | void devConfigure(SystemConfig &config); 21 | const romEntry_t *devGetROMEntries() { return driver.romEntries; } 22 | 23 | private: 24 | const SystemDriver &driver; 25 | 26 | protected: 27 | aspace::BusManager *busManager = nullptr; // system-wide bus manager for all devices 28 | }; 29 | -------------------------------------------------------------------------------- /src/emu/dibus.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * dibus.cpp - bus interface package 3 | * 4 | * Created on: Dec 16, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/dibus.h" 10 | 11 | using namespace aspace; 12 | 13 | diExternalBus::diExternalBus(device_t *owner, ctag_t *name) 14 | : DeviceInterface(owner, name) 15 | { 16 | owner->ifBus = this; 17 | 18 | AddressMapList.clear(); 19 | mapConfig.clear(); 20 | mapSpace.clear(); 21 | // mapMemories.clear(); 22 | } 23 | 24 | diExternalBus::~diExternalBus() 25 | { 26 | // Release all memory blocks 27 | // for (int idx = 0; idx < mapMemories.size(); idx++) 28 | // delete mapMemories[idx]; 29 | // mapMemories.clear(); 30 | 31 | // Release all addressing configurations and spaces 32 | mapConfig.clear(); 33 | mapSpace.clear(); 34 | } 35 | 36 | void diExternalBus::completeConfig() 37 | { 38 | mapConfigList list = getAddressConfigList(); 39 | 40 | for (const auto &entry : list) 41 | { 42 | if (entry.type >= mapConfig.size()) 43 | mapConfig.resize(entry.type + 1); 44 | mapConfig[entry.type] = entry.config; 45 | } 46 | } 47 | 48 | const mapAddressConfig *diExternalBus::getAddressConfig(int space) const 49 | { 50 | if (space >= 0 && space < mapConfig.size()) 51 | return mapConfig[space]; 52 | return nullptr; 53 | } 54 | 55 | AddressSpace *diExternalBus::getAddressSpace(int space) const 56 | { 57 | if (space >= 0 && space < mapSpace.size()) 58 | return mapSpace[space]; 59 | return nullptr; 60 | } 61 | 62 | Constructor diExternalBus::getAddressMap(int space) const 63 | { 64 | if (space >= 0 && space < AddressMapList.size()) 65 | return AddressMapList[space]; 66 | return Constructor(); 67 | } 68 | 69 | void diExternalBus::setAddressMap(int space, Constructor map) 70 | { 71 | // ctag_t *name = map.getName(); 72 | // fmt::printf("Binded object = %s\n", name); 73 | 74 | if (space >= AddressMapList.size()) 75 | AddressMapList.resize(space+1); 76 | AddressMapList[space] = std::move(map); 77 | } 78 | 79 | //void diBus::registerMemory(mapMemoryBlock *block, offs_t base, offs_t size, int prio) 80 | //{ 81 | // if (mapMemories.size() > 0) 82 | // { 83 | // 84 | // } 85 | // 86 | // mapMemory *mem = new mapMemory; 87 | // 88 | // mem->baseAddr = base; 89 | // mem->endAddr = base + size; 90 | // mem->length = size; 91 | // mem->data = block->getData(); 92 | // 93 | // mapMemories.push_back(mem); 94 | //} 95 | -------------------------------------------------------------------------------- /src/emu/didebug.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * didebug.cpp - Device Interface - Debugging Tools 3 | * 4 | * Created on: Nov 27, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/didebug.h" 10 | #include "emu/machine.h" 11 | 12 | diDebug::diDebug(device_t *owner) 13 | : DeviceInterface(owner, "debug") 14 | { 15 | owner->ifDebug = this; 16 | } 17 | 18 | //void diDebug::ifStart() 19 | //{ 20 | // Machine *sys = getDevice()->getMachine(); 21 | // assert(sys != nullptr); 22 | // 23 | //#ifdef DEBUG 24 | // dbg.setLogFile(sys->getLogFile()); 25 | //#endif /* DEBUG */ 26 | //} 27 | 28 | void diDebug::setLogFile(Machine *sys) 29 | { 30 | assert(sys != nullptr); 31 | dbg.setLogFile(sys->getLogFile()); 32 | } 33 | 34 | int diDebug::list(Console *cty, offs_t vAddr) 35 | { 36 | return 0; 37 | } -------------------------------------------------------------------------------- /src/emu/didebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * didebug.h - Device Interface - Debugging tools 3 | * 4 | * Created on: Nov 27, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/map/map.h" 11 | #include "emu/debug.h" 12 | 13 | class diDebug : public DeviceInterface 14 | { 15 | public: 16 | diDebug(device_t *owner); 17 | virtual ~diDebug() = default; 18 | 19 | void setLogFile(Machine *sys); // { dbg.setLogFile(sys->getLogFile()); } 20 | 21 | virtual int list(Console *cty, offs_t vAddr); 22 | 23 | #ifdef ENABLE_DEBUG 24 | inline Debug *getDebugSetting() const { return &dbg; } 25 | #endif /* ENABLE_DEBUG */ 26 | 27 | #ifdef ENABLE_DEBUG 28 | protected: 29 | mutable Debug dbg; 30 | #endif /* ENABLE_DEBUG */ 31 | 32 | private: 33 | }; 34 | -------------------------------------------------------------------------------- /src/emu/diexec.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * diexec.cpp - Device Interface - Execution 3 | * 4 | * Created on: Nov 27, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/diexec.h" 10 | 11 | diExecute::diExecute(device_t *owner) 12 | : DeviceInterface(owner, "execute"), 13 | ownerDevice(*owner) 14 | { 15 | owner->ifExecute = this; 16 | } 17 | 18 | void diExecute::setPCAddress(offs_t addr) 19 | { 20 | } 21 | 22 | bool diExecute::load(ifstream &fin, offs_t off) 23 | { 24 | return false; 25 | } 26 | 27 | void diExecute::step(Console *user) 28 | { 29 | 30 | } 31 | 32 | void diExecute::execute() 33 | { 34 | // thread myThis; 35 | 36 | run(); 37 | } 38 | 39 | void diExecute::halt() 40 | { 41 | // thread myThis; 42 | 43 | // sendSignal(CPU_HALT); 44 | // myThis.join(); 45 | } 46 | 47 | void diExecute::ifUpdateClock() 48 | { 49 | cyclePerSecond = executeClockToCycle(ownerDevice.getClock()); 50 | cycleDuration = HZ_TO_ATTOSECONDS(cyclePerSecond); 51 | 52 | // printf("Clock: %lld Cycle/Second: %lld Time: %lld\n", ownerDevice.getClock(), 53 | // cyclePerSecond, uint64_t(cycleDuration / ATTOSECONDS_PER_NANOSECOND)); 54 | } 55 | 56 | attotime_t diExecute::getLocalTime() const 57 | { 58 | if (isExecuting()) 59 | { 60 | assert(cycleRunning >= *cycleCounter); 61 | int cycles = cycleRunning - *cycleCounter; 62 | return localTime + (cycles * cycleDuration); 63 | } 64 | return localTime; 65 | } 66 | 67 | void diExecute::eatCycles(int64_t cycles) 68 | { 69 | if (!isExecuting() || cycleCounter == nullptr) 70 | return; 71 | 72 | if (cycles < 0 || cycles > *cycleCounter) 73 | *cycleCounter = 0; 74 | else 75 | *cycleCounter -= cycles; 76 | } 77 | 78 | void diExecute::abortTimeslice() 79 | { 80 | if (!isExecuting() || cycleCounter == nullptr) 81 | return; 82 | 83 | int64_t delta = *cycleCounter; 84 | 85 | cycleStolen += delta; 86 | cycleRunning -= delta; 87 | *cycleCounter -= delta; 88 | } 89 | 90 | void diExecute::runTimeslice() 91 | { 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/emu/diexec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * diexec.h - Device Interface - Execution 3 | * 4 | * Created on: Nov 27, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | enum irqLine 11 | { 12 | MAX_IRQ_LINES = 64, 13 | IRQ_LINE0 = 0, 14 | IRQ_LINE1 = 1, 15 | IRQ_LINE2 = 2, 16 | IRQ_LINE3 = 3, 17 | IRQ_LINE4 = 4, 18 | IRQ_LINE5 = 5, 19 | IRQ_LINE6 = 6, 20 | IRQ_LINE7 = 7, 21 | 22 | IRQ_NMI = MAX_IRQ_LINES+0, 23 | IRQ_RESET = MAX_IRQ_LINES+1, 24 | IRQ_HALT = MAX_IRQ_LINES+2 25 | }; 26 | 27 | class diExecute : public DeviceInterface 28 | { 29 | friend class DeviceScheduler; 30 | 31 | public: 32 | diExecute(device_t *owner); 33 | virtual ~diExecute() = default; 34 | 35 | // execution state 36 | enum execState 37 | { 38 | execStopped = 0, 39 | execStopping, 40 | execRunning, 41 | execIdle, 42 | execWait 43 | }; 44 | 45 | inline bool isExecuting() const { return pState == execRunning; } 46 | 47 | // Abstract function calls 48 | virtual void run() = 0; 49 | virtual void step(Console *user); // single step function call 50 | 51 | virtual void setPCAddress(offs_t addr); 52 | 53 | virtual bool load(ifstream &fin, offs_t off); 54 | // virtual bool save(ofstream &fout) = 0; 55 | 56 | // void boot(); 57 | void execute(); 58 | void halt(); 59 | 60 | void eatCycles(int64_t cycles); 61 | void abortTimeslice(); 62 | void runTimeslice(); // handle time slice period 63 | 64 | attotime_t getLocalTime() const; 65 | 66 | attoseconds_t getMinQuantum() const { return cycleDuration * executeGetMinCycles(); } 67 | 68 | // Virtual interface function calls 69 | void ifUpdateClock() override; 70 | 71 | protected: 72 | inline void setCycleCounter(int64_t *counter) { cycleCounter = counter; } 73 | 74 | // debugging hook funtion calls 75 | inline void debugInstructionHook(offs_t pcAddr) 76 | { 77 | 78 | } 79 | 80 | // Virtual execute function calls for scheduler 81 | virtual uint64_t executeClockToCycle(uint64_t clock) const { return clock; } 82 | virtual uint64_t executeCycleToClock(uint64_t cycle) const { return cycle; } 83 | virtual int executeGetMinCycles() const { return 1; } 84 | virtual int executeGetMaxCycles() const { return 1; } 85 | virtual int executeGetInputLines() const { return 0; } 86 | virtual void executeRun() {} 87 | 88 | protected: 89 | execState pState = execStopped; 90 | 91 | private: 92 | Device &ownerDevice; 93 | 94 | // Scheduler parameters 95 | DeviceScheduler *scheduler = nullptr; 96 | 97 | diExecute *execNext = nullptr; 98 | 99 | uint64_t cyclePerSecond = 0; // cycles per second (clock rate) 100 | attoseconds_t cycleDuration = 0; // cycle duration (in attoseconds) 101 | 102 | attotime_t localTime; 103 | 104 | // Cycle countdown definitions for scheduler 105 | int64_t cycleTotal = 0; 106 | int64_t cycleRunning = 0; 107 | int64_t cycleStolen = 0; 108 | int64_t *cycleCounter = nullptr; // opcode/cycle counter 109 | 110 | // Suspend state definitions 111 | uint32_t suspend = 0; 112 | uint32_t nextSuspend = 0; 113 | uint32_t eatingCycles = 0; 114 | uint32_t nextEatingCycles = 0; 115 | }; 116 | -------------------------------------------------------------------------------- /src/emu/divideo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * divideo.cpp - Device Interface - Video 3 | * 4 | * Created on: Sep 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/divideo.h" 10 | 11 | diVideo::diVideo(device_t *owner) 12 | : DeviceInterface(owner, "video") 13 | { 14 | } -------------------------------------------------------------------------------- /src/emu/divideo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * divideo.h - Device Interface - Video 3 | * 4 | * Created on: Sep 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/screen.h" 11 | 12 | class diVideo : public DeviceInterface 13 | { 14 | public: 15 | diVideo(device_t *owner); 16 | virtual ~diVideo() = default; 17 | 18 | void setScreenName(ctag_t *name) { screenName = name; } 19 | 20 | protected: 21 | bool screenRequired = false; 22 | Device *screenBase = nullptr; 23 | ctag_t *screenName = nullptr; 24 | 25 | screen_t *screen = nullptr; 26 | }; 27 | -------------------------------------------------------------------------------- /src/emu/engine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * engine.h - System engine package 3 | * 4 | * Created on: Jul 31, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/command.h" 11 | 12 | class Machine; 13 | class SystemEngine 14 | { 15 | public: 16 | using cmdFunc_t = CommandStatus (SystemEngine::*)(Console *, args_t &); 17 | using cmdDevice_t = CommandStatus (SystemEngine::*)(Console *, Machine *, Device *, args_t &); 18 | 19 | struct command_t 20 | { 21 | ctag_t *name; 22 | cmdFunc_t func; 23 | command_t *options; 24 | }; 25 | 26 | struct gdevCommand_t 27 | { 28 | ctag_t *name; 29 | cmdDevice_t func; 30 | }; 31 | 32 | SystemEngine() = default; 33 | SystemEngine(Console *user) : user(user) {} 34 | ~SystemEngine() = default; 35 | 36 | // Global system initialization 37 | void ginit(); 38 | void gexit(); 39 | 40 | Machine *findSystem(cstag_t name); 41 | Machine *findSystem(Console *user); 42 | Device *findDevice(Console *user, cstag_t name); 43 | Device *findDevice(cstag_t name); 44 | 45 | void dial(Console *user, Machine *system); 46 | 47 | uint64_t getValue(cstag_t sValue); 48 | 49 | // command handlers 50 | CommandStatus cmdCreate(Console *user, args_t &args); 51 | CommandStatus cmdDial(Console *user, args_t &args); 52 | CommandStatus cmdDebug(Console *user, args_t &args); 53 | CommandStatus cmdDeposit(Console *user, args_t &args); 54 | CommandStatus cmdDump(Console *user, args_t &args); 55 | CommandStatus cmdDumpr(Console *user, args_t &args); 56 | CommandStatus cmdExecute(Console *user, args_t &args); 57 | CommandStatus cmdExit(Console *user, args_t &args); 58 | CommandStatus cmdHalt(Console *user, args_t &args); 59 | CommandStatus cmdList(Console *user, args_t &args); 60 | CommandStatus cmdLoad(Console *user, args_t &args); 61 | CommandStatus cmdLog(Console *user, args_t &args); 62 | CommandStatus cmdRegisters(Console *user, args_t &args); 63 | CommandStatus cmdReset(Console *user, args_t &args); 64 | CommandStatus cmdRun(Console *user, args_t &args); 65 | CommandStatus cmdSet(Console *user, args_t &args); 66 | CommandStatus cmdShow(Console *user, args_t &args); 67 | CommandStatus cmdShowDevice(Console *user, args_t &args); 68 | CommandStatus cmdShowSystem(Console *user, args_t &args); 69 | CommandStatus cmdStart(Console *user, args_t &args); 70 | CommandStatus cmdStep(Console *user, args_t &args); 71 | CommandStatus cmdStop(Console *user, args_t &args); 72 | 73 | CommandStatus cmdSetFolder(Console *user, Machine *sys, Device *dev, args_t &args); 74 | 75 | CommandStatus cmdShowRegisters(Console *user, Machine *sys, Device *dev, args_t &args); 76 | 77 | private: 78 | Console *user = nullptr; 79 | 80 | Machine *dialedMachine = nullptr; 81 | Device *dialedSystem = nullptr; 82 | 83 | // Continuously output for last command 84 | command_t *lastCommand = nullptr; 85 | Device *lastDevice = nullptr; 86 | offs_t lastAddress = 0; 87 | 88 | // Machines 89 | static vector machines; 90 | 91 | static command_t mseCommands[]; 92 | static gdevCommand_t mseSetDeviceCommands[]; 93 | static gdevCommand_t mseShowDeviceCommands[]; 94 | // static command_t mseShowCommands[]; 95 | // static command_t mseSetCommands[]; 96 | }; 97 | -------------------------------------------------------------------------------- /src/emu/fileio.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "emu/core.h" 3 | #include "emu/fileio.h" 4 | 5 | using namespace emu; 6 | 7 | ioFile::ioFile(uint64_t flags) 8 | { 9 | } 10 | 11 | bool ioFile::open(fs::path fname) 12 | { 13 | file.open(fname, ios::in|ios::binary); 14 | 15 | return file.is_open(); 16 | } 17 | 18 | void ioFile::close() 19 | { 20 | file.close(); 21 | } 22 | 23 | int ioFile::read(uint8_t *data, int length) 24 | { 25 | file.read((char *)data, length); 26 | return file.gcount(); 27 | } 28 | 29 | int ioFile::write(uint8_t *data, int length) 30 | { 31 | file.write((char *)data, length); 32 | return file.gcount(); 33 | } -------------------------------------------------------------------------------- /src/emu/fileio.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #pragma once 5 | 6 | namespace emu 7 | { 8 | class ioFile 9 | { 10 | public: 11 | ioFile(uint64_t flags); 12 | virtual ~ioFile() = default; 13 | 14 | bool open(fs::path fname); 15 | 16 | void close(); 17 | 18 | int read(uint8_t *data, int length); 19 | int write(uint8_t *data, int length); 20 | 21 | private: 22 | fstream file; 23 | }; 24 | } -------------------------------------------------------------------------------- /src/emu/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * list.h - list package 3 | * 4 | * Created on: Nov 27, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | template 11 | class List 12 | { 13 | public: 14 | List() { list.clear(); } 15 | ~List() = default; 16 | 17 | inline void addNode(T *node) { list.push_back(node); } 18 | 19 | inline bool hasChildren() { return list.size() > 0; } 20 | inline int size() { return list.size(); } 21 | 22 | inline T *getNode(int index) { return index < list.size() ? list[index] : nullptr; } 23 | inline T *getFirst() { cidx = 0; return list[cidx++]; } 24 | inline T *getNext() { return cidx < list.size() ? list[cidx++] : nullptr; } 25 | 26 | inline void reset() { cidx = 0; } 27 | 28 | vector getList() { return list; } 29 | 30 | private: 31 | vector list; 32 | int cidx = 0; 33 | }; 34 | -------------------------------------------------------------------------------- /src/emu/machine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * machine.h 3 | * 4 | * Created on: Oct 11, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/map/map.h" 11 | #include "emu/sysconfig.h" 12 | #include "emu/scheduler.h" 13 | #include "emu/devsys.h" 14 | #include "emu/video.h" 15 | 16 | class romLoader; 17 | 18 | // Debug flags definition 19 | constexpr uint32_t DBGFLG_ENABLED = 0x00000001; 20 | constexpr uint32_t SYSTEM_HALT = 0x80000000; 21 | 22 | class SystemEngine; 23 | 24 | class Machine 25 | { 26 | public: 27 | Machine(const SystemEngine &engine, const SystemConfig &config, cstag_t &tagName); 28 | ~Machine(); 29 | 30 | inline cstag_t &getDeviceName() const { return devName; } 31 | inline device_t *getSystemDevice() const { return system; } 32 | inline LogFile *getLogFile() const { return &logFile; } 33 | inline DeviceScheduler &getScheduler() { return scheduler; } 34 | inline attotime_t getTime() const { return scheduler.getCurrentTime(); } 35 | inline void setConsole(Console *user) { logFile.setConsole(user); } 36 | inline void setDialedDevice(Device *dev) { dialedDevice = dev; } 37 | inline Device *getDialedDevice() const { return dialedDevice; } 38 | 39 | inline aspace::BusManager &getExternalBusManager() { return busManager; } 40 | 41 | inline bool isDebuggerEnabled() { return debugFlags & DBGFLG_ENABLED; } 42 | 43 | static Machine *create(ostream &out, const SystemEngine &engine, const SystemDriver *driver, cstag_t &devName); 44 | 45 | void startAllDevices(Console *cty); 46 | 47 | // Command function calls 48 | void reset(Console *cty); 49 | void start(Console *cty); 50 | void stop(Console *cty); 51 | void halt(Console *cty); 52 | void run(Console *cty); 53 | 54 | private: 55 | void launch(); 56 | 57 | private: 58 | const SystemConfig &config; 59 | sysDevice *system = nullptr; 60 | 61 | uint32_t debugFlags = 0; 62 | 63 | mutable Device *dialedDevice = nullptr; 64 | 65 | cstag_t devName; 66 | 67 | mutable fs::path ownFolder; 68 | mutable LogFile logFile; 69 | 70 | romLoader *loader = nullptr; 71 | 72 | thread thisThread; 73 | bool running = false; 74 | uint32_t flags = 0; 75 | 76 | // External bus manager 77 | aspace::BusManager busManager; 78 | DeviceScheduler scheduler; 79 | VideoManager video; 80 | }; 81 | -------------------------------------------------------------------------------- /src/emu/map.new/map.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | // address space namespace 4 | namespace aspace2 5 | { 6 | // Data width size definitions for handler function calls 7 | // 8 | // 0 = 8-bit data width 9 | // 1 = 16-bit data width 10 | // 2 = 32-bit data width 11 | // 3 = 64-bit data width 12 | 13 | template struct HandlerSize {}; 14 | template <> struct HandlerSize<0> { using uintx_t = uint8_t; }; 15 | template <> struct HandlerSize<1> { using uintx_t = uint16_t; } 16 | template <> struct HandlerSize<2> { using uintx_t = uint32_t; } 17 | template <> struct HandlerSize<3> { using uintx_t = uint64_t; } 18 | 19 | // Address space type definitions 20 | enum spaceType 21 | { 22 | asProgram = 0, 23 | asData = 1, 24 | asIOPort = 2 25 | }; 26 | 27 | 28 | class AddressSpaceConfig 29 | { 30 | 31 | }; 32 | 33 | template 34 | class MemoryAccessSpecific 35 | { 36 | using uintx_t = typename HandlerSize::uintx_t; 37 | 38 | 39 | 40 | 41 | }; 42 | 43 | 44 | class AddressSpace 45 | { 46 | public: 47 | // Read/write access type definitions 48 | enum accessType { accRead, accWrite, accReadWrit }; 49 | 50 | 51 | // Prepare for address map list 52 | void prepare(Console *user) 53 | { 54 | 55 | } 56 | 57 | // Populate memory space from map list 58 | void populate(Console *user) 59 | { 60 | 61 | } 62 | }; 63 | } -------------------------------------------------------------------------------- /src/emu/map/access.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * access.cpp - Mapping Address Space package 3 | * 4 | * Created on: Dec 12, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/map/addrmap.h" 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/emu/map/hea.h: -------------------------------------------------------------------------------- 1 | /* 2 | * hea.h - Handler Entry - Address space access 3 | * 4 | * Created on: Apr 3, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | namespace aspace 11 | { 12 | template 13 | class HandlerReadAddress : public HandlerRead 14 | { 15 | public: 16 | using uintx_t = typename HandlerSize::uintx_t; 17 | 18 | HandlerReadAddress(AddressSpace *space, uint32_t flags) 19 | : HandlerRead(space, flags) 20 | { } 21 | ~HandlerReadAddress() = default; 22 | 23 | inline void setAddressSpace(offs_t base, offs_t mask) 24 | { 25 | baseAddress = base & ~HandlerRead::nativeMask; 26 | maskAddress = mask; 27 | } 28 | 29 | protected: 30 | offs_t baseAddress = 0; 31 | offs_t maskAddress = 0; 32 | }; 33 | 34 | template 35 | class HandlerWriteAddress : public HandlerWrite 36 | { 37 | public: 38 | 39 | using uintx_t = typename HandlerSize::uintx_t; 40 | HandlerWriteAddress(AddressSpace *space, uint32_t flags) 41 | : HandlerWrite(space, flags) 42 | { } 43 | ~HandlerWriteAddress() = default; 44 | 45 | inline void setAddressSpace(offs_t base, offs_t mask) 46 | { 47 | baseAddress = base & ~HandlerWrite::nativeMask; 48 | maskAddress = mask; 49 | } 50 | 51 | protected: 52 | offs_t baseAddress = 0; 53 | offs_t maskAddress = 0; 54 | }; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/emu/map/hedp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * hedp.cpp - Handler entry delegate package 3 | * 4 | * Created on: Dec 5, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/map/map.h" 10 | -------------------------------------------------------------------------------- /src/emu/map/hedri.h: -------------------------------------------------------------------------------- 1 | /* 2 | * hedri.h - Read Handler Entry package - Dispatch (forward function calls) 3 | * 4 | * Created on: Aug 26, 2021 5 | * Author: Tim Stark 6 | */ -------------------------------------------------------------------------------- /src/emu/map/hedwi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * hedwi.h - Write Handler Entry package - Dispatch (forward function calls) 3 | * 4 | * Created on: Aug 26, 2021 5 | * Author: Tim Stark 6 | */ -------------------------------------------------------------------------------- /src/emu/map/hem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * hem.cpp 3 | * 4 | * Created on: Apr 3, 2021 5 | * Author: fswor 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/map/map.h" 10 | #include "emu/map/hea.h" 11 | #include "emu/map/hem.h" 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/emu/map/hem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * hem.h - Handler entry - memory access 3 | * 4 | * Created on: Apr 3, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | namespace aspace 11 | { 12 | 13 | template 14 | class HandlerReadMemory : public HandlerReadAddress 15 | { 16 | public: 17 | using uintx_t = typename HandlerSize::uintx_t; 18 | 19 | HandlerReadMemory(AddressSpace *space, void *base) 20 | : HandlerReadAddress(space, 0), 21 | baseData(reinterpret_cast(base)) 22 | { } 23 | 24 | ~HandlerReadMemory() = default; 25 | 26 | string getName() const override { return "memory"; } 27 | // void setBase(uintx_t *base) override { baseData = base; } 28 | 29 | uintx_t read(offs_t offset, cpuDevice *cpu) const override 30 | { 31 | // printf("Memory: (%X - %X)& %X >> %d => %X\n", offset, inh::baseAddress, inh::maskAddress, (dWidth + aShift), 32 | // ((offset - this->baseAddress) & this->maskAddress) >> (dWidth + aShift)); 33 | assert(baseData != nullptr); 34 | return baseData[((offset - this->baseAddress) & this->maskAddress) >> (dWidth + aShift)]; 35 | } 36 | 37 | uintx_t read(offs_t offset, uintx_t mask, cpuDevice *cpu) const override 38 | { 39 | assert(baseData != nullptr); 40 | return baseData[((offset - this->baseAddress) & this->maskAddress) >> (dWidth + aShift)]; 41 | } 42 | 43 | void *getAccess(offs_t offset) const override 44 | { 45 | assert(baseData != nullptr); 46 | return &baseData[((offset - this->baseAddress) & this->maskAddress) >> (dWidth + aShift)]; 47 | } 48 | 49 | private: 50 | mutable uintx_t *baseData = nullptr; 51 | }; 52 | 53 | template 54 | class HandlerWriteMemory : public HandlerWriteAddress 55 | { 56 | public: 57 | using uintx_t = typename HandlerSize::uintx_t; 58 | 59 | HandlerWriteMemory(AddressSpace *space, void *base) 60 | : HandlerWriteAddress(space, 0), 61 | baseData(reinterpret_cast(base)) 62 | { } 63 | 64 | ~HandlerWriteMemory() = default; 65 | 66 | string getName() const override { return "memory"; } 67 | // void setBase(uintx_t *base) override { baseData = base; } 68 | 69 | void write(offs_t offset, uintx_t data, cpuDevice *cpu) const override 70 | { 71 | assert(baseData != nullptr); 72 | baseData[((offset - this->baseAddress) & this->maskAddress) >> (dWidth + aShift)] = data; 73 | } 74 | 75 | void write(offs_t offset, uintx_t data, uintx_t mask, cpuDevice *cpu) const override 76 | { 77 | assert(baseData != nullptr); 78 | offs_t off = ((offset - this->baseAddress) & this->maskAddress) >> (dWidth + aShift); 79 | baseData[off] = (baseData[off] & ~mask) | (data & mask); 80 | } 81 | 82 | void *getAccess(offs_t offset) const override 83 | { 84 | assert(baseData != nullptr); 85 | return &baseData[((offset - this->baseAddress) & this->maskAddress) >> (dWidth + aShift)]; 86 | } 87 | 88 | private: 89 | mutable uintx_t *baseData = nullptr; 90 | }; 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/emu/map/hep.h: -------------------------------------------------------------------------------- 1 | /* 2 | * hep.h - Handler entry - passthrough access 3 | * 4 | * Created on: Aug 26, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | namespace aspace 11 | { 12 | 13 | template 14 | class HandlerReadPassthrough : public HandlerReadAddress 15 | { 16 | public: 17 | using uintx_t = typename HandlerSize::uintx_t; 18 | using inh = HandlerReadAddress; 19 | 20 | HandlerReadPassthrough(AddressSpace *space) 21 | : HandlerReadAddress(space, HandlerEntry::hePassthrough) 22 | { } 23 | 24 | ~HandlerReadPassthrough() = default; 25 | 26 | string getName() const override { return "passthrough"; } 27 | // void setBase(uintx_t *base) override { baseData = base; } 28 | 29 | uintx_t read(offs_t offset, cpuDevice *cpu) const override 30 | { 31 | // assert(baseData != nullptr); 32 | // return baseData[((offset - inh::baseAddress) & inh::maskAddress) >> (dWidth + aShift)]; 33 | return 0; 34 | } 35 | 36 | uintx_t read(offs_t offset, uintx_t mask, cpuDevice *cpu) const override 37 | { 38 | // assert(baseData != nullptr); 39 | // return baseData[((offset - inh::baseAddress) & inh::maskAddress) >> (dWidth + aShift)]; 40 | return 0; 41 | } 42 | 43 | void *getAccess(offs_t offset) const override 44 | { 45 | // assert(baseData != nullptr); 46 | // return &baseData[((offset - inh::baseAddress) & inh::maskAddress) >> (dWidth + aShift)]; 47 | return nullptr; 48 | } 49 | 50 | private: 51 | }; 52 | 53 | template 54 | class HandlerWritePassthrough : public HandlerWriteAddress 55 | { 56 | public: 57 | using uintx_t = typename HandlerSize::uintx_t; 58 | using inh = HandlerWriteAddress; 59 | 60 | HandlerWritePassthrough(AddressSpace *space) 61 | : HandlerWriteAddress(space, HandlerEntry::hePassthrough) 62 | { } 63 | 64 | ~HandlerWritePassthrough() = default; 65 | 66 | string getName() const override { return "passthrough"; } 67 | // void setBase(uintx_t *base) override { baseData = base; } 68 | 69 | void write(offs_t offset, uintx_t data, cpuDevice *cpu) const override 70 | { 71 | // assert(baseData != nullptr); 72 | // baseData[((offset - inh::baseAddress) & inh::maskAddress) >> (dWidth + aShift)] = data; 73 | } 74 | 75 | void write(offs_t offset, uintx_t data, uintx_t mask, cpuDevice *cpu) const override 76 | { 77 | // assert(baseData != nullptr); 78 | // offs_t off = ((offset - inh::baseAddress) & inh::maskAddress) >> (dWidth + aShift); 79 | // baseData[off] = (baseData[off] & ~mask) | (data & mask); 80 | } 81 | 82 | void *getAccess(offs_t offset) const override 83 | { 84 | // assert(baseData != nullptr); 85 | // return &baseData[((offset - inh::baseAddress) & inh::maskAddress) >> (dWidth + aShift)]; 86 | return nullptr; 87 | } 88 | 89 | private: 90 | }; 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/emu/map/heun.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * heun.cpp - Handler Entry - Unmapped/NOP 3 | * 4 | * Created on: Jan 10, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/map/map.h" 10 | 11 | using namespace aspace; 12 | 13 | template class HandlerReadUnmapped<0, 0>; 14 | template class HandlerReadUnmapped<1, 0>; 15 | template class HandlerReadUnmapped<1, 1>; 16 | template class HandlerReadUnmapped<2, 0>; 17 | template class HandlerReadUnmapped<2, 1>; 18 | template class HandlerReadUnmapped<2, 2>; 19 | template class HandlerReadUnmapped<3, 0>; 20 | template class HandlerReadUnmapped<3, 1>; 21 | template class HandlerReadUnmapped<3, 2>; 22 | template class HandlerReadUnmapped<3, 3>; 23 | 24 | template class HandlerWriteUnmapped<0, 0>; 25 | template class HandlerWriteUnmapped<1, 0>; 26 | template class HandlerWriteUnmapped<1, 1>; 27 | template class HandlerWriteUnmapped<2, 0>; 28 | template class HandlerWriteUnmapped<2, 1>; 29 | template class HandlerWriteUnmapped<2, 2>; 30 | template class HandlerWriteUnmapped<3, 0>; 31 | template class HandlerWriteUnmapped<3, 1>; 32 | template class HandlerWriteUnmapped<3, 2>; 33 | template class HandlerWriteUnmapped<3, 3>; 34 | 35 | template class HandlerReadNop<0, 0>; 36 | template class HandlerReadNop<1, 0>; 37 | template class HandlerReadNop<1, 1>; 38 | template class HandlerReadNop<2, 0>; 39 | template class HandlerReadNop<2, 1>; 40 | template class HandlerReadNop<2, 2>; 41 | template class HandlerReadNop<3, 0>; 42 | template class HandlerReadNop<3, 1>; 43 | template class HandlerReadNop<3, 2>; 44 | template class HandlerReadNop<3, 3>; 45 | 46 | template class HandlerWriteNop<0, 0>; 47 | template class HandlerWriteNop<1, 0>; 48 | template class HandlerWriteNop<1, 1>; 49 | template class HandlerWriteNop<2, 0>; 50 | template class HandlerWriteNop<2, 1>; 51 | template class HandlerWriteNop<2, 2>; 52 | template class HandlerWriteNop<3, 0>; 53 | template class HandlerWriteNop<3, 1>; 54 | template class HandlerWriteNop<3, 2>; 55 | template class HandlerWriteNop<3, 3>; 56 | -------------------------------------------------------------------------------- /src/emu/map/heun.h: -------------------------------------------------------------------------------- 1 | /* 2 | * heun.h - Handler entry unmapped package 3 | * 4 | * Created on: Jan 10, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | namespace aspace 11 | { 12 | 13 | template 14 | class HandlerReadUnmapped : public HandlerRead 15 | { 16 | public: 17 | using uintx_t = typename HandlerRead::uintx_t; 18 | using rhe = HandlerRead; 19 | 20 | HandlerReadUnmapped(AddressSpace *space) 21 | : HandlerRead(space, 0) 22 | { } 23 | 24 | ~HandlerReadUnmapped() = default; 25 | 26 | // ctag_t *getName() const { return "unmapped"; } 27 | string getName() const { return "unmapped"; } 28 | 29 | uintx_t read(offs_t offset, cpuDevice *cpu) const override 30 | { 31 | return rhe::space->getUnmapped(); 32 | } 33 | 34 | uintx_t read(offs_t offset, uintx_t mask, cpuDevice *cpu) const override 35 | { 36 | return rhe::space->getUnmapped(); 37 | } 38 | }; 39 | 40 | template 41 | class HandlerWriteUnmapped : public HandlerWrite 42 | { 43 | public: 44 | using uintx_t = typename HandlerRead::uintx_t; 45 | using whe = HandlerWrite; 46 | 47 | 48 | HandlerWriteUnmapped(AddressSpace *space) 49 | : HandlerWrite(space, 0) 50 | { } 51 | 52 | ~HandlerWriteUnmapped() = default; 53 | 54 | // ctag_t *getName() const { return "unmapped"; } 55 | string getName() const { return "unmapped"; } 56 | 57 | void write(offs_t offset, uintx_t data, cpuDevice *cpu) const override 58 | { 59 | 60 | } 61 | 62 | void write(offs_t offset, uintx_t data, uintx_t mask, cpuDevice *cpu) const override 63 | { 64 | 65 | } 66 | }; 67 | 68 | template 69 | class HandlerReadNop : public HandlerRead 70 | { 71 | public: 72 | using uintx_t = typename HandlerRead::uintx_t; 73 | using rhe = HandlerRead; 74 | 75 | HandlerReadNop(AddressSpace *space) 76 | : HandlerRead(space, 0) 77 | { } 78 | 79 | ~HandlerReadNop() = default; 80 | 81 | // ctag_t *getName() const { return "nop"; } 82 | string getName() const { return "nop"; } 83 | 84 | uintx_t read(offs_t offset, cpuDevice *cpu) const override 85 | { 86 | return rhe::space->getUnmapped(); 87 | } 88 | 89 | uintx_t read(offs_t offset, uintx_t mask, cpuDevice *cpu) const override 90 | { 91 | return rhe::space->getUnmapped(); 92 | } 93 | }; 94 | 95 | template 96 | class HandlerWriteNop : public HandlerWrite 97 | { 98 | public: 99 | using uintx_t = typename HandlerRead::uintx_t; 100 | using whe = HandlerWrite; 101 | 102 | HandlerWriteNop(AddressSpace *space) 103 | : HandlerWrite(space, 0) 104 | { } 105 | 106 | ~HandlerWriteNop() = default; 107 | 108 | // ctag_t *getName() const { return "nop"; } 109 | string getName() const { return "nop"; } 110 | 111 | void write(offs_t offset, uintx_t data, cpuDevice *cpu) const override 112 | { 113 | 114 | } 115 | 116 | void write(offs_t offset, uintx_t data, uintx_t mask, cpuDevice *cpu) const override 117 | { 118 | 119 | } 120 | }; 121 | 122 | } 123 | -------------------------------------------------------------------------------- /src/emu/map/rom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * rom.h - ROM image management 3 | * 4 | * Created on: Feb 9, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #define ROM_TYPE_MASK 0x0000000F 11 | #define ROM_TYPE_END 0 12 | #define ROM_TYPE_REGION 1 13 | #define ROM_TYPE_IMAGE 2 14 | #define ROM_TYPE_FILL 3 15 | #define ROM_TYPE_COPY 4 16 | #define ROM_TYPE_RELOAD 5 17 | #define ROM_TYPE_IGNORE 6 18 | #define ROM_TYPE_CONTINUE 7 19 | 20 | #define ROM_REGION_WIDTH 0x00000030 // Data bit width 21 | #define ROM_REGION_8BIT 0x00000000 22 | #define ROM_REGION_16BIT 0x00000010 23 | #define ROM_REGION_32BIT 0x00000020 24 | #define ROM_REGION_64BIT 0x00000030 25 | 26 | #define ROM_REGION_ENDIAN 0x00000040 // Endianess Type (0 = Little, 1 = Big) 27 | #define ROM_REGION_LE 0x00000000 // Little-endian 28 | #define ROM_REGION_BE 0x00000040 // Big-endian 29 | 30 | #define ROM_REGION_INVERT 0x00000080 // Invert data 31 | #define ROM_REGION_NOINVERT 0x00000000 32 | #define ROM_REGION_INVERT 0x00000080 33 | 34 | #define ROM_REGION_ERASE 0x00000100 // Erase region before loading 35 | 36 | #define ROM_REGION_ERASEVAL 0x00FF0000 37 | #define ROM_ERASE_VAL(x) ((((x) & 0xFF) << 16) | ROM_REGION_ERASE) 38 | #define ROM_REGION_ERASE00 ROM_ERASE_VAL(0x00) 39 | #define ROM_REGION_ERASEFF ROM_ERASE_VAL(0xFF) 40 | 41 | 42 | 43 | 44 | 45 | 46 | #define ROM_END { nullptr, nullptr, 0, 0, 0, ROM_TYPE_END } 47 | 48 | struct romEntry_t 49 | { 50 | ctag_t *name; 51 | ctag_t *hash; 52 | const uint32_t offset; 53 | const uint32_t length; 54 | const uint32_t value; 55 | const uint32_t flags; 56 | }; 57 | -------------------------------------------------------------------------------- /src/emu/romloader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * romloader.h - ROM image loader package 3 | * 4 | * Created on: Mar 30, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/map/romentry.h" 11 | #include "emu/fileio.h" 12 | 13 | class romLoader 14 | { 15 | public: 16 | romLoader(Machine *sys, Console &cty); 17 | ~romLoader() = default; 18 | 19 | inline Machine *getMachine() const { return system; } 20 | 21 | protected: 22 | 23 | cromEntry_t *first(Device &dev); 24 | cromEntry_t *next(cromEntry_t *entry); 25 | 26 | emu::ioFile *processImageFile(fs::path pname, cromEntry_t *entry); 27 | void openImageFile(fs::path pkgName, cromEntry_t *entry); 28 | void closeImageFile(); 29 | int readImageData(uint8_t *buffer, int length, cromEntry_t *entry); 30 | bool loadImageData(cromEntry_t *parent, cromEntry_t *entry); 31 | 32 | void processImageEntries(ctag_t *pkgName, cromEntry_t *&entry, const Device &dev); 33 | void processRegionList(); 34 | 35 | Console &cty; 36 | Machine *system = nullptr; 37 | 38 | emu::ioFile *imageFile = nullptr; 39 | aspace::MemoryRegion *region = nullptr; 40 | }; 41 | -------------------------------------------------------------------------------- /src/emu/scheduler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * scheduler.h - per-machine device scheduler package 3 | * 4 | * Created on: Sep 22, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "lib/util/time.h" 11 | 12 | class LogFile; 13 | class Machine; 14 | class DeviceScheduler; 15 | 16 | typedef NamedDelegate TimerDelegate; 17 | 18 | #define TIMER_CALLBACK(name) void name(void *ptr, int64_t param) 19 | 20 | class Timer 21 | { 22 | friend class DeviceScheduler; 23 | 24 | public: 25 | Timer() = default; 26 | Timer(Device &device, TimerDeviceID_t id, void *ptr, bool flag); 27 | Timer(Machine &system, TimerDelegate cb, void *ptr, bool flag); 28 | ~Timer() = default; 29 | 30 | Timer &release(); 31 | 32 | static void executeDevice(Timer &timer, void *ptr, int64_t param); 33 | 34 | bool enable(bool enable); 35 | void adjust(const attotime_t &duration, int64_t param = 0, 36 | const attotime_t &periodic = attotime_t::never); 37 | void scheduleNextPeriod(); 38 | 39 | private: 40 | Timer *next = nullptr; 41 | Timer *prev = nullptr; 42 | 43 | cstag_t name; 44 | Machine *system = nullptr; 45 | Device *device = nullptr; 46 | 47 | bool temporary = false; 48 | bool enabled = false; 49 | 50 | attotime_t start; // time when timer starts 51 | attotime_t expire; // time when timer expires 52 | attotime_t period; // repeating frequency of timer 53 | 54 | // Timer callback function 55 | TimerDelegate callback; 56 | void *ptr = nullptr; 57 | int32_t param = 0; 58 | TimerDeviceID_t id = 0; 59 | }; 60 | 61 | struct QuantumEntry 62 | { 63 | QuantumEntry *next = nullptr; 64 | attoseconds_t actual; 65 | attoseconds_t requested; 66 | attotime_t expire; 67 | }; 68 | 69 | class DeviceScheduler 70 | { 71 | friend class Timer; 72 | 73 | public: 74 | DeviceScheduler(Machine &system); 75 | 76 | void init(); 77 | 78 | inline Timer *getFirstTimer() const { return timerList; } 79 | 80 | attotime_t getCurrentTime() const; 81 | 82 | void addSchedulingQuantum(const attotime_t &quantum, const attotime_t &duratrion); 83 | void rebuildExecuteList(); 84 | void executeTimers(); 85 | void timeslice(); 86 | void abortTimeslice(); 87 | 88 | Timer *allocateTimer(Device &device, int32_t id, void *data); 89 | Timer *allocateTimer(TimerDelegate cb, void *data = nullptr); 90 | void setTimer(Device &device, const attotime_t &duration, int32_t id, void *data, uint64_t param); 91 | 92 | // Timer *allocateTimer(void *data); 93 | // void setTimer(const attotime_t &duration, void *data, int32_t param); 94 | void insertTimer(Timer *timer); 95 | void removeTimer(Timer *timer); 96 | void dumpTimers(Console *user); 97 | 98 | private: 99 | Machine &system; 100 | diExecute *execDevice = nullptr; 101 | diExecute *execList = nullptr; 102 | LogFile *logFile = nullptr; 103 | 104 | attotime_t baseTime = attotime_t(); 105 | 106 | // Periodic interval list 107 | vector quantumList; 108 | attoseconds_t minQuantuam = 0; 109 | 110 | // SimpleList quantumList2; 111 | // FixedAllocator quantumAllocator; 112 | 113 | // Timer list for each scheduling quantum 114 | Timer *timerList = nullptr; 115 | Timer *cbTimer = nullptr; 116 | attotime_t cbTimerExpire; 117 | bool cbTimerModified = false; 118 | }; -------------------------------------------------------------------------------- /src/emu/sysconfig.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * sysconfig.cpp - system configuration package 3 | * 4 | * Created on: Jul 14, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/driver.h" 10 | #include "emu/sysconfig.h" 11 | 12 | SystemConfig::SystemConfig(const SystemDriver &driver, cstag_t &tagName) 13 | : systemDriver(driver) 14 | { 15 | // Create root of system device 16 | addDeviceType(tagName, driver.type, 0); 17 | 18 | // Complete final configuration 19 | for (auto &dev : DeviceIterator(*systemDevice)) 20 | { 21 | fmt::printf("%s: Completing final configuration\n", dev.getDeviceName()); 22 | dev.completeConfig(); 23 | } 24 | } 25 | 26 | Device *SystemConfig::addDeviceType(cstag_t &tagName, const DeviceType &type, uint64_t clock) 27 | { 28 | Device *owner = nullptr; 29 | 30 | fmt::printf("%s: Creating %s system...\n", tagName, type.getShortName()); 31 | 32 | device_t *sys = type.create(*this, tagName, nullptr, clock); 33 | 34 | return addDevice(sys, owner); 35 | } 36 | 37 | Device *SystemConfig::addDevice(Device *dev, Device *owner) 38 | { 39 | const ConfigDeviceStack context(*this); 40 | 41 | if (owner != nullptr) { 42 | // assert(configDevice != nullptr); 43 | fmt::printf("%s: Owner %s(%s) device\n", dev->getDeviceName(), owner->getDeviceName(), owner->getShortName()); 44 | 45 | owner->addNode(dev); 46 | } else { 47 | // System device 48 | assert(systemDevice == nullptr); 49 | systemDevice = dev; 50 | } 51 | 52 | // Initialize device 53 | dev->configure(*this); 54 | 55 | return dev; 56 | } 57 | 58 | void SystemConfig::begin(Device *dev) 59 | { 60 | assert(configDevice == nullptr); 61 | configDevice = dev; 62 | fmt::printf("%s: Start device configuration\n", dev->getDeviceName()); 63 | } 64 | -------------------------------------------------------------------------------- /src/emu/sysconfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sysconfig.h - system configuration package 3 | * 4 | * Created on: Jul 14, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/driver.h" 11 | #include "emu/device.h" 12 | 13 | class SystemConfig 14 | { 15 | public: 16 | SystemConfig(const SystemDriver &driver, cstag_t &tagName); 17 | 18 | inline Device *getSystemDevice() const { return systemDevice; } 19 | inline Device *getConfigDevice() const { return configDevice; } 20 | inline cstag_t getModelName() const { return string(systemDriver.name); } 21 | 22 | Device *addDeviceType(cstag_t &tagName, const DeviceType &type, uint64_t clock); 23 | Device *addDevice(Device *dev, Device *owner); 24 | 25 | template 26 | auto *addDeviceType(cstag_t &tagName, Creator &&type, Args &&... args) 27 | { 28 | Device *owner = systemDevice; 29 | 30 | fmt::printf("%s: Creating %s device...\n", tagName, type.getShortName()); 31 | auto dev = type.create(*this, tagName, owner, forward(args)...); 32 | return addDevice(dev, owner); 33 | } 34 | 35 | const SystemDriver &getSystemDriver() const { return systemDriver; } 36 | 37 | void begin(Device *dev); 38 | 39 | protected: 40 | class ConfigDeviceStack 41 | { 42 | public: 43 | ConfigDeviceStack(SystemConfig &config) 44 | : host(config), device(config.configDevice) 45 | { 46 | host.configDevice = nullptr; 47 | } 48 | 49 | ~ConfigDeviceStack() 50 | { 51 | host.configDevice = device; 52 | } 53 | 54 | private: 55 | SystemConfig &host; 56 | Device *device = nullptr; 57 | }; 58 | 59 | private: 60 | const SystemDriver &systemDriver; 61 | 62 | Device *systemDevice = nullptr; 63 | Device *configDevice = nullptr; 64 | }; 65 | -------------------------------------------------------------------------------- /src/emu/syslist.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * syslist.cpp - system list package (handler) 3 | * 4 | * Created on: Jul 5, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/syslist.h" 10 | 11 | const SystemDriver *SystemList::find(const string name) 12 | { 13 | for (int idx = 0; sysList[idx]; idx++) 14 | { 15 | const SystemDriver *driver = sysList[idx]; 16 | if (string(driver->name) == name) 17 | return driver; 18 | } 19 | 20 | return nullptr; 21 | } 22 | 23 | void SystemList::list(ostream &out) 24 | { 25 | const SystemDriver *model; 26 | 27 | out << fmt::sprintf("Name Description\n"); 28 | out << fmt::sprintf("---------- -----------\n"); 29 | for (int idx = 0; sysList[idx] != nullptr; idx++) 30 | { 31 | model = sysList[idx]; 32 | out << fmt::sprintf("%-10s %s\n", model->name, model->description); 33 | } 34 | out << flush; 35 | } 36 | -------------------------------------------------------------------------------- /src/emu/syslist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * syslist.h - system list handler package 3 | * 4 | * Created on: Jul 5, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/driver.h" 11 | 12 | class SystemList 13 | { 14 | public: 15 | SystemList() = default; 16 | ~SystemList() = default; 17 | 18 | const SystemDriver *find(const string name); 19 | 20 | void list(ostream &out); 21 | 22 | private: 23 | static const SystemDriver *sysList[]; 24 | }; 25 | -------------------------------------------------------------------------------- /src/emu/systems.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * systems.cpp - system list 3 | * 4 | * Created on: Jul 5, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/syslist.h" 10 | 11 | #include "printers/epson/externs.h" 12 | 13 | #include "system/dec/axp/externs.h" 14 | #include "system/dec/vax/externs.h" 15 | #include "terminals/dec/externs.h" 16 | 17 | const SystemDriver *SystemList::sysList[] = 18 | { 19 | // Digital Electric Corporation (DEC) 20 | // AXP family series 21 | &SYSTEM_NAME(pc164), 22 | &SYSTEM_NAME(pc164lx), 23 | &SYSTEM_NAME(pc164sx), 24 | 25 | &SYSTEM_NAME(es40), 26 | &SYSTEM_NAME(es45), 27 | 28 | // VAX family series 29 | &SYSTEM_NAME(mv3900), 30 | &SYSTEM_NAME(mv3900x), 31 | 32 | &SYSTEM_NAME(vs3900), 33 | &SYSTEM_NAME(vs3900x), 34 | 35 | // Terminal series 36 | &SYSTEM_NAME(vt100), 37 | 38 | // Epson 39 | // Printer series 40 | &SYSTEM_NAME(mx80), 41 | &SYSTEM_NAME(mx100), 42 | 43 | // terminator 44 | nullptr 45 | }; 46 | -------------------------------------------------------------------------------- /src/emu/templates.h: -------------------------------------------------------------------------------- 1 | /* 2 | * templates.h 3 | * 4 | * Created on: Dec 12, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | template template 11 | inline DeviceClass *DeviceCreator::operator ()(SystemConfig &config, cstag_t &devName, Args&&... args) const 12 | { 13 | return dynamic_cast(config.addDeviceType(devName, *this, forward(args)...)); 14 | } 15 | 16 | template template 17 | DeviceClass &DeviceCreator::operator ()(SystemConfig &config, DeviceFinder &finder, cstag_t &devName, Args &&... args) const 18 | { 19 | // assert(&config.getCurrentDevice() == &finder.getOwnerDevice()); 20 | DeviceClass &device(dynamic_cast(*config.addDeviceType(devName, *this, std::forward(args)...))); 21 | 22 | finder = device; 23 | return device; 24 | } 25 | -------------------------------------------------------------------------------- /src/emu/video.h: -------------------------------------------------------------------------------- 1 | /* 2 | * video.h - video manager package 3 | * 4 | * Created on: Sep 26, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | class VideoManager 11 | { 12 | public: 13 | VideoManager(Machine &system); 14 | 15 | void updateFrame(); 16 | void synchronizeRealTime(attotime_t time); 17 | osdTicks_t sleepUntilTicks(osdTicks_t ticks); 18 | 19 | private: 20 | Machine &system; 21 | DeviceScheduler &scheduler; 22 | LogFile *logFile = nullptr; 23 | 24 | // Timer device callback function calls 25 | void cbUpdateScreenless(void *data, int64_t param); 26 | 27 | inline void resetTime(attotime_t time) { emuTime = time; realTime = time; }; 28 | 29 | // Screenless systems (mainframe, etc) 30 | Timer *frameTimer = nullptr; 31 | 32 | double throttleRate = 1.0; 33 | osdTicks_t avgOversleep = 0; 34 | osdTicks_t lastTicks = 0; 35 | 36 | attotime_t realTime = attotime_t::zero; 37 | attotime_t emuTime = attotime_t::zero; 38 | }; -------------------------------------------------------------------------------- /src/emu/xtal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * xtal.h - crystal oscillator package 3 | * 4 | * Created on: Dec 12, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #define XTAL(clock) (clock) -------------------------------------------------------------------------------- /src/lib/util/bitmap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * bitmap.h - Bitmap package 3 | * 4 | * Created on: Sep 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "lib/util/bitmap.h" 10 | 11 | using namespace emu::lib::util; 12 | 13 | Bitmap::Bitmap(BitmapFormat format, int bpp, int width, int height) 14 | : format(format), bpp(bpp) 15 | { 16 | assert(hasValidFormat()); 17 | allocate(width, height); 18 | } 19 | 20 | Bitmap::Bitmap(BitmapFormat format, int bpp, void *base, int width, int height) 21 | : format(format), bpp(bpp) 22 | { 23 | assert(hasValidFormat()); 24 | } 25 | 26 | // Validate bitmap formt and bits per pixel 27 | bool Bitmap::hasValidFormat() 28 | { 29 | switch (format) 30 | { 31 | case BitmapFormatInvalid: 32 | return false; 33 | 34 | case BitmapFormatIndex16: 35 | return bpp == 16; 36 | 37 | case BitmapFormatIndex32: 38 | case BitmapFormatRGB32: 39 | case BitmapFormatRGBA32: 40 | return bpp == 32; 41 | 42 | case BitmapFormatIndex64: 43 | return bpp == 64; 44 | } 45 | 46 | return false; 47 | } 48 | 49 | inline int Bitmap::computeRowPixels(int width) 50 | { 51 | return width; 52 | } 53 | 54 | void Bitmap::allocate(int width, int height) 55 | { 56 | // Check valid values first 57 | assert(format != BitmapFormatInvalid); 58 | assert(bpp == 8 || bpp == 16 || bpp == 32 || bpp == 64); 59 | 60 | // If width or height is zero or negative, 61 | // do nothing and return 62 | if (width <= 0 || height <= 0) 63 | return; 64 | 65 | rowPixels = computeRowPixels(width); 66 | this->width = width; 67 | this->height = height; 68 | 69 | dataSize = rowPixels * height * bpp / 8; 70 | data = new uint8_t[dataSize]; 71 | 72 | memset(data, 0, dataSize); 73 | } 74 | 75 | void Bitmap::resize(int width, int height) 76 | { 77 | 78 | } 79 | 80 | template class BitmapSpecific; 81 | template class BitmapSpecific; 82 | template class BitmapSpecific; 83 | template class BitmapSpecific; 84 | -------------------------------------------------------------------------------- /src/lib/util/color.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * color.h - color/palette package 3 | * 4 | * Created on: Oct 17, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "lib/util/color.h" -------------------------------------------------------------------------------- /src/lib/util/color.h: -------------------------------------------------------------------------------- 1 | /* 2 | * color.h - color/palette package 3 | * 4 | * Created on: Oct 17, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | class Color 11 | { 12 | public: 13 | constexpr Color() = default; 14 | 15 | constexpr Color(uint32_t rgba) : data(rgba) {} 16 | 17 | constexpr Color(uint8_t r, uint8_t g, uint8_t b) 18 | : data((255 << 24) | (r << 16) | (g << 8) | b) 19 | {} 20 | 21 | constexpr Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) 22 | : data((a << 24) | (r << 16) | (g << 8) | b) 23 | {} 24 | 25 | // Getters 26 | constexpr uint8_t getAlpha() const { return data >> 24; } 27 | constexpr uint8_t getRed() const { return data >> 16; } 28 | constexpr uint8_t getGreen() const { return data >> 8; } 29 | constexpr uint8_t getBlue() const { return data; } 30 | 31 | // Colors for monochrome monitors 32 | static constexpr Color black() { return Color(0, 0, 0); } 33 | static constexpr Color white() { return Color(255, 255, 255); } 34 | static constexpr Color green() { return Color(0, 255, 0); } 35 | static constexpr Color amber() { return Color(255, 191, 0); } 36 | 37 | static constexpr Color transparent() { return Color(0, 0, 0, 0); } 38 | 39 | private: 40 | uint32_t data = 0; 41 | }; 42 | -------------------------------------------------------------------------------- /src/lib/util/time.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * time.cpp - time in attoseconds package 3 | * 4 | * Created on: Sep 23, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "lib/util/time.h" 10 | 11 | using namespace emu::lib::util; 12 | 13 | Attotime Attotime::zero = Attotime(0); 14 | Attotime Attotime::never = Attotime(ATTOTIME_MAX_SECONDS); 15 | 16 | cstag_t Attotime::getAsString(int precision) const 17 | { 18 | string str; 19 | 20 | if (*this == never) 21 | str = fmt::sprintf("%-*s", precision, "(never)"); 22 | else if (precision == 0) // seconds only 23 | str = fmt::sprintf("%lld", attoseconds / ATTOSECONDS_PER_SECOND); 24 | else if (precision <= 9) 25 | { 26 | uint64_t upper = attoseconds / ATTOSECONDS_PER_NANOSECOND; 27 | uint64_t temp = precision; 28 | while (temp < 9) 29 | { 30 | upper /= 10; 31 | temp++; 32 | } 33 | str = fmt::sprintf("%lld.%0*lld", attoseconds / ATTOSECONDS_PER_SECOND, precision, upper); 34 | } 35 | 36 | return str; 37 | } -------------------------------------------------------------------------------- /src/main/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * main.cpp 3 | * 4 | * Created on: Jul 5, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/console.h" 10 | #include "emu/engine.h" 11 | 12 | int main(int argc, char **argv) 13 | { 14 | Console cty; 15 | SystemEngine engine; 16 | 17 | cout << fmt::sprintf("Multi-System Emulator System\n\n"); 18 | 19 | // System initialization 20 | engine.ginit(); 21 | 22 | if (argc > 1) 23 | cty.script(argv[1]); 24 | cty.prompt(); 25 | 26 | // System shut down and cleanup 27 | engine.gexit(); 28 | exit(0); 29 | } 30 | -------------------------------------------------------------------------------- /src/merged/formats/dec/image.cpp: -------------------------------------------------------------------------------- 1 | #include "emu/emucore.h" 2 | #include "formats/dec/word10.h" 3 | 4 | 5 | // CORE-DUMP Format 6 | // 7 | // 00 01 02 03 04 05 06|07 8 | // 08 09 10 11 12 13|14 15 9 | // 16 17 18 19 20|21 22 23 10 | // 24 25 26 27|28 29 30 31 11 | // __ __ __ __|32 33 34 35 12 | 13 | uint36_t dec_img_decodeCoreDump(uint8_t *data8) 14 | { 15 | uint36_t data36; 16 | 17 | data36 = (uint36_t)(data8[0] & 0xFF) << 29; 18 | data36 |= (uint36_t)(data8[1] & 0xFF) << 22; 19 | data36 |= (uint36_t)(data8[2] & 0xFF) << 15; 20 | data36 |= (uint36_t)(data8[3] & 0xFF) << 8; 21 | data36 |= (uint36_t)(data8[4] & 0x0F) << 1; 22 | 23 | return data36; 24 | } 25 | 26 | 27 | // ANSI Format 28 | // 29 | // __|00 01 02 03 04 05 06 30 | // __|07 08 09 10 11 12 13 31 | // __|14 15 16 17 18 19 20 32 | // __|21 22 23 24 25 26 27 33 | // 35|28 29 30 31 32 33 34 34 | 35 | uint36_t dec_img_decodeANSI(uint8_t *data8) 36 | { 37 | uint36_t data36; 38 | 39 | data36 = (uint36_t)(data8[0] & 0x7F) << 29; 40 | data36 |= (uint36_t)(data8[1] & 0x7F) << 22; 41 | data36 |= (uint36_t)(data8[2] & 0x7F) << 15; 42 | data36 |= (uint36_t)(data8[3] & 0x7F) << 8; 43 | data36 |= (uint36_t)(data8[4] & 0x7F) << 1; 44 | if (data8[4] & 0x80) 45 | data36 |= 1; 46 | 47 | return data36; 48 | } 49 | 50 | // FTP High Density Format 51 | // 52 | // 00 01 02 03 04 05 06 07 53 | // 08 09 10 11 12 13 14 15 54 | // 16 17 18 19 20 21 22 23 55 | // 24 25 26 27 28 29 30 31 56 | // 32 33 34 35|00 01 02 03 57 | // 04 05 06 07 08 09 10 11 58 | // 12 13 14 15 16 17 18 19 59 | // 20 21 22 23 24 25 26 27 60 | // 28 29 30 31 32 33 34 35 61 | -------------------------------------------------------------------------------- /src/merged/formats/dec/word10.h: -------------------------------------------------------------------------------- 1 | /* 2 | * word10.h 3 | * 4 | * Created on: Sep 6, 2015 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | typedef uint32_t uint18_t; 11 | typedef uint64_t uint36_t; 12 | 13 | typedef int32_t sint18_t; 14 | typedef int64_t sint36_t; 15 | 16 | typedef uint18_t h10_t; 17 | typedef uint36_t w10_t; 18 | 19 | #define H10_WIDTH 18 20 | #define H10_MASK 0777777 21 | 22 | #define W10_WIDTH (H10_WIDTH << 2) 23 | #define W10_FMASK 0777777777777LL 24 | #define W10_CMASK 0377777777777LL 25 | #define W10_SIGN 0400000000000LL 26 | #define W10_C1MASK 01000000000000LL 27 | #define W10_LMASK 0777777000000LL 28 | #define W10_RMASK 0000000777777LL 29 | 30 | #define W10_LEFT(d) (((d) >> H10_WIDTH) & H10_MASK) 31 | #define W10_RIGHT(d) ((d) & H10_MASK) 32 | 33 | #define W10_SWAP(var) (((var >> H10_WIDTH) & W10_RMASK) | ((var & W10_RMASK) << H10_WIDTH)) 34 | -------------------------------------------------------------------------------- /src/merged/formats/int36.h: -------------------------------------------------------------------------------- 1 | /* 2 | * int36.h - Octal-based 18/36-bit integer package 3 | * 4 | * Created on: Nov 3, 2019 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #define I18_BITS 18 11 | #define I18_FMASK 00777777 12 | #define I18_CMASK 00377777 13 | #define I18_CRYMASK 01000000 14 | 15 | #define I36_BITS 36 16 | #define I36_FMASK 00777777777777LL 17 | #define I36_CMASK 00377777777777LL 18 | #define I36_CRYMASK 01000000000000LL 19 | #define I36_LMASK 00777777000000LL 20 | #define I36_LCMASK 00377777000000LL 21 | #define I36_RMASK 00000000777777LL 22 | #define I36_RCMASK 00000000377777LL 23 | 24 | #define op36_invert(x) ((x) ^ I36_CMASK) 25 | #define op36_negate(x) (op36_invert(x) + 1) 26 | #define op36_swap(x) (((x) & I36_LMASK) >> I18_BITS) | ((x) & I36_RMASK) << I18_BITS)) 27 | 28 | typedef uint32_t uint18_t; 29 | typedef uint64_t uint36_t; 30 | typedef int32_t sint18_t; 31 | typedef int64_t sint36_t; 32 | -------------------------------------------------------------------------------- /src/merged/osd/ether.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ether.cpp 3 | * 4 | * Created on: Mar 18, 2017 5 | * Author: Timothy Stark 6 | * 7 | * Virtual Ethernet interface 8 | * 9 | */ 10 | 11 | #include "emu/emucore.h" 12 | #include "osd/ether.h" 13 | #include "osd/socket.h" 14 | 15 | -------------------------------------------------------------------------------- /src/merged/osd/ether.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ether.h 3 | * 4 | * Created on: Mar 18, 2017 5 | * Author: Timothy Stark 6 | * 7 | * Virtual Ethernet interface 8 | * 9 | */ 10 | 11 | #pragma once 12 | 13 | #if defined(HAVE_PCAP) 14 | #define USE_BPF 1 15 | #include 16 | #endif 17 | -------------------------------------------------------------------------------- /src/merged/osd/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "emu/emucore.h" 3 | #include "osd/socket.h" 4 | 5 | #if __WIN32__ 6 | static WSADATA wsaData; 7 | #endif 8 | 9 | void osdExit(std::string reason) 10 | { 11 | std::cout << "System Shutdown..." << std::endl; 12 | exit(0); 13 | } 14 | 15 | int main(int argc, char **argv) 16 | { 17 | #if __WIN32__ 18 | if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) 19 | { 20 | printf("Winsock 2 API Error Code: %d", WSAGetLastError()); 21 | return 1; 22 | } 23 | #endif 24 | 25 | // Create root core device and console handler 26 | // Core *app = new Core(); 27 | // Console *con = new Console(app); 28 | console_base *con = new console_base(); 29 | 30 | printf("Welcome to Multi-System Emulator System\n\n"); 31 | 32 | if (argc > 1) 33 | con->script(std::string(argv[1])); 34 | con->prompt(); 35 | 36 | delete con; 37 | // delete app; 38 | 39 | osdExit(""); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /src/merged/osd/osdfile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * osdfile.h 3 | * 4 | * Created on: Feb 26, 2019 5 | * Author: fswor 6 | */ 7 | 8 | #pragma once 9 | 10 | #define OPEN_FLAG_READ 0x0001 11 | #define OPEN_FLAG_WRITE 0x0002 12 | #define OPEN_FLAG_CREATE 0x0004 13 | 14 | class osdFile 15 | { 16 | public: 17 | typedef osdFile *ptr; 18 | 19 | enum error { 20 | NONE, 21 | FAILURE, 22 | OUT_OF_MEMORY, 23 | NOT_FOUND, 24 | ACCESS_DENIED, 25 | INVALID_DATA, 26 | INVALID_ACCESS 27 | }; 28 | 29 | virtual ~osdFile() {} 30 | 31 | static error open(const std::string &path, uint32_t openFlags, ptr &file, uint64_t &fsize); 32 | 33 | virtual error read(void *buffer, uint64_t offset, uint32_t count, uint32_t &actual) = 0; 34 | virtual error write(void *buffer, uint64_t offset, uint32_t count, uint32_t &actual) = 0; 35 | 36 | }; 37 | -------------------------------------------------------------------------------- /src/merged/osd/posixfile.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * posixFile.cpp - POSIX file I/O library 3 | * 4 | * Created on: Feb 26, 2019 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include "osd/posixfile.h" 17 | 18 | 19 | 20 | osdFile::error osdError(int errCode) 21 | { 22 | switch (errCode) 23 | { 24 | case 0: 25 | return osdFile::NONE; 26 | 27 | case ENOENT: 28 | case ENOTDIR: 29 | return osdFile::NOT_FOUND; 30 | 31 | case EACCES: 32 | case EROFS: 33 | case EEXIST: 34 | case EPERM: 35 | case EISDIR: 36 | case EINVAL: 37 | return osdFile::ACCESS_DENIED; 38 | 39 | // case ENFILE: 40 | // case EMFILE: 41 | // return osdFile::TOO_MANY_FILES; 42 | 43 | default: 44 | return osdFile::FAILURE; 45 | } 46 | } 47 | 48 | 49 | class posixFile : public osdFile 50 | { 51 | public: 52 | posixFile(int fd) 53 | : fd(fd) 54 | { 55 | assert(fd >= 0); 56 | } 57 | 58 | virtual ~posixFile() 59 | { 60 | ::close(fd); 61 | } 62 | 63 | virtual osdFile::error read(void *buffer, uint64_t offset, uint32_t count, uint32_t &actual) 64 | { 65 | ssize_t result; 66 | 67 | if (lseek(fd, offset, SEEK_SET) < 0) 68 | return osdError(errno); 69 | result = ::read(fd, buffer, size_t(count)); 70 | if (result < 0) 71 | return osdError(errno); 72 | actual = result; 73 | return osdFile::NONE; 74 | } 75 | 76 | virtual osdFile::error write(void *buffer, uint64_t offset, uint32_t count, uint32_t &actual) 77 | { 78 | ssize_t result; 79 | 80 | if (lseek(fd, offset, SEEK_SET) < 0) 81 | return osdError(errno); 82 | result = ::write(fd, buffer, size_t(count)); 83 | if (result < 0) 84 | return osdError(errno); 85 | actual = result; 86 | return osdFile::NONE; 87 | } 88 | 89 | private: 90 | int fd; 91 | }; 92 | 93 | osdFile::error osdFile::open(const std::string &path, uint32_t openFlags, ptr &file, uint64_t &fsize) 94 | { 95 | int access; 96 | int fd = -1; 97 | int mode = 0666; 98 | 99 | // Determine POSIX access flags 100 | if (openFlags & OPEN_FLAG_WRITE) { 101 | access = (openFlags & OPEN_FLAG_READ) ? O_RDWR : O_WRONLY; 102 | access |= (openFlags & OPEN_FLAG_CREATE) ? (O_CREAT|O_TRUNC) : 0; 103 | } else if (openFlags & OPEN_FLAG_READ) { 104 | access = O_RDONLY; 105 | } 106 | access |= O_BINARY; 107 | 108 | fd = ::open(path.c_str(), access, mode); 109 | 110 | if (fd < 0) 111 | return osdError(errno); 112 | 113 | struct stat fst; 114 | if (::fstat(fd, &fst) < 0) { 115 | int errCode = errno; 116 | ::close(fd); 117 | return osdError(errCode); 118 | } 119 | 120 | fsize = fst.st_size; 121 | file = new posixFile(fd); 122 | 123 | return osdFile::NONE; 124 | } 125 | -------------------------------------------------------------------------------- /src/merged/osd/posixfile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * osdfile.h 3 | * 4 | * Created on: Feb 25, 2019 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "osd/osdfile.h" 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/merged/osd/socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * socket.h 3 | * 4 | * Created on: Feb 19, 2017 5 | * Author: Timothy Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #if __WIN32__ 11 | #include 12 | #else 13 | #include 14 | #endif 15 | -------------------------------------------------------------------------------- /src/merged/osd/telnet.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * telnet.cpp 3 | * 4 | * Created on: May 7, 2018 5 | * Author: Timothy Stark 6 | */ 7 | 8 | #include "osd/telnet.h" 9 | 10 | #include "emu/emucore.h" 11 | 12 | // Telnet Code Initialization 13 | static uint8_t tlnCodes[] = 14 | { 15 | TLN_IAC, TLN_WILL, TLN_LINEMODE, // IAC WILL LINEMODE 16 | TLN_IAC, TLN_WILL, TLN_SGA, // IAC WILL SGA 17 | TLN_IAC, TLN_WILL, TLN_ECHO, // IAC WILL ECHO 18 | TLN_IAC, TLN_WILL, TLN_BINARY, // IAC WILL BINARY 19 | TLN_IAC, TLN_DO, TLN_BINARY // IAC DO BINARY 20 | }; 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/merged/osd/telnet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * telnet.h 3 | * 4 | * Created on: May 7, 2018 5 | * Author: Timothy Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #define TLN_BINARY 0 // Binary Transmission 11 | #define TLN_IS 0 // Used by Terminal-Type Negotiation 12 | #define TLN_SEND 1 // Used by Terminal-Type Negotiation 13 | #define TLN_ECHO_OPTION 1 // Echo Option 14 | #define TLN_ECHO 1 // Echo Option 15 | #define TLN_SUPPRESS_GA 3 // Suppress Go-Ahead Option 16 | #define TLN_SGA 3 // Suppress Go-Ahead Option 17 | #define TLN_TIMING_MARK 6 // Timing Mark 18 | #define TLN_TERM_TYPE 24 // Terminal Type Option 19 | #define TLN_EOR 25 // End of Record Marker 20 | #define TLN_LINEMODE 34 // Line Mode 21 | #define TLN_EOR_MARK 239 // End of Record Marker 22 | #define TLN_SE 240 // End of Subnegotiation Parameters 23 | #define TLN_NOP 241 // No Operation 24 | #define TLN_DATA_MARK 242 25 | #define TLN_BRK 243 // Break Character 26 | #define TLN_IP 244 // Interrupt Process 27 | #define TLN_AO 245 // Abort Output 28 | #define TLN_AYT 246 // Are You There? 29 | #define TLN_EC 247 // Erase Character 30 | #define TLN_EL 248 // Erase Line 31 | #define TLN_GA 249 // Go Ahead 32 | #define TLN_SB 250 // Beginning of Subnegotiation 33 | #define TLN_WILL 251 // 34 | #define TLN_WONT 252 // 35 | #define TLN_DO 253 // 36 | #define TLN_DONT 254 // 37 | #define TLN_IAC 255 // Interpret as Command 38 | -------------------------------------------------------------------------------- /src/osd/osdcore.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * osdcore.cpp - OSD interface package 3 | * 4 | * Created on: Sep 27, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | 10 | 11 | osdTicks_t osdGetTicks() 12 | { 13 | return std::chrono::high_resolution_clock::now().time_since_epoch().count(); 14 | } 15 | 16 | osdTicks_t osdGetTicksPerSecond() 17 | { 18 | return std::chrono::high_resolution_clock::period::den / 19 | std::chrono::high_resolution_clock::period::num; 20 | } 21 | 22 | void osdSleep(osdTicks_t duration) 23 | { 24 | std::this_thread::sleep_for(std::chrono::high_resolution_clock::duration(duration)); 25 | } -------------------------------------------------------------------------------- /src/osd/osdcore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * osdcore.h - OSD interface package 3 | * 4 | * Created on: Sep 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | typedef uint64_t osdTicks_t; 11 | 12 | osdTicks_t osdGetTicks(); 13 | osdTicks_t osdGetTicksPerSecond(); 14 | void osdSleep(osdTicks_t ticks); 15 | 16 | namespace mse::osd 17 | { 18 | class osdInteface 19 | { 20 | 21 | }; 22 | } 23 | 24 | using osdInterface = mse::osd::osdInteface; -------------------------------------------------------------------------------- /src/osd/sdl/sdlmain.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * adlmain.cpp - main package with Qt/SDL interface 3 | * 4 | * Created on: Sep 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include 9 | 10 | #include "emu/core.h" 11 | #include "osd/osdcore.h" 12 | #include "osd/sdl/sdlmain.h" 13 | 14 | -------------------------------------------------------------------------------- /src/osd/sdl/sdlmain.h: -------------------------------------------------------------------------------- 1 | /* 2 | * adlmain.h - main package with Qt/SDL interface 3 | * 4 | * Created on: Sep 14, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "osd/osdcore.h" 11 | 12 | namespace mse::osd::sdl 13 | { 14 | class sdl_osdInterface : public sdl_osdInterface 15 | { 16 | 17 | }; 18 | } -------------------------------------------------------------------------------- /src/printers/epson/externs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * externs.h - externs for DEC Alpha emulators 3 | * 4 | * Created on: Jul 15, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | SYSTEM_EXTERN(mx80); 11 | SYSTEM_EXTERN(mx100); 12 | -------------------------------------------------------------------------------- /src/printers/epson/mx.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * mx.cpp - Epson MX80/MX100 printer emulation package 3 | * 4 | * Created on: Mar 26, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/map/addrmap.h" 10 | #include "emu/map/map.h" 11 | #include "emu/devsys.h" 12 | #include "emu/driver.h" 13 | #include "emu/machine.h" 14 | #include "emu/engine.h" 15 | 16 | #include "printers/epson/mx.h" 17 | 18 | using namespace aspace; 19 | 20 | CommandStatus mx_SetMemory(Console *user, Machine *sys, Device *dev, args_t &args) 21 | { 22 | BusManager &manager = sys->getExternalBusManager(); 23 | SystemEngine engine; 24 | 25 | string name = args.getNext(); 26 | string size = args.getNext(); 27 | 28 | // fmt::printf("%s: Region: name=%s size=%s\n", dev->getDeviceName(), name, size); 29 | 30 | uint64_t val = engine.getValue(size); 31 | 32 | manager.allocateRegion(name, val, 8, LittleEndian); 33 | user->printf("%s: Successfully allocated %lld (%llX) to region '%s'\n", 34 | dev->getDeviceName(), val, val, name); 35 | 36 | return CommandStatus::cmdOk; 37 | } 38 | 39 | devCommand_t mx_Commands[] = 40 | { 41 | { "mem", mx_SetMemory }, 42 | 43 | // null terminal 44 | nullptr 45 | }; 46 | 47 | // Create system routines 48 | void mx_prDevice::mx80(SystemConfig &config) 49 | { 50 | 51 | setCommands(mx_Commands); 52 | 53 | cpu = i8049(config, "cpu", 0); 54 | cpu->setAddressMap(AS_PROGRAM, &mx_prDevice::mx_sbus); 55 | 56 | 57 | // cssc = CSSC(config, "cssc", 0); 58 | //// cpu->setSystemSupport(cssc); 59 | // cmctl = CMCTL(config, "cmctl", 0); 60 | // cqbic = CQBIC(config, "cqbic", 0); 61 | // 62 | // cssc->setDeviceName("cssc"); 63 | // cmctl->setDeviceName("cmctl"); 64 | // cqbic->setDeviceName("cqbic"); 65 | 66 | } 67 | 68 | void mx_prDevice::mx100(SystemConfig &config) 69 | { 70 | 71 | cpu = i8049(config, "cpu", 0); 72 | cpu->setAddressMap(AS_PROGRAM, &mx_prDevice::mx_sbus); 73 | 74 | // cssc = CSSC(config, "cssc", 0); 75 | //// cpu->setSystemSupport(cssc); 76 | // cmctl = CMCTL(config, "cmctl", 0); 77 | // cqbic = CQBIC(config, "cqbic", 0); 78 | // 79 | // cssc->setDeviceName("cssc"); 80 | // cmctl->setDeviceName("cmctl"); 81 | // cqbic->setDeviceName("cqbic"); 82 | 83 | } 84 | 85 | // Initialize system routines 86 | void mx_prDevice::mx80_init() 87 | { 88 | 89 | } 90 | 91 | void mx_prDevice::mx100_init() 92 | { 93 | 94 | } 95 | 96 | 97 | void mx_prDevice::mx_sbus(AddressList &map) 98 | { 99 | map(0x000, 0x7FF).ram().region("main"); // 2048 bytes 100 | } 101 | 102 | static const romEntry_t ROM_NAME(mx80)[] = 103 | { 104 | ROM_REGION("mx80fw", 0x800, 0), 105 | // ROM_LOAD("graftrax1.rom", 0x000, 0x7FF, 0, nullptr), 106 | // ROM_LOAD("graftrax2.rom", 0x000, 0x7FF, 0, nullptr), 107 | ROM_LOAD("graftrax3.rom", 0x000, 0x7FF, 0, nullptr), 108 | ROM_END 109 | }; 110 | 111 | static const romEntry_t ROM_NAME(mx100)[] = 112 | { 113 | ROM_END 114 | }; 115 | 116 | PRINTER(mx80, nullptr, epson, MX80, mx_prDevice, mx80, mx80_init, "Epson", "MX80", SYSTEM_NOT_WORKING) 117 | PRINTER(mx100, nullptr, epson, MX100, mx_prDevice, mx100, mx100_init, "Epson", "MX100", SYSTEM_NOT_WORKING) 118 | 119 | 120 | -------------------------------------------------------------------------------- /src/printers/epson/mx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mx.h - Epson MX80/MX100 printer emulation package 3 | * 4 | * Created on: Mar 26, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/devsys.h" 11 | #include "dev/cpu/mcs48/mcs48.h" 12 | 13 | class mx_prDevice : public sysDevice 14 | { 15 | public: 16 | mx_prDevice(const SystemConfig &config, const DeviceType &type, cstag_t &tagName, uint64_t clock) 17 | : sysDevice(config, type, tagName, clock), 18 | config("printer", LittleEndian, 8, 16, 8, 12, 16, 0) 19 | { 20 | 21 | } 22 | ~mx_prDevice() = default; 23 | 24 | // System creator routines 25 | void mx80(SystemConfig &config); 26 | void mx100(SystemConfig &config); 27 | 28 | // Model-specific system initialize routines 29 | static void mx80_init(); 30 | static void mx100_init(); 31 | 32 | void mx_sbus(aspace::AddressList &map); 33 | 34 | private: 35 | i8049_cpuDevice *cpu = nullptr; 36 | // i8041_cpuDevice *scpu = nullptr; 37 | 38 | mapAddressConfig config; 39 | }; 40 | -------------------------------------------------------------------------------- /src/system/dec/axp/alphapc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * alphapc.h - AlphaPC 164 systems 3 | * 4 | * Created on: Feb 7, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "emu/devsys.h" 11 | #include "dev/cpu/alpha/ev5.h" 12 | 13 | class alphapc_sysDevice : public sysDevice 14 | { 15 | public: 16 | alphapc_sysDevice(const SystemConfig &config, const DeviceType &type, cstag_t &tagName, uint64_t clock) 17 | : sysDevice(config, type, tagName, clock), 18 | config("system", LittleEndian, 64, 16, 8, 40, 16, 0) 19 | { 20 | 21 | } 22 | ~alphapc_sysDevice() = default; 23 | 24 | // System creator routines 25 | void pc164(SystemConfig &config); 26 | void pc164lx(SystemConfig &config); 27 | void pc164sx(SystemConfig &config); 28 | 29 | // Model-specific system initialize routines 30 | static void pc164_init(); 31 | static void pc164lx_init(); 32 | static void pc164sx_init(); 33 | 34 | void pc164_sbus(aspace::AddressList &map); 35 | void pc164lx_sbus(aspace::AddressList &map); 36 | void pc164sx_sbus(aspace::AddressList &map); 37 | 38 | private: 39 | dec21164_cpuDevice *cpu = nullptr; 40 | 41 | mapAddressConfig config; 42 | }; 43 | -------------------------------------------------------------------------------- /src/system/dec/axp/externs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * externs.h - externs for DEC Alpha emulators 3 | * 4 | * Created on: Jul 15, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | SYSTEM_EXTERN(pc164); 11 | SYSTEM_EXTERN(pc164lx); 12 | SYSTEM_EXTERN(pc164sx); 13 | 14 | SYSTEM_EXTERN(es40); 15 | SYSTEM_EXTERN(es45); 16 | -------------------------------------------------------------------------------- /src/system/dec/axp/tsunami.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tsunami.h - AlphaServer systems (tsunami family) 3 | * 4 | * Created on: Nov 22, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | #define ES40_NCPU 1 /* up to 4 processors */ 11 | #define ES45_NCPU 1 /* up to 32 processors */ 12 | 13 | class tsunami_sysDevice : public sysDevice 14 | { 15 | public: 16 | tsunami_sysDevice(const SystemConfig &config, const DeviceType &type, cstag_t &tagName, uint64_t clock) 17 | : sysDevice(config, type, tagName, clock), 18 | config("system", LittleEndian, 64, 16, 8, 44, 16, 0) 19 | { 20 | 21 | } 22 | ~tsunami_sysDevice() = default; 23 | 24 | // System creator routines 25 | void es40(SystemConfig &config); 26 | void es45(SystemConfig &config); 27 | 28 | // Model-specific system initialize routines 29 | static void es40_init(); 30 | static void es45_init(); 31 | 32 | void es40_sbus(aspace::AddressList &map); 33 | void es45_sbus(aspace::AddressList &map); 34 | 35 | private: 36 | dec21264_cpuDevice *cpu[ES40_NCPU]; 37 | 38 | mapAddressConfig config; 39 | }; 40 | -------------------------------------------------------------------------------- /src/system/dec/vax/externs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * externs.h - externs for DEC emulators 3 | * 4 | * Created on: Jul 15, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | SYSTEM_EXTERN(mv3900); 11 | SYSTEM_EXTERN(mv3900x); 12 | 13 | SYSTEM_EXTERN(vs3900); 14 | SYSTEM_EXTERN(vs3900x); 15 | -------------------------------------------------------------------------------- /src/system/dec/vax/ka650.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ka650.cpp - MicroVAX 3500/3600 (KA650 board) system driver package 3 | * 4 | * Created on: Jul 15, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/devsys.h" 10 | #include "emu/driver.h" 11 | 12 | #include "system/dec/vax/ka655.h" 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/system/dec/vax/ka650.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ka650.h - MicroVAX 3500/3600 (KA650 board) system driver package 3 | * 4 | * Created on: Jul 15, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | -------------------------------------------------------------------------------- /src/terminals/dec/externs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * externs.h - externs for DEC terminal emulators 3 | * 4 | * Created on: Aug 19, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | SYSTEM_EXTERN(vt100); 11 | -------------------------------------------------------------------------------- /src/terminals/dec/vt100.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * vt100.cpp - DEC VT100 terminal 3 | * 4 | * Created on: Aug 19, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #include "emu/core.h" 9 | #include "emu/map/addrmap.h" 10 | #include "emu/map/map.h" 11 | #include "emu/devsys.h" 12 | #include "emu/driver.h" 13 | #include "emu/machine.h" 14 | #include "emu/engine.h" 15 | 16 | #include "dev/cpu/i8080/i8080.h" 17 | #include "dev/video/dec/vt100.h" 18 | #include "terminals/dec/vt100.h" 19 | #include "emu/xtal.h" 20 | 21 | 22 | using namespace aspace; 23 | 24 | uint32_t vt100_vtDevice::vt100_updateScreen(ScreenDevice &screen, bitmap16_t &bitmap, const rect_t &clip) 25 | { 26 | crt->updateVideo(bitmap, clip); 27 | return 0; 28 | } 29 | 30 | uint8_t vt100_vtDevice::readData(offs_t addr) 31 | { 32 | return ramData[addr]; 33 | } 34 | 35 | void vt100_vtDevice::vt100(SystemConfig &config) 36 | { 37 | 38 | i8080(config, cpu, "cpu", XTAL(24'883'200) / 9); 39 | cpu->setAddressMap(AS_PROGRAM, &vt100_vtDevice::vt100_mem); 40 | cpu->setAddressMap(AS_IOPORT, &vt100_vtDevice::vt100_iomem); 41 | 42 | screen_t *screen = Screen(config, "screen", scrRaster, Color::amber()); 43 | screen->setScreenArea(XTAL(24'073'400) * 2/3, 102*10, 0, 80*10, 262, 0, 25*10); 44 | screen->setScreenUpdate(FUNC(vt100_vtDevice::vt100_updateScreen)); 45 | 46 | VT100_VIDEO(config, crt, "crt", XTAL(24'073'400)); 47 | crt->setScreenName("screen"); 48 | crt->setCharData("chargen"); 49 | crt->getReadRAMDataCallback().set(FUNC(vt100_vtDevice::readData)); 50 | } 51 | 52 | void vt100_vtDevice::vt100_init() 53 | { 54 | 55 | } 56 | 57 | // DEC VT100 memory map 58 | // 59 | // 0000 - 1FFF ROM space (4 x 2K ROM chips) 60 | // 2000 - 3FFF RAM space (screen and scratch) 61 | // 4000 - 7FFF (unassigned space) 62 | // 8000 - 9FFF ROM space program expansion (4 x 2K ROM chips) 63 | // A000 - BFFF ROM space program expension (1 x 8K ROM chips) 64 | // C000 - FFFF (unassigned space) 65 | 66 | void vt100_vtDevice::vt100_mem(AddressList &map) 67 | { 68 | map.setUnmapHigh(); 69 | map(0x0000, 0x1FFF).rom().region("vt100fw"); 70 | map(0x2000, 0x3FFF).ram().share("ram"); 71 | map(0x8000, 0x9FFF).rom(); 72 | map(0xA000, 0xBFFF).rom(); 73 | } 74 | 75 | // DEC VT100 I/O port address map 76 | // 77 | // 00, 01 Intel 8250 PUSART 78 | // 02 Baud rate generator 79 | // 22 Modem buffer 80 | // 42 Flags buffer (R) 81 | // 42 Brightness D/A latch (W) 82 | // 62 NVR latch 83 | // 82 Keyboard UART data 84 | // A2 Video processor DC012 85 | // C2 Video processor DC011 86 | // E2 Graphics port 87 | 88 | void vt100_vtDevice::vt100_iomem(AddressList &map) 89 | { 90 | map.setUnmapHigh(); 91 | 92 | map(0x42, 0x42).w(crt, FUNC(vt100video_t::write8_brightness)); 93 | map(0xA2, 0xA2).w(crt, FUNC(vt100video_t::write8_dc012)); 94 | map(0xC2, 0xC2).w(crt, FUNC(vt100video_t::write8_dc011)); 95 | } 96 | 97 | static const romEntry_t ROM_NAME(vt100)[] = 98 | { 99 | ROM_REGION("vt100fw", 0x2000, 0), 100 | ROM_LOAD("23-061e2-00.e56", 0x0000, 0x0800, 0, nullptr), 101 | ROM_LOAD("23-032e2-00.e52", 0x0800, 0x0800, 0, nullptr), 102 | ROM_LOAD("23-033e2-00.e45", 0x1000, 0x0800, 0, nullptr), 103 | ROM_LOAD("23-034e2-00.e40", 0x1800, 0x0800, 0, nullptr), 104 | 105 | ROM_REGION("chargen", 0x0800, 0), 106 | ROM_LOAD("23-018e2-00.e4", 0x0000, 0x0800, 0, nullptr), 107 | 108 | ROM_END 109 | }; 110 | 111 | TERMINAL(vt100, nullptr, dec, VT100, vt100_vtDevice, vt100, vt100_init, "DEC", "VT100 terminal", SYSTEM_NOT_WORKING) 112 | -------------------------------------------------------------------------------- /src/terminals/dec/vt100.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vt100.h - DEC VT100 terminal 3 | * 4 | * Created on: Aug 19, 2021 5 | * Author: Tim Stark 6 | */ 7 | 8 | #pragma once 9 | 10 | class vt100_vtDevice : public sysDevice 11 | { 12 | public: 13 | vt100_vtDevice(const SystemConfig &config, const DeviceType &type, cstag_t &tagName, uint64_t clock) 14 | : sysDevice(config, type, tagName, clock), 15 | ramData(*this, "ram"), 16 | cpu(*this, "i8080"), 17 | crt(*this, "VT100_Video") 18 | { 19 | 20 | } 21 | 22 | ~vt100_vtDevice() = default; 23 | 24 | void vt100(SystemConfig &config); 25 | 26 | void vt100_init(); 27 | 28 | void vt100_mem(aspace::AddressList &map); 29 | void vt100_iomem(aspace::AddressList &map); 30 | 31 | uint32_t vt100_updateScreen(ScreenDevice &screen, bitmap16_t &bitmap, const rect_t &clip); 32 | uint8_t readData(offs_t addr); 33 | 34 | private: 35 | RequiredDevice cpu; 36 | RequiredDevice crt; 37 | 38 | RequiredSharedPointer ramData; 39 | }; 40 | -------------------------------------------------------------------------------- /src/tools/dump.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * dump.cpp - dump utility 3 | * 4 | * Created on: Dec 29, 2020 5 | * Author: Tim Stark 6 | */ 7 | 8 | 9 | 10 | 11 | --------------------------------------------------------------------------------