mirror of
https://github.com/rkujawa/rk65c02.git
synced 2025-04-09 12:38:19 +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_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_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;
|
||||
}
|
||||
|
||||
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
|
||||
disassemble(bus_t *b, uint16_t addr)
|
||||
{
|
||||
|
@ -41,13 +41,6 @@ struct instrdef {
|
||||
|
||||
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);
|
||||
instrdef_t instruction_decode(uint8_t);
|
||||
void instruction_print(instruction_t *);
|
||||
@ -64,11 +57,4 @@ void program_counter_increment(rk65c02emu_t *, instrdef_t *);
|
||||
bool instruction_modify_pc(instrdef_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_ */
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "bus.h"
|
||||
#include "rk65c02.h"
|
||||
#include "assembler.h"
|
||||
#include "instruction.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "bus.h"
|
||||
#include "rk65c02.h"
|
||||
#include "assembler.h"
|
||||
#include "instruction.h"
|
||||
#include "debug.h"
|
||||
#include "utils.h"
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "bus.h"
|
||||
#include "rk65c02.h"
|
||||
#include "assembler.h"
|
||||
#include "instruction.h"
|
||||
#include "debug.h"
|
||||
#include "log.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user