243 lines
5.9 KiB
C
243 lines
5.9 KiB
C
#include "contiki-net.h"
|
|
#include "ctk/ctk-draw.h"
|
|
|
|
#include <cbm.h>
|
|
#include <c64.h>
|
|
#include <string.h>
|
|
|
|
static struct {
|
|
struct psock sout, sin;
|
|
struct pt inpt, outpt;
|
|
char outputbuf[200];
|
|
char inputbuf[200];
|
|
unsigned short len;
|
|
} s;
|
|
|
|
#define CURSOR_ON() *(char *)0xcc = 0
|
|
#define CURSOR_OFF() *(char *)0xcc = 1
|
|
static void ctkmode(void);
|
|
/*---------------------------------------------------------------------------*/
|
|
static
|
|
PT_THREAD(send(void))
|
|
{
|
|
PSOCK_BEGIN(&s.sout);
|
|
|
|
PSOCK_SEND(&s.sout, s.outputbuf, s.len);
|
|
PSOCK_END(&s.sout);
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
static
|
|
PT_THREAD(handle_output(void))
|
|
{
|
|
ctk_arch_key_t c;
|
|
char *ptr;
|
|
|
|
PT_BEGIN(&s.outpt);
|
|
|
|
while(1) {
|
|
PT_WAIT_UNTIL(&s.outpt, (ctk_mode_get() == CTK_MODE_EXTERNAL) &&
|
|
kbhit());
|
|
|
|
|
|
ptr = s.outputbuf;
|
|
s.len = 0;
|
|
while(kbhit() && s.len < sizeof(s.outputbuf)) {
|
|
c = cgetc();
|
|
*ptr = c;
|
|
++ptr;
|
|
++s.len;
|
|
}
|
|
|
|
PT_WAIT_THREAD(&s.outpt, send());
|
|
}
|
|
PT_END(&s.outpt);
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
static
|
|
PT_THREAD(handle_input(void))
|
|
{
|
|
unsigned short i;
|
|
char *ptr;
|
|
char next;
|
|
|
|
next = 1;
|
|
PT_BEGIN(&s.inpt);
|
|
|
|
while(1) {
|
|
/* Wait until data arrives. */
|
|
next = 0;
|
|
PT_WAIT_UNTIL(&s.inpt, next && uip_newdata());
|
|
|
|
CURSOR_OFF();
|
|
/* Print it out on the screen. */
|
|
ptr = (char *)uip_appdata;
|
|
for(i = 0; i < uip_len; ++i) {
|
|
cbm_k_bsout(*ptr);
|
|
++ptr;
|
|
}
|
|
CURSOR_ON();
|
|
}
|
|
PT_END(&s.inpt);
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
static void
|
|
appcall(void *state)
|
|
{
|
|
if(uip_closed() || uip_aborted() || uip_timedout()) {
|
|
ctkmode();
|
|
} else if(uip_connected()) {
|
|
} else {
|
|
handle_input();
|
|
handle_output();
|
|
}
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
static struct uip_conn *
|
|
connect(u16_t *host, u16_t port)
|
|
{
|
|
PSOCK_INIT(&s.sin, s.inputbuf, sizeof(s.inputbuf));
|
|
PSOCK_INIT(&s.sout, s.inputbuf, sizeof(s.inputbuf));
|
|
PT_INIT(&s.inpt);
|
|
PT_INIT(&s.outpt);
|
|
return tcp_connect(host, htons(port), NULL);
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
PROCESS(cgterm_process, "C/G terminal");
|
|
|
|
static struct uip_conn *conn;
|
|
static u16_t serveraddr[2];
|
|
static u16_t serverport;
|
|
/*---------------------------------------------------------------------------*/
|
|
static struct ctk_window window;
|
|
static struct ctk_label hostlabel =
|
|
{CTK_LABEL(0, 0, 4, 1, "Host")};
|
|
static char host[32];
|
|
static struct ctk_textentry hostentry =
|
|
{CTK_TEXTENTRY(5, 0, 20, 1, host, sizeof(host) - 1)};
|
|
static struct ctk_label portlabel =
|
|
{CTK_LABEL(27, 0, 4, 1, "Port")};
|
|
static char port[7];
|
|
static struct ctk_textentry portentry =
|
|
{CTK_TEXTENTRY(32, 0, 4, 1, port, sizeof(port) - 1)};
|
|
static struct ctk_button connectbutton =
|
|
{CTK_BUTTON(0, 2, 7, "Connect")};
|
|
static struct ctk_button switchbutton =
|
|
{CTK_BUTTON(30, 2, 6, "Switch")};
|
|
static struct ctk_label helplabel =
|
|
{CTK_LABEL(0, 4, 37, 1, "RUN/STOP to return from terminal view")};
|
|
/*---------------------------------------------------------------------------*/
|
|
static void
|
|
ctkmode(void)
|
|
{
|
|
ctk_mode_set(CTK_MODE_NORMAL);
|
|
ctk_draw_init();
|
|
ctk_desktop_redraw(NULL);
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
static void
|
|
textmode(void)
|
|
{
|
|
ctk_mode_set(CTK_MODE_EXTERNAL);
|
|
|
|
VIC.ctrl1 = 0x1b; /* $D011 */
|
|
VIC.addr = 0x17; /* $D018 */
|
|
VIC.ctrl2 = 0xc8; /* $D016 */
|
|
CIA2.pra = 0x03; /* $DD00 */
|
|
|
|
VIC.bordercolor = 0x00; /* $D020 */
|
|
VIC.bgcolor0 = 0x00; /* $D021 */
|
|
|
|
CURSOR_ON();
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
static void
|
|
pollhandler(void)
|
|
{
|
|
if(ctk_mode_get() == CTK_MODE_EXTERNAL) {
|
|
if(CIA1.prb == 0x7f) {
|
|
ctkmode();
|
|
} else if(kbhit() && conn != NULL) {
|
|
tcpip_poll_tcp(conn);
|
|
}
|
|
}
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
PROCESS_THREAD(cgterm_process, ev, data)
|
|
{
|
|
u16_t *ipaddr;
|
|
char *cptr;
|
|
|
|
PROCESS_POLLHANDLER(pollhandler());
|
|
|
|
PROCESS_BEGIN();
|
|
|
|
ctk_window_new(&window, 38, 5, "C/G term");
|
|
CTK_WIDGET_ADD(&window, &hostlabel);
|
|
CTK_WIDGET_ADD(&window, &hostentry);
|
|
CTK_WIDGET_ADD(&window, &portlabel);
|
|
CTK_WIDGET_ADD(&window, &portentry);
|
|
CTK_WIDGET_ADD(&window, &connectbutton);
|
|
CTK_WIDGET_ADD(&window, &switchbutton);
|
|
CTK_WIDGET_ADD(&window, &helplabel);
|
|
ctk_window_open(&window);
|
|
|
|
while(1) {
|
|
PROCESS_WAIT_EVENT();
|
|
|
|
if(ev == tcpip_event) {
|
|
appcall(data);
|
|
} else if(ev == ctk_signal_widget_activate) {
|
|
|
|
if(data == &switchbutton) {
|
|
textmode();
|
|
} else if(data == &connectbutton) {
|
|
serverport = 0;
|
|
for(cptr = port; *cptr != ' ' && *cptr != 0; ++cptr) {
|
|
if(*cptr < '0' || *cptr > '9') {
|
|
continue;
|
|
}
|
|
serverport = 10 * serverport + *cptr - '0';
|
|
}
|
|
|
|
ipaddr = serveraddr;
|
|
if(uiplib_ipaddrconv(host, (u8_t *)serveraddr) == 0) {
|
|
ipaddr = resolv_lookup(host);
|
|
if(ipaddr == NULL) {
|
|
resolv_query(host);
|
|
} else {
|
|
uip_ipaddr_copy(serveraddr, ipaddr);
|
|
}
|
|
}
|
|
if(ipaddr != NULL) {
|
|
conn = connect(serveraddr, serverport);
|
|
if(conn != NULL) {
|
|
memset((char *)0x0400, 0x20, 40*25);
|
|
memset((char *)0xd800, 0x01, 40*25);
|
|
textmode();
|
|
}
|
|
}
|
|
}
|
|
} else if(ev == resolv_event_found) {
|
|
ipaddr = resolv_lookup(host);
|
|
if(ipaddr != NULL) {
|
|
uip_ipaddr_copy(serveraddr, ipaddr);
|
|
|
|
conn = connect(serveraddr, serverport);
|
|
if(conn != NULL) {
|
|
memset((char *)0x0400, 0x20, 40*25);
|
|
memset((char *)0xd800, 0x01, 40*25);
|
|
textmode();
|
|
}
|
|
}
|
|
} else if(ev == PROCESS_EVENT_EXIT ||
|
|
ev == ctk_signal_window_close) {
|
|
|
|
break;
|
|
}
|
|
}
|
|
ctk_window_close(&window);
|
|
|
|
PROCESS_END();
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|