Skip to content

Instantly share code, notes, and snippets.

@untodesu
Last active November 25, 2019 12:27
Show Gist options
  • Save untodesu/a3d5cc945320780285ddfd56a00f2e1f to your computer and use it in GitHub Desktop.
Save untodesu/a3d5cc945320780285ddfd56a00f2e1f to your computer and use it in GitHub Desktop.
V16 MMU
/*
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);
}
/*
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