g10/g1m bullshit

This commit is contained in:
Triss 2022-04-21 22:30:45 +02:00
parent 53b6034272
commit c4bb26ead1
11 changed files with 749 additions and 271 deletions

View File

@ -35,6 +35,8 @@ void cli_tool78_g10_ocdtest(void);
void cli_tool78_glitch_dump(void);
void cli_tool78_glitch_paramsearch(void);
void cli_tool78_glitch_ocd_dump(void);
void cli_tool78_glitch_param_g10(void);
void cli_tool78_glitch_ocd_g10(void);
static void adc_init_stuff() {
adc_init();
@ -80,6 +82,8 @@ static struct cli_cmd cmds[] = {
{ "g78dump", cli_tool78_glitch_dump },
{ "g78param", cli_tool78_glitch_paramsearch },
{ "g78ocd", cli_tool78_glitch_ocd_dump },
{ "g10param", cli_tool78_glitch_param_g10 },
{ "g10ocd", cli_tool78_glitch_ocd_g10 },
{ "zap", cli_dragonzap_test },

View File

@ -10,7 +10,15 @@ void cli_dragonzap_test(void);
void cli_dragonzap_test(void) {
zap_init_default();
zap_dac_set_enable(zap_dac_a | zap_dac_b);
#if 1 /* MCP48x2 */
zap_dac_set_mulx2(zap_dac_a | zap_dac_b);
#else
zap_dac_set_mulx2(0);
zap_dac_set_shutdown(false);
#endif
zap_max_use_vhi_jp300(true);
zap_max_set_inhibit(false);
sio_hw->gpio_oe_set = ZAP_GPIO_MASK;
sio_hw->gpio_clr = ZAP_GPIO_MASK;

View File

@ -18,6 +18,8 @@
void cli_tool78_glitch_dump(void);
void cli_tool78_glitch_paramsearch(void);
void cli_tool78_glitch_ocd_dump(void);
void cli_tool78_glitch_param_g10(void);
void cli_tool78_glitch_ocd_g10(void);
#define DUMP_OFFSET 0/*0xef000*/
#define DUMP_SIZE 1024/*65536*/
@ -45,7 +47,7 @@ static uint8_t databuf[DUMP_SIZE];
static struct glitch_param_randrange offset;
static struct glitch_param_adc length;
static bool glitch_init_core1_stuff(bool exttrig) {
static bool glitch_init_core1_stuff(bool exttrig, uint glitchpin) {
offset.min = 10*1000;
offset.max = 35433*1000;
length.min = 100;
@ -81,11 +83,12 @@ static bool glitch_init_core1_stuff(bool exttrig) {
// * with REGC, 10uF@VDD, long pulses: 0..3mV (strict upper limit)
// * 100uF@VDD: too much, even w/o REGC
.trigger_in_pin = -2,
.glitch_out_pin = GLITCH_OUT_PIN,
.glitch_out_pin = -2,//glitchpin,//GLITCH_OUT_PIN,
.trigger_in_polarity = glitch_positive,
.glitch_out_polarity = glitch_positive,
.impl = glitch_impl_pio,//core1,
};
gparam.glitch_out_pin = glitchpin;
gparam.offset_ns = (struct glitch_param){
.ud = &offset,
.getter = glitch_param_randrange_fn
@ -206,9 +209,9 @@ deinit_bad:
}
void cli_tool78_glitch_paramsearch(void) {
if (!glitch_init_core1_stuff(true)) {
if (!glitch_init_core1_stuff(true, GLITCH_OUT_PIN)) {
printf("bad glitcher params!\n");
while (1) asm volatile("");
return;
}
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
@ -361,14 +364,14 @@ do_reset_stuff:
}
void cli_tool78_glitch_ocd_dump(void) {
if (!glitch_init_core1_stuff(false)) {
if (!glitch_init_core1_stuff(false, GLITCH_OUT_PIN)) {
printf("bad glitcher params!\n");
while (1) asm volatile("");
return;
}
gpio_set_function(2, GPIO_FUNC_SIO);
/*gpio_set_function(2, GPIO_FUNC_SIO);
gpio_set_dir(2, GPIO_OUT);
gpio_put(2, false);
gpio_put(2, false);*/
//gpio_set_function(3, GPIO_FUNC_SIO);
//gpio_set_dir(3, GPIO_OUT);
@ -383,7 +386,7 @@ void cli_tool78_glitch_ocd_dump(void) {
restart:
//trl78_uart1_set_exclusive(true);
//tool78_hw_rl78_uart1.rx_set_stop_bit(false);
gpio_put(2, false);
//gpio_put(2, false);
/*glitch_disarm();
busy_wait_ms(40);*/
@ -456,7 +459,7 @@ do_reset_stuff:
goto restart;
success:;
gpio_put(2, true);
//gpio_put(2, true);
//busy_wait_ms(5);
// (02): read from above (checkbuf) code
// 03 06 18 00 df 03
@ -534,3 +537,319 @@ deinit_bad:
return;
}
static uint8_t DATA_G1M_paramtest[47] = {
0xcf, 0x77, 0x00, 0x00, 0xce, 0x00, 0x00, 0xcf, 0x30, 0x00, 0x00, 0xcf, 0x50,
0x00, 0x00, 0xcf, 0x60, 0x00, 0x7f, 0xcf, 0x20, 0xff, 0x00, 0xcf, 0xf0, 0x00,
0xe5, 0xcf, 0xf3, 0x00, 0x10, 0xce, 0x00, 0xff, 0x51, 0x48, 0xfc, 0xdc, 0xff,
0x0e, 0x51, 0x69, 0xfc, 0xdc, 0xff, 0x0e, 0xd7
};
void cli_tool78_glitch_param_g10(void) {
struct tool78_hw* hw = &tool78_hw_rl78g10_uart1;
zap_dac_set_enable(zap_dac_a | zap_dac_b);
#if 1 /* MCP48x2 */
zap_dac_set_mulx2(zap_dac_a | zap_dac_b);
#else
zap_dac_set_mulx2(0);
zap_dac_set_shutdown(false);
#endif
zap_max_use_vhi_jp300(true);
zap_max_set_inhibit(false);
if (!glitch_init_core1_stuff(true, GLITCH_OUT_PIN)) {
printf("bad glitcher params!\n");
return;
}
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
enum tool78_stat st;
int rr;
static uint8_t checkbuf[256];
bool first = true;
restart:
/*glitch_disarm();
busy_wait_ms(40);*/
st = tool78_init_ocd(hw, NULL, passwd);
if (st == 0xc3) {
printf("aa\n");
st = 0;
rr = tool78_hw_rl78_uart1.recv(1, (uint8_t*)&st, 120*1000);
printf("rr=%d\n", rr);
if (rr != 1) {
printf("aaaa\n");
goto do_reset_stuff;
}
}
//printf("result: 0x%02x ver=%04x\n", st, ver);
if (st != 0xf2 && st != 0xf0) {
printf("init: 0x%02x\n", st);
goto deinit_bad;
}
if (first) printf("result: 0x%02x\n", st);
// TODO: upload other code!
// can't write too much at 0xf07e0 as 0xf0800 and up contains OCD state,
// overwrite this and suddenly the OCD system resets itself
st = tool78_ocd_write(hw, 0x07e0,
sizeof(exec_jmp_to_ram), exec_jmp_to_ram);
//printf("write trampoline res 0x%02x\n", st);
if (st != 0) {
printf("trampoline write failed: %d\n", st);
goto deinit_bad;
}
st = tool78_ocd_write(hw, 0xf900,
sizeof(DATA_test_dbg__paramtest), DATA_test_dbg__paramtest);
//printf("write code res 0x%02x\n", st);
if (st != 0) {
printf("code write failed: %d\n", st);
goto deinit_bad;
}
st = tool78_ocd_exec(hw);
//printf("exec res 0x%02x\n", st);
if (st != 0) {
printf("exec failed: %d\n", st);
goto deinit_bad;
}
// test custom tool_tx call
/*rr = tool78_hw_rl78_uart1.recv(1, checkbuf, 1000);
printf("rr=%d\n", rr);
if (rr == 1) printf("0x%02x %c\n", stuff[0], stuff[0]);*/
// wait for completion
rr = hw->recv(2, checkbuf, 120*1000);
if (rr != 2) {
printf("exec code: no response :/ (%d)\n", rr);
goto deinit_bad;
}
if (checkbuf[0] != 'H' && checkbuf[1] != 'i') {
printf("bad response: %02x %02x\n", checkbuf[0], checkbuf[1]);
goto deinit_bad;
}
rr = hw->recv(256, checkbuf, 120*1000);
if (rr != 256) {
printf("exec code: no data sendback (%d)\n", rr);
goto deinit_bad;
}
for (size_t i = 0; i < 256; ++i) {
if (checkbuf[i] != (0xff^0xaa)) {
printf("bad value at index %zu: %02x\n", i, checkbuf[i]^0xaa);
goto deinit_bad;
}
}
if (first) printf("all set, let's go\n");
first = false;
while (true) {
glitch_arm();
rr = hw->recv(2, checkbuf, 120*1000);
glitch_disarm();
if (rr == 2 && (checkbuf[0] != 'H' || checkbuf[1] != 'i')) rr = 0;
if (rr == 2) {
rr = hw->recv(256, checkbuf, 120*1000);
}
if (rr <= 0) {
// timeout or something
printf("X");
hw->deinit();
goto do_reset_stuff;
} else {
int firstbad = -1, lastbad = -1;
for (int i = 0; i < rr; ++i) {
if (checkbuf[i] != (0xaa^0xff)) {
if (firstbad == -1) firstbad = i;
lastbad = i;
}
}
if (firstbad >= 0) {
volatile uint32_t
*off = (volatile uint32_t*)&glitch_param_cur.offset_ns.cur,
*len = (volatile uint32_t*)&glitch_param_cur.length_ns.cur;
printf("glitch first=%d last=%d off=%lu len=%lu rr=%d v=%02x\n",
firstbad, lastbad, *off, *len, rr, checkbuf[firstbad]^0xaa);
} else {
printf(".");
}
}
}
deinit_bad:
hw->deinit();
return;
do_reset_stuff:
hw->deinit();
// glitch for way too long to power cycle
sio_hw->gpio_set = 1u << GLITCH_OUT_PIN;
busy_wait_ms(16);
sio_hw->gpio_clr = 1u << GLITCH_OUT_PIN;
goto restart;
}
void cli_tool78_glitch_ocd_g10(void) {
struct tool78_hw* hw = &tool78_hw_rl78g10_uart1;
zap_dac_set_enable(zap_dac_a | zap_dac_b);
#if 1 /* MCP48x2 */
zap_dac_set_mulx2(zap_dac_a | zap_dac_b);
#else
zap_dac_set_mulx2(0);
zap_dac_set_shutdown(false);
#endif
zap_max_use_vhi_jp300(true);
zap_max_set_inhibit(false);
if (!glitch_init_core1_stuff(false, ZAP_GLITCH_OUT)) {
printf("bad glitcher params!\n");
return;
}
gpio_set_function(2, GPIO_FUNC_SIO);
gpio_set_dir(2, GPIO_OUT);
gpio_put(2, false);
//gpio_set_function(3, GPIO_FUNC_SIO);
//gpio_set_dir(3, GPIO_OUT);
//gpio_put(3, false);
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
int st, rr/*, r0, r1, r2*/;
static uint8_t checkbuf[256];
bool first = true;
restart:
//trl78_uart1_set_exclusive(true);
//hw->rx_set_stop_bit(false);
gpio_put(2, false);
/*glitch_disarm();
busy_wait_ms(40);*/
st = tool78_init_ocd(hw, NULL, passwd);
if (st == 0xc3) {
printf("aa\n");
st = 0;
rr = hw->recv(1, (uint8_t*)&st, 120*1000);
printf("rr=%d\n", rr);
if (rr != 1) {
printf("aaaa\n");
goto do_reset_stuff;
}
}
if (first) printf("result: 0x%02x\n", st);
if (st == 0xc1) goto do_reset_stuff;
if (st != tool78_stat_no_ocd_status) {
printf("init: expected status timeout error, got %d\n", st);
goto deinit_bad;
}
busy_wait_ms(16); // leave time to recharge
// TODO: update description
// right now, the RL78 core is stuck in an infinite loop doing nothing in
// the debug monitor part of its bootrom. however, the code we need is
// right below it, so we can simply try to glitch it without having to meet
// the timing
// see https://fail0verflow.com/blog/2018/ps4-syscon/ for more info
// try up to 16 times because we can't discern between a reset and a glitch
// that had no effect. after 16 iterations without result, reset the RL78
// and try again.
// a successful glitch will output a single null byte over the TOOL0 line
// apparently we have about 95 ms until the infinite loop gets reset into
// the MCU flash automatically? somehow?? I suppose it's the WDT
if (first) printf("all set, let's go\n");
first = false;
//hw->rx_set_stop_bit(false);
glitch_arm();
for (size_t i = 0; i < 16; ++i) {
zap_dac_set_b(zap_adc_read(1));
zap_dac_latch();
//glitch_trigger_sw_core1();
glitch_trigger_sw_pio();
rr = hw->recv(1, checkbuf, 12*1000);
if (rr != 1 || checkbuf[0] == 0xff) {
busy_wait_ms(1); // leave time to recharge
printf(".");
continue;
}
printf("checkbuf: %d", checkbuf[0]);
printf("\n!!!\n");
hw->flags |= tool78_hw_flag_done_reset;
glitch_disarm();
goto success;
}
glitch_disarm();
printf(":");
do_reset_stuff:
hw->deinit();
// glitch for way too long to power cycle
sio_hw->gpio_set = 1u << GLITCH_OUT_PIN;
busy_wait_ms(16);
sio_hw->gpio_clr = 1u << GLITCH_OUT_PIN;
goto restart;
success:;
//gpio_put(2, true);
//busy_wait_ms(5);
// (02): read from above (checkbuf) code
// 03 06 18 00 df 03
// ^-- baud rate set response
// 00
// ^-- OCD entry response
rr = hw->recv(4, &checkbuf[1], 10000);
if (rr != 4) {
printf("#");
//printf("rr=%d, wut?\n", rr);
goto do_reset_stuff;
}
printf("recv %02x %02x %02x %02x %02x\n", checkbuf[0], checkbuf[1],
checkbuf[2], checkbuf[3], checkbuf[4]);
busy_wait_us_32(500);
printf("glitch len: %lu ns\n", *(volatile uint32_t*)&glitch_param_cur.length_ns.cur);
/*goto do_reset_stuff;*/
st = tool78_ocd_connect(hw, passwd);
if (st != 0xf0 && st != 0xf2) {
printf("OCD: connect failed: %d\n", st);
goto deinit_bad;
}
printf("connect! 0x%02x\n", st);
for (size_t i = 0; i < DUMP_SIZE; i += 256) {
st = tool78_ocd_read(hw, 0x8000+i, (uint8_t)0x100, &databuf[i]);
if (st) {
printf("no read! st=%d\n", st);
}
}
for (size_t iii = 0; iii < DUMP_SIZE; ++iii) {
printf("%02x%s", databuf[iii], ((iii & 0xf) == 0xf) ? "\n" : " ");
}
printf("\ndone!\n");
deinit_bad:
hw->deinit();
return;
}

View File

@ -27,6 +27,17 @@ static uint8_t shellcode_test[] = {
0xd7, // ret
};
static uint8_t G1M_test_1[] = {
0xcb, 0xf8, 0x00, 0xfe, // movw sp, #0xfe00
0xec, 0xba, 0xff, 0x0e, // br !!0xeffba
};
static uint8_t G1M_test_2[] = {
0x51, 0x61, // mov a, #'a'
0xfc, 0xdc, 0xff, 0x0e, // call !!tool_tx
0xd7, // ret
};
//static uint8_t DATA_test_dbg[7/*85*/] = {
// /*0xe0, 0x07, 0x52,*/ 0x51, 0x61, 0xfc, 0xa1, 0xff, 0x0e,
// 0xd7,
@ -207,15 +218,52 @@ void cli_tool78_g10_ocdtest(void) {
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
struct tool78_hw* hw = &tool78_hw_rl78g10_uart1;
int st = tool78_init_ocd(hw, NULL, passwd);
printf("init: %02x\n", st);
int st, rr;
uint8_t checkbuf[2];
while (true) {
st = tool78_init_ocd(hw, NULL, passwd);
if (st == 0xc3) {
rr = hw->recv(1, &st, 120*1000*1000);
if (rr != 1) {
printf("aaaa\n");
goto deinit_bad;
}
} else {
printf("result: 0x%02x\n", st);
if (st != 0xf2 && st != 0xf0) {
printf("init: %d\n", st);
goto deinit_bad;
}
break;
}
}
uint8_t val = 0;
st = tool78_ocd_read(hw, 0x0080, 1, &val);
printf("read: st=%d val=%02x\n", st, val);
st = tool78_ocd_write(hw, 0xfed0, sizeof G1M_test_1, G1M_test_1);
printf("write1: st=%d\n", st);
st = tool78_ocd_exec(hw);
printf("exec1: st=%d\n", st);
st = tool78_ocd_write(hw, 0xfed0, sizeof G1M_test_2, G1M_test_2);
printf("write2: st=%d\n", st);
st = tool78_ocd_exec(hw);
printf("exec2: st=%d\n", st);
// wait for completion
rr = hw->recv(2, checkbuf, 1000*1000);
if (rr != 2) {
printf("exec code: no response :/ (%d)\n", rr);
goto deinit_bad;
}
printf("result: '%c' (0x%02x)\n", checkbuf[0], checkbuf[0]);
busy_wait_ms(1000);
deinit_bad:
hw->deinit();
}

View File

@ -1167,7 +1167,7 @@ int tool78_ocd_connect(struct tool78_hw* hw, const uint8_t passwd[10]) {
}
int tool78_ocd_read(struct tool78_hw* hw, uint16_t off, uint8_t len,
uint8_t* data) {
busy_wait_us(300);//busy_wait_ms(1);
busy_wait_ms(1);
bool is_g10 = (hw->target & tool78_mcu_mask) == tool78_mcu_rl78g10;
@ -1325,6 +1325,8 @@ int tool78_ocd_write(struct tool78_hw* hw, uint16_t addr, uint8_t len,
// command echoed back
rr = hw->recv(4, hdr, 1000);
/*printf("wr p1: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]);*/
if (rr != 4) return -2;
if (hdr[0] == 0xff) { // frame error bullshit
hdr[0] = hdr[1];
@ -1333,24 +1335,45 @@ int tool78_ocd_write(struct tool78_hw* hw, uint16_t addr, uint8_t len,
rr = hw->recv(1, &hdr[3], 1000);
if (rr != 1) return -2;
}
/*printf("wr p1: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]);*/
// status
rr = hw->recv(1, hdr, 1000);
/*printf("wr p2: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]);*/
if (rr != 1) return -1;
if (hdr[0] == len) {
rr = hw->recv(1, hdr, 1000);
/*printf("wr p2: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]);*/
if (rr != 1) return -1;
}
if (hdr[0] != 0x00) return -3;
hdr[0] = tool78ocd_cmdg10_write_raw;
rr = hw->send(1, hdr, -1);
if (rr != 1) return -1;
rr = hw->recv(1, hdr, 1000); // sigh
if (rr != 1) return -1;
/*printf("wr p3: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]);*/
rr = hw->send(len, data, -1);
if (rr != len) return -1;
rr = hw->recv(len, NULL, 1000*len); // sigh
if (rr != len) return -1;
/*printf("wr p4: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]);*/
rr = hw->recv(2, hdr, 1000*len);
if (rr != 2) return -1;
rr = hw->recv(1, hdr, 1000);
/*printf("wr p5: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]);
printf("recv %d: %02x %02x\n", rr, hdr[0], hdr[1]);*/
if (rr != 1) return -1;
return (hdr[1] == 0) ? 0 : -2;
return (hdr[0] == 0) ? 0 : -2;
}
} else {
hdr[0] = tool78ocd_cmd_write;
@ -1380,11 +1403,11 @@ int tool78_ocd_exec(struct tool78_hw* hw) {
int rr = hw->send(1, hdr, -1);
rr = hw->recv(2, hdr, 1000);
rr = hw->recv(1, hdr, 1000);
if (rr != 1 && rr != 2) return -1;
//printf("h[0]=0x%02x, h[1]=0x%02x\n", hdr[0], hdr[1]);
return (hdr[0] == cmd) ? 0 : -2;
return 0;//(hdr[0] == cmd) ? 0 : -2;
}
int tool78_ocd_leave(struct tool78_hw* hw, bool exit_to_ram) {
busy_wait_ms(1);
@ -1455,9 +1478,11 @@ static enum tool78_stat tool78_init_common(struct tool78_hw* hw) {
//printf("init rr:%d st=%02x\n", rr, st);
if (rr != 2) return tool78_stat_timeout_error;
if (st == 0x06) {
// should be 5 zero bytes, but let's not check
rr = hw->recv(5, data, 1000*1000);
if (rr != 5) return tool78_stat_timeout_error;
rr = hw->recv(5, data, 5*1000);
if (rr != 5) return tool78_stat_no_ocd_status;
}
}
return st;

View File

@ -122,6 +122,7 @@ enum tool78_stat {
tool78_stat_fatal_hw_error = 0xc4,
tool78_stat_parity_error = 0xc5,
tool78_stat_bad_flash_size = 0xc6,
tool78_stat_no_ocd_status = 0xc7,
// TODO: OCD status stuff (for 0x91)
};

View File

@ -126,8 +126,13 @@ int tool78_hw_help_recv(const struct tool78_pio_vars* vars,
// TODO: sleep a bit? idk
}
data[i] = *(volatile uint8_t*)&PINOUT_TOOL78_PIO->rxf[vars->smrx];
uint8_t v = *(volatile uint8_t*)&PINOUT_TOOL78_PIO->rxf[vars->smrx];
if (data) {
data[i] = v;
if (vars->bitswap) data[i] = bitswap(data[i]);
} else {
(void)v;
}
}
end:

View File

@ -5,7 +5,7 @@ OBJCOPY := rl78-elf-objcopy
all: test-rom.srec test-dbg.srec test-rom.bin test-dbg.bin
test.S.o: test.S
test.S.o: test.S hw.S
$(AS) -c -o "$@" "$<"
romhdr.S.o: romhdr.S
$(AS) -c -o "$@" "$<"

254
test/rl78g10/dumper.S Normal file
View File

@ -0,0 +1,254 @@
#include "hw.S"
.global _start
_start:
/*mov es, #0*/
movw sp, #0xfed0
; IAWCTL = 0 -> none?
call !siniport
call !siniclk
;call !sinitau
;call !siniuart0
call !main
delay_long:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
delay_data:
nop
ret
tx_byte:
; start condition
clr1 P0.0
call !delay_long ;27 cyc = 4 cyc + 16 cyc + 7 cyc
; data bits
mov c, #8 ; 1 cyc
.Lbitloop:
; set 1 bit
bf a.0, $.Lsetlo ; 3 cyc hi // 5 cyc lo
.Lsethi:
nop ; 1 cyc hi //
nop ; 1 cyc hi //
set1 P0.0 ; 2 cyc hi //
br $.Lafterset ; 3 cyc hi //
.Lsetlo:
clr1 P0.0 ; // 2 cyc lo
nop ; // 1 cyc lo
nop ; // 1 cyc lo
nop ; // 1 cyc lo
.Lafterset:
; delay
call !delay_data ;12 cyc
; next bit
shr a, 1 ; 1 cyc
dec c ; 1 cyc
bnz $.Lbitloop ; 4 cyc
; stop condition
set1 P0.0
call !delay_long
call !delay_long
ret
main:
set1 P0.0
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
loop:
mov es, #0xe
;movw bc, #0x0200
mov c, #0
movw hl, #0xfe00
innerloop:
mov a, es:[hl]
push ax
push bc
call !tx_byte
pop bc
pop ax
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
incw hl
;decw bc
;cmpw bc, #0
dec c
cmp0 c
bnz $innerloop
;movw bc, #0x0200
mov c, #0
;movw hl, #0xfe00
innerloop2:
mov a, es:[hl]
push ax
push bc
call !tx_byte
pop bc
pop ax
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
incw hl
;decw bc
;cmpw bc, #0
dec c
cmp0 c
bnz $innerloop2
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
mov a, #'E'
call !delay_long
call !delay_long
mov a, #'N'
call !delay_long
call !delay_long
mov a, #'D'
call !delay_long
call !delay_long
mov a, #' '
call !delay_long
call !delay_long
br !loop
mov a, #' '
call !tx_byte
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
;set1 P0.0
br !loop
siniport:
; P00 GPIO
; P06 TxD0
mov !PIOR, #0
; set P0 as output
mov !P0, #0
; disable pullups
mov !PU0, #0
; push-pull output
mov !POM0, #0
; not analog in
mov !PMC0, #0x7f
; set port modes
;mov !PM0, #0x0f ; P00 GPIO ; P06 TxD0
mov !PM0, #0
ret
siniclk:
mov !PER0, #0xe5 ; enable many peripherals
mov !OSMC, #0x10
;mov !HOCODIV, #1
ret

View File

@ -18,6 +18,8 @@
/*#define PD1 0x0075*/
#define PIOR 0xf0077
#define tool_tx 0xeffdc
/*#define CMC 0xfffa0
#define CSC 0xfffa1
#define CKC 0xfffa4*/

View File

@ -3,252 +3,64 @@
.global _start
_start:
/*mov es, #0*/
movw sp, #0xfed0
movw sp, #0xfe00
;di
; IAWCTL = 0 -> none?
call !siniport
call !siniclk
;call !sinitau
;call !siniuart0
call !main
delay_long:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
delay_data:
nop
ret
tx_byte:
; start condition
clr1 P0.0
call !delay_long ;27 cyc = 4 cyc + 16 cyc + 7 cyc
; data bits
mov c, #8 ; 1 cyc
.Lbitloop:
; set 1 bit
bf a.0, $.Lsetlo ; 3 cyc hi // 5 cyc lo
.Lsethi:
nop ; 1 cyc hi //
nop ; 1 cyc hi //
set1 P0.0 ; 2 cyc hi //
br $.Lafterset ; 3 cyc hi //
.Lsetlo:
clr1 P0.0 ; // 2 cyc lo
nop ; // 1 cyc lo
nop ; // 1 cyc lo
nop ; // 1 cyc lo
.Lafterset:
; delay
call !delay_data ;12 cyc
; next bit
shr a, 1 ; 1 cyc
dec c ; 1 cyc
bnz $.Lbitloop ; 4 cyc
; stop condition
set1 P0.0
call !delay_long
call !delay_long
ret
main:
set1 P0.0
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
loop:
mov es, #0xe
;movw bc, #0x0200
mov c, #0
movw hl, #0xfe00
innerloop:
mov a, es:[hl]
push ax
push bc
call !tx_byte
pop bc
pop ax
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
incw hl
;decw bc
;cmpw bc, #0
dec c
cmp0 c
bnz $innerloop
;movw bc, #0x0200
mov c, #0
;movw hl, #0xfe00
innerloop2:
mov a, es:[hl]
push ax
push bc
call !tx_byte
pop bc
pop ax
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
incw hl
;decw bc
;cmpw bc, #0
dec c
cmp0 c
bnz $innerloop2
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
mov a, #'E'
call !delay_long
call !delay_long
mov a, #'N'
call !delay_long
call !delay_long
mov a, #'D'
call !delay_long
call !delay_long
mov a, #' '
call !delay_long
call !delay_long
br !loop
mov a, #' '
call !tx_byte
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
call !delay_long
;set1 P0.0
br !loop
siniport:
; P00 GPIO
; P06 TxD0
mov !PIOR, #0
; set P0 as output
mov !P0, #0
; disable pullups
mov !PU0, #0
; push-pull output
mov !POM0, #0
; not analog in
mov !PMC0, #0x7f
; set port modes
;mov !PM0, #0x0f ; P00 GPIO ; P06 TxD0
mov !PM0, #0
ret
siniclk:
mov !PER0, #0xe5 ; enable many peripherals
mov !OSMC, #0x10
;mov !HOCODIV, #1
ret
mov a, #'a'
call !!tool_tx
br !!0xeffba
; mov !PIOR, #0
; mov P0, #0
; mov !PU0, #0
; mov !POM0, #0
; mov !PMC0, #0x7f
; mov !PM0, #0
;
; mov !PER0, #0xe5 ; enable peripherals
; mov !OSMC, #0x10
;
;looper:
; mov P0, #0xff
; ;movw ax, #0xfae0
;
;/* mov hl, ax
; mov c, #0
;
;1: mov b, #0xff
; mov a, #0xff
;
;2: inc a
; dec b
; bnz 2b
;
; mov [hl+c], a
; dec c
; bnz 1b
;
; mov P0, #0
;
; mov c, #0x18
;3: mov b, #0xff
;4: dec b
; bnz 4b
; dec c
; bnz 3b*/
;
; mov a, #0x48
; call !!tool_tx
; mov a, #0x69
; call !!tool_tx
;
;/* mov x, #0xaa
; mov c, #0
;
;5: dec c
; mov a, [hl+c]
; xor a, x
; call !!tool_tx
; cmp0 c
; bnz 5b
; br $looper*/
;
; ret