From c296dce6835487b3712a03bdd4b95159b868ec20 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Thu, 17 Jun 2021 02:37:29 -0500 Subject: [PATCH] chore: general update --- 2021-03-16/zig8/src/display.zig | 1 - 2021-03-16/zig8/src/{cpu.zig => emu.zig} | 28 ++--- 2021-03-16/zig8/src/main.zig | 126 +++++++++-------------- 3 files changed, 62 insertions(+), 93 deletions(-) rename 2021-03-16/zig8/src/{cpu.zig => emu.zig} (87%) diff --git a/2021-03-16/zig8/src/display.zig b/2021-03-16/zig8/src/display.zig index 57b09dc..389ffc2 100644 --- a/2021-03-16/zig8/src/display.zig +++ b/2021-03-16/zig8/src/display.zig @@ -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; diff --git a/2021-03-16/zig8/src/cpu.zig b/2021-03-16/zig8/src/emu.zig similarity index 87% rename from 2021-03-16/zig8/src/cpu.zig rename to 2021-03-16/zig8/src/emu.zig index 2ac98a7..5154e65 100644 --- a/2021-03-16/zig8/src/cpu.zig +++ b/2021-03-16/zig8/src/emu.zig @@ -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); diff --git a/2021-03-16/zig8/src/main.zig b/2021-03-16/zig8/src/main.zig index d72a97f..05ed7ee 100644 --- a/2021-03-16/zig8/src/main.zig +++ b/2021-03-16/zig8/src/main.zig @@ -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; + } } } \ No newline at end of file