diff --git a/Makefile b/Makefile index 5ec4fa9..c35b6ab 100644 --- a/Makefile +++ b/Makefile @@ -45,9 +45,13 @@ KERN_OBJECTS = $(patsubst %.c,build/%.o,$(KERN_SOURCES)) all: bin/vm bin/build_disk_image -bin/vm: $(VM_OBJECTS) $(ASM_OBJECTS) +bin/vm: $(VM_OBJECTS) $(ASM_OBJECTS) build/image @mkdir -p $(dir $@) - $(CC) $^ -o $@ $(F_FLAGS) $(OPTIMIZATION) $(L_FLAGS) + $(CC) $(VM_OBJECTS) $(ASM_OBJECTS) -o $@ $(F_FLAGS) $(OPTIMIZATION) $(L_FLAGS) + +build/image: bin/build_disk_image + @mkdir -p $(dir $@) + ./bin/build_disk_image bin/build_disk_image: $(KERN_OBJECTS) $(ASM_OBJECTS) @mkdir -p $(dir $@) diff --git a/vm/main.c b/vm/main.c index 822d784..466b531 100644 --- a/vm/main.c +++ b/vm/main.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -358,6 +359,45 @@ void memdrive_drive_write(Drive* in_drive, const uint8_t* block, uint16_t i) drive->drive.block_size); } +typedef struct { + Drive drive; + FILE* fp; +} FileDrive; + +void filedrive_construct( + FileDrive* drive, FILE* fp, uint16_t block_size, uint16_t block_amount); +void filedrive_drive_read(Drive* in_drive, uint8_t* block, uint16_t i); +void filedrive_drive_write(Drive* in_drive, const uint8_t* block, uint16_t i); + +void filedrive_construct( + FileDrive* drive, FILE* fp, uint16_t block_size, uint16_t block_amount) +{ + *drive = (FileDrive) { + .drive = (Drive) { + .self = drive, + .block_size = block_size, + .block_amount = block_size, + .read = filedrive_drive_read, + .write = filedrive_drive_write, + }, + .fp = fp, + }; +} + +void filedrive_drive_read(Drive* in_drive, uint8_t* block, uint16_t i) +{ + FileDrive* drive = in_drive->self; + fseek(drive->fp, drive->drive.block_size * i, SEEK_SET); + fread(block, sizeof(uint8_t), drive->drive.block_size, drive->fp); +} + +void filedrive_drive_write(Drive* in_drive, const uint8_t* block, uint16_t i) +{ + FileDrive* drive = in_drive->self; + fseek(drive->fp, drive->drive.block_size * i, SEEK_SET); + fwrite(block, sizeof(uint8_t), drive->drive.block_size, drive->fp); +} + __attribute__((unused)) static inline void dump_program(uint16_t* program) { for (size_t rip = 20; rip < 60; ++rip) { @@ -379,189 +419,25 @@ int main(void) int label_ids = 0; - int main_loop = label_ids++; - int interrupt_table = label_ids++; - int keyboard_interrupt = label_ids++; - int keyboard_interrupt_0 = label_ids++; - int keyboard_interrupt_1 = label_ids++; - int keyboard_interrupt_2 = label_ids++; - int keyboard_interrupt_3 = label_ids++; - int keyboard_interrupt_4 = label_ids++; - int put_char = label_ids++; - int put_char_0 = label_ids++; - int put_char_1 = label_ids++; - int screen_x = label_ids++; - int screen_y = label_ids++; - -#define L(LABEL) s_label(LABEL) - - Line program_asm[] = { - // clang-format off - - // rsp points *at* the top element - s_mov16_r_i(Rbp, 2048), - s_mov16_r_i(Rsp, 2048 - 2), - - s_lit_l(interrupt_table), - s_or_i(Rfl, Rfl, 1 << Fl_Int), - - s_or_i(Rfl, Rfl, 1 << Fl_Vcd), - - s_mov16_r_i(R0, 512), - s_mov16_r_i(R1, 1), - s_int(Int_DiskRead), - - L(main_loop), - s_hlt(), - s_jmp_l(main_loop), - - L(interrupt_table), - // size - s_data_i(1), - s_data_l(keyboard_interrupt), - s_nop(), - - L(keyboard_interrupt), - s_and_i(Rfl, Rfl, (uint16_t)~(1 << Fl_Int)), - s_push_r(Rbp), - s_mov16_r_r(Rbp, Rsp), - s_push_r(R0), - s_push_r(R1), - s_push_r(R2), - s_push_r(R3), - - s_in_i(R0, Device_Keyboard), - - s_cmp_i(R0, 44), - s_mov16_r_r(R1, Rfl), - s_and_i(R1, R1, 1 << Fl_Eq), - s_jnz_l(R1, keyboard_interrupt_0), - - s_cmp_i(R0, 42), - s_mov16_r_r(R1, Rfl), - s_and_i(R1, R1, 1 << Fl_Eq), - s_jnz_l(R1, keyboard_interrupt_1), - - s_cmp_i(R0, 40), - s_mov16_r_r(R1, Rfl), - s_and_i(R1, R1, 1 << Fl_Eq), - s_jnz_l(R1, keyboard_interrupt_2), - - s_jmp_l(keyboard_interrupt_3), - - L(keyboard_interrupt_0), - s_mov16_r_i(R0, ' '), - s_call_l(put_char), - s_jmp_l(keyboard_interrupt_4), - - L(keyboard_interrupt_1), - s_mov16_r_ml(R1, screen_x), - s_cmp_i(R1, 0), - s_mov16_r_r(R2, Rfl), - s_and_i(R2, R2, 1 << Fl_Eq), - s_jnz_l(R2, keyboard_interrupt_4), - s_sub_i(R1, R1, 1), - s_mov16_ml_r(screen_x, R1), - s_mov16_r_i(R0, ' '), - s_call_l(put_char), - s_mov16_r_ml(R1, screen_x), - s_sub_i(R1, R1, 1), - s_mov16_ml_r(screen_x, R1), - s_jmp_l(keyboard_interrupt_4), - - L(keyboard_interrupt_2), - s_mov16_r_ml(R1, screen_y), - s_add_i(R1, R1, 1), - s_mov16_ml_r(screen_y, R1), - s_mov16_r_i(R1, 0), - s_mov16_ml_r(screen_x, R1), - s_jmp_l(keyboard_interrupt_4), - - L(keyboard_interrupt_3), - s_add_i(R0, R0, 'A' - 4), - s_call_l(put_char), - s_jmp_l(keyboard_interrupt_4), - - L(keyboard_interrupt_4), - - s_pop_r(R3), - s_pop_r(R2), - s_pop_r(R1), - s_pop_r(R0), - s_mov16_r_r(Rsp, Rbp), - s_pop_r(Rbp), - s_or_i(Rfl, Rfl, 1 << Fl_Int), - s_iret(), - - L(put_char), - s_push_r(Rbp), - s_mov16_r_r(Rbp, Rsp), - s_push_r(R1), - s_push_r(R2), - - s_mov16_r_ml(R2, screen_y), - s_mul_i(R2, R2, vcd_width_in_ch), - s_mov16_r_ml(R1, screen_x), - s_add_i(R1, R1, 0x0c00), - s_add_r(R1, R1, R2), - s_mov8_mr_r(R1, R0), - - s_mov16_r_ml(R1, screen_x), - s_add_i(R1, R1, 1), - s_mov16_ml_r(screen_x, R1), - - s_cmp_i(R1, vcd_width_in_ch), - s_mov16_r_r(R2, Rfl), - s_and_i(R2, R2, 1 << Fl_Eq), - s_jnz_l(R2, put_char_0), - s_jmp_l(put_char_1), - - L(put_char_0), - s_mov16_r_ml(R1, screen_y), - s_add_i(R1, R1, 1), - s_mov16_ml_r(screen_y, R1), - s_mov16_r_i(R1, 0), - s_mov16_ml_r(screen_x, R1), - - L(put_char_1), - - s_pop_r(R1), - s_pop_r(R2), - s_mov16_r_r(Rsp, Rbp), - s_pop_r(Rbp), - s_ret(), - - L(screen_x), - s_data_i(0), - L(screen_y), - s_data_i(0), - - // clang-format on - }; - - size_t program_asm_size = sizeof(program_asm) / sizeof(program_asm[0]); - - uint16_t* program = calloc(512 * 2, sizeof(uint16_t)); - uint16_t program_size - = assemble_to_binary(program, program_asm, program_asm_size); - printf("program size = %d\n", program_size); - - // dump_program(program); - - // return 0; - - MemDrive drive; - memdrive_construct(&drive, (uint64_t*)program, 512); - SdlDevice io_device; res = sdldevice_construct(&io_device); if (res != 0) { exit(1); } + FILE* fp = fopen("build/image", "rb"); + if (!fp) { + fprintf( + stderr, "error: could not open build/image: %s\n", strerror(errno)); + exit(1); + } + + FileDrive drive; + filedrive_construct(&drive, fp, 512, 32); + vm_start(&drive.drive, &io_device.io_device); - free(program); + fclose(fp); sdldevice_destroy(&io_device); }