use disk image file
This commit is contained in:
parent
335822afc6
commit
dd2d919e2d
8
Makefile
8
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 $@)
|
||||
|
226
vm/main.c
226
vm/main.c
@ -10,6 +10,7 @@
|
||||
#include <SDL2/SDL_render.h>
|
||||
#include <SDL2/SDL_video.h>
|
||||
#include <bits/pthreadtypes.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user