Implemented ROM loading and program loading. Implemented interrupts.
This commit is contained in:
7
main.cpp
7
main.cpp
@@ -1,11 +1,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "vm.h"
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
int i = 1;
|
vm_init("test.bin");
|
||||||
char a[4] = { 1, 2, 3, 4 };
|
vm_step();
|
||||||
int x = a[i++] + a[i++];
|
|
||||||
// aci, i == 12 ; x == 21
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
49
vm.cpp
49
vm.cpp
@@ -1,4 +1,5 @@
|
|||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define MAX_EXTERNAL_CALLS 256
|
#define MAX_EXTERNAL_CALLS 256
|
||||||
#define MAX_DATA_STACK 256
|
#define MAX_DATA_STACK 256
|
||||||
@@ -89,29 +90,52 @@ typedef byte(*t_in_port)();
|
|||||||
t_out_port out_ports[256];
|
t_out_port out_ports[256];
|
||||||
t_in_port in_ports[256];
|
t_in_port in_ports[256];
|
||||||
|
|
||||||
const unsigned char* vm_program = nullptr;
|
unsigned char mem[65536];
|
||||||
|
const unsigned char* vm_program = mem;
|
||||||
int vm_pc = 0;
|
int vm_pc = 0;
|
||||||
int vm_cycles = 0;
|
int vm_cycles = 0;
|
||||||
t_stack vm_datastack;
|
t_stack vm_datastack;
|
||||||
t_stack vm_callstack;
|
t_stack vm_callstack;
|
||||||
unsigned char mem[65536];
|
|
||||||
unsigned short rX = 0;
|
unsigned short rX = 0;
|
||||||
unsigned char rY = 0;
|
unsigned char rY = 0;
|
||||||
unsigned char rZ = 0;
|
unsigned char rZ = 0;
|
||||||
|
|
||||||
|
|
||||||
void vm_init(const unsigned char* program) {
|
static void load_rom() {
|
||||||
vm_program = program;
|
FILE *f = fopen("rom.bin", "rb");
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
long fsize = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
fread(&mem[0x8000], fsize, 1, f);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void load_program(const char* filename) {
|
||||||
|
FILE *f = fopen(filename, "rb");
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
long fsize = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
fread(mem, fsize, 1, f);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vm_init(const char* filename) {
|
||||||
vm_pc = rX = rY = rZ = 0;
|
vm_pc = rX = rY = rZ = 0;
|
||||||
stack_init(vm_datastack, MAX_DATA_STACK);
|
vm_datastack.data = &mem[0x8800];
|
||||||
stack_init(vm_callstack, MAX_CALL_STACK);
|
vm_callstack.data = &mem[0x8900];
|
||||||
|
vm_datastack.top = vm_callstack.top = 0;
|
||||||
|
vm_datastack.max = MAX_DATA_STACK;
|
||||||
|
vm_callstack.max = MAX_CALL_STACK;
|
||||||
|
load_rom();
|
||||||
|
load_program(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned short WORD() { vm_pc += 2; return vm_program[vm_pc - 2] + (vm_program[vm_pc - 1] << 8); }
|
inline unsigned short WORD() { vm_pc += 2; return vm_program[vm_pc - 2] + (vm_program[vm_pc - 1] << 8); }
|
||||||
|
|
||||||
void vm_step() {
|
const int vm_step() {
|
||||||
char val, val2;
|
char val, val2;
|
||||||
switch (vm_program[vm_pc++]) {
|
switch (vm_program[vm_pc++]) {
|
||||||
|
|
||||||
case OP_NOP: vm_cycles++; break;
|
case OP_NOP: vm_cycles++; break;
|
||||||
case OP_PUSH: stack_push(vm_datastack, vm_program[vm_pc++]); vm_cycles++; break;
|
case OP_PUSH: stack_push(vm_datastack, vm_program[vm_pc++]); vm_cycles++; break;
|
||||||
case OP_POP: stack_pop(vm_datastack); vm_cycles++; break;
|
case OP_POP: stack_pop(vm_datastack); vm_cycles++; break;
|
||||||
@@ -181,6 +205,7 @@ void vm_step() {
|
|||||||
case OP_IN: stack_push(vm_datastack, in_ports[vm_program[vm_pc++]]()); vm_cycles++; break;
|
case OP_IN: stack_push(vm_datastack, in_ports[vm_program[vm_pc++]]()); vm_cycles++; break;
|
||||||
case OP_OUT: out_ports[vm_program[vm_pc++]](stack_pop(vm_datastack)); vm_cycles++; break;
|
case OP_OUT: out_ports[vm_program[vm_pc++]](stack_pop(vm_datastack)); vm_cycles++; break;
|
||||||
}
|
}
|
||||||
|
return vm_cycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vm_register_call(void(*callback)(t_stack&)) {
|
void vm_register_call(void(*callback)(t_stack&)) {
|
||||||
@@ -194,3 +219,13 @@ void vm_register_in_port(const byte port, t_in_port callback) {
|
|||||||
void vm_register_out_port(const byte port, t_out_port callback) {
|
void vm_register_out_port(const byte port, t_out_port callback) {
|
||||||
out_ports[port] = callback;
|
out_ports[port] = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vm_call_interrupt(const char num) {
|
||||||
|
stack_push(vm_callstack, vm_pc);
|
||||||
|
stack_push(vm_callstack, rX & 255);
|
||||||
|
stack_push(vm_callstack, rX >> 8);
|
||||||
|
stack_push(vm_callstack, rY);
|
||||||
|
stack_push(vm_callstack, rZ);
|
||||||
|
vm_pc = num == 0 ? 0xFFFA : 0xFFFD;
|
||||||
|
vm_cycles++;
|
||||||
|
}
|
||||||
|
|||||||
8
vm.h
8
vm.h
@@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
|
|
||||||
void vm_init(const unsigned char* program);
|
void vm_init(const char* filename);
|
||||||
void vm_step();
|
const int vm_step();
|
||||||
void vm_register_call(void(*callback)(t_stack&));
|
|
||||||
void vm_register_in_port(const unsigned char port, unsigned char(*callback)(void));
|
void vm_register_in_port(const unsigned char port, unsigned char(*callback)(void));
|
||||||
void vm_register_out_port(const unsigned char port, void(*callback)(const unsigned char&));
|
void vm_register_out_port(const unsigned char port, void(*callback)(const unsigned char&));
|
||||||
|
void vm_call_interrupt(const char num);
|
||||||
|
|
||||||
|
void vm_register_call(void(*callback)(t_stack&));
|
||||||
|
|||||||
Reference in New Issue
Block a user