Last active
November 25, 2019 12:27
-
-
Save untodesu/a3d5cc945320780285ddfd56a00f2e1f to your computer and use it in GitHub Desktop.
V16 MMU
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| The V16 Virtual Machine | |
| Licensed under the MIT License | |
| File: Implement V16 MMU stuff. | |
| NOTE: THIS FILE CONTAINS AN ABSOLUTELY CURSED CODE, | |
| SO IF YOU ARE A VIRGIN PROGRAMMER WHO DID NOT | |
| SEE SOME SHIT DO NOT LOOK HERE | |
| */ | |
| #include <cstring> | |
| #include "./v16.hh" | |
| //Max physical ram size | |
| #define V16_RAMSIZE 0x1000000 | |
| //Constructor. | |
| mmu::mmu() : m_RAM(new byte_t[V16_RAMSIZE]) | |
| { | |
| m_UMA.clear(); | |
| } | |
| //Destructor | |
| mmu::~mmu() | |
| { | |
| delete m_RAM; | |
| } | |
| //Claim single memory unit. | |
| void mmu::claim_byte(pointer_t address, byte_t *byte) | |
| { | |
| //We cannot claim stuff lower than V16_RAMSIZE, | |
| //because its RAM | |
| if(byte && (address >= V16_RAMSIZE)) { | |
| m_UMA[address] = byte; | |
| } | |
| } | |
| //Write value to specified address | |
| void mmu::write_byte(pointer_t address, byte_t value) | |
| { | |
| //UMA - try to find and set, else - do nothing | |
| if(address >= V16_RAMSIZE) { | |
| uma::iterator it = m_UMA.find(address); | |
| if(it != m_UMA.end()) { | |
| //We must not allow programmer to write some stuff to UMA without claiming | |
| *m_UMA[address] = value; | |
| } | |
| } | |
| //RAM - just set value | |
| else { | |
| m_RAM[address] = value; | |
| } | |
| } | |
| //Write value (word) to specified address (+1) | |
| void mmu::write_word(pointer_t address, word_t value) | |
| { | |
| //Convert word to two bytes. | |
| //This is evil pointer magic and i am wizard so dont judge me. | |
| byte_t *data = (byte_t *)&value; | |
| write_byte(address, data[0]); | |
| write_byte((address + 1), data[1]); | |
| } | |
| //Write value (dword) to specified address (+3) | |
| void mmu::write_dword(pointer_t address, dword_t value) | |
| { | |
| //Convert d-word to four bytes. | |
| //This is evil pointer magic and i am wizard so dont judge me. | |
| byte_t *data = (byte_t *)&value; | |
| write_byte(address, data[0]); | |
| write_byte((address + 1), data[1]); | |
| write_byte((address + 2), data[2]); | |
| write_byte((address + 3), data[3]); | |
| } | |
| //Read byte from specified address | |
| byte_t mmu::read_byte(pointer_t address) | |
| { | |
| //Read from UMA | |
| if(address >= V16_RAMSIZE) { | |
| uma::iterator it = m_UMA.find(address); | |
| return (it != m_UMA.end()) ? *it->second : 0; | |
| } | |
| //Read from RAM | |
| return m_RAM[address]; | |
| } | |
| //Read value (word) from specified address | |
| word_t mmu::read_word(pointer_t address) | |
| { | |
| //Convert two bytes to word through arrays. | |
| //This is evil pointer magic and i am wizard so dont judge me. | |
| byte_t data[2] = { read_byte(address), read_byte(address + 1) }; | |
| return *((word_t *)data); | |
| } | |
| //Read value (dword) from specified address | |
| dword_t mmu::read_dword(pointer_t address) | |
| { | |
| //Convert four bytes to dword through arrays. | |
| //This is evil pointer magic and i am wizard so dont judge me. | |
| byte_t data[4] = { | |
| read_byte(address), read_byte(address + 1), | |
| read_byte(address + 2), read_byte(address + 3) | |
| }; | |
| return *((dword_t *)data); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| The V16 Virtual Machine | |
| Licensed under the MIT License | |
| File: Declare common stuff for VM | |
| */ | |
| #ifndef _V16_HH | |
| #define _V16_HH | |
| #include <cstdint> | |
| #include <cstddef> | |
| #include <map> | |
| //V16 RAM wide types | |
| using byte_t = uint8_t; //Standard 8-bit value, minimal addressable unit | |
| using word_t = uint16_t; //A word. Two-byte length. | |
| using dword_t = uint32_t; //A double-word. | |
| using pointer_t = uint32_t; //Pointer to specific location in virtual address space | |
| //A memory managing unit for V16. | |
| //This translates logical 32-bit addresses to physical 24-bit addresses for RAM and free space. | |
| //So addresses 00000000..00FFFFFF are RAM, 01000000...FFFFFFFF are free address space (e.g devices) | |
| class mmu { | |
| public: | |
| using uma = std::map<dword_t, byte_t *>; | |
| using ram = byte_t *; | |
| private: | |
| ram m_RAM; //Addresses from 0x00000000 to 0x00FFFFFF | |
| uma m_UMA; //Addresses from 0x01000000 to 0xFFFFFFFF | |
| public: | |
| mmu(); ~mmu(); | |
| void claim_byte(pointer_t address, byte_t *byte); | |
| void write_byte(pointer_t address, byte_t value); | |
| void write_word(pointer_t address, word_t value); | |
| void write_dword(pointer_t address, dword_t value); | |
| byte_t read_byte(pointer_t address); | |
| word_t read_word(pointer_t address); | |
| dword_t read_dword(pointer_t address); | |
| }; | |
| #endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment