1
0
mirror of https://github.com/pevans/erc-c.git synced 2024-09-29 11:55:01 +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:
Peter Evans 2017-12-30 22:50:23 -06:00
parent 7e142e2736
commit b42d5370aa
3 changed files with 44 additions and 30 deletions

View File

@ -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

View File

@ -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.

View File

@ -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);
}