diff options
author | Thomas Voss <mail@thomasvoss.com> | 2024-02-14 00:43:35 +0100 |
---|---|---|
committer | Thomas Voss <mail@thomasvoss.com> | 2024-02-14 00:43:35 +0100 |
commit | 5d7ee4168b03ed7d95da3425d843bec5743eaeb6 (patch) | |
tree | 3b1c55880a91fde6e7570753b319df0383a35d62 /src/c8asm | |
parent | 4a039b51bba5ee384e921d4407b976f996546fce (diff) |
Align opcodes on even byte boundaries
Diffstat (limited to 'src/c8asm')
-rw-r--r-- | src/c8asm/assembler.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/src/c8asm/assembler.c b/src/c8asm/assembler.c index ea292b7..2e8693b 100644 --- a/src/c8asm/assembler.c +++ b/src/c8asm/assembler.c @@ -77,6 +77,8 @@ assemble(FILE *stream, struct ast ast) fwrite(&__x, 1, sizeof(__x), stream); \ } while (false) + bool pad = false; + da_foreach (&ast, node) { if (node->kind == D_LABEL) { struct label lbl = { @@ -96,6 +98,11 @@ assemble(FILE *stream, struct ast ast) if (node->kind != D_INSTR) unreachable(); + /* Instructions need to be 0-padded so they appear on an even byte + boundary. */ + if (node->instr.kind != I_DB && pad) + putchar(0); + switch (node->instr.kind) { case I_ADD_I_VX: PUT(0xF01E | (node->instr.args[0].val << 8)); @@ -124,6 +131,8 @@ assemble(FILE *stream, struct ast ast) case I_DB: da_foreach (&node->instr, byte) fputc(*byte, stream); + if (node->instr.len & 1) + pad = !pad; break; case I_DRW: PUT(0xD000 | (node->instr.args[0].val << 8) |