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]
add r0, r0, VCD
mov r1, [KBC_CODE]
mov r1, [KBD_CODE]
cmp r1, 44 ; spacebar
mov r2, rfl
and r2, r2, FL_EQ

View File

@ -12,6 +12,7 @@
#include <ios>
#include <memory>
#include <print>
#include <string>
#include <string_view>
#include <unordered_map>
#include <utility>
@ -100,7 +101,7 @@ auto Assembler::assemble_file()
}
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()) {
auto stmt = parser.parse_align();
@ -153,6 +154,11 @@ auto Assembler::assemble_file()
parser.try_recover();
continue;
}
if (line->labels) {
define_labels(*line->labels);
}
lines.push_back(std::move(line));
}
}
@ -165,33 +171,36 @@ auto Assembler::assemble_file()
m_second_pass = true;
for (const auto& line : lines) {
std::println("[{}] = {}", m_builder.ip(), line->ident);
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);
}
void Assembler::assemble_define_labels(const std::vector<Label>& labels)
void Assembler::define_labels(const std::vector<Label>& labels)
{
for (const auto& label : labels) {
if (label.is_local) {
m_sublabels[label.ident] = m_builder.ip();
m_sublabels[label_ident(label)] = m_builder.ip();
} else {
m_sublabels.clear();
m_syms[label.ident] = m_builder.ip();
m_superlabel = label.ident;
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 {
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());
case Expr::Ty::Mem:
case Expr::Ty::MemWord:
return eval_operand_mem(expr);
return eval_operand_mem(*expr.as_unary());
case Expr::Ty::MemByte: {
auto evaled = eval_operand_mem(expr);
auto evaled = eval_operand_mem(*expr.as_unary());
switch (evaled->ty) {
case EOT::MemWordImm:
evaled->ty = EOT::MemByteImm;
@ -587,7 +596,7 @@ auto Assembler::eval_operand(const Expr& expr) -> std::unique_ptr<EvaledOperand>
evaled->ty = EOT::MemByteReg;
break;
default:
break;
assert(false && "should be either of the above");
}
return evaled;
}
@ -631,7 +640,8 @@ auto Assembler::eval_operand_mem(const Expr& expr)
expr.loc, EOT::MemWordImm, op->as_imm());
}
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::Mem:
case Expr::Ty::MemByte:
@ -704,7 +714,8 @@ auto Assembler::eval_operand_to_imm(const Expr& expr)
auto loc = expr.loc;
switch (expr.ty) {
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) {
error(expr.loc,
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);
}
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) {
error(expr.loc,
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);
}
case Expr::Ty::Reg:
@ -908,7 +920,9 @@ auto Parser::parse_line() -> std::unique_ptr<Line>
error(current_loc(), "expected identifier");
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();
if (not eat(':')) {

View File

@ -210,15 +210,18 @@ namespace asmer {
auto assemble_file()
-> 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
{
return not m_failed;
}
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_mem(const Expr& expr)
-> std::unique_ptr<EvaledOperand>;
@ -237,8 +240,9 @@ namespace asmer {
std::string_view m_text;
std::vector<uint8_t> m_program;
Builder m_builder;
std::unordered_map<std::string_view, uint16_t> m_syms {};
std::unordered_map<std::string_view, uint16_t> m_sublabels {};
std::unordered_map<std::string, uint16_t> m_syms {};
std::string m_superlabel {};
std::unordered_map<std::string, uint16_t> m_sublabels {};
bool m_second_pass = false;
bool m_failed = false;
};

View File

@ -53,7 +53,8 @@ private:
class FileDisk final : public BlockDevice {
public:
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) {
throw std::invalid_argument(std::format(

View File

@ -29,6 +29,29 @@ int main(int argc, char** argv)
} else {
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);
vm.run();
}