This commit is contained in:
sfja 2026-01-24 01:32:29 +01:00
parent 680e952d04
commit 19f68cc6ac
5 changed files with 72 additions and 30 deletions

View File

@ -51,7 +51,7 @@ key_press_int:
mov r0, [0x600] mov r0, [0x600]
add r0, r0, VCD add r0, r0, VCD
mov r1, [KBC_CODE] mov r1, [KBD_CODE]
cmp r1, 44 ; spacebar cmp r1, 44 ; spacebar
mov r2, rfl mov r2, rfl
and r2, r2, FL_EQ and r2, r2, FL_EQ

View File

@ -12,6 +12,7 @@
#include <ios> #include <ios>
#include <memory> #include <memory>
#include <print> #include <print>
#include <string>
#include <string_view> #include <string_view>
#include <unordered_map> #include <unordered_map>
#include <utility> #include <utility>
@ -100,7 +101,7 @@ auto Assembler::assemble_file()
} }
assert(value->ty == EOT::Imm); assert(value->ty == EOT::Imm);
m_syms[stmt->ident] = value->as_imm(); m_syms[std::string(stmt->ident)] = value->as_imm();
} else if (parser.next_is_align()) { } else if (parser.next_is_align()) {
auto stmt = parser.parse_align(); auto stmt = parser.parse_align();
@ -153,6 +154,11 @@ auto Assembler::assemble_file()
parser.try_recover(); parser.try_recover();
continue; continue;
} }
if (line->labels) {
define_labels(*line->labels);
}
lines.push_back(std::move(line)); lines.push_back(std::move(line));
} }
} }
@ -165,33 +171,36 @@ auto Assembler::assemble_file()
m_second_pass = true; m_second_pass = true;
for (const auto& line : lines) { for (const auto& line : lines) {
std::println("[{}] = {}", m_builder.ip(), line->ident);
assemble_line(*line); assemble_line(*line);
} }
for (size_t i = 0; i < 64; i += 4) {
std::println("{:02x} {:02x} {:02x} {:02x}",
m_program[i],
m_program[i + 1],
m_program[i + 2],
m_program[i + 3]);
}
return std::move(m_program); return std::move(m_program);
} }
void Assembler::assemble_define_labels(const std::vector<Label>& labels) void Assembler::define_labels(const std::vector<Label>& labels)
{ {
for (const auto& label : labels) { for (const auto& label : labels) {
if (label.is_local) { if (label.is_local) {
m_sublabels[label.ident] = m_builder.ip(); m_sublabels[label_ident(label)] = m_builder.ip();
} else { } else {
m_sublabels.clear(); m_superlabel = label.ident;
m_syms[label.ident] = m_builder.ip(); m_syms[std::string(label.ident)] = m_builder.ip();
} }
} }
} }
auto Assembler::label_ident(const Label& label) const -> std::string
{
if (not label.is_local)
return std::string(label.ident);
return sublabel_ident(label.ident);
}
auto Assembler::sublabel_ident(std::string_view ident) const -> std::string
{
return std::format("{}{}", m_superlabel, ident);
}
namespace { namespace {
enum class Mnemonic { enum class Mnemonic {
@ -576,9 +585,9 @@ auto Assembler::eval_operand(const Expr& expr) -> std::unique_ptr<EvaledOperand>
return std::make_unique<EO>(loc, EOT::Str, expr.as_str()); return std::make_unique<EO>(loc, EOT::Str, expr.as_str());
case Expr::Ty::Mem: case Expr::Ty::Mem:
case Expr::Ty::MemWord: case Expr::Ty::MemWord:
return eval_operand_mem(expr); return eval_operand_mem(*expr.as_unary());
case Expr::Ty::MemByte: { case Expr::Ty::MemByte: {
auto evaled = eval_operand_mem(expr); auto evaled = eval_operand_mem(*expr.as_unary());
switch (evaled->ty) { switch (evaled->ty) {
case EOT::MemWordImm: case EOT::MemWordImm:
evaled->ty = EOT::MemByteImm; evaled->ty = EOT::MemByteImm;
@ -587,7 +596,7 @@ auto Assembler::eval_operand(const Expr& expr) -> std::unique_ptr<EvaledOperand>
evaled->ty = EOT::MemByteReg; evaled->ty = EOT::MemByteReg;
break; break;
default: default:
break; assert(false && "should be either of the above");
} }
return evaled; return evaled;
} }
@ -631,7 +640,8 @@ auto Assembler::eval_operand_mem(const Expr& expr)
expr.loc, EOT::MemWordImm, op->as_imm()); expr.loc, EOT::MemWordImm, op->as_imm());
} }
case Expr::Ty::Reg: case Expr::Ty::Reg:
return std::make_unique<EO>(expr.loc, EOT::Reg, expr.as_reg()); return std::make_unique<EO>(
expr.loc, EOT::MemWordReg, expr.as_reg());
case Expr::Ty::Str: case Expr::Ty::Str:
case Expr::Ty::Mem: case Expr::Ty::Mem:
case Expr::Ty::MemByte: case Expr::Ty::MemByte:
@ -704,7 +714,8 @@ auto Assembler::eval_operand_to_imm(const Expr& expr)
auto loc = expr.loc; auto loc = expr.loc;
switch (expr.ty) { switch (expr.ty) {
case Expr::Ty::Ident: { case Expr::Ty::Ident: {
if (!m_syms.contains(expr.as_ident())) { auto ident = std::string(expr.as_ident());
if (!m_syms.contains(ident)) {
if (m_second_pass) { if (m_second_pass) {
error(expr.loc, error(expr.loc,
std::format( std::format(
@ -715,11 +726,12 @@ auto Assembler::eval_operand_to_imm(const Expr& expr)
} }
} }
auto value = m_syms[expr.as_ident()]; auto value = m_syms[ident];
return std::make_unique<EO>(loc, EOT::Imm, value); return std::make_unique<EO>(loc, EOT::Imm, value);
} }
case Expr::Ty::SubLabel: { case Expr::Ty::SubLabel: {
if (!m_sublabels.contains(expr.as_ident())) { auto ident = sublabel_ident(expr.as_ident());
if (!m_sublabels.contains(ident)) {
if (m_second_pass) { if (m_second_pass) {
error(expr.loc, error(expr.loc,
std::format( std::format(
@ -730,7 +742,7 @@ auto Assembler::eval_operand_to_imm(const Expr& expr)
} }
} }
auto value = m_sublabels[expr.as_ident()]; auto value = m_sublabels[ident];
return std::make_unique<EO>(loc, EOT::Imm, value); return std::make_unique<EO>(loc, EOT::Imm, value);
} }
case Expr::Ty::Reg: case Expr::Ty::Reg:
@ -908,7 +920,9 @@ auto Parser::parse_line() -> std::unique_ptr<Line>
error(current_loc(), "expected identifier"); error(current_loc(), "expected identifier");
return nullptr; return nullptr;
} }
ident = m_tok.text; ident = is_local
? std::string_view(m_tok.text.data() - 1, m_tok.text.size() + 1)
: m_tok.text;
step(); step();
if (not eat(':')) { if (not eat(':')) {

View File

@ -210,15 +210,18 @@ namespace asmer {
auto assemble_file() auto assemble_file()
-> std::expected<std::vector<uint8_t>, std::string>; -> std::expected<std::vector<uint8_t>, std::string>;
void assemble_define_labels(const std::vector<Label>& labels);
void assemble_line(const Line& line);
auto ok() const -> bool auto ok() const -> bool
{ {
return not m_failed; return not m_failed;
} }
private: private:
void define_labels(const std::vector<Label>& labels);
void assemble_line(const Line& line);
auto label_ident(const Label& label) const -> std::string;
auto sublabel_ident(std::string_view ident) const -> std::string;
auto eval_operand(const Expr& expr) -> std::unique_ptr<EvaledOperand>; auto eval_operand(const Expr& expr) -> std::unique_ptr<EvaledOperand>;
auto eval_operand_mem(const Expr& expr) auto eval_operand_mem(const Expr& expr)
-> std::unique_ptr<EvaledOperand>; -> std::unique_ptr<EvaledOperand>;
@ -237,8 +240,9 @@ namespace asmer {
std::string_view m_text; std::string_view m_text;
std::vector<uint8_t> m_program; std::vector<uint8_t> m_program;
Builder m_builder; Builder m_builder;
std::unordered_map<std::string_view, uint16_t> m_syms {}; std::unordered_map<std::string, uint16_t> m_syms {};
std::unordered_map<std::string_view, uint16_t> m_sublabels {}; std::string m_superlabel {};
std::unordered_map<std::string, uint16_t> m_sublabels {};
bool m_second_pass = false; bool m_second_pass = false;
bool m_failed = false; bool m_failed = false;
}; };

View File

@ -53,7 +53,8 @@ private:
class FileDisk final : public BlockDevice { class FileDisk final : public BlockDevice {
public: public:
explicit FileDisk(fs::path file_path) explicit FileDisk(fs::path file_path)
: m_file(file_path, std::ios_base::binary) : m_file(file_path,
std::ios_base::binary | std::ios_base::in | std::ios_base::out)
{ {
if (not m_file) { if (not m_file) {
throw std::invalid_argument(std::format( throw std::invalid_argument(std::format(

View File

@ -29,6 +29,29 @@ int main(int argc, char** argv)
} else { } else {
auto disk = FileDisk(argv[1]); auto disk = FileDisk(argv[1]);
auto memory_disk = MemoryDisk(128);
make_program(memory_disk.data());
auto file_block = std::vector<uint8_t>(BlockDevice::block_size);
disk.read(file_block.data(), 0);
auto memory_block = std::vector<uint8_t>(BlockDevice::block_size);
memory_disk.read(memory_block.data(), 0);
std::println("file memory");
for (size_t i = 0; i < 64; i += 4) {
std::println(
"{:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}",
file_block[i],
file_block[i + 1],
file_block[i + 2],
file_block[i + 3],
memory_block[i],
memory_block[i + 1],
memory_block[i + 2],
memory_block[i + 3]);
}
auto vm = VM(*device, disk); auto vm = VM(*device, disk);
vm.run(); vm.run();
} }