diff options
| author | Julian Blake Kongslie | 2022-10-08 00:39:15 -0700 |
|---|---|---|
| committer | Julian Blake Kongslie | 2022-10-08 00:39:15 -0700 |
| commit | 85b34e1c9dc03585ec4f13f6241cd8f0ecaf9cd9 (patch) | |
| tree | 0ec9a990fab8c06d0e2c6aa67447f3a8003aaf3d | |
| parent | Minor cleanup and some compilation fixes. (diff) | |
| download | biggolf-85b34e1c9dc03585ec4f13f6241cd8f0ecaf9cd9.tar.xz | |
Trivial support for running the checker on an image.
| -rw-r--r-- | Makefile | 20 | ||||
| -rw-r--r-- | image.hex | 4 | ||||
| -rw-r--r-- | isa/checker.cpp | 2 | ||||
| -rw-r--r-- | isa/checker.h | 33 | ||||
| -rw-r--r-- | main.cpp | 28 | ||||
| l--------- | minigolf | 1 |
6 files changed, 78 insertions, 10 deletions
| @@ -9,7 +9,7 @@ DEBUG := -g | |||
| 9 | CXX := g++ | 9 | CXX := g++ |
| 10 | CXXFLAGS := $(WARNINGS) $(OPTIMIZE) $(DEBUG) | 10 | CXXFLAGS := $(WARNINGS) $(OPTIMIZE) $(DEBUG) |
| 11 | 11 | ||
| 12 | SED := sed | 12 | LD := ld |
| 13 | 13 | ||
| 14 | XXD := xxd | 14 | XXD := xxd |
| 15 | 15 | ||
| @@ -30,15 +30,27 @@ clean: | |||
| 30 | rm -rf $(BUILD) | 30 | rm -rf $(BUILD) |
| 31 | .PHONY: clean | 31 | .PHONY: clean |
| 32 | 32 | ||
| 33 | .SECONDARY: | ||
| 33 | .SUFFIXES: | 34 | .SUFFIXES: |
| 34 | 35 | ||
| 35 | override SOURCES := $(shell find -\( -name build -prune -\) -o -\( -name \*.cpp -print -\)) | 36 | override SOURCES := $(shell find -\( -name build -prune -\) -o -\( -\( -name \*.bin -o -name \*.hex -o -name \*.cpp -\) -print -\)) |
| 36 | 37 | ||
| 37 | override OBJECTS := $(addprefix $(BUILD)/, $(addsuffix .o, $(basename $(SOURCES)))) | 38 | override OBJECTS := $(addprefix $(BUILD)/, $(addsuffix .o, $(basename $(SOURCES)))) |
| 38 | override DEPENDS := $(addprefix $(BUILD)/, $(addsuffix .d, $(basename $(SOURCES)))) | 39 | override DEPENDS := $(addprefix $(BUILD)/, $(addsuffix .d, $(basename $(SOURCES)))) |
| 39 | 40 | ||
| 40 | -include $(DEPENDS) | 41 | -include $(DEPENDS) |
| 41 | 42 | ||
| 43 | $(BUILD)/%.bin: %.hex | ||
| 44 | @mkdir -p $(dir $@) | ||
| 45 | $(XXD) -r -p $< $@ | ||
| 46 | |||
| 47 | $(BUILD)/%.o: %.bin | ||
| 48 | @mkdir -p $(dir $@) | ||
| 49 | $(LD) -r -b binary -z noexecstack -o $@ $< | ||
| 50 | |||
| 51 | $(BUILD)/%.o: $(BUILD)/%.bin | ||
| 52 | $(LD) -r -b binary -z noexecstack -o $@ $< | ||
| 53 | |||
| 42 | $(BUILD)/%.o: %.cpp | 54 | $(BUILD)/%.o: %.cpp |
| 43 | @mkdir -p $(dir $@) | 55 | @mkdir -p $(dir $@) |
| 44 | $(CXX) $(CXXFLAGS) $(COMPILE_FLAGS) -c -o $@ $< | 56 | $(CXX) $(CXXFLAGS) $(COMPILE_FLAGS) -c -o $@ $< |
| @@ -46,7 +58,3 @@ $(BUILD)/%.o: %.cpp | |||
| 46 | $(BUILD)/minigolf: $(OBJECTS) | 58 | $(BUILD)/minigolf: $(OBJECTS) |
| 47 | @mkdir -p $(dir $@) | 59 | @mkdir -p $(dir $@) |
| 48 | $(CXX) $(CXXFLAGS) -o $@ -Wl,--start-group $+ -Wl,--end-group $(LINK_FLAGS) | 60 | $(CXX) $(CXXFLAGS) -o $@ -Wl,--start-group $+ -Wl,--end-group $(LINK_FLAGS) |
| 49 | |||
| 50 | $(BUILD)/%.bin: %.hex | ||
| 51 | @mkdir -p $(dir $@) | ||
| 52 | $(SED) -e "s/\\s*#.*//" $< | $(XXD) -r -p > $@ | ||
diff --git a/image.hex b/image.hex new file mode 100644 index 0000000..6c7573e --- /dev/null +++ b/image.hex | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | 0001 0002 0004 | ||
| 2 | 0008 0010 0020 | ||
| 3 | 0040 0080 0100 | ||
| 4 | 0200 0400 0800 | ||
diff --git a/isa/checker.cpp b/isa/checker.cpp index 604279a..05b59a9 100644 --- a/isa/checker.cpp +++ b/isa/checker.cpp | |||
| @@ -10,7 +10,7 @@ void checker::execute() { | |||
| 10 | // check for interrupt | 10 | // check for interrupt |
| 11 | } | 11 | } |
| 12 | ctlregs[INT_ENABLE] = (int_enable_delay << 1) | int_enable_delay; | 12 | ctlregs[INT_ENABLE] = (int_enable_delay << 1) | int_enable_delay; |
| 13 | auto inst = decode(ctlregs[DATA_INSTRUCTION_FIELD_BUFFER], | 13 | inst = decode(ctlregs[DATA_INSTRUCTION_FIELD_BUFFER], |
| 14 | pc, | 14 | pc, |
| 15 | mem.fetch(pc)); | 15 | mem.fetch(pc)); |
| 16 | auto next_pc = inst.next_pc; | 16 | auto next_pc = inst.next_pc; |
diff --git a/isa/checker.h b/isa/checker.h index 6aae3ff..70393b6 100644 --- a/isa/checker.h +++ b/isa/checker.h | |||
| @@ -1,19 +1,46 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include <array> | 3 | #include <array> |
| 4 | #include <map> | ||
| 4 | 5 | ||
| 5 | #include "isa/isa.h" | 6 | #include "isa/isa.h" |
| 6 | 7 | ||
| 7 | struct funcmem { | 8 | struct funcmem { |
| 8 | unsigned int fetch(unsigned int address); | 9 | static constexpr unsigned int PAGE_BYTES_LOG2 = 20; |
| 9 | void store(unsigned int address, unsigned int value); | 10 | static constexpr unsigned int PAGE_BYTES = 1 << PAGE_BYTES_LOG2; |
| 11 | static constexpr unsigned int PAGE_BYTE_OFFSET_MASK = PAGE_BYTES - 1; | ||
| 12 | |||
| 13 | typedef std::array<unsigned int, PAGE_BYTES> page; | ||
| 14 | |||
| 15 | std::map<unsigned int, page> image; | ||
| 16 | |||
| 17 | unsigned int fetch(unsigned int address) const { | ||
| 18 | auto page_address = address >> PAGE_BYTES_LOG2; | ||
| 19 | auto page_offset = address & PAGE_BYTE_OFFSET_MASK; | ||
| 20 | if (auto p = image.find(page_address); p != image.end()) { | ||
| 21 | const auto &page = p->second; | ||
| 22 | return page[page_offset]; | ||
| 23 | } | ||
| 24 | return 0; | ||
| 25 | } | ||
| 26 | |||
| 27 | void store(unsigned int address, unsigned int value) { | ||
| 28 | auto page_address = address >> PAGE_BYTES_LOG2; | ||
| 29 | auto page_offset = address & PAGE_BYTE_OFFSET_MASK; | ||
| 30 | auto [p, emplaced] = image.try_emplace(page_address); | ||
| 31 | auto &page = p->second; | ||
| 32 | if (emplaced) | ||
| 33 | page.fill(0); | ||
| 34 | page[page_offset] = value; | ||
| 35 | } | ||
| 10 | }; | 36 | }; |
| 11 | 37 | ||
| 12 | struct checker { | 38 | struct checker { |
| 13 | unsigned int acc = 0; | 39 | unsigned int acc = 0; |
| 14 | unsigned int link = 0; | 40 | unsigned int link = 0; |
| 15 | unsigned int pc = 0; | 41 | unsigned int pc = 00200; |
| 16 | std::array<unsigned int, NUM_CTLREGS> ctlregs; | 42 | std::array<unsigned int, NUM_CTLREGS> ctlregs; |
| 43 | instruction_context inst; | ||
| 17 | bool halted = false; | 44 | bool halted = false; |
| 18 | funcmem mem; | 45 | funcmem mem; |
| 19 | void execute(); | 46 | void execute(); |
diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..bc17427 --- /dev/null +++ b/main.cpp | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | #include <arpa/inet.h> | ||
| 2 | #include <cstdint> | ||
| 3 | #include <fmt/format.h> | ||
| 4 | #include <iostream> | ||
| 5 | |||
| 6 | #include "isa/checker.h" | ||
| 7 | |||
| 8 | extern std::uint16_t _binary_build___image_bin_start[]; | ||
| 9 | extern std::uint16_t _binary_build___image_bin_end[]; | ||
| 10 | |||
| 11 | int main(int argc, const char *argv[]) { | ||
| 12 | checker checker; | ||
| 13 | |||
| 14 | unsigned int address = 0; | ||
| 15 | for (auto *src = _binary_build___image_bin_start; src < _binary_build___image_bin_end; ++src, ++address) { | ||
| 16 | auto word = ntohs(*src); | ||
| 17 | std::cout << fmt::format("mem[{:04o}] = {:04o}\n", address, word); | ||
| 18 | checker.mem.store(address, word); | ||
| 19 | } | ||
| 20 | |||
| 21 | while (!checker.halted) { | ||
| 22 | std::cout << fmt::format("{:04o}: ", checker.pc); | ||
| 23 | checker.execute(); | ||
| 24 | std::cout << fmt::format("acc={:04o}\n", checker.acc); | ||
| 25 | } | ||
| 26 | |||
| 27 | return 0; | ||
| 28 | } | ||
diff --git a/minigolf b/minigolf new file mode 120000 index 0000000..b6cb41a --- /dev/null +++ b/minigolf | |||
| @@ -0,0 +1 @@ | |||
| build/minigolf \ No newline at end of file | |||
