chore: general update
This commit is contained in:
		| @@ -37,7 +37,6 @@ pub fn draw_sprite(disp: *Display, pos: *const Point, data: *const []u8) bool { | ||||
|  | ||||
|             const temp = (byte >> x_bit_offset) & 0x01; | ||||
|             const bit = @intCast(u1, temp); | ||||
|             // const bit = @as(u1, temp); | ||||
|  | ||||
|             const i = DISPLAY_WIDTH * y + x; | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ pub const Cpu = struct { | ||||
|     sp: u16, | ||||
|     v: [16]u8, | ||||
|     stack: [16]u16, | ||||
|     memory: [4096]u8, | ||||
|     memory: [0x1000]u8, | ||||
|     disp: Display, | ||||
| }; | ||||
| 
 | ||||
| @@ -34,7 +34,6 @@ pub fn decode(cpu: *Cpu, word: u16) ?Instruction { | ||||
|     const nib3: u4 = @intCast(u4, (word & 0x00F0) >> 4); | ||||
|     const nib4: u4 = @intCast(u4, (word & 0x000F) >> 0); | ||||
| 
 | ||||
| 
 | ||||
|     if (nib1 == 0x0) { | ||||
|         // nib2 is 0x0, nib3 is 0xE | ||||
| 
 | ||||
| @@ -84,20 +83,20 @@ pub fn decode(cpu: *Cpu, word: u16) ?Instruction { | ||||
| 
 | ||||
| pub fn execute(cpu: *Cpu, instr: Instruction) void { | ||||
|     switch (instr) { | ||||
|         .CLS => std.debug.print("CLS\n", .{}), | ||||
|         .CLS => std.log.debug("CLS", .{}), | ||||
|         .RET => { | ||||
|             std.debug.print("RET\n", .{}); | ||||
|             std.log.debug("RET", .{}); | ||||
| 
 | ||||
|             cpu.pc = cpu.stack[cpu.sp]; | ||||
|             cpu.sp -= 1; | ||||
|         }, | ||||
|         .JP => |addr| { | ||||
|             std.debug.print("JP 0x{X:}\n", .{ addr }); | ||||
|             std.log.debug("JP 0x{X:}", .{ addr }); | ||||
| 
 | ||||
|             cpu.pc = addr; | ||||
|         }, | ||||
|         .CALL => |addr| { | ||||
|             std.debug.print("CALL 0x{X:}\n", .{ addr }); | ||||
|             std.log.debug("CALL 0x{X:}", .{ addr }); | ||||
| 
 | ||||
|             cpu.sp += 1; | ||||
|             cpu.stack[cpu.sp] = cpu.pc; | ||||
| @@ -106,7 +105,7 @@ pub fn execute(cpu: *Cpu, instr: Instruction) void { | ||||
|         .SE_3 => |args| { | ||||
|             const x = args.x; | ||||
|             const kk = args.kk; | ||||
|             std.debug.print("SE V{}, 0x{X:}\n", .{ x, kk }); | ||||
|             std.log.debug("SE V{}, 0x{X:}", .{ x, kk }); | ||||
| 
 | ||||
|             if (cpu.v[x] != kk) { | ||||
|                 cpu.pc += 2; | ||||
| @@ -115,19 +114,19 @@ pub fn execute(cpu: *Cpu, instr: Instruction) void { | ||||
|         .LD_6 => |args| { | ||||
|             const x = args.x; | ||||
|             const kk = args.kk; | ||||
|             std.debug.print("LD V{} 0x{X:}\n", .{ x, kk }); | ||||
|             std.log.debug("LD V{} 0x{X:}", .{ x, kk }); | ||||
| 
 | ||||
|             cpu.v[x] = kk; | ||||
|         }, | ||||
|         .LD_I => |addr| { | ||||
|             std.debug.print("LD I, 0x{X:}\n", .{ addr }); | ||||
|             std.log.debug("LD I, 0x{X:}", .{ addr }); | ||||
|             cpu.i = addr; | ||||
|         }, | ||||
|         .DRW => |args| { | ||||
|             const x = args.x; | ||||
|             const y = args.y; | ||||
|             const n = args.n; | ||||
|             std.debug.print("DRW V{}, V{}, 0x{X:}\n", .{ x, y, n }); | ||||
|             std.log.debug("DRW V{}, V{}, 0x{X:}", .{ x, y, n }); | ||||
| 
 | ||||
|             const draw_pos: Point = .{ .x = cpu.v[x], .y = cpu.v[y] }; | ||||
|             const sprite_data = cpu.memory[cpu.i..(cpu.i + n)]; | ||||
| @@ -141,7 +140,7 @@ pub fn execute(cpu: *Cpu, instr: Instruction) void { | ||||
|         .ADD_7 => |args| { | ||||
|             const x = args.x; | ||||
|             const kk = args.kk; | ||||
|             std.debug.print("ADD V{}, 0x{X:}\n", .{ x, kk }); | ||||
|             std.log.debug("ADD V{}, 0x{X:}", .{ x, kk }); | ||||
| 
 | ||||
|             cpu.v[x] = cpu.v[x] + kk; | ||||
|         } | ||||
| @@ -158,18 +157,19 @@ fn load_rom(cpu: *Cpu, buf: []u8) void { | ||||
| } | ||||
| 
 | ||||
| pub fn load_rom_path(cpu: *Cpu, path: []const u8) !void { | ||||
|     var alloc = std.heap.page_allocator; | ||||
|     var heap = std.heap.page_allocator; | ||||
| 
 | ||||
|     const file = try std.fs.cwd().openFile(path, .{ .read = true }); | ||||
|     defer file.close(); | ||||
| 
 | ||||
|     const file_size = try file.getEndPos(); | ||||
|     const rom_buf = try file.readToEndAlloc(alloc, file_size); | ||||
|     const rom_buf = try file.readToEndAlloc(heap, file_size); | ||||
|     defer heap.free(rom_buf); | ||||
| 
 | ||||
|     load_rom(cpu, rom_buf); | ||||
| } | ||||
| 
 | ||||
| pub fn cycle(cpu: *Cpu) void { | ||||
| pub fn step(cpu: *Cpu) void { | ||||
|     const opcode = fetch(cpu); | ||||
|     const maybe_instr = decode(cpu, opcode); | ||||
| 
 | ||||
| @@ -1,107 +1,77 @@ | ||||
| const std = @import("std"); | ||||
| const cpu = @import("cpu.zig"); | ||||
| const emu = @import("emu.zig"); | ||||
| const Display = @import("display.zig").Display; | ||||
| const c = @cImport({ | ||||
|     @cInclude("SDL2/SDL.h"); | ||||
| }); | ||||
| const assert = @import("std").debug.assert; | ||||
| const c = @cImport(@cInclude("SDL.h")); | ||||
|  | ||||
| // See https://github.com/zig-lang/zig/issues/565 | ||||
| // SDL_video.h:#define SDL_WINDOWPOS_UNDEFINED         SDL_WINDOWPOS_UNDEFINED_DISPLAY(0) | ||||
| // SDL_video.h:#define SDL_WINDOWPOS_UNDEFINED_DISPLAY(X)  (SDL_WINDOWPOS_UNDEFINED_MASK|(X)) | ||||
| // SDL_video.h:#define SDL_WINDOWPOS_UNDEFINED_MASK    0x1FFF0000u | ||||
| const SDL_WINDOWPOS_UNDEFINED = @bitCast(c_int, c.SDL_WINDOWPOS_UNDEFINED_MASK); | ||||
| const Cpu = emu.Cpu; | ||||
|  | ||||
| extern fn SDL_PollEvent(event: *c.SDL_Event) c_int; | ||||
| const WIDTH = 64; | ||||
| const HEIGHT = 32; | ||||
| const WINDOW_WIDTH = WIDTH * 10; | ||||
| const WINDOW_HEIGHT = HEIGHT * 10; | ||||
| const PIXELBUF_LEN = WIDTH * HEIGHT * @sizeOf(u32); | ||||
|  | ||||
| // SDL_RWclose is fundamentally unrepresentable in Zig, because `ctx` is | ||||
| // evaluated twice. One could make the case that this is a bug in SDL, | ||||
| // especially since the docs list a real function prototype that would not | ||||
| // have this double-evaluation of the parameter. | ||||
| // If SDL would instead of a macro use a static inline function, | ||||
| // it would resolve the SDL bug as well as make the function visible to Zig | ||||
| // and to debuggers. | ||||
| // SDL_rwops.h:#define SDL_RWclose(ctx)        (ctx)->close(ctx) | ||||
| inline fn SDL_RWclose(ctx: [*]c.SDL_RWops) c_int { | ||||
|     return ctx[0].close.?(ctx); | ||||
| } | ||||
|  | ||||
| pub fn main() !void { | ||||
|     // Initialize SDL2 | ||||
|     if (c.SDL_Init(c.SDL_INIT_VIDEO) != 0) { | ||||
|         c.SDL_Log("Unable to initialize SDL: %s", c.SDL_GetError()); | ||||
|         return error.SDLInitializationFailed; | ||||
|     } | ||||
|     _ = c.SDL_Init(c.SDL_INIT_VIDEO); | ||||
|     defer c.SDL_Quit(); | ||||
|  | ||||
|     // Create Screen (Maybe introduce scaling somehow?) | ||||
|     const screen = c.SDL_CreateWindow("Zig8", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 320, c.SDL_WINDOW_OPENGL) orelse | ||||
|         { | ||||
|         c.SDL_Log("Unable to create window: %s", c.SDL_GetError()); | ||||
|         return error.SDLInitializationFailed; | ||||
|     }; | ||||
|     defer c.SDL_DestroyWindow(screen); | ||||
|     const window = c.SDL_CreateWindow("CHIP-8", c.SDL_WINDOWPOS_CENTERED, c.SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, c.SDL_WINDOW_OPENGL); | ||||
|     defer c.SDL_DestroyWindow(window); | ||||
|  | ||||
|     // Create Renderer | ||||
|     const renderer = c.SDL_CreateRenderer(screen, -1, c.SDL_RENDERER_ACCELERATED) orelse { | ||||
|         c.SDL_Log("Unable to create renderer: %s", c.SDL_GetError()); | ||||
|         return error.SDLInitializationFailed; | ||||
|     }; | ||||
|     const renderer = c.SDL_CreateRenderer(window, -1, c.SDL_RENDERER_ACCELERATED); | ||||
|     defer c.SDL_DestroyRenderer(renderer); | ||||
|  | ||||
|     // Create RGBA Texture | ||||
|     const texture = c.SDL_CreateTexture(renderer, c.SDL_PIXELFORMAT_RGBA8888, c.SDL_TEXTUREACCESS_STREAMING, 64, 32) orelse { | ||||
|         c.SDL_Log("Unable to create texture: %s", c.SDL_GetError()); | ||||
|         return error.SDLInitializationFailed; | ||||
|     }; | ||||
|     const texture = c.SDL_CreateTexture(renderer, c.SDL_PIXELFORMAT_RGBA8888, c.SDL_TEXTUREACCESS_STATIC, WIDTH, HEIGHT); | ||||
|     defer c.SDL_DestroyTexture(texture); | ||||
|  | ||||
|     // Initialize CHIP-8 Emulator | ||||
|     var chip8 = cpu.Cpu { | ||||
|     var zig8 = emu.Cpu { | ||||
|         .i = 0x00, | ||||
|         .pc = 0x0200, | ||||
|         .pc = 0x200, | ||||
|         .sp = 0x00, | ||||
|         .v = [_]u8{0x0} ** 16, | ||||
|         .stack = [_]u16{0x0} ** 16, | ||||
|         .memory = [_]u8{0x0} ** 4096, | ||||
|         .v = [_]u8{0x00} ** 16, | ||||
|         .stack = [_]u16{0x00} ** 16, | ||||
|         .memory = [_]u8{0x0000} ** 0x1000, | ||||
|         .disp = Display.new(), | ||||
|     }; | ||||
|  | ||||
|     var path = "./bin/IBM Logo.ch8"; | ||||
|     try emu.load_rom_path(&zig8, "./bin/IBM Logo.ch8"); | ||||
|     var pixel_buf: [PIXELBUF_LEN]u8 = [_]u8 {0x00} ** PIXELBUF_LEN; | ||||
|  | ||||
|     // Load Game ROM into CHIP-8 Emulator | ||||
|     try cpu.load_rom_path(&chip8, path); | ||||
|     emuloop: while(true) { | ||||
|         _ = c.SDL_UpdateTexture(texture, null, @ptrCast(*const c_void, &pixel_buf), WIDTH * @sizeOf(u32)); | ||||
|         _ = c.SDL_RenderCopy(renderer, texture, null, null); | ||||
|         _ = c.SDL_RenderPresent(renderer); | ||||
|  | ||||
|  | ||||
|     // Create Pixel Buffer (Temporary) | ||||
|     const buf_size = 64 * 32 * @sizeOf(u32); | ||||
|     var pixels: [buf_size]u8 = [_]u8{255} ** buf_size; | ||||
|  | ||||
|     // Render | ||||
|     var quit = false; | ||||
|     while (!quit) { | ||||
|  | ||||
|         var buf_ptr: [*c]?*c_void = &@ptrCast(?*c_void, &pixels[0]); | ||||
|  | ||||
|         _ = c.SDL_LockTexture(texture, null, buf_ptr, 64 * @sizeOf(u32)); | ||||
|         c.SDL_UnlockTexture(texture); | ||||
|          | ||||
|         var event: c.SDL_Event = undefined; | ||||
|         while (SDL_PollEvent(&event) != 0) { | ||||
|             switch (event.@"type") { | ||||
|                 c.SDL_QUIT => { | ||||
|                     quit = true; | ||||
|                 }, | ||||
|                 else => {}, | ||||
|         while(c.SDL_PollEvent(&event) != 0) { | ||||
|             switch(event.type) { | ||||
|                 c.SDL_QUIT => break :emuloop, | ||||
|                 else => {} | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         _ = c.SDL_RenderClear(renderer); | ||||
|         _ = c.SDL_RenderCopy(renderer, texture, null, null); | ||||
|         c.SDL_RenderPresent(renderer); | ||||
|         emu.step(&zig8); | ||||
|         draw(&zig8.disp, &pixel_buf);   | ||||
|     } | ||||
| } | ||||
|  | ||||
|         cpu.cycle(&chip8); | ||||
| fn draw(display: *const Display, pixel_buf: *[8192]u8) void { | ||||
|     var emu_i: usize = 0; | ||||
|  | ||||
|         c.SDL_Delay(17); | ||||
|     while (emu_i < display.buf.len) : (emu_i += 1) { | ||||
|         var pixel_i = emu_i * 4; | ||||
|  | ||||
|         if (display.buf[emu_i] == 0x01) { | ||||
|             pixel_buf[pixel_i] = 0xFF; | ||||
|             pixel_buf[pixel_i + 1] = 0xFF; | ||||
|             pixel_buf[pixel_i + 2] = 0xFF; | ||||
|             pixel_buf[pixel_i + 3] = 0xFF; | ||||
|         } else { | ||||
|             pixel_buf[pixel_i] = 0xFF; | ||||
|             pixel_buf[pixel_i + 1] = 0x00; | ||||
|             pixel_buf[pixel_i + 2] = 0x00; | ||||
|             pixel_buf[pixel_i + 3] = 0x00; | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user