blob: fa85a40f87cd1eeda42f174cba9ea342a50eb952 [file] [log] [blame]
kthacker62e146c2006-04-17 15:11:35 +00001#include "contiki.h"
2#include "socket.h"
3#include "ctk-draw.h"
4
5#include <cbm.h>
6#include <c64.h>
7#include <string.h>
8
9static struct {
10 struct socket sout, sin;
11 struct pt inpt, outpt;
12 char outputbuf[200];
13 char inputbuf[200];
14 unsigned short len;
15} s;
16
17#define CURSOR_ON() *(char *)0xcc = 0
18#define CURSOR_OFF() *(char *)0xcc = 1
19static void ctkmode(void);
20/*---------------------------------------------------------------------------*/
21static
22PT_THREAD(send(void))
23{
24 SOCKET_BEGIN(&s.sout);
25
26 SOCKET_SEND(&s.sout, s.outputbuf, s.len);
27 SOCKET_END(&s.sout);
28}
29/*---------------------------------------------------------------------------*/
30static
31PT_THREAD(handle_output(void))
32{
33 ctk_arch_key_t c;
34 char *ptr;
35
36 PT_BEGIN(&s.outpt);
37
38 while(1) {
39 PT_WAIT_UNTIL(&s.outpt, (ctk_mode_get() == CTK_MODE_EXTERNAL) &&
40 kbhit());
41
42
43 ptr = s.outputbuf;
44 s.len = 0;
45 while(kbhit() && s.len < sizeof(s.outputbuf)) {
46 c = cgetc();
47 *ptr = c;
48 ++ptr;
49 ++s.len;
50 }
51
52 PT_WAIT_THREAD(&s.outpt, send());
53 }
54 PT_END(&s.outpt);
55}
56/*---------------------------------------------------------------------------*/
57static
58PT_THREAD(handle_input(void))
59{
60 unsigned short i;
61 char *ptr;
62 char next;
63
64 next = 1;
65 PT_BEGIN(&s.inpt);
66
67 while(1) {
68 /* Wait until data arrives. */
69 next = 0;
70 PT_WAIT_UNTIL(&s.inpt, next && uip_newdata());
71
72 CURSOR_OFF();
73 /* Print it out on the screen. */
74 ptr = (char *)uip_appdata;
75 for(i = 0; i < uip_len; ++i) {
76 cbm_k_bsout(*ptr);
77 ++ptr;
78 }
79 CURSOR_ON();
80 }
81 PT_END(&s.inpt);
82}
83/*---------------------------------------------------------------------------*/
84static void
85appcall(void *state)
86{
87 if(uip_closed() || uip_aborted() || uip_timedout()) {
88 ctkmode();
89 } else if(uip_connected()) {
90 } else {
91 handle_input();
92 handle_output();
93 }
94}
95/*---------------------------------------------------------------------------*/
96static struct uip_conn *
97connect(u16_t *host, u16_t port)
98{
99 SOCKET_INIT(&s.sin, s.inputbuf, sizeof(s.inputbuf));
100 SOCKET_INIT(&s.sout, s.inputbuf, sizeof(s.inputbuf));
101 PT_INIT(&s.inpt);
102 PT_INIT(&s.outpt);
103 return tcp_connect(host, htons(port), NULL);
104}
105/*---------------------------------------------------------------------------*/
106EK_POLLHANDLER(pollhandler);
107EK_EVENTHANDLER(eventhandler, ev, data);
108EK_PROCESS(p, "C/G terminal", EK_PRIO_NORMAL,
109 eventhandler, pollhandler, NULL);
110static ek_id_t id = EK_ID_NONE;
111static struct uip_conn *conn;
112static u16_t serveraddr[2];
113static u16_t serverport;
114/*---------------------------------------------------------------------------*/
115static struct ctk_window window;
116static struct ctk_label hostlabel =
117 {CTK_LABEL(0, 0, 4, 1, "Host")};
118static char host[32];
119static struct ctk_textentry hostentry =
120 {CTK_TEXTENTRY(5, 0, 20, 1, host, sizeof(host) - 1)};
121static struct ctk_label portlabel =
122 {CTK_LABEL(27, 0, 4, 1, "Port")};
123static char port[7];
124static struct ctk_textentry portentry =
125 {CTK_TEXTENTRY(32, 0, 4, 1, port, sizeof(port) - 1)};
126static struct ctk_button connectbutton =
127 {CTK_BUTTON(0, 2, 7, "Connect")};
128static struct ctk_button switchbutton =
129 {CTK_BUTTON(30, 2, 6, "Switch")};
130static struct ctk_label helplabel =
131 {CTK_LABEL(0, 4, 37, 1, "RUN/STOP to return from terminal view")};
132/*---------------------------------------------------------------------------*/
133LOADER_INIT_FUNC(cgterm_init, arg)
134{
135 arg_free(arg);
136 if(id == EK_ID_NONE) {
137 id = ek_start(&p);
138 }
139}
140/*---------------------------------------------------------------------------*/
141static void
142ctkmode(void)
143{
144 ctk_mode_set(CTK_MODE_NORMAL);
145 ctk_draw_init();
146 ctk_desktop_redraw(NULL);
147}
148/*---------------------------------------------------------------------------*/
149static void
150textmode(void)
151{
152 ctk_mode_set(CTK_MODE_EXTERNAL);
153
154 VIC.ctrl1 = 0x1b; /* $D011 */
155 VIC.addr = 0x17; /* $D018 */
156 VIC.ctrl2 = 0xc8; /* $D016 */
157 CIA2.pra = 0x03; /* $DD00 */
158
159 VIC.bordercolor = 0x00; /* $D020 */
160 VIC.bgcolor0 = 0x00; /* $D021 */
161
162 CURSOR_ON();
163}
164/*---------------------------------------------------------------------------*/
165EK_EVENTHANDLER(eventhandler, ev, data)
166{
167 u16_t *ipaddr;
168 char *cptr;
169
170 if(ev == tcpip_event) {
171 appcall(data);
172 } else if(ev == EK_EVENT_INIT) {
173 ctk_window_new(&window, 38, 5, "C/G term");
174 CTK_WIDGET_ADD(&window, &hostlabel);
175 CTK_WIDGET_ADD(&window, &hostentry);
176 CTK_WIDGET_ADD(&window, &portlabel);
177 CTK_WIDGET_ADD(&window, &portentry);
178 CTK_WIDGET_ADD(&window, &connectbutton);
179 CTK_WIDGET_ADD(&window, &switchbutton);
180 CTK_WIDGET_ADD(&window, &helplabel);
181 ctk_window_open(&window);
182 } else if(ev == ctk_signal_widget_activate) {
183
184 if(data == (ek_data_t)&switchbutton) {
185 textmode();
186 } else if(data == (ek_data_t)&connectbutton) {
187 serverport = 0;
188 for(cptr = port; *cptr != ' ' && *cptr != 0; ++cptr) {
189 if(*cptr < '0' || *cptr > '9') {
190 return;
191 }
192 serverport = 10 * serverport + *cptr - '0';
193 }
194
195 ipaddr = serveraddr;
196 if(uiplib_ipaddrconv(host, (u8_t *)serveraddr) == 0) {
197 ipaddr = resolv_lookup(host);
198 if(ipaddr == NULL) {
199 resolv_query(host);
200 } else {
201 uip_ipaddr_copy(serveraddr, ipaddr);
202 }
203 }
204 if(ipaddr != NULL) {
205 conn = connect(serveraddr, serverport);
206 if(conn != NULL) {
207 memset((char *)0x0400, 0x20, 40*25);
208 memset((char *)0xd800, 0x01, 40*25);
209 textmode();
210 }
211 }
212 }
213 } else if(ev == resolv_event_found) {
214 ipaddr = resolv_lookup(host);
215 if(ipaddr != NULL) {
216 uip_ipaddr_copy(serveraddr, ipaddr);
217
218 conn = connect(serveraddr, serverport);
219 if(conn != NULL) {
220 memset((char *)0x0400, 0x20, 40*25);
221 memset((char *)0xd800, 0x01, 40*25);
222 textmode();
223 }
224 }
225 } else if(ev == EK_EVENT_REQUEST_EXIT ||
226 ev == ctk_signal_window_close) {
227 ctk_window_close(&window);
228 ek_exit();
229 LOADER_UNLOAD();
230 }
231}
232/*---------------------------------------------------------------------------*/
233EK_POLLHANDLER(pollhandler)
234{
235 if(ctk_mode_get() == CTK_MODE_EXTERNAL) {
236 if(CIA1.prb == 0x7f) {
237 ctkmode();
238 } else if(kbhit() && conn != NULL) {
239 tcpip_poll_tcp(conn);
240 }
241 }
242}
243/*---------------------------------------------------------------------------*/