Split files to domains.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
package machine
|
||||
|
||||
import "core:log"
|
||||
|
||||
// CPU.odin -> instructions, fetch, decode, execute, run loop
|
||||
|
||||
cycle :: proc(s: ^System) {
|
||||
program_counter := s.pc
|
||||
|
||||
// Fetch
|
||||
// ---------------
|
||||
high_byte := s.memory[program_counter]
|
||||
low_byte := s.memory[program_counter + 1]
|
||||
|
||||
// advance past this instruction early for our next opcode
|
||||
s.pc += 2
|
||||
|
||||
// Instructions are made of 2 bytes we combine the high and low byte
|
||||
opcode := (u16(high_byte) << 8) | u16(low_byte)
|
||||
|
||||
// mask off everything except the first byte.
|
||||
// shift it 12 bits 'back' left with the first number
|
||||
kind := (opcode & 0xF000) >> 12
|
||||
|
||||
// Decode + Execute
|
||||
// 1. opcodes are broken up to get their particulars
|
||||
// 2. first nibble (4bits half byte) is the first hex number, this is the category
|
||||
// ---------------
|
||||
switch kind {
|
||||
case 0x0:
|
||||
switch opcode {
|
||||
case 0x00E0: op_cls(s)
|
||||
}
|
||||
case 0x1: op_jp_add(s)
|
||||
case 0xD: log.info("D instruction a draw call!")
|
||||
}
|
||||
}
|
||||
|
||||
// Instruction procs
|
||||
// -----------------------------------
|
||||
// CLS: Clear the display
|
||||
op_cls :: proc(s: ^System) {
|
||||
log.info("found clear screen instruction, zero out display buffer")
|
||||
}
|
||||
|
||||
// JP addr: Jump to location nnn
|
||||
op_jp_add :: proc(s: ^System) {
|
||||
log.info("found jump instruction, set pc to nnn")
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package machine
|
||||
|
||||
// keypad mapping, input state update
|
||||
@@ -1,8 +1,9 @@
|
||||
package machine
|
||||
|
||||
import "core:os"
|
||||
import "core:log"
|
||||
|
||||
// System struct, init, constants, fontset
|
||||
|
||||
System :: struct {
|
||||
// 4kb ram
|
||||
memory: [4096]u8,
|
||||
@@ -55,30 +56,3 @@ init :: proc() -> System {
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
load_rom :: proc(s: ^System, file_path: string) -> os.Error {
|
||||
log.info("Loading rom from file")
|
||||
|
||||
data, read_err := os.read_entire_file(file_path, context.allocator)
|
||||
if read_err != os.ERROR_NONE {
|
||||
log.errorf("failed to read rom %v", read_err)
|
||||
return read_err
|
||||
}
|
||||
defer delete(data)
|
||||
|
||||
for byte,i in data {
|
||||
s.memory[0x200 + i] = byte
|
||||
}
|
||||
|
||||
log.infof("First few bytes: %X %X %X %X", s.memory[0x200], s.memory[0x201], s.memory[0x202], s.memory[0x203])
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// fetch decode execute loop
|
||||
run :: proc(s: ^System) {
|
||||
log.info("=== TODO loop ===")
|
||||
// maybe needs a few functions for the 'screen' ie raylib.
|
||||
// also a cycle function or something that will do the ops
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package machine
|
||||
|
||||
// load_rom, anything rom related
|
||||
|
||||
import "core:log"
|
||||
import "core:os"
|
||||
|
||||
load_rom :: proc(s: ^System, file_path: string) -> os.Error {
|
||||
log.info("Loading rom from file")
|
||||
|
||||
data, read_err := os.read_entire_file(file_path, context.allocator)
|
||||
if read_err != os.ERROR_NONE {
|
||||
log.errorf("failed to read rom %v", read_err)
|
||||
return read_err
|
||||
}
|
||||
defer delete(data)
|
||||
|
||||
for byte,i in data {
|
||||
s.memory[0x200 + i] = byte
|
||||
}
|
||||
|
||||
log.infof("First few bytes: %X %X %X %X", s.memory[0x200], s.memory[0x201], s.memory[0x202], s.memory[0x203])
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -5,7 +5,6 @@ import "core:mem"
|
||||
|
||||
import chip "machine"
|
||||
|
||||
// false = release default
|
||||
DEV :: #config(DEV, false)
|
||||
|
||||
main :: proc() {
|
||||
@@ -30,7 +29,7 @@ main :: proc() {
|
||||
}
|
||||
|
||||
// start the cycle
|
||||
chip.run(&system)
|
||||
chip.init_display_and_cycle(&system)
|
||||
|
||||
when DEV {
|
||||
if len(track.allocation_map) > 0 {
|
||||
|
||||
Reference in New Issue
Block a user