📄 xds510.cpp
字号:
int cmd = (value >> 12) & 0xF;
switch (cmd)
{
case 4:
case 5:
if (value & 0x0080)
{
/* if (low_register_val[0xB] >> 12 == 3)
{
fprintf(debugf, "i %0*x o %0*x\nExecute %04X, count = %i ",
(databitsp + 3) / 4, indata & ~(-1 << (indatap - 16)),
(databitsp + 3) / 4, outdata >> 16,
low_register_val[0xB], counter1 - 15);
fflush(debugf);
outdata = 0;
indata = 0;
indatap = 0;
outdatap = 0;
databitsp = counter1 - 15;
}*/
active_command = 1;
TRACE("Just activated a command.\n");
}
if (value & 0xF7F)
{
FIXME("Unsupported bits in minor command 4\n");
}
break;
case 6:
if (value & 0x001)
{
counter1 = counter1_update;
TRACE("counter1 loaded with : %08x\n", counter1);
}
if (value & 0x004)
{
counter1_capture = counter1;
TRACE("counter1 captured with : %08x\n", counter1);
}
if (value & 0x040)
{
status_register[0] = 0xF; // ####
status_register[1] = (active_command ? 0x8000 : 0);
status_register[2] = tap_state & 0x7;
if (read_buffer_pos >= 16) status_register[2] |= 0x1000;
if (read_buffer_pos >= 32) status_register[2] |= 0x2000;
if (write_buffer_pos > 0) status_register[2] |= 0x0100;
if (write_buffer_pos > 16) status_register[2] |= 0x0200;
status_register[3] = 0;
}
if (value & (0x002 | 0x030 | 0xF88))
{
FIXME("Unsupported bits in minor command 6\n");
}
break;
case 7:
if (value & 0x0001)
{
XDS510_reset();
}
if (value & 0x0FFE)
{
FIXME("Unsupported bits in minor command 7\n");
}
break;
default:
FIXME(BTAB"Unknown minor command %04x\n", value);
}
TRACE(BTAB"minor_command(%04x)\n", value);
}
static int scannable_bits()
{
int rslt = counter1 + 1;
if (rslt > 32 - read_buffer_pos && (low_register_val[4] & 0x0400))
{
rslt = 32 - read_buffer_pos;
}
if (rslt > write_buffer_pos &&
(low_register_val[4] & 0x0300) == 0x0300)
{
rslt = write_buffer_pos;
}
return rslt;
}
static void shift_bit(int tdi0)
{
if (!(low_register_val[4] & 0x0080))
{
tdi0 = get_outbit();
}
TRACE("s4 : %04x tdi : %i w : %08x f : %04x r : %08x\n",
low_register_val[4], tdi0, write_buffer, fifo_buffer, read_buffer);
if (low_register_val[4] & 0x0400)
{
read_buffer = (read_buffer & ~(-1 << read_buffer_pos)) |
((fifo_buffer & 1) << read_buffer_pos);
read_buffer_pos++;
}
fifo_buffer >>= 1;
{
int mask = (low_register_val[4] & 0x0020) ? 0x80000000 : 0x8000;
if (tdi0)
fifo_buffer |= mask;
else
fifo_buffer &= ~mask;
}
if ((low_register_val[4] & 0x0300) == 0x0300)
{
write_buffer >>= 1;
write_buffer_pos--;
}
}
static void scan_bits(int pause_state)
{
int bits = scannable_bits();
if (bits > 0)
{
go_tap_state(pause_state);
io_cycle(1); // Switch to scan state
io_cycle(0);
while (bits > 1)
{
counter1--;
bits--;
shift_bit(io_cycle(0));
}
counter1--;
shift_bit(io_cycle(1)); // Return to pause state
io_cycle(0);
}
}
static void execute_command()
{
if (active_command)
{
int fcmd = low_register_val[0xB];
int cmd = (fcmd >> 12) & 0xF;
switch (cmd)
{
case 1:
TRACE("STATE command to TAP state %i.\n", fcmd & 0x7);
active_command = 0;
go_tap_state2(fcmd & 0x7);
if (fcmd & 0x0FF8)
{
FIXME("Unsupported bits in major command 1.\n");
}
break;
case 3:
scan_bits((fcmd & 0x0008) ? TAP_PAUSE_IR : TAP_PAUSE_DR);
if (fcmd & 0xF80)
{
FIXME("Unsupported bits in major command 3.\n");
}
if (counter1 < 0)
{
TRACE("SCAN command finished.\n");
go_tap_state(fcmd & 0x7);
active_command = 0;
read_buffer_pos = (read_buffer_pos + 15) & 0xFFF0;
write_buffer_pos &= 0xFFF0;
}
break;
default:
active_command = 0;
FIXME("Tried to execute unsupported major command %04x\n", fcmd);
break;
}
}
}
int XDS510_read(int port)
{
int retval = 0xFFFF;
TRACE("XDS510_read(%03x)\n", port);
switch (port)
{
case 0x18: // counter1 low
TRACE("Read counter1 capture low\n");
retval = counter1_capture & 0xFFFF;
break;
case 0x1A: // counter1 high
TRACE("Read counter1 capture high\n");
retval = (counter1_capture >> 16) & 0xFFFF;
break;
case 0x40C: // Read buffer
retval = read_buffer & 0xFFFF;
// outdata |= retval << outdatap;
// outdatap += 16;
read_buffer >>= 16;
read_buffer_pos -= 16;
TRACE("Read %04x from read buffer.\n", retval);
if (read_buffer_pos < 0)
{
FIXME("Read buffer underflow.\n");
read_buffer_pos = 0;
}
break;
case 0x800: // The interface word
/* if (read800)
{
fprintf(debugf, "\nread800 %i\n", interface_interrupt);
interface_interrupt = (interface_interrupt + 1) & 0x1FF;
}*/
retval = (((-INTERFACE_VERSION) & 0x7) << 5) |
/*(read800 && interface_interrupt == 0) |*/ 0x10 |
(!!interface_reset << 8);
/* if (retval & 0x0001)
FIXME("interrupt flag %i\n", interface_interrupt);
read800 = !read800;*/
break;
default:
if (port >= 0 && port < 2 * NUM_LOW_REGISTERS)
{
retval = low_register_val[port / 2];
}
else if (port >= 0x400 && port < 0x400 + 2 * NUM_STATUS_REGISTERS)
{
retval = status_register[(port - 0x400) / 2];
}
else
{
FIXME(BTAB"Unhandled port %03x.\n", port);
}
break;
}
execute_command();
/* if (port != 0x800)
read800 = 0;*/
TRACE("returning %04x\n\n", retval);
return retval;
}
void XDS510_write(int port, int value)
{
TRACE("XDS510_write(%03x, %04x)\n", port, value);
// read800 = 0;
if (port >= 0 && port < 2 * NUM_LOW_REGISTERS)
low_register_val[port / 2] = value & 0xFFFF;
switch (port)
{
case 0x0A: //Control 5
FIXME("Write of %04x to 00A -> emu = %i\n", value, !!(value & 0x0004));
xds510_io_write_trst(value & 0x0004);
go_tap_state(tap_state);
go_tap_state(tap_state);
break;
case 0x14: // Minor command
minor_command(value);
break;
case 0x8:
case 0x16: // Major command
// major_command(value); // #### Useless
break;
case 0x18: // Counter1 low
counter1_update = (counter1_update & 0xFFFF0000) | (value & 0xFFFF);
TRACE("Write counter1 update low. New value : %08x\n", counter1_update);
break;
case 0x1A: // Counter1 high
counter1_update = (counter1_update & 0xFFFF) | ((value & 0xFFFF) << 16);
TRACE("Write counter1 update high. New value : %08x\n", counter1_update);
break;
case 0x40E: // Write buffer
write_buffer = (value << write_buffer_pos) |
(write_buffer & ~(-1 << write_buffer_pos));
write_buffer_pos += 16;
TRACE("Wrote %04x to write buffer.\n", value);
TRACE("Total bits in buffer : %i\n", write_buffer_pos);
if (write_buffer_pos > 32)
{
WARN("Write buffer overflow.\n");
write_buffer_pos = 32;
}
// indata |= (value & 0xFFFF) << indatap;
// indatap += 16;
break;
case 0x800: // The interface word
if (!!(value & 0x100) != interface_reset)
{
interface_reset = !!(value & 0x100);
TRACE("New unknown pin value is %i\n", interface_reset);
// xds510_io_write_trst(!interface_reset);
}
break;
default:
FIXME(BTAB"Unhandled port %03x. (writing %4x)\n", port, value);
break;
}
execute_command();
TRACE("returning\n\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -