rl78/g23 probe and glitching routines
This commit is contained in:
parent
8fab6d984c
commit
8820a9b40e
|
@ -11,7 +11,7 @@
|
|||
|
||||
#define TRIGGER_IN_PIN ZAP_TRIG_IN
|
||||
// use CROWBAR_1 / CROWBAR_2 / GLITCH_OUT to select glitching method
|
||||
#define GLITCH_OUT_PIN ZAP_CROWBAR_1
|
||||
#define GLITCH_OUT_PIN ZAP_GLITCH_OUT/*ZAP_CROWBAR_1*/
|
||||
|
||||
#define PINOUT_SBW_PIO BREADBOARD_SBW_PIO
|
||||
#define PINOUT_SBW_TCK (ZAP_GPIO_BASE+0)
|
||||
|
@ -33,7 +33,7 @@
|
|||
#define PINOUT_TOOL78_78K0R_FLMD0 (ZAP_GPIO_BASE+1)
|
||||
#define PINOUT_TOOL78_78K0R_TOOL0 (ZAP_GPIO_BASE+2)
|
||||
|
||||
#define PINOUT_TOOL78_RL78_TOOL0 (ZAP_GPIO_BASE+1)
|
||||
#define PINOUT_TOOL78_RL78_TOOL0 (ZAP_GPIO_BASE+1) /* welp, lvl shifter pin2 is dead(?) */
|
||||
#define PINOUT_TOOL78_RL78_TX (ZAP_GPIO_BASE+2)
|
||||
#define PINOUT_TOOL78_RL78_RX (ZAP_GPIO_BASE+3)
|
||||
|
||||
|
|
|
@ -33,8 +33,11 @@ void cli_tool78_g10_prototest(void);
|
|||
void cli_tool78_g10_ocdtest(void);
|
||||
|
||||
void cli_tool78_glitch_dump(void);
|
||||
void cli_tool78_glitch_dump_g23(void);
|
||||
void cli_tool78_glitch_paramsearch(void);
|
||||
void cli_tool78_glitch_param_g23(void);
|
||||
void cli_tool78_glitch_ocd_dump(void);
|
||||
void cli_tool78_glitch_ocd_dump_g23(void);
|
||||
void cli_tool78_glitch_param_g10(void);
|
||||
void cli_tool78_glitch_ocd_g10(void);
|
||||
|
||||
|
@ -85,8 +88,11 @@ static struct cli_cmd cmds[] = {
|
|||
{ "rl10ocd", cli_tool78_g10_ocdtest },
|
||||
|
||||
{ "g78dump", cli_tool78_glitch_dump },
|
||||
{ "g23dump", cli_tool78_glitch_dump_g23 },
|
||||
{ "g78param", cli_tool78_glitch_paramsearch },
|
||||
{ "g23param", cli_tool78_glitch_param_g23 },
|
||||
{ "g78ocd", cli_tool78_glitch_ocd_dump },
|
||||
{ "g23ocd", cli_tool78_glitch_ocd_dump_g23 },
|
||||
{ "g10param", cli_tool78_glitch_param_g10 },
|
||||
{ "g10ocd", cli_tool78_glitch_ocd_g10 },
|
||||
|
||||
|
|
|
@ -16,13 +16,19 @@
|
|||
#include "glitch.h"
|
||||
|
||||
void cli_tool78_glitch_dump(void);
|
||||
void cli_tool78_glitch_dump_g23(void);
|
||||
void cli_tool78_glitch_paramsearch(void);
|
||||
void cli_tool78_glitch_param_g23(void);
|
||||
void cli_tool78_glitch_ocd_dump(void);
|
||||
void cli_tool78_glitch_ocd_dump_g23(void);
|
||||
void cli_tool78_glitch_param_g10(void);
|
||||
void cli_tool78_glitch_ocd_g10(void);
|
||||
|
||||
#define DUMP_OFFSET 0xef000
|
||||
#define DUMP_SIZE 4096/*65536*/
|
||||
#define USE_PICOEMP 0
|
||||
#define LEN_USE_ADC 0
|
||||
|
||||
#define DUMP_OFFSET /*0*//*0xee000*/
|
||||
#define DUMP_SIZE /*0x100*/8192/*65536*/
|
||||
|
||||
// test with decoupling caps: length in 20..500(..1500) -> ok
|
||||
// testing on ocd lock: length: 5..35
|
||||
|
@ -45,25 +51,37 @@ sec: flg=fe bot=03 fsws=0000 fswe=003f
|
|||
|
||||
static uint8_t databuf[DUMP_SIZE];
|
||||
static struct glitch_param_randrange offset;
|
||||
static struct glitch_param_randrange/*adc*/ length;
|
||||
#if LEN_USE_ADC
|
||||
static struct glitch_param_adc length;
|
||||
#else
|
||||
static struct glitch_param_randrange length;
|
||||
#endif
|
||||
//static struct glitch_param_const length;
|
||||
|
||||
#define LENGTH_1 (50/*26*1000/3*/)
|
||||
#define LENGTH_2 (40/*LENGTH_1/2*/)
|
||||
|
||||
static bool glitch_init_core1_stuff(bool exttrig, uint glitchpin) {
|
||||
offset.min = 10*1000;
|
||||
offset.max = 35433*1000;
|
||||
length.min = 100;
|
||||
length.max = /*10*50*/26*1000;
|
||||
offset.max = 35433*1000/25;
|
||||
length.min = 25;//100;
|
||||
length.max = /*10*50*/LENGTH_1;
|
||||
//length.value = 5*1000; // 5 us
|
||||
#if LEN_USE_ADC
|
||||
#if PINOUT_USE_DRAGONZAP
|
||||
//length.adc_index = 0;//999;
|
||||
length.adc_index = 0;//999;
|
||||
#else
|
||||
//length.adc_index = 999;
|
||||
length.adc_index = 999;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
glitch_param_randrange_init(&offset);
|
||||
//glitch_param_const_init(&length);
|
||||
#if LEN_USE_ADC
|
||||
glitch_param_adc_init(&length);
|
||||
#else
|
||||
glitch_param_randrange_init(&length);
|
||||
//glitch_param_adc_init(&length);
|
||||
#endif
|
||||
|
||||
// REGC = 2.11V / 0.47..1 uF // WUFM: REGC = 1.80V // BUT: OCD mode: always 2.1!
|
||||
static struct glitch_params gparam = (struct glitch_params){
|
||||
|
@ -98,7 +116,11 @@ static bool glitch_init_core1_stuff(bool exttrig, uint glitchpin) {
|
|||
};
|
||||
gparam.length_ns = (struct glitch_param){
|
||||
.ud = &length,
|
||||
.getter = glitch_param_randrange_fn,//adc_fn
|
||||
#if LEN_USE_ADC
|
||||
.getter = glitch_param_adc_fn
|
||||
#else
|
||||
.getter = glitch_param_randrange_fn
|
||||
#endif
|
||||
};
|
||||
gparam.trigger_in_pin = exttrig ? TRIGGER_IN_PIN/*7*/ : (-1);
|
||||
return glitch_ready(&gparam);
|
||||
|
@ -137,13 +159,50 @@ static uint8_t DATA_test_dbg__paramtest[102] = {
|
|||
0x0e, 0xd2, 0xdf, 0xf4, 0xef, 0xbf
|
||||
};
|
||||
|
||||
static uint8_t DATA_test_dbg__paramtest_g23[] = {
|
||||
0x71, 0x7b, 0xfa, 0xf5, 0xf0, 0x02, 0xf5, 0x78, 0x00, 0xce, 0x22, 0x00, 0xf5,
|
||||
0x62, 0x00, 0xf5, 0x77, 0x00, 0xf5, 0x79, 0x00, 0xf5, 0x75, 0x00, 0xf5, 0x7c,
|
||||
0x00, 0xf4, 0x02, 0xcb, 0xf8, 0x00, 0xfe, 0xce, 0x02, 0xff, 0xce, 0x02, 0xff,
|
||||
0x30, 0x00, 0xc0, 0x30, 0x00, 0xc0, 0x16, 0x16, 0x52, 0x00, 0x53, 0xff, 0x51,
|
||||
0x00, 0x81, 0x93, 0xdf, 0xfc, 0x92, 0x61, 0xf9, 0xdf, 0xf3, 0xf4, 0x02, 0xf4,
|
||||
0x02, 0x52, 0x18, 0x53, 0xff, 0x93, 0xdf, 0xfd, 0x92, 0xdf, 0xf8, 0x51, 0x48,
|
||||
0xfe, 0x16, 0x00, 0x51, 0x69, 0xfe, 0x11, 0x00, 0x50, 0xaa, 0x52, 0x00, 0x92,
|
||||
0x61, 0xe9, 0x61, 0x78, 0xfe, 0x05, 0x00, 0xd2, 0xdf, 0xf5, 0xef, 0xba, 0x71,
|
||||
0x7a, 0xaf, 0x00, 0x9e, 0xad, 0x31, 0xb4, 0xaf, 0xfc, 0x71, 0x3b, 0xaf, 0x71,
|
||||
0x7b, 0xaf, 0xd7
|
||||
};
|
||||
|
||||
|
||||
static uint8_t dumper_shellcode[0x26] = {
|
||||
//0xe0, 0x07, 0x26, // 0xF07E0 location, 0x26 length of packet
|
||||
0x41, 0x00, 0x34, 0x00, 0x00, 0x00, 0x11, 0x89, 0xFC, 0xA1, 0xFF, 0x0E, 0xA5,
|
||||
0x15, 0x44, 0x00, 0x00, 0xDF, 0xF3, 0xEF, 0x04, 0x55, 0x00, 0x00, 0x00, 0x8E,
|
||||
0xFD, 0x81, 0x5C, 0x0F, 0x9E, 0xFD, 0x71, 0x00, 0x90, 0x00, 0xEF, 0xE0
|
||||
0x41, 0x00, // mov es, #0
|
||||
0x34, 0x00, 0x00, // movw de, #0
|
||||
// next:
|
||||
0x00, 0x11, 0x89, // mov a, es:[de]
|
||||
0xFC, 0xA1, 0xFF, 0x0E, // call !!0xeffa1
|
||||
0xA5, // incw de
|
||||
0x15, // movw ax, de
|
||||
0x44, 0x00, 0x00, // cmpw ax, #0
|
||||
0xDF, 0xF3, // bnz $next
|
||||
0xEF, 0x04, // br $after_ocd_flag
|
||||
0x55, // ocd_flag
|
||||
// nop
|
||||
// mov a, es
|
||||
// inc a
|
||||
// and a, #0xf
|
||||
// mov es, a
|
||||
0x00, 0x00, 0x00, 0x8E, 0xFD, 0x81, 0x5C, 0x0F, 0x9E, 0xFD, 0x71, 0x00, 0x90, 0x00,
|
||||
0xEF, 0xE0 // br $next
|
||||
};
|
||||
|
||||
static uint8_t dumper_g23[] = {
|
||||
0x41, 0x00, 0x34, 0x00, 0x00, 0x11, 0x89, 0xef, 0x10, 0xa5, 0x15, 0x44, 0x00,
|
||||
0x00, 0xdf, 0xf5, 0x8e, 0xfd, 0x81, 0x5c, 0x0f, 0x9e, 0xfd, 0xef, 0xec, 0x71,
|
||||
0x7a, 0xaf, 0x00, 0x9e, 0xad, 0x31, 0xb4, 0xaf, 0xfc, 0x71, 0x3b, 0xaf, 0x71,
|
||||
0x7b, 0xaf, 0xef, 0xde
|
||||
};
|
||||
|
||||
|
||||
static uint8_t G1M_payload_1[] = {
|
||||
0xcb, 0xf8, 0xc0, 0xfe, // movw sp, #0xfea0
|
||||
0xec, 0xba, 0xff, 0x0e, // br !!0xeffba
|
||||
|
@ -166,7 +225,7 @@ static uint8_t G1M_paramtest[] = {
|
|||
};
|
||||
|
||||
|
||||
void cli_tool78_glitch_dump(void) {
|
||||
static void cli_tool78_glitch_dump_base(size_t pl_size, const uint8_t* payload) {
|
||||
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint16_t ver;
|
||||
enum tool78_stat st;
|
||||
|
@ -200,8 +259,7 @@ void cli_tool78_glitch_dump(void) {
|
|||
goto deinit_bad;
|
||||
}
|
||||
|
||||
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0xf900,
|
||||
sizeof(dumper_shellcode), dumper_shellcode);
|
||||
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0xf900, pl_size, payload);
|
||||
//printf("write shellcode res 0x%02x\n", st);
|
||||
if (st != 0) {
|
||||
printf("shellcode write failed: %d\n", st);
|
||||
|
@ -233,11 +291,20 @@ deinit_bad:
|
|||
tool78_hw_rl78_uart1.deinit();
|
||||
return;
|
||||
}
|
||||
void cli_tool78_glitch_dump(void) {
|
||||
cli_tool78_glitch_dump_base(sizeof(dumper_shellcode), dumper_shellcode);
|
||||
}
|
||||
void cli_tool78_glitch_dump_g23(void) {
|
||||
cli_tool78_glitch_dump_base(sizeof(dumper_g23), dumper_g23);
|
||||
}
|
||||
|
||||
void cli_tool78_glitch_paramsearch(void) {
|
||||
static void glitch_paramsearch_base(size_t pl_size, const uint8_t* payload) {
|
||||
zap_gpio_set_en(true);
|
||||
#if USE_PICOEMP
|
||||
zap_picoemp_init();
|
||||
#endif
|
||||
|
||||
if (!glitch_init_core1_stuff(true, ZAP_GLITCH_OUT/*GLITCH_OUT_PIN*/)) {
|
||||
if (!glitch_init_core1_stuff(true, GLITCH_OUT_PIN)) {
|
||||
printf("bad glitcher params!\n");
|
||||
return;
|
||||
}
|
||||
|
@ -250,12 +317,15 @@ void cli_tool78_glitch_paramsearch(void) {
|
|||
bool first = true;
|
||||
|
||||
restart:
|
||||
#if USE_PICOEMP
|
||||
zap_picoemp_set_armed(false);
|
||||
#endif
|
||||
glitch_disarm();
|
||||
/*busy_wait_ms(40);*/
|
||||
|
||||
#if USE_PICOEMP
|
||||
zap_picoemp_set_armed(true);
|
||||
while (!zap_picoemp_has_hv()) ;
|
||||
#endif
|
||||
|
||||
ver=0;
|
||||
st = tool78_init_ocd(&tool78_hw_rl78_uart1, &ver, passwd);
|
||||
|
@ -285,14 +355,17 @@ restart:
|
|||
printf("trampoline write failed: %d\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0xf900,
|
||||
sizeof(DATA_test_dbg__paramtest), DATA_test_dbg__paramtest);
|
||||
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0xf900, pl_size, payload);
|
||||
//printf("write code res 0x%02x\n", st);
|
||||
if (st != 0) {
|
||||
printf("code write failed: %d\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
|
||||
#if USE_PICOEMP
|
||||
while (!zap_picoemp_has_hv()) ;
|
||||
#endif
|
||||
|
||||
st = tool78_ocd_exec(&tool78_hw_rl78_uart1);
|
||||
//printf("exec res 0x%02x\n", st);
|
||||
if (st != 0) {
|
||||
|
@ -370,19 +443,33 @@ restart:
|
|||
}
|
||||
|
||||
first_=false;
|
||||
if (!zap_picoemp_has_hv()) {
|
||||
rr = tool78_hw_rl78_uart1.recv(2, checkbuf, 150*1000);
|
||||
} else break;
|
||||
|
||||
#if USE_PICOEMP
|
||||
while (!zap_picoemp_has_hv()) {
|
||||
rr = tool78_hw_rl78_uart1.recv(2, checkbuf, 150);
|
||||
if (rr == 2 && (checkbuf[0] != 'H' || checkbuf[1] != 'i')) rr = 0;
|
||||
if (rr == 2) {
|
||||
rr = tool78_hw_rl78_uart1.recv(256, checkbuf, 120*1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
glitch_arm();
|
||||
rr = tool78_hw_rl78_uart1.recv(2, checkbuf, 150*1000);
|
||||
glitch_disarm();
|
||||
} while (true);
|
||||
}
|
||||
|
||||
deinit_bad:
|
||||
#if USE_PICOEMP
|
||||
zap_picoemp_set_armed(false);
|
||||
#endif
|
||||
tool78_hw_rl78_uart1.deinit();
|
||||
return;
|
||||
|
||||
do_reset_stuff:
|
||||
#if USE_PICOEMP
|
||||
zap_picoemp_set_armed(false);
|
||||
#endif
|
||||
tool78_hw_rl78_uart1.deinit();
|
||||
|
||||
// glitch for way too long to power cycle
|
||||
|
@ -392,6 +479,13 @@ do_reset_stuff:
|
|||
|
||||
goto restart;
|
||||
}
|
||||
void cli_tool78_glitch_paramsearch(void) {
|
||||
glitch_paramsearch_base(sizeof(DATA_test_dbg__paramtest), DATA_test_dbg__paramtest);
|
||||
}
|
||||
|
||||
void cli_tool78_glitch_param_g23(void) {
|
||||
glitch_paramsearch_base(sizeof(DATA_test_dbg__paramtest_g23), DATA_test_dbg__paramtest_g23);
|
||||
}
|
||||
|
||||
void cli_tool78_glitch_ocd_dump(void) {
|
||||
if (!glitch_init_core1_stuff(false, GLITCH_OUT_PIN)) {
|
||||
|
@ -399,9 +493,9 @@ void cli_tool78_glitch_ocd_dump(void) {
|
|||
return;
|
||||
}
|
||||
|
||||
/*gpio_set_function(2, GPIO_FUNC_SIO);
|
||||
gpio_set_dir(2, GPIO_OUT);
|
||||
gpio_put(2, false);*/
|
||||
gpio_set_function(11, GPIO_FUNC_SIO);
|
||||
gpio_set_dir(11, GPIO_OUT);
|
||||
gpio_put(11, false);
|
||||
|
||||
//gpio_set_function(3, GPIO_FUNC_SIO);
|
||||
//gpio_set_dir(3, GPIO_OUT);
|
||||
|
@ -489,7 +583,7 @@ do_reset_stuff:
|
|||
goto restart;
|
||||
|
||||
success:;
|
||||
//gpio_put(2, true);
|
||||
gpio_put(11, true);
|
||||
//busy_wait_ms(5);
|
||||
// (02): read from above (checkbuf) code
|
||||
// 03 06 18 00 df 03
|
||||
|
@ -567,6 +661,253 @@ deinit_bad:
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
void cli_tool78_glitch_ocd_dump_g23(void) {
|
||||
zap_gpio_set_en(true);
|
||||
#if USE_PICOEMP
|
||||
zap_picoemp_init();
|
||||
#endif
|
||||
|
||||
if (!glitch_init_core1_stuff(false, GLITCH_OUT_PIN)) {
|
||||
printf("bad glitcher params!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_set_function(14, GPIO_FUNC_SIO);
|
||||
gpio_set_dir(14, GPIO_OUT);
|
||||
//gpio_put(16, true);
|
||||
|
||||
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint16_t ver;
|
||||
int st, rr/*, r0, r1, r2*/;
|
||||
static uint8_t checkbuf[256];
|
||||
bool first = true;
|
||||
bool phase1;
|
||||
|
||||
restart:
|
||||
#if USE_PICOEMP
|
||||
zap_picoemp_set_armed(false);
|
||||
#endif
|
||||
glitch_disarm();
|
||||
|
||||
#if USE_PICOEMP
|
||||
zap_picoemp_set_armed(true);
|
||||
while (!zap_picoemp_has_hv()) ;
|
||||
#endif
|
||||
|
||||
tool78_hw_rl78_uart1.flags &= ~tool78_hw_flag_done_reset;
|
||||
phase1 = true;
|
||||
((struct glitch_param_randrange*)glitch_param_cur.length_ns.ud)->max = LENGTH_1;
|
||||
//trl78_uart1_set_exclusive(true);
|
||||
//tool78_hw_rl78_uart1.rx_set_stop_bit(false);
|
||||
//gpio_put(2, false);
|
||||
/*glitch_disarm();
|
||||
busy_wait_ms(40);*/
|
||||
|
||||
ver=0;
|
||||
st = tool78_init_ocd(&tool78_hw_rl78_uart1, &ver, 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) {
|
||||
//gpio_put(11, true);
|
||||
printf("aaaa\n");
|
||||
//printf("glitch len: %lu ns\n", *(volatile uint32_t*)&glitch_param_cur.length_ns.cur);
|
||||
busy_wait_ms(1000);
|
||||
goto do_reset_stuff;
|
||||
}
|
||||
}
|
||||
if (first) printf("result: 0x%02x ver=%04x\n", st, ver);
|
||||
if (st == 0xc1) goto do_reset_stuff;
|
||||
if (st != 0x10) {
|
||||
printf("init: expected protect error, got %d\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
busy_wait_ms(16); // leave time to recharge
|
||||
|
||||
// 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;
|
||||
|
||||
glitch_continue:
|
||||
//tool78_hw_rl78_uart1.rx_set_stop_bit(false);
|
||||
glitch_arm();
|
||||
for (size_t i = 0; i < (phase1 ? 16 : 64); ++i) {
|
||||
#if USE_PICOEMP
|
||||
while (!zap_picoemp_has_hv()) {
|
||||
rr = tool78_hw_rl78_uart1.recv(1, checkbuf, 150);
|
||||
if (rr > 0) goto welp;
|
||||
}
|
||||
#endif
|
||||
//glitch_trigger_sw_core1();
|
||||
glitch_trigger_sw_pio();
|
||||
rr = tool78_hw_rl78_uart1.recv(1, checkbuf, 12*1000);
|
||||
welp:
|
||||
if (rr != 1) {
|
||||
busy_wait_ms(1); // leave time to recharge
|
||||
printf(".");
|
||||
continue;
|
||||
}
|
||||
|
||||
/*printf("checkbuf: %d", checkbuf[0]);
|
||||
printf("\n!!!\n");*/
|
||||
tool78_hw_rl78_uart1.flags |= tool78_hw_flag_done_reset;
|
||||
|
||||
glitch_disarm();
|
||||
goto success;
|
||||
}
|
||||
glitch_disarm();
|
||||
|
||||
printf(":");
|
||||
do_reset_stuff:
|
||||
tool78_hw_rl78_uart1.deinit();
|
||||
|
||||
busy_wait_ms(15);
|
||||
//gpio_put(16, false);
|
||||
// glitch for way too long to power cycle
|
||||
/*sio_hw->gpio_set = 1u << GLITCH_OUT_PIN;
|
||||
sio_hw->gpio_clr = 1u << GLITCH_OUT_PIN;*/
|
||||
//busy_wait_ms(15);
|
||||
//gpio_put(16, true);
|
||||
//busy_wait_ms(15);
|
||||
|
||||
goto restart;
|
||||
|
||||
success:;
|
||||
//busy_wait_ms(5);
|
||||
if (phase1) {
|
||||
// (02): read from above (checkbuf) code
|
||||
// 01 XX YY 03
|
||||
// ^-- baud rate set response
|
||||
// ^ XX is some err. code (variable, should be 0x23 but can vary due to glitch), YY is checksum
|
||||
|
||||
//gpio_put(11, true);
|
||||
rr = tool78_hw_rl78_uart1.recv(4, &databuf[0], 10000);
|
||||
if (rr != 4) {
|
||||
printf("wut? rr=%d prev=%02x\n", rr, checkbuf[0]);
|
||||
goto do_reset_stuff;
|
||||
} else {
|
||||
//gpio_put(14, true);
|
||||
printf("glitch phase1 done: %02x %02x %02x %02x %02x\n", checkbuf[0],
|
||||
databuf[0], databuf[1], databuf[2], databuf[3]);
|
||||
printf("glitch len: %lu ns\n", *(volatile uint32_t*)&glitch_param_cur.length_ns.cur);
|
||||
busy_wait_ms(1); // time to settle
|
||||
phase1 = false;
|
||||
((struct glitch_param_randrange*)glitch_param_cur.length_ns.ud)->max = LENGTH_2;
|
||||
//gpio_put(14, false);
|
||||
goto glitch_continue;
|
||||
}
|
||||
} else {
|
||||
// (02): read from above (checkbuf) code
|
||||
// 03 06 18 00 df 03
|
||||
// 00
|
||||
gpio_put(14, true);
|
||||
rr = tool78_hw_rl78_uart1.recv(6, &databuf[0], 10000);
|
||||
if (rr != 6) {
|
||||
printf("wut? rr=%d prev=%02x\n", rr, checkbuf[0]);
|
||||
restart_to_ph1:
|
||||
phase1 = true;
|
||||
((struct glitch_param_randrange*)glitch_param_cur.length_ns.ud)->max = LENGTH_1;
|
||||
gpio_put(14, false);
|
||||
goto do_reset_stuff;
|
||||
} else {
|
||||
printf("glitch phase2 done: %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
checkbuf[0], databuf[0], databuf[1], databuf[2],
|
||||
databuf[3], databuf[4], databuf[5]);
|
||||
printf("glitch len: %lu ns\n", *(volatile uint32_t*)&glitch_param_cur.length_ns.cur);
|
||||
busy_wait_ms(1); // time to settle
|
||||
rr = tool78_hw_rl78_uart1.recv(1, &checkbuf[0], 10000);
|
||||
if (rr != 1) {
|
||||
printf("wut? rr=%d no ack null byte\n", rr);
|
||||
goto restart_to_ph1;
|
||||
}
|
||||
printf("got ack!\n");
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_PICOEMP
|
||||
zap_picoemp_set_armed(false);
|
||||
#endif
|
||||
glitch_disarm();
|
||||
busy_wait_us_32(500);
|
||||
gpio_put(14, false);
|
||||
|
||||
ver = 0;
|
||||
st = tool78_ocd_version(&tool78_hw_rl78_uart1, &ver);
|
||||
if (st) {
|
||||
printf("OCD: get version failed: %d\n", st);
|
||||
goto do_reset_stuff;
|
||||
}
|
||||
printf("got ver! %04x\n", ver);
|
||||
|
||||
/*goto do_reset_stuff;*/
|
||||
|
||||
st = tool78_ocd_connect(&tool78_hw_rl78_uart1, passwd);
|
||||
if (st != 0xf0 && st != 0xf2) {
|
||||
printf("OCD: connect failed: %d\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
printf("connect! 0x%02x\n", st);
|
||||
|
||||
// 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(&tool78_hw_rl78_uart1, 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(&tool78_hw_rl78_uart1, 0xf900,
|
||||
sizeof(dumper_g23), dumper_g23);
|
||||
//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(&tool78_hw_rl78_uart1);
|
||||
//printf("exec res 0x%02x\n", st);
|
||||
if (st != 0) {
|
||||
printf("exec failed: %d\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
|
||||
for (size_t iii = 0; iii < DUMP_SIZE + DUMP_OFFSET; ++iii) {
|
||||
// wait for completion
|
||||
size_t off = (iii < DUMP_OFFSET) ? 0 : (iii - DUMP_OFFSET);
|
||||
rr = tool78_hw_rl78_uart1.recv(1, &databuf[off], 120*1000*1000);
|
||||
if (rr != 1) {
|
||||
printf("exec code: no response :/ (%d)\n", rr);
|
||||
goto deinit_bad;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t iii = 0; iii < DUMP_SIZE; ++iii) {
|
||||
printf("0x%02x%s", databuf[iii], ((iii & 0xf) == 0xf) ? "\n" : " ");
|
||||
}
|
||||
|
||||
printf("\ndone!\n");
|
||||
|
||||
deinit_bad:
|
||||
tool78_hw_rl78_uart1.deinit();
|
||||
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,
|
||||
|
|
|
@ -38,6 +38,17 @@ static uint8_t G1M_test_2[] = {
|
|||
0xd7, // ret
|
||||
};
|
||||
|
||||
static uint8_t G23_test[19] = {
|
||||
0x51, 0x61, // mov a, #'a'
|
||||
0x71, 0x7a, 0xaf, // set1 ASIM.7
|
||||
0x00, // nop
|
||||
0x9e, 0xad, // mov TXS, a
|
||||
0x31, 0xb4, 0xaf, 0xfc, // bf ASIM.3, $.
|
||||
0x71, 0x3b, 0xaf, // clr1 ASIM.3
|
||||
0x71, 0x7b, 0xaf, // clr1 ASIM.7
|
||||
0xd7 // ret
|
||||
};
|
||||
|
||||
|
||||
//static uint8_t DATA_test_dbg[7/*85*/] = {
|
||||
// /*0xe0, 0x07, 0x52,*/ 0x51, 0x61, 0xfc, 0xa1, 0xff, 0x0e,
|
||||
|
@ -178,8 +189,13 @@ void cli_tool78_ocdtest(void) {
|
|||
|
||||
// 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(&tool78_hw_rl78_uart1, 0x07e0,
|
||||
sizeof(shellcode_test), shellcode_test);
|
||||
if (ver < 0x500) {
|
||||
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0x07e0,
|
||||
sizeof(shellcode_test), shellcode_test);
|
||||
} else {
|
||||
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0x07e0,
|
||||
sizeof(G23_test), G23_test);
|
||||
}
|
||||
//printf("write shellcode res 0x%02x\n", st);
|
||||
if (st != 0) {
|
||||
printf("shellcode write failed: %d\n", st);
|
||||
|
@ -193,6 +209,21 @@ void cli_tool78_ocdtest(void) {
|
|||
goto deinit_bad;
|
||||
}
|
||||
|
||||
// wait for completion
|
||||
rr = tool78_hw_rl78_uart1.recv(1, checkbuf, 120*1000*1000);
|
||||
if (rr != 1) {
|
||||
printf("exec code: no response :/ (%d)\n", rr);
|
||||
goto deinit_bad;
|
||||
}
|
||||
printf("result: '%c' (0x%02x)\n", checkbuf[0], checkbuf[0]);
|
||||
|
||||
st = tool78_ocd_exec(&tool78_hw_rl78_uart1);
|
||||
//printf("exec res 0x%02x\n", st);
|
||||
if (st != 0) {
|
||||
printf("exec failed: %d\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
|
||||
// wait for completion
|
||||
rr = tool78_hw_rl78_uart1.recv(1, checkbuf, 120*1000*1000);
|
||||
if (rr != 1) {
|
||||
|
|
|
@ -127,7 +127,7 @@ static void CORE1_FUNC(glitch_core1_thread_core1_fifoirq)(void) {
|
|||
CORE1_DO_GLITCH();
|
||||
multicore_fifo_drain();
|
||||
multicore_fifo_clear_irq();
|
||||
gpio_put(25, true);
|
||||
//gpio_put(25, true);
|
||||
continue_:
|
||||
irq_set_enabled(irq, true);
|
||||
}
|
||||
|
@ -151,6 +151,7 @@ static void CORE1_FUNC(glitch_core1_thread_core1_gpio)(void) {
|
|||
CORE1_PRE_CALC();
|
||||
|
||||
__WFI();
|
||||
//while (!(sio_hw->gpio_in & (1u<<gpio))) ;
|
||||
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq
|
||||
bool arm = *(volatile bool*)¶m_cur.armed;
|
||||
if (!arm) continue;
|
||||
|
@ -166,6 +167,7 @@ static void CORE1_FUNC(glitch_core1_thread_core1_gpio)(void) {
|
|||
sio_hw->gpio_clr = iom;
|
||||
cont:
|
||||
irq_set_enabled(irq, true);
|
||||
//while ((sio_hw->gpio_in & (1u<<gpio))) ;
|
||||
}
|
||||
}
|
||||
__attribute__((__noreturn__))
|
||||
|
@ -178,6 +180,7 @@ static void CORE1_FUNC(glitch_core1_thread_pio)(void) {
|
|||
irq_set_enabled(irq, true);
|
||||
|
||||
while (true) {
|
||||
//gpio_put(25, gpio_get(10));
|
||||
CORE1_PRE_CALC();
|
||||
(void)iom;
|
||||
param_cur.offset_ns.cur = off;
|
||||
|
@ -185,9 +188,8 @@ static void CORE1_FUNC(glitch_core1_thread_pio)(void) {
|
|||
trigctl_push_off_len(trigctl_pio, trigctl_sm, off>>2, len>>2);
|
||||
|
||||
trigctl_wait_glitch_irq(trigctl_pio, trigctl_sm, true);
|
||||
trigctl_ack_glitch_irq(trigctl_pio, trigctl_sm);
|
||||
//gpio_put(25, true);
|
||||
//sio_hw->gpio_togl = 1u<<25;
|
||||
trigctl_ack_glitch_irq(trigctl_pio, trigctl_sm);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -252,7 +252,7 @@ inline static enum tool78_stat tool78_data_recv(struct tool78_hw* hw,
|
|||
/*#define tool78_wait_status(hw, l, timeout_us, ...) \
|
||||
tool78_wait_status__impl(hw, l, timeout_us, __VA_OPT__(1 ? __VA_ARGS__ : ) -1) \
|
||||
*/
|
||||
static enum tool78_stat tool78_wait_status/*__impl*/(struct tool78_hw* hw, int l, int timeout_us/*, int minl*/) {
|
||||
static enum tool78_stat tool78_wait_status__impl(struct tool78_hw* hw, int l, int timeout_us/*, int minl*/, const char* fnname, int line) {
|
||||
/*if (hw->target == tool78k0_spi && timeout_us >= 0) {
|
||||
busy_wait_us_32(timeout_us);
|
||||
timeout_us *= 2;
|
||||
|
@ -289,9 +289,10 @@ static enum tool78_stat tool78_wait_status/*__impl*/(struct tool78_hw* hw, int l
|
|||
busy_wait_us_32(timeout_us/64);
|
||||
}
|
||||
|
||||
printf("wait t/o\n");
|
||||
printf("wait t/o: %s:%d\n", fnname, line);
|
||||
return tool78_stat_timeout_error;
|
||||
}
|
||||
#define tool78_wait_status(hw, l, to) tool78_wait_status__impl(hw, l, to, __func__, __LINE__);
|
||||
|
||||
// ----
|
||||
|
||||
|
@ -1115,7 +1116,8 @@ int tool78_ocd_version(struct tool78_hw* hw, uint16_t* ver) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
*ver = bytes[0] | ((uint16_t)bytes[1] << 8);
|
||||
// BCD, so big-endian
|
||||
*ver = bytes[1] | ((uint16_t)bytes[0] << 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// NOTE:
|
||||
// * RL78/x1y flash block size: 0x400
|
||||
// * RL78/x2y flash block size: 0x800
|
||||
|
||||
enum tool78_target {
|
||||
tool78k0_uart2 = 0x12,
|
||||
tool78k0_spi = 0x13,
|
||||
|
@ -44,7 +48,8 @@ enum tool78_entry {
|
|||
// TOOL0 initial byte values
|
||||
tool78_entry_rl78_uart1 = 0x3a,
|
||||
tool78_entry_rl78_uart2 = 0x00,
|
||||
tool78_entry_rl78_ocd = 0xc5
|
||||
tool78_entry_rl78_ocd = 0xc5,
|
||||
tool78_entry_rl78_ocd2 = 0xca, // 2-wire OCD (RL78/G23 only)
|
||||
};
|
||||
|
||||
// TODO: initial baudrates? 9600 for 78k, 115.2k for RL78
|
||||
|
@ -141,6 +146,7 @@ enum tool78ocd_cmd {
|
|||
// execute code at 0xf07e0 (TODO: verify addr across versions)
|
||||
tool78ocd_cmd_exec = 0x94,
|
||||
tool78ocd_cmd_exit_reti = 0x95, // TODO: what is this?
|
||||
// TODO: 96 too?
|
||||
tool78ocd_cmd_exit_ram = 0x97, // TODO: what is this?
|
||||
|
||||
tool78ocd_cmdg10_connect = 0x55,
|
||||
|
|
135
test/rl78/test.S
135
test/rl78/test.S
|
@ -1,135 +0,0 @@
|
|||
|
||||
/*#include "romhdr.S"*/
|
||||
#include "hw.S"
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
;mov a, #'a'
|
||||
;call !!0xeffa1
|
||||
;ret
|
||||
|
||||
; call !hw_init
|
||||
|
||||
;1: call !glitch_mainloop
|
||||
; br $1b
|
||||
|
||||
;1: br $1b
|
||||
|
||||
hw_init:
|
||||
di
|
||||
|
||||
clrb !CRC0CTL
|
||||
clrb !IAWCTL
|
||||
;CRC0CTL = 0 ; f02f0
|
||||
;IAWCTL = 0 ; f0078
|
||||
|
||||
; CSC=fffa1
|
||||
; CKC=fffa4
|
||||
;CMC = 0 ; 0xfffa0
|
||||
;MSTOP = 1 ; CSC.7
|
||||
;MCM0 = 0 ; CKC.4
|
||||
;XTSTOP = 0 ; CSC.6
|
||||
;OSMC = 0 ; f00f3
|
||||
;CSS = 0 ; CKC.6 ;!
|
||||
set1 CKC.6
|
||||
;HIOSTOP = 0 ; CSC.0
|
||||
|
||||
mov !ADPC, #1
|
||||
;ADPC = 1 ; f0076
|
||||
mov PM2, #0
|
||||
|
||||
clrb !PMC2
|
||||
clrb !PIOR0
|
||||
clrb !PIOR1
|
||||
clrb !PIOR2
|
||||
clrb !PIOR3
|
||||
|
||||
mov P2, #0
|
||||
; ret
|
||||
|
||||
/* DUMPS EVERYTHING */
|
||||
|
||||
|
||||
/* LONG WAITCODE THAT DOESNT DO ANYTHING */
|
||||
|
||||
/* mov c, #0xff
|
||||
mov b, #0xff
|
||||
|
||||
1: dec c
|
||||
bnz $1b
|
||||
mov c, #0xff
|
||||
dec b
|
||||
bnz $1b
|
||||
xor P2, #0xff
|
||||
|
||||
br $1b*/
|
||||
|
||||
/* GLITCH TESTING CODE */
|
||||
|
||||
|
||||
/* TODO: how many segments do we need? */
|
||||
mov es, #0
|
||||
call !dump_segment
|
||||
|
||||
1: br $1b
|
||||
|
||||
dump_segment:
|
||||
movw hl, #0
|
||||
1: mov a, es:[hl]
|
||||
push hl
|
||||
call !!tool_tx
|
||||
pop hl
|
||||
incw hl
|
||||
movw ax, hl
|
||||
cmpw ax, #0
|
||||
bnz $1b
|
||||
mov es, #0xf
|
||||
ret
|
||||
|
||||
/*
|
||||
glitch_mainloop:
|
||||
mov P2, #0xff
|
||||
|
||||
movw ax, #0xfa00
|
||||
movw hl, ax
|
||||
|
||||
mov c, #0
|
||||
2: mov b, #0xff
|
||||
mov a, #0
|
||||
1: inc a
|
||||
dec b
|
||||
bnz $1b
|
||||
dec c
|
||||
mov [hl+c], a
|
||||
bnz $2b
|
||||
|
||||
mov P2, #0
|
||||
|
||||
; wait a bit
|
||||
mov c, #0x18
|
||||
4: mov b, #0xff
|
||||
5: dec b
|
||||
bnz $5b
|
||||
dec c
|
||||
bnz $4b
|
||||
|
||||
mov a, #'H'
|
||||
call !!tool_tx
|
||||
mov a, #'i'
|
||||
call !!tool_tx
|
||||
|
||||
mov x, #0xaa
|
||||
mov c, #0
|
||||
3: dec c
|
||||
mov a, [hl+c]
|
||||
xor a, x
|
||||
call !!tool_tx
|
||||
cmp0 c
|
||||
bnz $3b
|
||||
|
||||
br $glitch_mainloop
|
||||
|
||||
;ret
|
||||
|
||||
;data:
|
||||
*/
|
|
@ -0,0 +1 @@
|
|||
test_g13_param.S
|
|
@ -0,0 +1,91 @@
|
|||
|
||||
/*#include "romhdr.S"*/
|
||||
#include "hw.S"
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
;mov a, #'a'
|
||||
;call !!0xeffa1
|
||||
;ret
|
||||
|
||||
di
|
||||
|
||||
clrb !CRC0CTL
|
||||
clrb !IAWCTL
|
||||
;CRC0CTL = 0 ; f02f0
|
||||
;IAWCTL = 0 ; f0078
|
||||
|
||||
; CSC=fffa1
|
||||
; CKC=fffa4
|
||||
;CMC = 0 ; 0xfffa0
|
||||
;MSTOP = 1 ; CSC.7
|
||||
;MCM0 = 0 ; CKC.4
|
||||
;XTSTOP = 0 ; CSC.6
|
||||
;OSMC = 0 ; f00f3
|
||||
;CSS = 0 ; CKC.6 ;!
|
||||
set1 CKC.6
|
||||
;HIOSTOP = 0 ; CSC.0
|
||||
|
||||
mov !ADPC, #1
|
||||
;ADPC = 1 ; f0076
|
||||
mov PM2, #0
|
||||
|
||||
clrb !PMC2
|
||||
clrb !PIOR0
|
||||
clrb !PIOR1
|
||||
clrb !PIOR2
|
||||
clrb !PIOR3
|
||||
|
||||
mov P2, #0
|
||||
|
||||
|
||||
glitch_mainloop:
|
||||
mov P2, #0xff
|
||||
|
||||
movw ax, #0xfa00
|
||||
movw hl, ax
|
||||
|
||||
mov c, #0
|
||||
2: mov b, #0xff
|
||||
mov a, #0
|
||||
1: inc a
|
||||
dec b
|
||||
bnz $1b
|
||||
dec c
|
||||
mov [hl+c], a
|
||||
bnz $2b
|
||||
|
||||
mov P2, #0
|
||||
|
||||
; wait a bit
|
||||
mov c, #0x18
|
||||
4: mov b, #0xff
|
||||
5: dec b
|
||||
bnz $5b
|
||||
dec c
|
||||
bnz $4b
|
||||
|
||||
mov a, #'H'
|
||||
call !!tool_tx
|
||||
mov a, #'i'
|
||||
call !!tool_tx
|
||||
|
||||
mov x, #0xaa
|
||||
mov c, #0
|
||||
3: dec c
|
||||
mov a, [hl+c]
|
||||
xor a, x
|
||||
call !!tool_tx
|
||||
cmp0 c
|
||||
bnz $3b
|
||||
|
||||
; wait a bit
|
||||
mov c, #0x30
|
||||
4: mov b, #0xff
|
||||
5: dec b
|
||||
bnz $5b
|
||||
dec c
|
||||
bnz $4b
|
||||
|
||||
br $glitch_mainloop
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
/*#include "romhdr.S"*/
|
||||
#include "hw.S"
|
||||
|
||||
#define REG_ASIM 0xfffaf
|
||||
#define REG_TXS 0xfffad
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
/* ROM starts at 0xee000 on G23 */
|
||||
mov es, #0
|
||||
movw de, #0
|
||||
|
||||
/*mov a, es:[de]
|
||||
|
||||
mov a, #'a'*/
|
||||
|
||||
next:
|
||||
mov a, es:[de]
|
||||
br $tool_tx_fake
|
||||
return_bleh:
|
||||
incw de
|
||||
movw ax, de
|
||||
cmpw ax, #0
|
||||
bnz $next
|
||||
mov a, es
|
||||
inc a
|
||||
and a, #0xf
|
||||
mov es, a
|
||||
br $next
|
||||
|
||||
tool_tx_fake:
|
||||
set1 REG_ASIM.7
|
||||
nop
|
||||
mov REG_TXS, a
|
||||
wait_sent:
|
||||
bf REG_ASIM.3, $wait_sent
|
||||
clr1 REG_ASIM.3
|
||||
clr1 REG_ASIM.7
|
||||
br $return_bleh
|
||||
/*ret*/
|
|
@ -0,0 +1,106 @@
|
|||
|
||||
/*#include "romhdr.S"*/
|
||||
#include "hw.S"
|
||||
|
||||
#define REG_ASIM 0xfffaf
|
||||
#define REG_TXS 0xfffad
|
||||
|
||||
#define tool_tx_g23 0xeeac0
|
||||
|
||||
/*#define TX_FUNC !!tool_tx_g23*/
|
||||
#define TX_FUNC $!my_tool_tx
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
;mov a, #'a'
|
||||
;call !!0xeffa1
|
||||
;ret
|
||||
|
||||
di
|
||||
|
||||
clrb !CRC0CTL
|
||||
clrb !IAWCTL
|
||||
;CRC0CTL = 0 ; f02f0
|
||||
;IAWCTL = 0 ; f0078
|
||||
|
||||
; CSC=fffa1
|
||||
; CKC=fffa4
|
||||
;CMC = 0 ; 0xfffa0
|
||||
;MSTOP = 1 ; CSC.7
|
||||
;MCM0 = 0 ; CKC.4
|
||||
;XTSTOP = 0 ; CSC.6
|
||||
;OSMC = 0 ; f00f3
|
||||
;CSS = 0 ; CKC.6 ;!
|
||||
;set1 CKC.6
|
||||
;HIOSTOP = 0 ; CSC.0
|
||||
|
||||
; mov !ADPC, #1
|
||||
;ADPC = 1 ; f0076
|
||||
mov PM2, #0
|
||||
|
||||
clrb !PMC2
|
||||
clrb !PIOR0
|
||||
clrb !PIOR1
|
||||
clrb !PIOR2
|
||||
clrb !PIOR3
|
||||
|
||||
clrb P2
|
||||
|
||||
movw sp, #0xfe00
|
||||
|
||||
glitch_mainloop:
|
||||
mov P2, #0xff
|
||||
mov P2, #0xff
|
||||
|
||||
movw ax, #0xc000
|
||||
movw ax, #0xc000
|
||||
movw hl, ax
|
||||
movw hl, ax
|
||||
|
||||
mov c, #0
|
||||
2: mov b, #0xff
|
||||
mov a, #0
|
||||
1: inc a
|
||||
dec b
|
||||
bnz $1b
|
||||
dec c
|
||||
mov [hl+c], a
|
||||
bnz $2b
|
||||
|
||||
clrb P2
|
||||
clrb P2
|
||||
|
||||
; wait a bit
|
||||
mov c, #0x18
|
||||
4: mov b, #0xff
|
||||
5: dec b
|
||||
bnz $5b
|
||||
dec c
|
||||
bnz $4b
|
||||
|
||||
mov a, #'H'
|
||||
call TX_FUNC
|
||||
mov a, #'i'
|
||||
call TX_FUNC
|
||||
|
||||
mov x, #0xaa
|
||||
mov c, #0
|
||||
3: dec c
|
||||
mov a, [hl+c]
|
||||
xor a, x
|
||||
call TX_FUNC
|
||||
cmp0 c
|
||||
bnz $3b
|
||||
|
||||
br $glitch_mainloop
|
||||
|
||||
my_tool_tx:
|
||||
set1 REG_ASIM.7
|
||||
nop
|
||||
mov REG_TXS, a
|
||||
wait_sent:
|
||||
bf REG_ASIM.3, $wait_sent
|
||||
clr1 REG_ASIM.3
|
||||
clr1 REG_ASIM.7
|
||||
ret
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
|
||||
/*#include "romhdr.S"*/
|
||||
#include "hw.S"
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
;mov a, #'a'
|
||||
;call !!0xeffa1
|
||||
;ret
|
||||
|
||||
; call !hw_init
|
||||
|
||||
;1: call !glitch_mainloop
|
||||
; br $1b
|
||||
|
||||
;1: br $1b
|
||||
|
||||
hw_init:
|
||||
di
|
||||
|
||||
clrb !CRC0CTL
|
||||
clrb !IAWCTL
|
||||
;CRC0CTL = 0 ; f02f0
|
||||
;IAWCTL = 0 ; f0078
|
||||
|
||||
; CSC=fffa1
|
||||
; CKC=fffa4
|
||||
;CMC = 0 ; 0xfffa0
|
||||
;MSTOP = 1 ; CSC.7
|
||||
;MCM0 = 0 ; CKC.4
|
||||
;XTSTOP = 0 ; CSC.6
|
||||
;OSMC = 0 ; f00f3
|
||||
;CSS = 0 ; CKC.6 ;!
|
||||
set1 CKC.6
|
||||
;HIOSTOP = 0 ; CSC.0
|
||||
|
||||
mov !ADPC, #1
|
||||
;ADPC = 1 ; f0076
|
||||
mov PM2, #0
|
||||
|
||||
clrb !PMC2
|
||||
clrb !PIOR0
|
||||
clrb !PIOR1
|
||||
clrb !PIOR2
|
||||
clrb !PIOR3
|
||||
|
||||
mov P2, #0
|
||||
; ret
|
||||
|
||||
/* DUMPS EVERYTHING */
|
||||
|
||||
|
||||
/* LONG WAITCODE THAT DOESNT DO ANYTHING */
|
||||
|
||||
/* mov c, #0xff
|
||||
mov b, #0xff
|
||||
|
||||
1: dec c
|
||||
bnz $1b
|
||||
mov c, #0xff
|
||||
dec b
|
||||
bnz $1b
|
||||
xor P2, #0xff
|
||||
|
||||
br $1b*/
|
||||
|
||||
/* GLITCH TESTING CODE */
|
||||
|
||||
|
||||
/* TODO: how many segments do we need? */
|
||||
mov es, #0
|
||||
call !dump_segment
|
||||
|
||||
1: br $1b
|
||||
|
||||
dump_segment:
|
||||
movw hl, #0
|
||||
1: mov a, es:[hl]
|
||||
push hl
|
||||
call !!tool_tx
|
||||
pop hl
|
||||
incw hl
|
||||
movw ax, hl
|
||||
cmpw ax, #0
|
||||
bnz $1b
|
||||
mov es, #0xf
|
||||
ret
|
||||
|
||||
/*
|
||||
glitch_mainloop:
|
||||
mov P2, #0xff
|
||||
|
||||
movw ax, #0xfa00
|
||||
movw hl, ax
|
||||
|
||||
mov c, #0
|
||||
2: mov b, #0xff
|
||||
mov a, #0
|
||||
1: inc a
|
||||
dec b
|
||||
bnz $1b
|
||||
dec c
|
||||
mov [hl+c], a
|
||||
bnz $2b
|
||||
|
||||
mov P2, #0
|
||||
|
||||
; wait a bit
|
||||
mov c, #0x18
|
||||
4: mov b, #0xff
|
||||
5: dec b
|
||||
bnz $5b
|
||||
dec c
|
||||
bnz $4b
|
||||
|
||||
mov a, #'H'
|
||||
call !!tool_tx
|
||||
mov a, #'i'
|
||||
call !!tool_tx
|
||||
|
||||
mov x, #0xaa
|
||||
mov c, #0
|
||||
3: dec c
|
||||
mov a, [hl+c]
|
||||
xor a, x
|
||||
call !!tool_tx
|
||||
cmp0 c
|
||||
bnz $3b
|
||||
|
||||
br $glitch_mainloop
|
||||
|
||||
;ret
|
||||
|
||||
;data:
|
||||
*/
|
Loading…
Reference in New Issue