Add ability to send debug messages over GDB
This commit is contained in:
parent
e26ea540e7
commit
ea9665a100
6 changed files with 305 additions and 67 deletions
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
|
@ -30,7 +30,7 @@
|
|||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/tikeys",
|
||||
"args": ["--subtype=mirage", "--log-level=trace"],
|
||||
"args": ["--program=u1BERSHRD", "--log-level=trace"],
|
||||
"stopAtEntry": true,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
|
|
31
.vscode/settings.json
vendored
31
.vscode/settings.json
vendored
|
@ -4,7 +4,36 @@
|
|||
"ticalcs.h": "c",
|
||||
"ticables.h": "c",
|
||||
"vector": "c",
|
||||
"random": "c"
|
||||
"random": "c",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cmath": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"optional": "cpp",
|
||||
"string_view": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"functional": "cpp",
|
||||
"fstream": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"new": "cpp",
|
||||
"numeric": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"cstddef": "c"
|
||||
},
|
||||
"cmake.configureOnOpen": true
|
||||
}
|
|
@ -7,9 +7,12 @@ find_package(PkgConfig REQUIRED)
|
|||
PKG_CHECK_MODULES(GLIB REQUIRED glib-2.0)
|
||||
PKG_CHECK_MODULES(TICABLES REQUIRED ticables2)
|
||||
PKG_CHECK_MODULES(TICALCS REQUIRED ticalcs2)
|
||||
PKG_CHECK_MODULES(TIFILES REQUIRED tifiles2)
|
||||
|
||||
file(GLOB COMMON_SRC src/common/*.c)
|
||||
|
||||
####################################### TIBRIDGE ###############################
|
||||
|
||||
file(GLOB TIBRIDGE_SRC src/tibridge.c)
|
||||
|
||||
add_executable(tibridge ${COMMON_SRC} ${TIBRIDGE_SRC})
|
||||
|
@ -30,6 +33,8 @@ target_link_directories(tibridge PRIVATE ${TICABLES_LIBRARIES})
|
|||
|
||||
PKG_CHECK_MODULES(READLINE REQUIRED readline)
|
||||
|
||||
####################################### TIKEYS ###############################
|
||||
|
||||
file(GLOB TIKEYS_SRC src/tikeys.c)
|
||||
|
||||
add_executable(tikeys ${COMMON_SRC} ${TIKEYS_SRC})
|
||||
|
@ -41,15 +46,18 @@ target_include_directories(tikeys
|
|||
PRIVATE ${GLIB_INCLUDE_DIRS}
|
||||
PRIVATE ${TICABLES_INCLUDE_DIRS}
|
||||
PRIVATE ${TICALCS_INCLUDE_DIRS}
|
||||
PRIVATE ${TIFILES_INCLUDE_DIRS}
|
||||
PRIVATE ${READLINE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(tikeys PRIVATE ${GLIB_LIBRARIES})
|
||||
target_link_libraries(tikeys PRIVATE ${TICABLES_LIBRARIES})
|
||||
target_link_libraries(tikeys PRIVATE ${TICALCS_LIBRARIES})
|
||||
target_link_libraries(tikeys PRIVATE ${TIFILES_LIBRARIES})
|
||||
target_link_libraries(tikeys PRIVATE ${READLINE_LIBRARIES})
|
||||
|
||||
target_link_directories(tikeys PRIVATE ${GLIB_LIBRARY_DIRS})
|
||||
target_link_directories(tikeys PRIVATE ${TICABLES_LIBRARIES})
|
||||
target_link_directories(tikeys PRIVATE ${TICALCS_LIBRARIES})
|
||||
target_link_directories(tikeys PRIVATE ${TIFILES_LIBRARIES})
|
||||
target_link_directories(tikeys PRIVATE ${READLINE_LIBRARIES})
|
|
@ -42,6 +42,7 @@ void utils_parse_args(int argc, char *argv[]) {
|
|||
{0,0,0,0}
|
||||
};
|
||||
|
||||
opterr = 0;
|
||||
optind = 0;
|
||||
int opt_index = 0;
|
||||
int opt;
|
||||
|
@ -64,4 +65,6 @@ void utils_parse_args(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
opterr = 1;
|
||||
}
|
|
@ -2,35 +2,53 @@
|
|||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <error.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "common/utils.h"
|
||||
|
||||
static CableDeviceInfo EmptyInfo;
|
||||
|
||||
static pthread_t tid;
|
||||
|
||||
static CableHandle* handle;
|
||||
static CableHandle* cable_handle;
|
||||
|
||||
static CablePort port;
|
||||
static CableModel model;
|
||||
int hex(char ch) {
|
||||
if ((ch >= 'a') && (ch <= 'f'))
|
||||
return (ch - 'a' + 10);
|
||||
if ((ch >= '0') && (ch <= '9'))
|
||||
return (ch - '0');
|
||||
if ((ch >= 'A') && (ch <= 'F'))
|
||||
return (ch - 'A' + 10);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
uint8_t *hex2mem(const char *buf, uint8_t *mem, uint32_t count) {
|
||||
unsigned char ch;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
ch = hex(*buf++) << 4;
|
||||
ch = ch + hex(*buf++);
|
||||
*(mem++) = (char)ch;
|
||||
}
|
||||
return (mem);
|
||||
}
|
||||
|
||||
void reset_cable(void) {
|
||||
unsigned char err;
|
||||
ticables_cable_reset(handle);
|
||||
ticables_cable_close(handle);
|
||||
ticables_handle_del(handle);
|
||||
handle = ticables_handle_new(model, port);
|
||||
ticables_options_set_delay(handle, 1);
|
||||
ticables_options_set_timeout(handle, 5);
|
||||
CablePort port;
|
||||
CableModel model;
|
||||
port = cable_handle->port;
|
||||
model = cable_handle->model;
|
||||
int err;
|
||||
ticables_cable_reset(cable_handle);
|
||||
ticables_cable_close(cable_handle);
|
||||
ticables_handle_del(cable_handle);
|
||||
cable_handle = ticables_handle_new(model, port);
|
||||
ticables_options_set_delay(cable_handle, 1);
|
||||
ticables_options_set_timeout(cable_handle, 5);
|
||||
|
||||
while(err = ticables_cable_open(handle)) {
|
||||
fprintf(stderr, "Could not open cable: %d\n", err);
|
||||
while(err = ticables_cable_open(cable_handle)) {
|
||||
log(LEVEL_ERROR, "Could not open cable: %d\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +56,7 @@ void retry_send(unsigned char* send, int sendCount) {
|
|||
unsigned char err = 0;
|
||||
log(LEVEL_DEBUG, "%d->", sendCount);
|
||||
log(LEVEL_TRACE, "%.*s\n", sendCount, send);
|
||||
while(err = ticables_cable_send(handle, send, sendCount)) {
|
||||
while(err = ticables_cable_send(cable_handle, send, sendCount)) {
|
||||
log(LEVEL_ERROR, "Error sending: %d", err);
|
||||
reset_cable();
|
||||
}
|
||||
|
@ -61,7 +79,6 @@ void retry_recv(unsigned char* recv, int recvCount) {
|
|||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int err;
|
||||
// z88dk-gdb doesn't like the ACKs -/+, so we just hide them
|
||||
int handle_acks = 1;
|
||||
|
||||
|
@ -87,30 +104,33 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
log(LEVEL_DEBUG, "handle acks: %d\n", handle_acks);
|
||||
|
||||
int err;
|
||||
ticables_library_init();
|
||||
|
||||
log(LEVEL_INFO, "PROCESS ID: %d\n", getpid());
|
||||
|
||||
handle = utils_setup_cable();
|
||||
if(handle == NULL) {
|
||||
cable_handle = utils_setup_cable();
|
||||
if(cable_handle == NULL) {
|
||||
log(LEVEL_ERROR, "Cable not found!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
err = ticables_cable_open(handle);
|
||||
//ticables_options_set_timeout(cable_handle , 1 * 60 * 60 * 10);
|
||||
|
||||
err = ticables_cable_open(cable_handle);
|
||||
if(err) {
|
||||
log(LEVEL_ERROR, "Could not open cable: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
CableDeviceInfo info = EmptyInfo;
|
||||
err = ticables_cable_get_device_info(handle, &info);
|
||||
CableDeviceInfo info;
|
||||
err = ticables_cable_get_device_info(cable_handle, &info);
|
||||
if(err) {
|
||||
log(LEVEL_ERROR, "Could not read device info: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
log(LEVEL_INFO, "INFO: Model %d, Port:%d, Family %d, Variant %d\n", model, port, info.family, info.variant);
|
||||
log(LEVEL_INFO, "Cable Family %d, Variant %d\n", info.family, info.variant);
|
||||
|
||||
bool handled_first_recv = false;
|
||||
|
||||
|
@ -124,7 +144,7 @@ int main(int argc, char *argv[]) {
|
|||
log(LEVEL_DEBUG, "RECEIVE PHASE\n");
|
||||
while(true) {
|
||||
do {
|
||||
if(err = ticables_cable_recv(handle, &recv[recvCount], 1)) {
|
||||
if(err = ticables_cable_recv(cable_handle, &recv[recvCount], 1)) {
|
||||
log(LEVEL_ERROR, "error receiving: %d\n", err);
|
||||
}
|
||||
} while(err);
|
||||
|
@ -132,12 +152,14 @@ int main(int argc, char *argv[]) {
|
|||
recvCount++;
|
||||
if(current == '#') {
|
||||
do {
|
||||
if(err = ticables_cable_recv(handle, &recv[recvCount], 2)) {
|
||||
if(err = ticables_cable_recv(cable_handle, &recv[recvCount], 2)) {
|
||||
log(LEVEL_ERROR, "error receiving: %d\n", err);
|
||||
}
|
||||
} while(err);
|
||||
recvCount += 2;
|
||||
|
||||
recv[recvCount] = '\0';
|
||||
|
||||
if(!handle_acks || handled_first_recv) {
|
||||
retry_recv(recv, recvCount);
|
||||
}
|
||||
|
@ -145,6 +167,20 @@ int main(int argc, char *argv[]) {
|
|||
log(LEVEL_DEBUG, "Discarded the first packet\n");
|
||||
}
|
||||
|
||||
char *packet_char = strchr(recv, '$');
|
||||
if(packet_char) {
|
||||
packet_char++;
|
||||
|
||||
if(*packet_char == 'O') {
|
||||
int data_size = (recvCount - 5) / 2;
|
||||
char buf[data_size];
|
||||
hex2mem(&packet_char[1], buf, data_size);
|
||||
log(LEVEL_INFO, "\n%.*s", data_size, buf);
|
||||
recvCount = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(handle_acks) {
|
||||
log(LEVEL_DEBUG, "Injecting an ACK\n");
|
||||
ack();
|
||||
|
|
192
src/tikeys.c
192
src/tikeys.c
|
@ -1,39 +1,115 @@
|
|||
#include <tilp2/ticables.h>
|
||||
#include <tilp2/ticalcs.h>
|
||||
#include "common/utils.h"
|
||||
#include <readline/readline.h>
|
||||
#include <tilp2/keys83p.h>
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *subtype = "mirage";
|
||||
#include <readline/readline.h>
|
||||
#include <glib-2.0/glib.h>
|
||||
|
||||
#include <tilp2/ticables.h>
|
||||
#include <tilp2/ticalcs.h>
|
||||
#include <tilp2/tifiles.h>
|
||||
#include <tilp2/keys83p.h>
|
||||
|
||||
#include "common/utils.h"
|
||||
|
||||
static char *subtype = "";
|
||||
static char *program = "";
|
||||
static char *keys = "";
|
||||
static int reset_ram = 0;
|
||||
|
||||
static CalcHandle *calc_handle = NULL;
|
||||
static CalcModel model = CALC_NONE;
|
||||
|
||||
void send_key(uint32_t key, int retry) {
|
||||
usleep(250000);
|
||||
static void send_key(uint32_t key, int retry) {
|
||||
usleep(100000);
|
||||
int err;
|
||||
while(err = ticalcs_calc_send_key(calc_handle, key) && retry);
|
||||
}
|
||||
|
||||
static int compare(const void *a, const void *b) {
|
||||
return strcmp(*(const char**)a, *(const char**)b);
|
||||
}
|
||||
|
||||
static int get_program_index(GNode *tree, char* program) {
|
||||
char *names[1024];
|
||||
int n = 0;
|
||||
|
||||
TreeInfo *info = tree->data;
|
||||
for (int i = 0; i < (int)g_node_n_children(tree); i++) {
|
||||
GNode *parent = g_node_nth_child(tree, i);
|
||||
VarEntry *ve = parent->data;
|
||||
|
||||
for (int j = 0; j < (int)g_node_n_children(parent); j++) {
|
||||
GNode *child = g_node_nth_child(parent, j);
|
||||
ve = child->data;
|
||||
|
||||
if(ve != NULL) {
|
||||
const char *str_type = tifiles_vartype2string(model, ve->type);
|
||||
|
||||
if (strlen(str_type) >= 4
|
||||
&& (
|
||||
strcmp(&str_type[strlen(str_type) - 4], "PRGM") == 0
|
||||
|| strcmp(str_type, "APPL") == 0
|
||||
)
|
||||
) {
|
||||
names[n++] = ve->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qsort(names, n, sizeof(names[0]), compare);
|
||||
for(int i = 0; i < n; i++) {
|
||||
if(strcmp(names[i], program) == 0) {
|
||||
return i+1; // Finance is always at the beginning
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void show_help() {
|
||||
log(LEVEL_INFO, "Syntax: tikeys [--reset-ram] [--keys=ABCDEFG123456789] [--subtype=mirage --program=PROGNAME]\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
utils_parse_args(argc, argv);
|
||||
|
||||
const struct option long_opts[] = {
|
||||
//{name,arg,flag,val}
|
||||
{"subtype", required_argument, 0, 's'},
|
||||
{"program", required_argument, 0, 'p'},
|
||||
{"keys", required_argument, 0, 'k'},
|
||||
{"reset-ram", no_argument, &reset_ram, 1},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{0,0,0,0}
|
||||
};
|
||||
|
||||
optind = 0;
|
||||
int opt_index = 0;
|
||||
int opt;
|
||||
while((opt = getopt_long(argc, argv, "s:", long_opts, &opt_index)) != -1) {
|
||||
if(opt == 's') {
|
||||
while((opt = getopt_long(argc, argv, "s:p:", long_opts, &opt_index)) != -1) {
|
||||
if(opt == 0 && long_opts[opt_index].flag) {
|
||||
// Do nothing
|
||||
}
|
||||
else if(opt == 's') {
|
||||
subtype = optarg;
|
||||
}
|
||||
else if(opt == 'p') {
|
||||
program = optarg;
|
||||
}
|
||||
else if(opt == 'k') {
|
||||
keys = optarg;
|
||||
}
|
||||
else if(opt == 'r') {
|
||||
reset_ram = 1;
|
||||
}
|
||||
else if(opt == 'h') {
|
||||
show_help();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int err;
|
||||
ticables_library_init();
|
||||
|
||||
CableHandle *cable_handle = utils_setup_cable();
|
||||
|
@ -42,15 +118,54 @@ int main(int argc, char *argv[]) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
err = ticables_cable_open(cable_handle);
|
||||
if(err) {
|
||||
log(LEVEL_ERROR, "Could not open cable: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
CableDeviceInfo info;
|
||||
err = ticables_cable_get_device_info(cable_handle, &info);
|
||||
if(err) {
|
||||
log(LEVEL_ERROR, "Could not read device info: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
err = ticables_cable_close(cable_handle);
|
||||
if(err) {
|
||||
log(LEVEL_ERROR, "Could not close cable: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ticables_handle_del(cable_handle);
|
||||
|
||||
cable_handle = utils_setup_cable();
|
||||
|
||||
ticables_options_set_timeout(cable_handle, 20);
|
||||
|
||||
calc_handle = ticalcs_handle_new(CALC_TI83P);
|
||||
model = CALC_TI83P;
|
||||
|
||||
calc_handle = ticalcs_handle_new(model);
|
||||
ticalcs_cable_attach(calc_handle, cable_handle);
|
||||
|
||||
if(reset_ram) {
|
||||
send_key(KEY83P_Quit, 1);
|
||||
send_key(KEY83P_Clear, 1);
|
||||
|
||||
log(LEVEL_WARN, "Resetting RAM...\n");
|
||||
send_key(KEY83P_ResetMem, 0);
|
||||
}
|
||||
|
||||
if(strlen(keys) > 0) {
|
||||
for(int i = 0; i < strlen(keys); i++) {
|
||||
send_key(ticalcs_keys_83p(keys[i])->normal.value, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(strlen(subtype) > 0 || strlen(program) > 0) {
|
||||
send_key(KEY83P_Quit, 1);
|
||||
send_key(KEY83P_Clear, 1);
|
||||
|
||||
int err;
|
||||
if(strcmp(subtype, "asm") == 0) {
|
||||
log(LEVEL_ERROR, "asm is not supported! Start it manually!\n");
|
||||
return 1;
|
||||
|
@ -72,12 +187,59 @@ int main(int argc, char *argv[]) {
|
|||
send_key(ticalcs_keys_83p('M')->normal.value, 1);
|
||||
send_key(KEY83P_Enter, 0);
|
||||
}
|
||||
else {
|
||||
log(LEVEL_WARN, "Subtype was not recognized! Start it manually!\n");
|
||||
else if(strlen(program) > 0) {
|
||||
if(strcmp(subtype, "noshell") != 0) {
|
||||
log(LEVEL_WARN, "Subtype was not recognized! It will be started with noshell!\n");
|
||||
}
|
||||
|
||||
log(LEVEL_INFO, "Verifying that noshell is correctly hooked.\n");
|
||||
|
||||
int err;
|
||||
GNode *vars, *apps;
|
||||
while(err = ticalcs_calc_get_dirlist(calc_handle, &vars, &apps));
|
||||
|
||||
log(LEVEL_DEBUG, "Got dirlist\n");
|
||||
|
||||
int noshell_idx = get_program_index(apps, "Noshell ");
|
||||
if(noshell_idx == -1) {
|
||||
log(LEVEL_ERROR, "Could not find noshell. Exiting\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
send_key(KEY83P_AppsMenu, 1);
|
||||
for(int i = 0; i < noshell_idx; i++) {
|
||||
send_key(KEY83P_Down, 1);
|
||||
}
|
||||
//send_key(KEY83P_Enter, 0);
|
||||
|
||||
return 1;
|
||||
|
||||
get_program_index(vars, program);
|
||||
|
||||
// There has to be a better way to do this...
|
||||
// Select a program then delete the name,
|
||||
// keeping only the pgrm token
|
||||
send_key(KEY83P_Prgm, 1);
|
||||
send_key(KEY83P_Enter, 1);
|
||||
send_key(KEY83P_Up, 1);
|
||||
send_key(KEY83P_Right, 1);
|
||||
for(int i = 0; i < 16; i++) {
|
||||
send_key(KEY83P_Del, 1);
|
||||
}
|
||||
|
||||
// Actually input the name
|
||||
for(int i = 0; i < strlen(program); i++) {
|
||||
send_key(ticalcs_keys_83p(program[i])->normal.value, 1);
|
||||
}
|
||||
send_key(KEY83P_Enter, 0);
|
||||
}
|
||||
}
|
||||
|
||||
ticalcs_cable_detach(calc_handle);
|
||||
ticalcs_handle_del(calc_handle);
|
||||
ticables_cable_close(cable_handle);
|
||||
ticables_handle_del(cable_handle);
|
||||
ticables_library_exit();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue