diff --git a/Examples/testingDisplay.bin b/Examples/testingDisplay.bin new file mode 100644 index 0000000..024ee82 Binary files /dev/null and b/Examples/testingDisplay.bin differ diff --git a/Examples/testingDisplay.txt b/Examples/testingDisplay.txt new file mode 100644 index 0000000..a2e5f86 --- /dev/null +++ b/Examples/testingDisplay.txt @@ -0,0 +1,71 @@ +//Adding F9 to register 1 +//F9: Display pixel +//byte 0 +ADD 0xFFF9 0xFF00 0x0001 + +//Telling bus to add pixel to display +//byte 6 +WBUS 0xFF00 0xFF00 0x0001 + +//I'll write "RISC-I" in memory, letter by letter + +//Adding R to register 2 +//R = 0x52 in ACII +ADD 0xFF52 0xFF00 0x0002 + +//Writing R to memory +STL 0xFFA0 0xFF00 0x0002 + + +//Adding I to register 2 +//I = 0x49 in ACII +ADD 0xFF49 0xFF00 0x0002 + +//writing I to memory +STL 0xFFA1 0xFF00 0x0002 + + + +//Adding S to register 2 +//S = 0x53 in ACII +ADD 0xFF53 0xFF00 0x0002 + +//writing S to memory +STL 0xFFA2 0xFF00 0x0002 + + +//Adding C to register 2 +//C = 0x43 in ACII +ADD 0xFF43 0xFF00 0x0002 + +//writing C to memory +STL 0xFFA3 0xFF00 0x0002 + + +//Adding - to register 2 +//- = 0x2D in ACII +ADD 0xFF2D 0xFF00 0x0002 + +//writing - to memory +STL 0xFFA4 0xFF00 0x0002 + + +//Adding I to register 2 +//I = 0x49 in ACII +ADD 0xFF49 0xFF00 0x0002 + +//writing I to memory +STL 0xFFA5 0xFF00 0x0002 + + + +//Adding instruction to display text +//in register 3 +ADD 0xFFFA 0xFF00 0x0003 + +//Size of the text: 6 -> 0xFF01 +//Address of text: 0xFFA0 +//Control: 0x0003 +WBUS 0xFF06 0xFFA0 0x0003 + +STP 0x0000 0x0000 0x0000 \ No newline at end of file diff --git a/Makefile b/Makefile index aa425d7..126906b 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,10 @@ # g++ ./src/main.cpp ./src/emulator/emulator.cpp -o Emulator SRCS := $(shell find src -name '*.cpp') - +CFLAGS := $(foreach src,$(SRCS),-c $(src)) # Define o alvo padrĂ£o all: - g++ $(SRCS) -g -o Emulator + g++ $(SRCS) -g -o Emulator -lraylib -lgdi32 -lwinmm + +clean: + rm Emulator \ No newline at end of file diff --git a/src/emulator/BUS/systemBus.cpp b/src/emulator/BUS/systemBus.cpp index 6766d30..8d26b44 100644 --- a/src/emulator/BUS/systemBus.cpp +++ b/src/emulator/BUS/systemBus.cpp @@ -44,8 +44,8 @@ void SystemBus::setDiskModule(ModuleInterface* module){ this->diskModule = module; } -void SystemBus::setScreenModule(ModuleInterface* module){ - this->screenModule = module; +void SystemBus::setDisplayModule(ModuleInterface* module){ + this->displayModule = module; } ModuleInterface* SystemBus::getMemoryModule(){ @@ -61,7 +61,7 @@ ModuleInterface* SystemBus::getDiskModule(){ } ModuleInterface* SystemBus::getScreenModule(){ - return this->screenModule; + return this->displayModule; } void SystemBus::execute(){ @@ -85,9 +85,18 @@ void SystemBus::execute(){ diskModule->execute(control, address, data); } + + else if((control >= SCREENSTART) && (control <= SCREENEND)){ + if(displayModule == NULL) { + std::cerr << "Display module not set\n"; + return; + } + + displayModule->execute(control, address, data); + } else{ - std::cout << "Invalid control signal : " << control << std::endl; + std::cout << "Invalid control signal : " << static_cast(control) << std::endl; } } \ No newline at end of file diff --git a/src/emulator/BUS/systemBus.hpp b/src/emulator/BUS/systemBus.hpp index 12fa3d3..45a7e5a 100644 --- a/src/emulator/BUS/systemBus.hpp +++ b/src/emulator/BUS/systemBus.hpp @@ -34,10 +34,14 @@ typedef unsigned char byte; #define DISKEND DISKWRITE // Info about the IO's SCREEN instructions -#define SCREENSTART SCREENWRITE -#define SCREENEND SCREENWRITE - -#define SCREENWRITE 0xF7 //Bus requesting to write to SCREEN; Bus write to SCREEN +#define SETCRDX 0xF7 //Setting X coordinate to display +#define SETCRDY 0xF8 //Setting Y coordinate to display +#define PXDSPL 0xF9 //Displaying pixel +#define TXTDSPL 0xFA //Displaying text +#define CLRDSPL 0xFB //Clearing display +#define CLRPXL 0xFC //Clearing pixel +#define SCREENSTART SETCRDX +#define SCREENEND CLRPXL class SystemBus{ @@ -50,7 +54,7 @@ class SystemBus{ ModuleInterface* memoryModule; ModuleInterface* cpuModule; ModuleInterface* diskModule; - ModuleInterface* screenModule; + ModuleInterface* displayModule; public: SystemBus(); @@ -64,7 +68,7 @@ class SystemBus{ void setMemoryModule(ModuleInterface* module); void setCpuModule(ModuleInterface* module); void setDiskModule(ModuleInterface* module); - void setScreenModule(ModuleInterface* module); + void setDisplayModule(ModuleInterface* module); ModuleInterface* getMemoryModule(); ModuleInterface* getCpuModule(); diff --git a/src/emulator/IO/display/display.cpp b/src/emulator/IO/display/display.cpp new file mode 100644 index 0000000..578e748 --- /dev/null +++ b/src/emulator/IO/display/display.cpp @@ -0,0 +1,98 @@ +#include "display.hpp" + +Display::Display(SystemBus &bus) : IOInterface(bus){ +} + +void Display::write(byte data){ +} + +void Display::read(long address){ +} + +void Display::displayText(byte address, byte size){ + + std::string text = ""; + for(int i = 0; i < size; i++){ + this->getBus()->writeAddress(address+i); + this->getBus()->writeControl(MEMREAD); + this->getBus()->execute(); + text += static_cast(this->getBus()->readData()); + } + + this->displayTexts.push_back({text, x, y}); + +} + +void Display::displayPixel(){ + + Rectangle pixel = {x, y, 1, 1}; + + this->displayRects.push_back(pixel); +} + +void Display::clearDisplay(){ + ClearBackground(WHITE); +} + +void Display::clearPixel(){ + + for(int i = 0; i < displayRects.size(); i++){ + + Rectangle rect = displayRects[i]; + + if(rect.x == x && rect.y == y){ + displayRects.erase(displayRects.begin() + i); + break; + } + } + +} + +void Display::setX(int x){ + this->x = x; +} + +void Display::setY(int y){ + this->y = y; +} + +byte Display::execute(byte control, byte address, byte data){ + switch(control){ + case SETCRDX: + this->setX(static_cast(data)); + break; + case SETCRDY: + this->setY(static_cast(data)); + break; + case PXDSPL: + this->displayPixel(); + break; + case TXTDSPL: + this->displayText(address, data); + break; + case CLRDSPL: + clearDisplay(); + break; + case CLRPXL: + clearPixel(); + break; + } + + return 0; +} + + +void Display::displayLoop(){ + ClearBackground(WHITE); + BeginDrawing(); + + for(const auto& rect: displayRects){ + DrawRectangle(rect.x, rect.y, rect.width*(GetScreenWidth()/64), rect.height*(GetScreenHeight()/64), BLACK); + } + + for(const auto& text: displayTexts){ + DrawText(text.text.c_str(), text.x, text.y, 20*(GetScreenHeight()/64), BLACK); + } + + EndDrawing(); +} \ No newline at end of file diff --git a/src/emulator/IO/display/display.hpp b/src/emulator/IO/display/display.hpp new file mode 100644 index 0000000..4a4e10c --- /dev/null +++ b/src/emulator/IO/display/display.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include "../IO.hpp" +#include "../../BUS/systemBus.hpp" +#include +#include +#include "raylib.h" + +struct Text{ + std::string text; + int x; + int y; +}; + + +class Display : public IOInterface{ + + private: + std::vector displayRects; + std::vector displayTexts; + + int x = 0; + int y = 0; + + + public: + Display(SystemBus &bus); + + void displayText(byte address, byte size); + + void displayPixel(); + + void clearDisplay(); + + void clearPixel(); + + void setX(int x); + void setY(int y); + + //Write to display + virtual void write(byte data) override; + + //Read from display + virtual void read(long address) override; + + //Execute IO operation + virtual byte execute(byte control, byte address, byte data) override; + + void displayLoop(); + +}; \ No newline at end of file diff --git a/src/emulator/cpu.cpp b/src/emulator/cpu.cpp index 13bc50e..782859f 100644 --- a/src/emulator/cpu.cpp +++ b/src/emulator/cpu.cpp @@ -51,9 +51,9 @@ Cpu::Cpu(SystemBus &bus) : bus (bus){ Cpu(); } -void Cpu::cycle(){ +int Cpu::cycle(){ - while(true){ + // Maybe put this in main this->bus.writeControl(MEMREAD); @@ -65,13 +65,13 @@ void Cpu::cycle(){ if(instruction == NULL){ std::cerr<<"Invalid instruction" << static_cast(instruction) << "\n"; - break; + return -1; } int result = executeInstruction(instruction); if(result == 1){ - break; + return 1; } this->bus.execute(); @@ -80,7 +80,7 @@ void Cpu::cycle(){ pc+=6; - } + return 0; } diff --git a/src/emulator/cpu.h b/src/emulator/cpu.h index 8be25b8..398971b 100644 --- a/src/emulator/cpu.h +++ b/src/emulator/cpu.h @@ -52,6 +52,6 @@ class Cpu{ void loadIntoMemory(byte toLoad[]); byte getOperandValue(byte lower, byte higher); int executeInstruction(byte instruction); - void cycle(); + int cycle(); }; diff --git a/src/main.cpp b/src/main.cpp index 564a2af..0199230 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,7 @@ #include "./emulator/memory/memory.hpp" #include "./emulator/BUS/systemBus.hpp" #include "./emulator/IO/disk/disk.hpp" +#include "./Emulator/IO/display/display.hpp" #include typedef unsigned char byte; @@ -33,8 +34,17 @@ int main(int argc, char* argv[]){ Disk* disk = new Disk(*bus); bus->setDiskModule(disk); + std::cout<<"Inicializando janela\n"; + + + std::cout<<"janela inicializada\n"; + + Display* display = new Display(*bus); + bus->setDisplayModule(display); + Cpu* cpu = new Cpu(*bus); + char* filePath = argv[2]; std::ifstream file(filePath, std::ios::binary); @@ -63,7 +73,26 @@ int main(int argc, char* argv[]){ file.close(); - cpu->cycle(); + std::cout<<"Tudo inicializado certo\n"; + + SetConfigFlags(FLAG_WINDOW_RESIZABLE); + InitWindow(64, 64, "RISC-I Emulator"); + + int result = 0; + + ClearBackground(WHITE); + while(!WindowShouldClose()){ + + if(result == 0){ + result = cpu->cycle(); + } + + display->displayLoop(); + + } + + CloseWindow(); + }