#pragma once #include typedef enum { R0 = 0, R1 = 1, R2 = 2, R3 = 3, Rbp = 4, Rsp = 5, Rip = 6, Rfl = 7, Rcs = 8, } Reg; typedef enum { Fl_Zero, Fl_Eq, Fl_Be, Fl_Lt, Fl_Err, Fl_Int, Fl_Vcd, } Flag; typedef enum { Op_Nop, Op_Hlt, Op_Jmp, Op_Jnz, Op_Test, Op_Cmp, Op_Mov8, Op_Mov16, Op_In, Op_Out, Op_Lit, Op_Int, Op_IRet, Op_Or, Op_Xor, Op_And, Op_Shl, Op_RShl, Op_Shr, Op_RShr, Op_Add, Op_Sub, Op_RSub, Op_Mul, Op_IMul, Op_Div, Op_IDiv, Op_RDiv, Op_RIDiv, Op_Mod, Op_RMod, } Op; typedef struct Drive Drive; typedef void (*DriveReadFn)(Drive* drive, uint8_t* block, uint16_t i); typedef void (*DriveWriteFn)(Drive* drive, const uint8_t* block, uint16_t i); struct Drive { void* self; uint16_t block_size; uint16_t block_amount; DriveReadFn read; DriveWriteFn write; }; typedef enum { InterruptType_None, InterruptType_Shutdown, InterruptType_KeyEvent, } InterruptType; typedef struct { InterruptType type; union { uint16_t keycode; }; } Interrupt; #define VCD_BUFFER_OFFSET 0x0c00 #define VCD_BUFFER_SIZE 480 #define VCD_SCREEN_WIDTH 40 #define VCD_SCREEN_HEIGHT 12 typedef struct IODevice IODevice; typedef void (*IODeviceSetCharFn)( IODevice* device, uint16_t offset, uint8_t value); typedef void (*IODeviceWaitForInterruptFn)(IODevice* device); typedef Interrupt (*IODeviceMaybeNextInterruptFn)(IODevice* device); struct IODevice { void* self; IODeviceSetCharFn set_char; IODeviceWaitForInterruptFn wait_for_interrupt; IODeviceMaybeNextInterruptFn maybe_next_interrupt; }; void vm_start(Drive* boot_drive, IODevice* io_device); const char* op_str(Op op);