mirror of
https://github.com/rkujawa/rk65c02.git
synced 2024-06-08 06:29:30 +00:00
Split assembler-related things into separate file.
This commit is contained in:
parent
b7986df553
commit
1ec075518c
|
@ -1,7 +1,7 @@
|
||||||
#CLI=rk65c02cli
|
#CLI=rk65c02cli
|
||||||
#CLI_OBJS=rk65c02cli.o
|
#CLI_OBJS=rk65c02cli.o
|
||||||
|
|
||||||
LIB_OBJS=rk65c02.o bus.o instruction.o emulation.o debug.o device_ram.o device_fb.o device_serial.o log.o
|
LIB_OBJS=rk65c02.o bus.o instruction.o emulation.o debug.o device_ram.o device_fb.o device_serial.o log.o assembler.o
|
||||||
LIB_SO=librk65c02.so
|
LIB_SO=librk65c02.so
|
||||||
LIB_STATIC=librk65c02.a
|
LIB_STATIC=librk65c02.a
|
||||||
|
|
||||||
|
|
104
src/assembler.c
Normal file
104
src/assembler.c
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <gc/gc.h>
|
||||||
|
|
||||||
|
#include "bus.h"
|
||||||
|
#include "rk65c02.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "assembler.h"
|
||||||
|
#include "instruction.h"
|
||||||
|
|
||||||
|
assembler_t
|
||||||
|
assemble_init(bus_t *b, uint16_t pc)
|
||||||
|
{
|
||||||
|
assembler_t asmblr;
|
||||||
|
|
||||||
|
asmblr.bus = b;
|
||||||
|
asmblr.pc = pc;
|
||||||
|
|
||||||
|
return asmblr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
assemble_single_implied(assembler_t *a, const char *mnemonic)
|
||||||
|
{
|
||||||
|
return assemble_single(a, mnemonic, IMPLIED, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
assemble_single(assembler_t *a, const char *mnemonic, addressing_t mode, uint8_t op1, uint8_t op2)
|
||||||
|
{
|
||||||
|
uint8_t *asmbuf;
|
||||||
|
uint8_t bsize;
|
||||||
|
bool rv;
|
||||||
|
|
||||||
|
rv = assemble_single_buf(&asmbuf, &bsize, mnemonic, mode, op1, op2);
|
||||||
|
if (rv == false)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
rv = bus_load_buf(a->bus, a->pc, asmbuf, bsize);
|
||||||
|
a->pc += bsize;
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
assemble_single_buf_implied(uint8_t **buf, uint8_t *bsize, const char *mnemonic)
|
||||||
|
{
|
||||||
|
return assemble_single_buf(buf, bsize, mnemonic, IMPLIED, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
assemble_single_buf(uint8_t **buf, uint8_t *bsize, const char *mnemonic, addressing_t mode, uint8_t op1, uint8_t op2)
|
||||||
|
{
|
||||||
|
instrdef_t id;
|
||||||
|
uint8_t opcode;
|
||||||
|
bool found;
|
||||||
|
|
||||||
|
found = false;
|
||||||
|
opcode = 0;
|
||||||
|
|
||||||
|
/* find the opcode for given mnemonic and addressing mode */
|
||||||
|
while (opcode <= 0xFF) { /* this is stupid */
|
||||||
|
id = instruction_decode(opcode);
|
||||||
|
if ((strcmp(mnemonic, id.mnemonic) == 0) && (id.mode == mode)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
opcode++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
rk65c02_log(LOG_ERROR,
|
||||||
|
"Couldn't find opcode for mnemonic %s mode %x.",
|
||||||
|
mnemonic, mode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*bsize = id.size;
|
||||||
|
*buf = GC_MALLOC(id.size);
|
||||||
|
if(*buf == NULL) {
|
||||||
|
rk65c02_log(LOG_ERROR, "Error allocating assembly buffer.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill the buffer */
|
||||||
|
memset(*buf, 0, id.size);
|
||||||
|
(*buf)[0] = opcode;
|
||||||
|
/* XXX */
|
||||||
|
if (id.size > 1)
|
||||||
|
(*buf)[1] = op1;
|
||||||
|
if (id.size > 2)
|
||||||
|
(*buf)[2] = op2;
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
22
src/assembler.h
Normal file
22
src/assembler.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef _ASSEMBLER_H_
|
||||||
|
#define _ASSEMBLER_H_
|
||||||
|
|
||||||
|
#include "instruction.h"
|
||||||
|
#include "rk65c02.h"
|
||||||
|
|
||||||
|
struct assembler {
|
||||||
|
bus_t *bus;
|
||||||
|
uint16_t pc;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct assembler assembler_t;
|
||||||
|
|
||||||
|
bool assemble_single_buf_implied(uint8_t **, uint8_t *, const char *);
|
||||||
|
bool assemble_single_buf(uint8_t **, uint8_t *, const char *, addressing_t, uint8_t, uint8_t);
|
||||||
|
|
||||||
|
assembler_t assemble_init(bus_t *, uint16_t);
|
||||||
|
bool assemble_single(assembler_t *, const char *, addressing_t, uint8_t, uint8_t);
|
||||||
|
bool assemble_single_implied(assembler_t *, const char *);
|
||||||
|
|
||||||
|
#endif /* _ASSEMBLER_H_ */
|
||||||
|
|
|
@ -135,93 +135,6 @@ instruction_string_get(instruction_t *i)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
assembler_t
|
|
||||||
assemble_init(bus_t *b, uint16_t pc)
|
|
||||||
{
|
|
||||||
assembler_t asmblr;
|
|
||||||
|
|
||||||
asmblr.bus = b;
|
|
||||||
asmblr.pc = pc;
|
|
||||||
|
|
||||||
return asmblr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
assemble_single_implied(assembler_t *a, const char *mnemonic)
|
|
||||||
{
|
|
||||||
return assemble_single(a, mnemonic, IMPLIED, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
assemble_single(assembler_t *a, const char *mnemonic, addressing_t mode, uint8_t op1, uint8_t op2)
|
|
||||||
{
|
|
||||||
uint8_t *asmbuf;
|
|
||||||
uint8_t bsize;
|
|
||||||
bool rv;
|
|
||||||
|
|
||||||
rv = assemble_single_buf(&asmbuf, &bsize, mnemonic, mode, op1, op2);
|
|
||||||
if (rv == false)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
rv = bus_load_buf(a->bus, a->pc, asmbuf, bsize);
|
|
||||||
a->pc += bsize;
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
assemble_single_buf_implied(uint8_t **buf, uint8_t *bsize, const char *mnemonic)
|
|
||||||
{
|
|
||||||
return assemble_single_buf(buf, bsize, mnemonic, IMPLIED, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
assemble_single_buf(uint8_t **buf, uint8_t *bsize, const char *mnemonic, addressing_t mode, uint8_t op1, uint8_t op2)
|
|
||||||
{
|
|
||||||
instrdef_t id;
|
|
||||||
uint8_t opcode;
|
|
||||||
bool found;
|
|
||||||
|
|
||||||
found = false;
|
|
||||||
opcode = 0;
|
|
||||||
|
|
||||||
/* find the opcode for given mnemonic and addressing mode */
|
|
||||||
while (opcode <= 0xFF) { /* this is stupid */
|
|
||||||
id = instruction_decode(opcode);
|
|
||||||
if ((strcmp(mnemonic, id.mnemonic) == 0) && (id.mode == mode)) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
opcode++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
rk65c02_log(LOG_ERROR,
|
|
||||||
"Couldn't find opcode for mnemonic %s mode %x.",
|
|
||||||
mnemonic, mode);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
*bsize = id.size;
|
|
||||||
*buf = GC_MALLOC(id.size);
|
|
||||||
if(*buf == NULL) {
|
|
||||||
rk65c02_log(LOG_ERROR, "Error allocating assembly buffer.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fill the buffer */
|
|
||||||
memset(*buf, 0, id.size);
|
|
||||||
(*buf)[0] = opcode;
|
|
||||||
/* XXX */
|
|
||||||
if (id.size > 1)
|
|
||||||
(*buf)[1] = op1;
|
|
||||||
if (id.size > 2)
|
|
||||||
(*buf)[2] = op2;
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
disassemble(bus_t *b, uint16_t addr)
|
disassemble(bus_t *b, uint16_t addr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,13 +41,6 @@ struct instrdef {
|
||||||
|
|
||||||
typedef struct instrdef instrdef_t;
|
typedef struct instrdef instrdef_t;
|
||||||
|
|
||||||
struct assembler {
|
|
||||||
bus_t *bus;
|
|
||||||
uint16_t pc;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct assembler assembler_t;
|
|
||||||
|
|
||||||
instruction_t instruction_fetch(bus_t *, uint16_t);
|
instruction_t instruction_fetch(bus_t *, uint16_t);
|
||||||
instrdef_t instruction_decode(uint8_t);
|
instrdef_t instruction_decode(uint8_t);
|
||||||
void instruction_print(instruction_t *);
|
void instruction_print(instruction_t *);
|
||||||
|
@ -64,11 +57,4 @@ void program_counter_increment(rk65c02emu_t *, instrdef_t *);
|
||||||
bool instruction_modify_pc(instrdef_t *);
|
bool instruction_modify_pc(instrdef_t *);
|
||||||
void program_counter_branch(rk65c02emu_t *, int8_t);
|
void program_counter_branch(rk65c02emu_t *, int8_t);
|
||||||
|
|
||||||
bool assemble_single_buf_implied(uint8_t **, uint8_t *, const char *);
|
|
||||||
bool assemble_single_buf(uint8_t **, uint8_t *, const char *, addressing_t, uint8_t, uint8_t);
|
|
||||||
|
|
||||||
assembler_t assemble_init(bus_t *, uint16_t);
|
|
||||||
bool assemble_single(assembler_t *, const char *, addressing_t, uint8_t, uint8_t);
|
|
||||||
bool assemble_single_implied(assembler_t *, const char *);
|
|
||||||
|
|
||||||
#endif /* _INSTRUCTION_H_ */
|
#endif /* _INSTRUCTION_H_ */
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
#include "rk65c02.h"
|
#include "rk65c02.h"
|
||||||
|
#include "assembler.h"
|
||||||
#include "instruction.h"
|
#include "instruction.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
#include "rk65c02.h"
|
#include "rk65c02.h"
|
||||||
|
#include "assembler.h"
|
||||||
#include "instruction.h"
|
#include "instruction.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
#include "rk65c02.h"
|
#include "rk65c02.h"
|
||||||
|
#include "assembler.h"
|
||||||
#include "instruction.h"
|
#include "instruction.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user