mirror of
https://github.com/pevans/erc-c.git
synced 2025-01-02 09:29:58 +00:00
Small bug in the jump label code for IND
This also required a rethink on some core functions which now needed to know about the memory segment; and further changes in the unit-testing code on the disassembly suite was also necessary.
This commit is contained in:
parent
7e142e2736
commit
b42d5370aa
@ -11,7 +11,7 @@ extern void mos6502_dis_instruction(FILE *, int);
|
||||
extern void mos6502_dis_jump_label(vm_16bit, vm_segment *, int, int);
|
||||
extern void mos6502_dis_jump_unlabel(int);
|
||||
extern void mos6502_dis_label(FILE *, int);
|
||||
extern void mos6502_dis_operand(FILE *, int, int, vm_16bit);
|
||||
extern void mos6502_dis_operand(FILE *, vm_segment *, int, int, vm_16bit);
|
||||
extern void mos6502_dis_scan(FILE *, vm_segment *, int, int);
|
||||
|
||||
#endif
|
||||
|
@ -79,9 +79,14 @@ static char *instruction_strings[] = {
|
||||
* type.
|
||||
*/
|
||||
void
|
||||
mos6502_dis_operand(FILE *stream, int address, int addr_mode, vm_16bit value)
|
||||
mos6502_dis_operand(FILE *stream,
|
||||
vm_segment *segment,
|
||||
int address,
|
||||
int addr_mode,
|
||||
vm_16bit value)
|
||||
{
|
||||
int rel_address;
|
||||
int ind_address;
|
||||
|
||||
switch (addr_mode) {
|
||||
case ACC:
|
||||
@ -101,8 +106,10 @@ mos6502_dis_operand(FILE *stream, int address, int addr_mode, vm_16bit value)
|
||||
case IMP:
|
||||
break;
|
||||
case IND:
|
||||
if (jump_table[value]) {
|
||||
mos6502_dis_label(stream, value);
|
||||
ind_address = vm_segment_get(segment, value) << 8;
|
||||
ind_address |= vm_segment_get(segment, value + 1);
|
||||
if (jump_table[ind_address]) {
|
||||
mos6502_dis_label(stream, ind_address);
|
||||
} else {
|
||||
fprintf(stream, "($%04X)", value);
|
||||
}
|
||||
@ -289,7 +296,7 @@ mos6502_dis_opcode(FILE *stream, vm_segment *segment, int address)
|
||||
fprintf(stream, " ");
|
||||
|
||||
// Print out the operand given the proper address mode.
|
||||
mos6502_dis_operand(stream, address, addr_mode, operand);
|
||||
mos6502_dis_operand(stream, segment, address, addr_mode, operand);
|
||||
}
|
||||
|
||||
// And let's terminate the line.
|
||||
|
@ -15,6 +15,8 @@ static char buf[BUFSIZ];
|
||||
* code into.
|
||||
*/
|
||||
static FILE *stream = NULL;
|
||||
static vm_segment *segment = NULL;
|
||||
|
||||
|
||||
static void
|
||||
setup()
|
||||
@ -35,12 +37,15 @@ setup()
|
||||
// check with Criterion. Uh, unless we blow out the buffer size...
|
||||
// don't do that :D
|
||||
setvbuf(stream, buf, _IOFBF, 256);
|
||||
|
||||
segment = vm_segment_create(65536);
|
||||
}
|
||||
|
||||
static void
|
||||
teardown()
|
||||
{
|
||||
fclose(stream);
|
||||
vm_segment_free(segment);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -66,50 +71,53 @@ TestSuite(mos6502_dis, .init = setup, .fini = teardown);
|
||||
|
||||
Test(mos6502_dis, operand)
|
||||
{
|
||||
mos6502_dis_operand(stream, 0, ABS, 0x1234);
|
||||
mos6502_dis_operand(stream, segment, 0, ABS, 0x1234);
|
||||
assert_buf("$1234");
|
||||
mos6502_dis_operand(stream, 0, ABX, 0x1234);
|
||||
mos6502_dis_operand(stream, segment, 0, ABX, 0x1234);
|
||||
assert_buf("$1234,X");
|
||||
mos6502_dis_operand(stream, 0, ABY, 0x1234);
|
||||
mos6502_dis_operand(stream, segment, 0, ABY, 0x1234);
|
||||
assert_buf("$1234,Y");
|
||||
mos6502_dis_operand(stream, 0, IMM, 0x12);
|
||||
mos6502_dis_operand(stream, segment, 0, IMM, 0x12);
|
||||
assert_buf("#$12");
|
||||
|
||||
vm_segment_set(segment, 0x1234, 0x33);
|
||||
vm_segment_set(segment, 0x1235, 0x48);
|
||||
|
||||
// For JMPs and JSRs (and BRKs), this should be a label and not a
|
||||
// literal value. So we need to test both the literal and
|
||||
// jump-labeled version.
|
||||
mos6502_dis_operand(stream, 0, IND, 0x1234);
|
||||
mos6502_dis_operand(stream, segment, 0, IND, 0x1234);
|
||||
assert_buf("($1234)");
|
||||
mos6502_dis_jump_label(0x1234, 0, IND);
|
||||
mos6502_dis_operand(stream, 0, IND, 0x1234);
|
||||
assert_buf("ADDR_4660"); // = 0x1234
|
||||
mos6502_dis_jump_label(0x1234, segment, 0, IND);
|
||||
mos6502_dis_operand(stream, segment, 0, IND, 0x1234);
|
||||
assert_buf("ADDR_13128"); // = 0x1234
|
||||
|
||||
// Let's undo our label above...
|
||||
mos6502_dis_jump_unlabel(0x1234);
|
||||
|
||||
mos6502_dis_operand(stream, 0, IDX, 0x12);
|
||||
mos6502_dis_operand(stream, segment, 0, IDX, 0x12);
|
||||
assert_buf("($12,X)");
|
||||
mos6502_dis_operand(stream, 0, IDY, 0x34);
|
||||
mos6502_dis_operand(stream, segment, 0, IDY, 0x34);
|
||||
assert_buf("($34),Y");
|
||||
mos6502_dis_operand(stream, 0, ZPG, 0x34);
|
||||
mos6502_dis_operand(stream, segment, 0, ZPG, 0x34);
|
||||
assert_buf("$34");
|
||||
mos6502_dis_operand(stream, 0, ZPX, 0x34);
|
||||
mos6502_dis_operand(stream, segment, 0, ZPX, 0x34);
|
||||
assert_buf("$34,X");
|
||||
mos6502_dis_operand(stream, 0, ZPY, 0x34);
|
||||
mos6502_dis_operand(stream, segment, 0, ZPY, 0x34);
|
||||
assert_buf("$34,Y");
|
||||
|
||||
// These should both end up printing nothing
|
||||
mos6502_dis_operand(stream, 0, ACC, 0);
|
||||
mos6502_dis_operand(stream, segment, 0, ACC, 0);
|
||||
assert_buf("");
|
||||
mos6502_dis_operand(stream, 0, IMP, 0);
|
||||
mos6502_dis_operand(stream, segment, 0, IMP, 0);
|
||||
assert_buf("");
|
||||
|
||||
// Test a forward jump (operand < 128)
|
||||
mos6502_dis_operand(stream, 500, REL, 52);
|
||||
mos6502_dis_operand(stream, segment, 500, REL, 52);
|
||||
assert_buf("ADDR_552");
|
||||
|
||||
// Test a backward jump (operand >= 128)
|
||||
mos6502_dis_operand(stream, 500, REL, 152);
|
||||
mos6502_dis_operand(stream, segment, 500, REL, 152);
|
||||
assert_buf("ADDR_396");
|
||||
}
|
||||
|
||||
@ -214,10 +222,6 @@ Test(mos6502_dis, opcode)
|
||||
|
||||
Test(mos6502_dis, scan)
|
||||
{
|
||||
vm_segment *segment;
|
||||
|
||||
segment = vm_segment_create(1000);
|
||||
|
||||
vm_segment_set(segment, 0, 0x29); // AND (imm)
|
||||
vm_segment_set(segment, 1, 0x38);
|
||||
vm_segment_set(segment, 2, 0x88); // DEY (imp)
|
||||
@ -236,19 +240,22 @@ Test(mos6502_dis, scan)
|
||||
Test(mos6502_dis, jump_label)
|
||||
{
|
||||
cr_assert_eq(mos6502_dis_is_jump_label(123), false);
|
||||
|
||||
vm_segment_set(segment, 123, 0);
|
||||
vm_segment_set(segment, 124, 5);
|
||||
|
||||
mos6502_dis_jump_label(123, 0, IND);
|
||||
cr_assert_eq(mos6502_dis_is_jump_label(123), true);
|
||||
mos6502_dis_jump_label(123, segment, 0, IND);
|
||||
cr_assert_eq(mos6502_dis_is_jump_label(5), true);
|
||||
mos6502_dis_jump_unlabel(123);
|
||||
cr_assert_eq(mos6502_dis_is_jump_label(123), false);
|
||||
|
||||
// Testing forward relative
|
||||
mos6502_dis_jump_label(123, 10, REL);
|
||||
mos6502_dis_jump_label(123, segment, 10, REL);
|
||||
cr_assert_eq(mos6502_dis_is_jump_label(123 + 10), true);
|
||||
mos6502_dis_jump_unlabel(123 + 10);
|
||||
|
||||
// Testing backward relative
|
||||
mos6502_dis_jump_label(133, 1000, REL);
|
||||
mos6502_dis_jump_label(133, segment, 1000, REL);
|
||||
cr_assert_eq(mos6502_dis_is_jump_label(133 + 1000 - 256), true);
|
||||
mos6502_dis_jump_unlabel(133 + 1000 - 256);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user