xref: /inferno-os/appl/cmd/rdp.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsythimplement Rdp;
2*37da2899SCharles.Forsythinclude "sys.m";
3*37da2899SCharles.Forsyth	sys: Sys;
4*37da2899SCharles.Forsyth	print, sprint: import sys;
5*37da2899SCharles.Forsythinclude "draw.m";
6*37da2899SCharles.Forsythinclude "string.m";
7*37da2899SCharles.Forsyth	str: String;
8*37da2899SCharles.Forsyth
9*37da2899SCharles.Forsythdf_port: con "/dev/eia0";
10*37da2899SCharles.Forsythdf_bps: con 38400;
11*37da2899SCharles.Forsyth
12*37da2899SCharles.ForsythRdp: module
13*37da2899SCharles.Forsyth{
14*37da2899SCharles.Forsyth	init:	fn(nil: ref Draw->Context, arg: list of string);
15*37da2899SCharles.Forsyth};
16*37da2899SCharles.Forsyth
17*37da2899SCharles.Forsythdfd: ref sys->FD;
18*37da2899SCharles.Forsythcfd: ref sys->FD;
19*37da2899SCharles.Forsythifd: ref sys->FD;
20*37da2899SCharles.Forsythpifd: ref sys->FD;
21*37da2899SCharles.Forsythp_isopen := 0;
22*37da2899SCharles.Forsyth
23*37da2899SCharles.ForsythR_R15: con 15;
24*37da2899SCharles.ForsythR_PC: con 16;
25*37da2899SCharles.ForsythR_CPSR: con 17;
26*37da2899SCharles.ForsythR_SPSR: con 18;
27*37da2899SCharles.ForsythNREG: con 19;
28*37da2899SCharles.Forsyth
29*37da2899SCharles.Forsythdebug := 0;
30*37da2899SCharles.Forsythnocr := 0;
31*37da2899SCharles.Forsythtmode := 0;
32*37da2899SCharles.Forsyth# echar := 16r1c;		# ctrl-\
33*37da2899SCharles.Forsythechar := 16r1d;		# ctrl-]  (because Tk grabs the ctrl-\ )
34*37da2899SCharles.Forsyth
35*37da2899SCharles.Forsythbint(x: int): array of byte
36*37da2899SCharles.Forsyth{
37*37da2899SCharles.Forsyth	b := array[4] of byte;
38*37da2899SCharles.Forsyth	b[0] = byte x;
39*37da2899SCharles.Forsyth	b[1] = byte (x>>8);
40*37da2899SCharles.Forsyth	b[2] = byte (x>>16);
41*37da2899SCharles.Forsyth	b[3] = byte (x>>24);
42*37da2899SCharles.Forsyth	return b;
43*37da2899SCharles.Forsyth}
44*37da2899SCharles.Forsyth
45*37da2899SCharles.Forsythintb(b: array of byte): int
46*37da2899SCharles.Forsyth{
47*37da2899SCharles.Forsyth	return int b[0] | (int b[1] << 8)
48*37da2899SCharles.Forsyth		| (int b[2] << 16) | (int b[3] << 24);
49*37da2899SCharles.Forsyth}
50*37da2899SCharles.Forsyth
51*37da2899SCharles.Forsyth
52*37da2899SCharles.Forsythstatusmsg(n: int): string
53*37da2899SCharles.Forsyth{
54*37da2899SCharles.Forsyth	m: string;
55*37da2899SCharles.Forsyth	case n {
56*37da2899SCharles.Forsyth	0 => 	m = nil;
57*37da2899SCharles.Forsyth	1 =>	m = "Reset";
58*37da2899SCharles.Forsyth	2 =>	m = "Undefined instruction";
59*37da2899SCharles.Forsyth	3 =>	m = "Software interrupt";
60*37da2899SCharles.Forsyth	4 =>	m = "Prefetch abort";
61*37da2899SCharles.Forsyth	5 =>	m = "Data abort";
62*37da2899SCharles.Forsyth	6 =>	m = "Address exception";
63*37da2899SCharles.Forsyth	7 =>	m = "IRQ";
64*37da2899SCharles.Forsyth	8 =>	m = "FIQ";
65*37da2899SCharles.Forsyth	9 =>	m = "Error";
66*37da2899SCharles.Forsyth	10 =>	m = "Branch Through 0";
67*37da2899SCharles.Forsyth	253 =>	m = "Insufficient privilege";
68*37da2899SCharles.Forsyth	254 =>	m = "Unimplemented message";
69*37da2899SCharles.Forsyth	255 =>	m = "Undefined message";
70*37da2899SCharles.Forsyth	* =>	m = sprint("Status %d", n);
71*37da2899SCharles.Forsyth	}
72*37da2899SCharles.Forsyth	return m;
73*37da2899SCharles.Forsyth}
74*37da2899SCharles.Forsyth
75*37da2899SCharles.Forsythsdc: chan of (array of byte, int);
76*37da2899SCharles.Forsythscc: chan of int;
77*37da2899SCharles.Forsyth
78*37da2899SCharles.Forsythserinp()
79*37da2899SCharles.Forsyth{
80*37da2899SCharles.Forsyth	b: array of byte = nil;
81*37da2899SCharles.Forsyth	save: array of byte = nil;
82*37da2899SCharles.Forsyth	x := 0;
83*37da2899SCharles.Forsyth	for(;;) {
84*37da2899SCharles.Forsyth		m := <- scc;
85*37da2899SCharles.Forsyth		if(m == 0) {
86*37da2899SCharles.Forsyth			save = b[0:x];
87*37da2899SCharles.Forsyth			continue;
88*37da2899SCharles.Forsyth		}
89*37da2899SCharles.Forsyth		b = nil;
90*37da2899SCharles.Forsyth		t: int;
91*37da2899SCharles.Forsyth		do {
92*37da2899SCharles.Forsyth			alt {
93*37da2899SCharles.Forsyth			m = <- scc =>
94*37da2899SCharles.Forsyth				if(m == 0)
95*37da2899SCharles.Forsyth					print("<strange error>\n");
96*37da2899SCharles.Forsyth				b = nil;
97*37da2899SCharles.Forsyth			* =>
98*37da2899SCharles.Forsyth				;
99*37da2899SCharles.Forsyth			}
100*37da2899SCharles.Forsyth			if(b == nil) {
101*37da2899SCharles.Forsyth				if(m >= 0)
102*37da2899SCharles.Forsyth					t = m;
103*37da2899SCharles.Forsyth				else
104*37da2899SCharles.Forsyth					t = -m;
105*37da2899SCharles.Forsyth				x = 0;
106*37da2899SCharles.Forsyth				b = array[t] of byte;
107*37da2899SCharles.Forsyth			}
108*37da2899SCharles.Forsyth			if(save != nil) {
109*37da2899SCharles.Forsyth				r := len save;
110*37da2899SCharles.Forsyth				if(r > (t-x))
111*37da2899SCharles.Forsyth					r = t-x;
112*37da2899SCharles.Forsyth				b[x:] = save[0:r];
113*37da2899SCharles.Forsyth				save = save[r:];
114*37da2899SCharles.Forsyth				if(len save == 0)
115*37da2899SCharles.Forsyth					save = nil;
116*37da2899SCharles.Forsyth				x += r;
117*37da2899SCharles.Forsyth				continue;
118*37da2899SCharles.Forsyth			}
119*37da2899SCharles.Forsyth			r := sys->read(dfd, b[x:], t-x);
120*37da2899SCharles.Forsyth			if(r < 0)
121*37da2899SCharles.Forsyth				sdc <-= (array of byte sprint("fail:%r"), -1);
122*37da2899SCharles.Forsyth			if(r == 0)
123*37da2899SCharles.Forsyth				sdc <-= (array of byte "fail:hangup", -1);
124*37da2899SCharles.Forsyth			if(debug) {
125*37da2899SCharles.Forsyth				if(r == 1)
126*37da2899SCharles.Forsyth					print("<%ux>", int b[x]);
127*37da2899SCharles.Forsyth				else
128*37da2899SCharles.Forsyth					print("<%ux,%ux...(%d)>", int b[x], int b[x+1], r);
129*37da2899SCharles.Forsyth			}
130*37da2899SCharles.Forsyth			x += r;
131*37da2899SCharles.Forsyth		} while(m >= 0 && x < t);
132*37da2899SCharles.Forsyth		sdc <-= (b, x);
133*37da2899SCharles.Forsyth	}
134*37da2899SCharles.Forsyth}
135*37da2899SCharles.Forsyth
136*37da2899SCharles.Forsyth
137*37da2899SCharles.Forsythsreadn(n: int): array of byte
138*37da2899SCharles.Forsyth{
139*37da2899SCharles.Forsyth	b: array of byte;
140*37da2899SCharles.Forsyth	if(n == 0)
141*37da2899SCharles.Forsyth		return array[0] of byte;
142*37da2899SCharles.Forsyth	scc <-= n;
143*37da2899SCharles.Forsyth	(b, n) = <- sdc;
144*37da2899SCharles.Forsyth	if(n < 0)
145*37da2899SCharles.Forsyth		raise string b;
146*37da2899SCharles.Forsyth	return b[0:n];
147*37da2899SCharles.Forsyth}
148*37da2899SCharles.Forsyth
149*37da2899SCharles.Forsyth
150*37da2899SCharles.Forsyth# yes, it's kind of a hack...
151*37da2899SCharles.Forsythfds := array[32] of ref Sys->FD;
152*37da2899SCharles.Forsyth
153*37da2899SCharles.Forsythoscmd()
154*37da2899SCharles.Forsyth{
155*37da2899SCharles.Forsyth	arg := array[4] of int;
156*37da2899SCharles.Forsyth	buf := array[4] of array of byte;
157*37da2899SCharles.Forsyth	b := sreadn(5);
158*37da2899SCharles.Forsyth	op := intb(b[:4]);
159*37da2899SCharles.Forsyth	argd := int b[4];
160*37da2899SCharles.Forsyth	for(i := 0; i<4; i++) {
161*37da2899SCharles.Forsyth		t := (argd >> (i*2))&3;
162*37da2899SCharles.Forsyth		case t {
163*37da2899SCharles.Forsyth		0 =>	;
164*37da2899SCharles.Forsyth		1 =>
165*37da2899SCharles.Forsyth			arg[i] = int sreadn(1)[0];
166*37da2899SCharles.Forsyth		2 =>
167*37da2899SCharles.Forsyth			arg[i] = intb(sreadn(4));
168*37da2899SCharles.Forsyth		3 =>
169*37da2899SCharles.Forsyth			c := int sreadn(1)[0];
170*37da2899SCharles.Forsyth			if(c < 255) {
171*37da2899SCharles.Forsyth				buf[i] = array[c] of byte;
172*37da2899SCharles.Forsyth				if(c <= 32) {
173*37da2899SCharles.Forsyth					buf[i][0:] = sreadn(c);
174*37da2899SCharles.Forsyth				} else
175*37da2899SCharles.Forsyth					arg[i] = intb(sreadn(4));
176*37da2899SCharles.Forsyth			} else {
177*37da2899SCharles.Forsyth				b: array of byte;
178*37da2899SCharles.Forsyth				b = sreadn(8);
179*37da2899SCharles.Forsyth				c = intb(b[:4]);
180*37da2899SCharles.Forsyth				arg[i] = intb(b[4:8]);
181*37da2899SCharles.Forsyth				buf[i] = array[c] of byte;
182*37da2899SCharles.Forsyth			}
183*37da2899SCharles.Forsyth		}
184*37da2899SCharles.Forsyth	}
185*37da2899SCharles.Forsyth	for(i = 0; i<4; i++)
186*37da2899SCharles.Forsyth		if(buf[i] != nil && len buf[i] > 32)
187*37da2899SCharles.Forsyth			rdi_read(arg[i], buf[i], len buf[i]);
188*37da2899SCharles.Forsyth
189*37da2899SCharles.Forsyth	r := 0;
190*37da2899SCharles.Forsyth	case op {
191*37da2899SCharles.Forsyth	0 or 2 => ;
192*37da2899SCharles.Forsyth	* =>
193*37da2899SCharles.Forsyth		out("");
194*37da2899SCharles.Forsyth	}
195*37da2899SCharles.Forsyth	case op {
196*37da2899SCharles.Forsyth	0 =>
197*37da2899SCharles.Forsyth		if(debug)
198*37da2899SCharles.Forsyth			print("SWI_WriteC(%d)\n", arg[0]);
199*37da2899SCharles.Forsyth		out(string byte arg[0]);
200*37da2899SCharles.Forsyth	2 =>
201*37da2899SCharles.Forsyth		if(debug)
202*37da2899SCharles.Forsyth			print("SWI_Write0(<%d>)\n", len buf[0]);
203*37da2899SCharles.Forsyth		out(string buf[0]);
204*37da2899SCharles.Forsyth	4 =>
205*37da2899SCharles.Forsyth		if(debug)
206*37da2899SCharles.Forsyth			print("SWI_ReadC()\n");
207*37da2899SCharles.Forsyth		sys->read(ifd, b, 1);
208*37da2899SCharles.Forsyth		r = int b[0];
209*37da2899SCharles.Forsyth	16r66 =>
210*37da2899SCharles.Forsyth		fname := string buf[0];
211*37da2899SCharles.Forsyth		if(debug)
212*37da2899SCharles.Forsyth			print("SWI_Open(%s, %d)\n", fname, arg[1]);
213*37da2899SCharles.Forsyth		fd: ref Sys->FD;
214*37da2899SCharles.Forsyth		case arg[1] {
215*37da2899SCharles.Forsyth		0 or 1 =>
216*37da2899SCharles.Forsyth			fd = sys->open(fname, Sys->OREAD);
217*37da2899SCharles.Forsyth		2 or 3 =>
218*37da2899SCharles.Forsyth			fd = sys->open(fname, Sys->ORDWR);
219*37da2899SCharles.Forsyth		4 or 5 =>
220*37da2899SCharles.Forsyth			fd = sys->open(fname, Sys->OWRITE);
221*37da2899SCharles.Forsyth			if(fd == nil)
222*37da2899SCharles.Forsyth				fd = sys->create(fname, Sys->OWRITE, 8r666);
223*37da2899SCharles.Forsyth		6 or 7 =>
224*37da2899SCharles.Forsyth			fd = sys->open(fname, Sys->OWRITE|Sys->OTRUNC);
225*37da2899SCharles.Forsyth			if(fd == nil)
226*37da2899SCharles.Forsyth				fd = sys->create(fname, Sys->OWRITE, 8r666);
227*37da2899SCharles.Forsyth		8 or 9 =>
228*37da2899SCharles.Forsyth			fd = sys->open(fname, Sys->OWRITE);
229*37da2899SCharles.Forsyth			if(fd == nil)
230*37da2899SCharles.Forsyth				fd = sys->create(fname, Sys->OWRITE, 8r666);
231*37da2899SCharles.Forsyth			else
232*37da2899SCharles.Forsyth				sys->seek(fd, big 0, Sys->SEEKEND);
233*37da2899SCharles.Forsyth		10 or 11 =>
234*37da2899SCharles.Forsyth			fd = sys->open(fname, Sys->ORDWR);
235*37da2899SCharles.Forsyth			if(fd == nil)
236*37da2899SCharles.Forsyth				fd = sys->create(fname, Sys->ORDWR, 8r666);
237*37da2899SCharles.Forsyth			else
238*37da2899SCharles.Forsyth				sys->seek(fd, big 0, Sys->SEEKEND);
239*37da2899SCharles.Forsyth		}
240*37da2899SCharles.Forsyth		if(fd != nil) {
241*37da2899SCharles.Forsyth			r = fd.fd;
242*37da2899SCharles.Forsyth			if(r >= len fds) {
243*37da2899SCharles.Forsyth				print("<fd %d out of range 1-%d>\n", r, len fds);
244*37da2899SCharles.Forsyth				r = 0;
245*37da2899SCharles.Forsyth			} else
246*37da2899SCharles.Forsyth				fds[r] = fd;
247*37da2899SCharles.Forsyth		}
248*37da2899SCharles.Forsyth	16r68 =>
249*37da2899SCharles.Forsyth		if(debug)
250*37da2899SCharles.Forsyth			print("SWI_Close(%d)\n", arg[0]);
251*37da2899SCharles.Forsyth		if(arg[0] <= 0 || arg[0] >= len fds)
252*37da2899SCharles.Forsyth			r = -1;
253*37da2899SCharles.Forsyth		else {
254*37da2899SCharles.Forsyth			if(fds[arg[0]] != nil)
255*37da2899SCharles.Forsyth				fds[arg[0]] = nil;
256*37da2899SCharles.Forsyth			else
257*37da2899SCharles.Forsyth				r = -1;
258*37da2899SCharles.Forsyth		}
259*37da2899SCharles.Forsyth	16r69 =>
260*37da2899SCharles.Forsyth		if(debug)
261*37da2899SCharles.Forsyth			print("SWI_Write(%d, <%d>)\n", arg[0], len buf[1]);
262*37da2899SCharles.Forsyth		if(arg[0] <= 0 || arg[0] >= len fds)
263*37da2899SCharles.Forsyth			r = -1;
264*37da2899SCharles.Forsyth		else
265*37da2899SCharles.Forsyth			r = sys->write(fds[arg[0]], buf[1], len buf[1]);
266*37da2899SCharles.Forsyth		r = arg[2]-r;
267*37da2899SCharles.Forsyth	16r6a =>
268*37da2899SCharles.Forsyth		if(debug)
269*37da2899SCharles.Forsyth			print("SWI_Read(%d, 0x%ux, %d)\n", arg[0], arg[1], arg[2]);
270*37da2899SCharles.Forsyth		if(arg[0] <= 0 || arg[0] >= len fds)
271*37da2899SCharles.Forsyth			r = -1;
272*37da2899SCharles.Forsyth		else {
273*37da2899SCharles.Forsyth			d := array[arg[2]] of byte;
274*37da2899SCharles.Forsyth			r = sys->read(fds[arg[0]], d, arg[2]);
275*37da2899SCharles.Forsyth			if(r > 0)
276*37da2899SCharles.Forsyth				rdi_write(d, arg[1], r);
277*37da2899SCharles.Forsyth		}
278*37da2899SCharles.Forsyth		r = arg[2]-r;
279*37da2899SCharles.Forsyth	16r6b =>
280*37da2899SCharles.Forsyth		if(debug)
281*37da2899SCharles.Forsyth			print("SWI_Seek(%d, %d)\n", arg[0], arg[1]);
282*37da2899SCharles.Forsyth		if(arg[0] <= 0 || arg[0] >= len fds)
283*37da2899SCharles.Forsyth			r = -1;
284*37da2899SCharles.Forsyth		else
285*37da2899SCharles.Forsyth			r = int sys->seek(fds[arg[0]], big arg[1], 0);
286*37da2899SCharles.Forsyth	16r6c =>
287*37da2899SCharles.Forsyth		if(debug)
288*37da2899SCharles.Forsyth			print("SWI_Flen(%d)\n", arg[0]);
289*37da2899SCharles.Forsyth		if(arg[0] <= 0 || arg[0] >= len fds)
290*37da2899SCharles.Forsyth			r = -1;
291*37da2899SCharles.Forsyth		else {
292*37da2899SCharles.Forsyth			d: Sys->Dir;
293*37da2899SCharles.Forsyth			(r, d) = sys->fstat(fds[arg[0]]);
294*37da2899SCharles.Forsyth			if(r >= 0)
295*37da2899SCharles.Forsyth				r = int d.length;
296*37da2899SCharles.Forsyth		}
297*37da2899SCharles.Forsyth	16r6e =>
298*37da2899SCharles.Forsyth		if(debug)
299*37da2899SCharles.Forsyth			print("SWI_IsTTY(%d)\n", arg[0]);
300*37da2899SCharles.Forsyth		r = 0;	# how can we detect if it's a TTY?
301*37da2899SCharles.Forsyth	* =>
302*37da2899SCharles.Forsyth		print("unsupported: SWI 0x%ux\n", op);
303*37da2899SCharles.Forsyth	}
304*37da2899SCharles.Forsyth	b = array[6] of byte;
305*37da2899SCharles.Forsyth	b[0] = byte 16r13;
306*37da2899SCharles.Forsyth	if(debug)
307*37da2899SCharles.Forsyth		print("r0=%d\n", r);
308*37da2899SCharles.Forsyth	if(r >= 0 && r <= 16rff) {
309*37da2899SCharles.Forsyth		b[1] = byte 1;
310*37da2899SCharles.Forsyth		b[2] = byte r;
311*37da2899SCharles.Forsyth		sys->write(dfd, b, 3);
312*37da2899SCharles.Forsyth	} else {
313*37da2899SCharles.Forsyth		b[1] = byte 2;
314*37da2899SCharles.Forsyth		b[2:] = bint(r);
315*37da2899SCharles.Forsyth		sys->write(dfd, b, 6);
316*37da2899SCharles.Forsyth	}
317*37da2899SCharles.Forsyth}
318*37da2899SCharles.Forsyth
319*37da2899SCharles.Forsyth
320*37da2899SCharles.Forsythterminal()
321*37da2899SCharles.Forsyth{
322*37da2899SCharles.Forsyth	b := array[1024] of byte;
323*37da2899SCharles.Forsyth	c := 3;	# num of invalid chars before resetting
324*37da2899SCharles.Forsyth	tmode = 1;
325*37da2899SCharles.Forsyth	for(;;) {
326*37da2899SCharles.Forsyth		n: int;
327*37da2899SCharles.Forsyth		b: array of byte;
328*37da2899SCharles.Forsyth		alt {
329*37da2899SCharles.Forsyth		scc <-= -8192 =>
330*37da2899SCharles.Forsyth			(b, n) = <- sdc;
331*37da2899SCharles.Forsyth		(b, n) = <- sdc =>
332*37da2899SCharles.Forsyth			;
333*37da2899SCharles.Forsyth		}
334*37da2899SCharles.Forsyth		if(n < 0)
335*37da2899SCharles.Forsyth			raise string b;
336*37da2899SCharles.Forsyth		c -= out(string b[:n]);
337*37da2899SCharles.Forsyth		if(c < 0) {
338*37da2899SCharles.Forsyth			scc <-= 0;
339*37da2899SCharles.Forsyth			raise "rdp:tmode";
340*37da2899SCharles.Forsyth		}
341*37da2899SCharles.Forsyth		if(!tmode) {
342*37da2899SCharles.Forsyth			return;
343*37da2899SCharles.Forsyth		}
344*37da2899SCharles.Forsyth	}
345*37da2899SCharles.Forsyth}
346*37da2899SCharles.Forsyth
347*37da2899SCharles.Forsythgetreply(n: int): (array of byte, int)
348*37da2899SCharles.Forsyth{
349*37da2899SCharles.Forsyth	loop: for(;;) {
350*37da2899SCharles.Forsyth		c := int sreadn(1)[0];
351*37da2899SCharles.Forsyth		case c {
352*37da2899SCharles.Forsyth		16r21 =>
353*37da2899SCharles.Forsyth			oscmd();
354*37da2899SCharles.Forsyth		16r7f =>
355*37da2899SCharles.Forsyth			raise "rdp:reset";
356*37da2899SCharles.Forsyth		16r5f =>
357*37da2899SCharles.Forsyth			break loop;
358*37da2899SCharles.Forsyth		* =>
359*37da2899SCharles.Forsyth			print("<%ux?>", c);
360*37da2899SCharles.Forsyth			scc <-= 0;
361*37da2899SCharles.Forsyth			raise "rdp:tmode";
362*37da2899SCharles.Forsyth		}
363*37da2899SCharles.Forsyth	}
364*37da2899SCharles.Forsyth	b := sreadn(n+1);
365*37da2899SCharles.Forsyth	s := int b[n];
366*37da2899SCharles.Forsyth	if(s != 0) {
367*37da2899SCharles.Forsyth		out("");
368*37da2899SCharles.Forsyth		print("[%s]\n", statusmsg(s));
369*37da2899SCharles.Forsyth	}
370*37da2899SCharles.Forsyth	return (b[:n], s);
371*37da2899SCharles.Forsyth}
372*37da2899SCharles.Forsyth
373*37da2899SCharles.Forsythoutstr: string;
374*37da2899SCharles.Forsythtpid: int;
375*37da2899SCharles.Forsyth
376*37da2899SCharles.Forsythtimeout(t: int, c: chan of int)
377*37da2899SCharles.Forsyth{
378*37da2899SCharles.Forsyth	tpid = sys->pctl(0, nil);
379*37da2899SCharles.Forsyth	if(t > 0)
380*37da2899SCharles.Forsyth		sys->sleep(t);
381*37da2899SCharles.Forsyth	c <-= 0;
382*37da2899SCharles.Forsyth	tpid = 0;
383*37da2899SCharles.Forsyth}
384*37da2899SCharles.Forsyth
385*37da2899SCharles.Forsythbsc: chan of string;
386*37da2899SCharles.Forsyth
387*37da2899SCharles.Forsythbufout()
388*37da2899SCharles.Forsyth{
389*37da2899SCharles.Forsyth	buf := "";
390*37da2899SCharles.Forsyth	tc := chan of int;
391*37da2899SCharles.Forsyth	n: int;
392*37da2899SCharles.Forsyth	s: string;
393*37da2899SCharles.Forsyth	for(;;) {
394*37da2899SCharles.Forsyth		alt {
395*37da2899SCharles.Forsyth		n = <- tc =>
396*37da2899SCharles.Forsyth			print("%s", buf);
397*37da2899SCharles.Forsyth			buf = "";
398*37da2899SCharles.Forsyth		s = <- bsc =>
399*37da2899SCharles.Forsyth			#if(tpid) {
400*37da2899SCharles.Forsyth			#	kill(tpid);
401*37da2899SCharles.Forsyth			#	tpid = 0;
402*37da2899SCharles.Forsyth			#}
403*37da2899SCharles.Forsyth			if((len buf+len s) >= 1024) {
404*37da2899SCharles.Forsyth				print("%s", buf);
405*37da2899SCharles.Forsyth				buf = s;
406*37da2899SCharles.Forsyth			}
407*37da2899SCharles.Forsyth			if(s == "" || debug) {
408*37da2899SCharles.Forsyth				print("%s", buf);
409*37da2899SCharles.Forsyth				buf = "";
410*37da2899SCharles.Forsyth			} else {
411*37da2899SCharles.Forsyth				buf += s;
412*37da2899SCharles.Forsyth				if(tpid == 0)
413*37da2899SCharles.Forsyth					spawn timeout(300, tc);
414*37da2899SCharles.Forsyth			}
415*37da2899SCharles.Forsyth		}
416*37da2899SCharles.Forsyth	}
417*37da2899SCharles.Forsyth}
418*37da2899SCharles.Forsyth
419*37da2899SCharles.Forsythout(s: string): int
420*37da2899SCharles.Forsyth{
421*37da2899SCharles.Forsyth	if(bsc == nil) {
422*37da2899SCharles.Forsyth		bsc = chan of string;
423*37da2899SCharles.Forsyth		spawn bufout();
424*37da2899SCharles.Forsyth	}
425*37da2899SCharles.Forsyth	c := 0;
426*37da2899SCharles.Forsyth	if(nocr || tmode) {
427*37da2899SCharles.Forsyth		n := "";
428*37da2899SCharles.Forsyth		for(i:=0; i<len s; i++) {
429*37da2899SCharles.Forsyth			if(!(nocr && s[i] == '\r'))
430*37da2899SCharles.Forsyth				n[len n] = s[i];
431*37da2899SCharles.Forsyth			if(s[i] >= 16r7f)
432*37da2899SCharles.Forsyth				c++;
433*37da2899SCharles.Forsyth		}
434*37da2899SCharles.Forsyth		bsc <-= n;
435*37da2899SCharles.Forsyth	} else
436*37da2899SCharles.Forsyth		bsc <-= s;
437*37da2899SCharles.Forsyth	return c;
438*37da2899SCharles.Forsyth}
439*37da2899SCharles.Forsyth
440*37da2899SCharles.Forsythreset(r: int)
441*37da2899SCharles.Forsyth{
442*37da2899SCharles.Forsyth	out("");
443*37da2899SCharles.Forsyth	if(debug)
444*37da2899SCharles.Forsyth		print("reset(%d)\n", r);
445*37da2899SCharles.Forsyth	p_isopen = 0;
446*37da2899SCharles.Forsyth	b := array of byte sprint("b9600");
447*37da2899SCharles.Forsyth	sys->write(cfd, b, len b);
448*37da2899SCharles.Forsyth	if(r) {
449*37da2899SCharles.Forsyth		b[0] = byte 127;
450*37da2899SCharles.Forsyth		sys->write(dfd, b, 1);
451*37da2899SCharles.Forsyth		print("<sending reset>");
452*37da2899SCharles.Forsyth	}
453*37da2899SCharles.Forsyth	ok := 0;
454*37da2899SCharles.Forsyth	s := "";
455*37da2899SCharles.Forsyth	for(;;) {
456*37da2899SCharles.Forsyth		n: int;
457*37da2899SCharles.Forsyth		b: array of byte;
458*37da2899SCharles.Forsyth		scc <-= -8192;
459*37da2899SCharles.Forsyth		(b, n) = <- sdc;
460*37da2899SCharles.Forsyth		if(n < 0)
461*37da2899SCharles.Forsyth			raise string b;
462*37da2899SCharles.Forsyth		for(i := 0; i<n; i++) {
463*37da2899SCharles.Forsyth			if(b[i] == byte 127) {
464*37da2899SCharles.Forsyth				if(!ok)
465*37da2899SCharles.Forsyth					print("\n");
466*37da2899SCharles.Forsyth				ok = 1;
467*37da2899SCharles.Forsyth				s = "";
468*37da2899SCharles.Forsyth				continue;
469*37da2899SCharles.Forsyth			}
470*37da2899SCharles.Forsyth			if(b[i] == byte 0) {
471*37da2899SCharles.Forsyth				if(ok && i == n-1) {
472*37da2899SCharles.Forsyth					out(s);
473*37da2899SCharles.Forsyth					out("");
474*37da2899SCharles.Forsyth					return;
475*37da2899SCharles.Forsyth				} else {
476*37da2899SCharles.Forsyth					s = "";
477*37da2899SCharles.Forsyth					continue;
478*37da2899SCharles.Forsyth				}
479*37da2899SCharles.Forsyth			}
480*37da2899SCharles.Forsyth			if(b[i] < byte 127)
481*37da2899SCharles.Forsyth				s += string b[i:i+1];
482*37da2899SCharles.Forsyth			else
483*37da2899SCharles.Forsyth				ok = 0;
484*37da2899SCharles.Forsyth		}
485*37da2899SCharles.Forsyth	}
486*37da2899SCharles.Forsyth}
487*37da2899SCharles.Forsyth
488*37da2899SCharles.Forsythsa1100_reset()
489*37da2899SCharles.Forsyth{
490*37da2899SCharles.Forsyth	rdi_write(bint(1), int 16r90030000, 4);
491*37da2899SCharles.Forsyth}
492*37da2899SCharles.Forsyth
493*37da2899SCharles.Forsythsetbps(bps: int)
494*37da2899SCharles.Forsyth{
495*37da2899SCharles.Forsyth	# for older Emu's using setserial hacks...
496*37da2899SCharles.Forsyth	if(bps > 38400)
497*37da2899SCharles.Forsyth		sys->write(cfd, array of byte "b38400", 6);
498*37da2899SCharles.Forsyth
499*37da2899SCharles.Forsyth	out("");
500*37da2899SCharles.Forsyth	print("<bps=%d>\n", bps);
501*37da2899SCharles.Forsyth	b := array of byte sprint("b%d", bps);
502*37da2899SCharles.Forsyth	if(sys->write(cfd, b, len b) != len b)
503*37da2899SCharles.Forsyth		print("setbps failed: %r\n");
504*37da2899SCharles.Forsyth}
505*37da2899SCharles.Forsyth
506*37da2899SCharles.Forsythrdi_open(bps: int)
507*37da2899SCharles.Forsyth{
508*37da2899SCharles.Forsyth	if(debug)
509*37da2899SCharles.Forsyth		print("rdi_open(%d)\n", bps);
510*37da2899SCharles.Forsyth	b := array[7] of byte;
511*37da2899SCharles.Forsyth	usehack := 0;
512*37da2899SCharles.Forsyth	if(!p_isopen) {
513*37da2899SCharles.Forsyth		b[0] = byte 0;
514*37da2899SCharles.Forsyth		b[1] = byte (0 | (1<<1));
515*37da2899SCharles.Forsyth		b[2:] = bint(0);
516*37da2899SCharles.Forsyth		case bps {
517*37da2899SCharles.Forsyth		9600 => b[6] = byte 1;
518*37da2899SCharles.Forsyth		19200 => b[6] = byte 2;
519*37da2899SCharles.Forsyth		38400 => b[6] = byte 3;
520*37da2899SCharles.Forsyth		# 57600 => b[6] = byte 4;
521*37da2899SCharles.Forsyth		# 115200 => b[6] = byte 5;
522*37da2899SCharles.Forsyth		# 230400 => b[6] = byte 6;
523*37da2899SCharles.Forsyth		* =>
524*37da2899SCharles.Forsyth			b[6] = byte 1;
525*37da2899SCharles.Forsyth			usehack = 1;
526*37da2899SCharles.Forsyth		}
527*37da2899SCharles.Forsyth		sys->write(dfd, b, 7);
528*37da2899SCharles.Forsyth		getreply(0);
529*37da2899SCharles.Forsyth		p_isopen = 1;
530*37da2899SCharles.Forsyth		if(usehack)
531*37da2899SCharles.Forsyth			sa1100_setbps(bps);
532*37da2899SCharles.Forsyth		else
533*37da2899SCharles.Forsyth			setbps(bps);
534*37da2899SCharles.Forsyth	}
535*37da2899SCharles.Forsyth}
536*37da2899SCharles.Forsyth
537*37da2899SCharles.Forsythrdi_close()
538*37da2899SCharles.Forsyth{
539*37da2899SCharles.Forsyth	if(debug)
540*37da2899SCharles.Forsyth		print("rdi_close()\n");
541*37da2899SCharles.Forsyth	b := array[1] of byte;
542*37da2899SCharles.Forsyth	if(p_isopen) {
543*37da2899SCharles.Forsyth		b[0] = byte 1;
544*37da2899SCharles.Forsyth		sys->write(dfd, b, 1);
545*37da2899SCharles.Forsyth		getreply(0);
546*37da2899SCharles.Forsyth		p_isopen = 0;
547*37da2899SCharles.Forsyth	}
548*37da2899SCharles.Forsyth}
549*37da2899SCharles.Forsyth
550*37da2899SCharles.Forsythrdi_cpuread(reg: array of int, mask: int)
551*37da2899SCharles.Forsyth{
552*37da2899SCharles.Forsyth	if(debug)
553*37da2899SCharles.Forsyth		print("rdi_cpuread(..., 0x%ux)\n", mask);
554*37da2899SCharles.Forsyth	n := 0;
555*37da2899SCharles.Forsyth	for(i := 0; i<NREG; i++)
556*37da2899SCharles.Forsyth		if(mask&(1<<i))
557*37da2899SCharles.Forsyth			n += 4;
558*37da2899SCharles.Forsyth	b := array[6+n] of byte;
559*37da2899SCharles.Forsyth	b[0] = byte 4;
560*37da2899SCharles.Forsyth	b[1] = byte 255;	# current mode
561*37da2899SCharles.Forsyth	b[2:] = bint(mask);
562*37da2899SCharles.Forsyth	sys->write(dfd, b, 6);
563*37da2899SCharles.Forsyth	(b, nil) = getreply(n);
564*37da2899SCharles.Forsyth	n = 0;
565*37da2899SCharles.Forsyth	for(i = 0; i<NREG; i++)
566*37da2899SCharles.Forsyth		if(mask&(1<<i)) {
567*37da2899SCharles.Forsyth			reg[i] = intb(b[n:n+4]);
568*37da2899SCharles.Forsyth			n += 4;
569*37da2899SCharles.Forsyth		}
570*37da2899SCharles.Forsyth}
571*37da2899SCharles.Forsyth
572*37da2899SCharles.Forsythrdi_cpuwrite(reg: array of int, mask: int)
573*37da2899SCharles.Forsyth{
574*37da2899SCharles.Forsyth	if(debug)
575*37da2899SCharles.Forsyth		print("rdi_cpuwrite(..., 0x%ux)\n", mask);
576*37da2899SCharles.Forsyth	n := 0;
577*37da2899SCharles.Forsyth	for(i := 0; i<32; i++)
578*37da2899SCharles.Forsyth		if(mask&(1<<i))
579*37da2899SCharles.Forsyth			n += 4;
580*37da2899SCharles.Forsyth	b := array[6+n] of byte;
581*37da2899SCharles.Forsyth	b[0] = byte 5;
582*37da2899SCharles.Forsyth	b[1] = byte 255;	# current mode
583*37da2899SCharles.Forsyth	b[2:] = bint(mask);
584*37da2899SCharles.Forsyth	n = 6;
585*37da2899SCharles.Forsyth	for(i = 0; i<32; i++)
586*37da2899SCharles.Forsyth		if(mask&(1<<i)) {
587*37da2899SCharles.Forsyth			b[n:] = bint(reg[i]);
588*37da2899SCharles.Forsyth			n += 4;
589*37da2899SCharles.Forsyth		}
590*37da2899SCharles.Forsyth	sys->write(dfd, b, n);
591*37da2899SCharles.Forsyth	getreply(0);
592*37da2899SCharles.Forsyth}
593*37da2899SCharles.Forsyth
594*37da2899SCharles.Forsythdump(b: array of byte, n: int)
595*37da2899SCharles.Forsyth{
596*37da2899SCharles.Forsyth	for(i := 0; i<n; i++)
597*37da2899SCharles.Forsyth		print(" %d: %2.2ux\n", i, int b[i]);
598*37da2899SCharles.Forsyth}
599*37da2899SCharles.Forsyth
600*37da2899SCharles.Forsythrdi_read(addr: int, b: array of byte, n: int): int
601*37da2899SCharles.Forsyth{
602*37da2899SCharles.Forsyth	if(debug)
603*37da2899SCharles.Forsyth		print("rdi_read(0x%ux, ..., 0x%ux)\n", addr, n);
604*37da2899SCharles.Forsyth	if(n == 0)
605*37da2899SCharles.Forsyth		return 0;
606*37da2899SCharles.Forsyth	sb := array[9] of byte;
607*37da2899SCharles.Forsyth	sb[0] = byte 2;
608*37da2899SCharles.Forsyth	sb[1:] = bint(addr);
609*37da2899SCharles.Forsyth	sb[5:] = bint(n);
610*37da2899SCharles.Forsyth	sys->write(dfd, sb, 9);
611*37da2899SCharles.Forsyth	(b[0:], nil) = getreply(n);
612*37da2899SCharles.Forsyth	# if error, need to read count of bytes transferred
613*37da2899SCharles.Forsyth	return n;
614*37da2899SCharles.Forsyth}
615*37da2899SCharles.Forsyth
616*37da2899SCharles.Forsythrdi_write(b: array of byte, addr: int, n: int): int
617*37da2899SCharles.Forsyth{
618*37da2899SCharles.Forsyth	if(debug)
619*37da2899SCharles.Forsyth		print("rdi_write(..., 0x%ux, 0x%ux)\n", addr, n);
620*37da2899SCharles.Forsyth	if(n == 0)
621*37da2899SCharles.Forsyth		return 0;
622*37da2899SCharles.Forsyth	sb := array[9+n] of byte;
623*37da2899SCharles.Forsyth	sb[0] = byte 3;
624*37da2899SCharles.Forsyth	sb[1:] = bint(addr);
625*37da2899SCharles.Forsyth	sb[5:] = bint(n);
626*37da2899SCharles.Forsyth	sb[9:] = b[:n];
627*37da2899SCharles.Forsyth	sys->write(dfd, sb, 9);
628*37da2899SCharles.Forsyth	x := 0;
629*37da2899SCharles.Forsyth	while(n) {
630*37da2899SCharles.Forsyth		q := n;
631*37da2899SCharles.Forsyth		if(q > 8192)
632*37da2899SCharles.Forsyth			q = 8192;
633*37da2899SCharles.Forsyth		r := sys->write(dfd, b[x:], q);
634*37da2899SCharles.Forsyth		if(debug)
635*37da2899SCharles.Forsyth			print("rdi_write: r=%d ofs=%d n=%d\n", r, x, n);
636*37da2899SCharles.Forsyth		if(r < 0)
637*37da2899SCharles.Forsyth			raise "fail:hangup";
638*37da2899SCharles.Forsyth		x += r;
639*37da2899SCharles.Forsyth		n -= r;
640*37da2899SCharles.Forsyth	}
641*37da2899SCharles.Forsyth	getreply(0);
642*37da2899SCharles.Forsyth	return n;
643*37da2899SCharles.Forsyth}
644*37da2899SCharles.Forsyth
645*37da2899SCharles.Forsythrdi_execute()
646*37da2899SCharles.Forsyth{
647*37da2899SCharles.Forsyth	if(debug)
648*37da2899SCharles.Forsyth		print("rdi_execute()\n");
649*37da2899SCharles.Forsyth	sb := array[2] of byte;
650*37da2899SCharles.Forsyth	sb[0] = byte 16r10;
651*37da2899SCharles.Forsyth	sb[1] = byte 0;
652*37da2899SCharles.Forsyth	sys->write(dfd, sb, 2);
653*37da2899SCharles.Forsyth	getreply(0);
654*37da2899SCharles.Forsyth	out("");
655*37da2899SCharles.Forsyth}
656*37da2899SCharles.Forsyth
657*37da2899SCharles.Forsythrdi_info(n: int, arg: int)
658*37da2899SCharles.Forsyth{
659*37da2899SCharles.Forsyth	sb := array[9] of byte;
660*37da2899SCharles.Forsyth	sb[0] = byte 16r12;
661*37da2899SCharles.Forsyth	sb[1:] = bint(n);
662*37da2899SCharles.Forsyth	sb[5:] = bint(arg);
663*37da2899SCharles.Forsyth	sys->write(dfd, sb, 9);
664*37da2899SCharles.Forsyth	getreply(0);
665*37da2899SCharles.Forsyth}
666*37da2899SCharles.Forsyth
667*37da2899SCharles.Forsyth
668*37da2899SCharles.Forsythregdump()
669*37da2899SCharles.Forsyth{
670*37da2899SCharles.Forsyth	out("");
671*37da2899SCharles.Forsyth	reg := array[NREG] of int;
672*37da2899SCharles.Forsyth	# rdi_cpuread(reg, 16rffff|(1<<R_PC)|(1<<R_CPSR)|(1<<R_SPSR));
673*37da2899SCharles.Forsyth	rdi_cpuread(reg, 16rffff|(1<<R_PC)|(1<<R_CPSR));
674*37da2899SCharles.Forsyth	for(i := 0; i < 16; i += 4)
675*37da2899SCharles.Forsyth		print("  r%-2d=%8.8ux  r%-2d=%8.8ux  r%-2d=%8.8ux  r%-2d=%8.8ux\n",
676*37da2899SCharles.Forsyth			i, reg[i], i+1, reg[i+1],
677*37da2899SCharles.Forsyth			i+2, reg[i+2], i+3, reg[i+3]);
678*37da2899SCharles.Forsyth	print("   pc=%8.8ux  psr=%8.8ux\n",
679*37da2899SCharles.Forsyth			reg[R_PC], reg[R_CPSR]);
680*37da2899SCharles.Forsyth}
681*37da2899SCharles.Forsyth
682*37da2899SCharles.Forsythprintable(b: array of byte): string
683*37da2899SCharles.Forsyth{
684*37da2899SCharles.Forsyth	s := "";
685*37da2899SCharles.Forsyth	for(i := 0; i < len b; i++)
686*37da2899SCharles.Forsyth		if(b[i] >= byte ' ' && b[i] <= byte 126)
687*37da2899SCharles.Forsyth			s += string b[i:i+1];
688*37da2899SCharles.Forsyth		else
689*37da2899SCharles.Forsyth			s += ".";
690*37da2899SCharles.Forsyth	return s;
691*37da2899SCharles.Forsyth}
692*37da2899SCharles.Forsyth
693*37da2899SCharles.Forsythexamine(a: int, n: int)
694*37da2899SCharles.Forsyth{
695*37da2899SCharles.Forsyth	b := array[4] of byte;
696*37da2899SCharles.Forsyth	for(i := 0; i<n; i++) {
697*37da2899SCharles.Forsyth		rdi_read(a, b, 4);
698*37da2899SCharles.Forsyth		print("0x%8.8ux: 0x%8.8ux  \"%s\"\n", a, intb(b), printable(b));
699*37da2899SCharles.Forsyth		a += 4;
700*37da2899SCharles.Forsyth	}
701*37da2899SCharles.Forsyth}
702*37da2899SCharles.Forsyth
703*37da2899SCharles.Forsythatoi(s: string): int
704*37da2899SCharles.Forsyth{
705*37da2899SCharles.Forsyth	b := 10;
706*37da2899SCharles.Forsyth	if(len s < 1)
707*37da2899SCharles.Forsyth		return 0;
708*37da2899SCharles.Forsyth	if(s[0] == '0') {
709*37da2899SCharles.Forsyth		b = 8;
710*37da2899SCharles.Forsyth		s = s[1:];
711*37da2899SCharles.Forsyth		if(len s < 1)
712*37da2899SCharles.Forsyth			return 0;
713*37da2899SCharles.Forsyth		if(s[0] == 'x' || s[0] == 'X') {
714*37da2899SCharles.Forsyth			b = 16;
715*37da2899SCharles.Forsyth			s = s[1:];
716*37da2899SCharles.Forsyth		}
717*37da2899SCharles.Forsyth	}
718*37da2899SCharles.Forsyth	n: int;
719*37da2899SCharles.Forsyth	(n, nil) = str->toint(s, b);
720*37da2899SCharles.Forsyth	return n;
721*37da2899SCharles.Forsyth}
722*37da2899SCharles.Forsyth
723*37da2899SCharles.Forsythregnum(s: string): int
724*37da2899SCharles.Forsyth{
725*37da2899SCharles.Forsyth	if(len s < 2)
726*37da2899SCharles.Forsyth		return -1;
727*37da2899SCharles.Forsyth	if(s[0] == 'r' && s[1] >= '0' && s[1] <= '9')
728*37da2899SCharles.Forsyth		return atoi(s[1:]);
729*37da2899SCharles.Forsyth	case s {
730*37da2899SCharles.Forsyth	"pc" => return R_PC;
731*37da2899SCharles.Forsyth	"cpsr" or "psr" => return R_CPSR;
732*37da2899SCharles.Forsyth	"spsr" => return R_SPSR;
733*37da2899SCharles.Forsyth	* => return -1;
734*37da2899SCharles.Forsyth	}
735*37da2899SCharles.Forsyth}
736*37da2899SCharles.Forsyth
737*37da2899SCharles.Forsythcmdhelp()
738*37da2899SCharles.Forsyth{
739*37da2899SCharles.Forsyth	print("	e <addr> [<count>]  - examine memory\n");
740*37da2899SCharles.Forsyth	print("	d <addr> [<value>...]  - deposit values in memory\n");
741*37da2899SCharles.Forsyth	print("	get <file> <addr>  - read file into memory at addr\n");
742*37da2899SCharles.Forsyth	print("	load <file>  - load AIF file and set the PC\n");
743*37da2899SCharles.Forsyth	print("	r  - print all registers\n");
744*37da2899SCharles.Forsyth	print("	<reg>=<val>  - set register value\n");
745*37da2899SCharles.Forsyth	print("	sb  - run builtin sboot (pc=0x40; g)\n");
746*37da2899SCharles.Forsyth	print("	reset - trigger SA1100 software reset\n");
747*37da2899SCharles.Forsyth	print("	bps <speed>  - change bps rate (SA1100 only)\n");
748*37da2899SCharles.Forsyth	print("	q  - quit\n");
749*37da2899SCharles.Forsyth}
750*37da2899SCharles.Forsyth
751*37da2899SCharles.Forsythcmdmode()
752*37da2899SCharles.Forsyth{
753*37da2899SCharles.Forsyth	b := array[1024] of byte;
754*37da2899SCharles.Forsyth	for(;;) {
755*37da2899SCharles.Forsyth		print("rdp: ");
756*37da2899SCharles.Forsyth		r := sys->read(ifd, b, len b);
757*37da2899SCharles.Forsyth		if(r < 0)
758*37da2899SCharles.Forsyth			raise sprint("fail:%r");
759*37da2899SCharles.Forsyth		if(r == 0 || (r == 1 && b[0] == byte 4))
760*37da2899SCharles.Forsyth			break;
761*37da2899SCharles.Forsyth		n: int;
762*37da2899SCharles.Forsyth		a: list of string;
763*37da2899SCharles.Forsyth		(n, a) = sys->tokenize(string b[0:r], " \t\n=");
764*37da2899SCharles.Forsyth		if(n < 1)
765*37da2899SCharles.Forsyth			continue;
766*37da2899SCharles.Forsyth		case hd a {
767*37da2899SCharles.Forsyth		"sb" =>
768*37da2899SCharles.Forsyth			sbmode();
769*37da2899SCharles.Forsyth			rdi_execute();
770*37da2899SCharles.Forsyth		"q" or "quit" =>
771*37da2899SCharles.Forsyth			return;
772*37da2899SCharles.Forsyth		"r" or "reg" =>
773*37da2899SCharles.Forsyth			regdump();
774*37da2899SCharles.Forsyth		"get" or "getfile" or "l" or "load" =>
775*37da2899SCharles.Forsyth			{
776*37da2899SCharles.Forsyth				if((hd a)[0] == 'l')
777*37da2899SCharles.Forsyth					aifload(hd tl a, -1);
778*37da2899SCharles.Forsyth				else
779*37da2899SCharles.Forsyth					aifload(hd tl a, atoi(hd tl tl a));
780*37da2899SCharles.Forsyth			}exception e{
781*37da2899SCharles.Forsyth			"fail:*" =>
782*37da2899SCharles.Forsyth				print("error: %s\n", e[5:]);
783*37da2899SCharles.Forsyth				continue;
784*37da2899SCharles.Forsyth			}
785*37da2899SCharles.Forsyth		"g" or "go" =>
786*37da2899SCharles.Forsyth			rdi_execute();
787*37da2899SCharles.Forsyth		"reset" =>
788*37da2899SCharles.Forsyth			sa1100_reset();
789*37da2899SCharles.Forsyth		"e" =>
790*37da2899SCharles.Forsyth			a = tl a;
791*37da2899SCharles.Forsyth			x := atoi(hd a);
792*37da2899SCharles.Forsyth			n = 1;
793*37da2899SCharles.Forsyth			a = tl a;
794*37da2899SCharles.Forsyth			if(a != nil)
795*37da2899SCharles.Forsyth				n = atoi(hd a);
796*37da2899SCharles.Forsyth			examine(x, n);
797*37da2899SCharles.Forsyth		"d" =>
798*37da2899SCharles.Forsyth			a = tl a;
799*37da2899SCharles.Forsyth			x := atoi(hd a);
800*37da2899SCharles.Forsyth			for(i := 2; i<n; i++) {
801*37da2899SCharles.Forsyth				a = tl a;
802*37da2899SCharles.Forsyth				rdi_write(bint(atoi(hd a)), x, 4);
803*37da2899SCharles.Forsyth				x += 4;
804*37da2899SCharles.Forsyth			}
805*37da2899SCharles.Forsyth		"info" =>
806*37da2899SCharles.Forsyth			a = tl a;
807*37da2899SCharles.Forsyth			rdi_info(16r180, atoi(hd a));
808*37da2899SCharles.Forsyth		"bps" =>
809*37da2899SCharles.Forsyth			sa1100_setbps(atoi(hd tl a));
810*37da2899SCharles.Forsyth		"help" or "?" =>
811*37da2899SCharles.Forsyth			cmdhelp();
812*37da2899SCharles.Forsyth		* =>
813*37da2899SCharles.Forsyth			if((rn := regnum(hd a)) > -1) {
814*37da2899SCharles.Forsyth				reg := array[NREG] of int;
815*37da2899SCharles.Forsyth				reg[rn] = atoi(hd tl a);
816*37da2899SCharles.Forsyth				rdi_cpuwrite(reg, 1<<rn);
817*37da2899SCharles.Forsyth			} else
818*37da2899SCharles.Forsyth				print("?\n");
819*37da2899SCharles.Forsyth		}
820*37da2899SCharles.Forsyth	}
821*37da2899SCharles.Forsyth}
822*37da2899SCharles.Forsyth
823*37da2899SCharles.Forsythsbmode()
824*37da2899SCharles.Forsyth{
825*37da2899SCharles.Forsyth	if(debug)
826*37da2899SCharles.Forsyth		print("sbmode()\n");
827*37da2899SCharles.Forsyth	reg := array[NREG] of int;
828*37da2899SCharles.Forsyth	reg[R_PC] = 16r40;
829*37da2899SCharles.Forsyth	rdi_cpuwrite(reg, 1<<R_PC);
830*37da2899SCharles.Forsyth}
831*37da2899SCharles.Forsyth
832*37da2899SCharles.Forsythsbmodeofs(ofs: int)
833*37da2899SCharles.Forsyth{
834*37da2899SCharles.Forsyth	if(debug)
835*37da2899SCharles.Forsyth		print("sbmode(0x%ux)\n", ofs);
836*37da2899SCharles.Forsyth	reg := array[NREG] of int;
837*37da2899SCharles.Forsyth	reg[0] = ofs;
838*37da2899SCharles.Forsyth	reg[R_PC] = 16r48;
839*37da2899SCharles.Forsyth	rdi_cpuwrite(reg, (1<<0)|(1<<R_PC));
840*37da2899SCharles.Forsyth}
841*37da2899SCharles.Forsyth
842*37da2899SCharles.Forsythinp: string = "";
843*37da2899SCharles.Forsyth
844*37da2899SCharles.Forsythhelp: con "(q)uit, (i)nt, (b)reak, !c(r), !(l)ine, !(t)erminal, (s<bps>), (.)cont, (!cmd)\n";
845*37da2899SCharles.Forsyth
846*37da2899SCharles.Forsythmenu(fi: ref Sys->FD)
847*37da2899SCharles.Forsyth{
848*37da2899SCharles.Forsyth	w := israw;
849*37da2899SCharles.Forsyth	if(israw)
850*37da2899SCharles.Forsyth		raw(0);
851*37da2899SCharles.Forsythmloop:	for(;;) {
852*37da2899SCharles.Forsyth		out("");
853*37da2899SCharles.Forsyth		print("rdp> ");
854*37da2899SCharles.Forsyth		b := array[256] of byte;
855*37da2899SCharles.Forsyth		r := sys->read(fi, b, len b);
856*37da2899SCharles.Forsyth		case int b[0] {
857*37da2899SCharles.Forsyth		'q' =>
858*37da2899SCharles.Forsyth			killgrp();
859*37da2899SCharles.Forsyth			exit;
860*37da2899SCharles.Forsyth		'i' =>
861*37da2899SCharles.Forsyth			b[0] = byte 16r18;
862*37da2899SCharles.Forsyth			sys->write(dfd, b[0:1], 1);
863*37da2899SCharles.Forsyth			break mloop;
864*37da2899SCharles.Forsyth		'b' =>
865*37da2899SCharles.Forsyth			sys->write(cfd, array of byte "k", 1);
866*37da2899SCharles.Forsyth			break mloop;
867*37da2899SCharles.Forsyth		'!' =>
868*37da2899SCharles.Forsyth			cmd := string b[1:r-1];
869*37da2899SCharles.Forsyth			print("!%s\n", cmd);
870*37da2899SCharles.Forsyth			# system(cmd)
871*37da2899SCharles.Forsyth			print("!\n");
872*37da2899SCharles.Forsyth			break mloop;
873*37da2899SCharles.Forsyth		'l' =>
874*37da2899SCharles.Forsyth			w = !w;
875*37da2899SCharles.Forsyth			break mloop;
876*37da2899SCharles.Forsyth		'r' =>
877*37da2899SCharles.Forsyth			nocr = !nocr;
878*37da2899SCharles.Forsyth			break mloop;
879*37da2899SCharles.Forsyth		'd' =>
880*37da2899SCharles.Forsyth			debug = !debug;
881*37da2899SCharles.Forsyth			break mloop;
882*37da2899SCharles.Forsyth		't' =>
883*37da2899SCharles.Forsyth			sys->write(pifd, array[] of { byte 4 }, 1);
884*37da2899SCharles.Forsyth			sdc <-= (array of byte "rdp:tmode", -1);
885*37da2899SCharles.Forsyth			break mloop;
886*37da2899SCharles.Forsyth		'.' =>
887*37da2899SCharles.Forsyth			break mloop;
888*37da2899SCharles.Forsyth		's' =>
889*37da2899SCharles.Forsyth			bps := atoi(string b[1:r-1]);
890*37da2899SCharles.Forsyth			setbps(bps);
891*37da2899SCharles.Forsyth		* =>
892*37da2899SCharles.Forsyth			print(help);
893*37da2899SCharles.Forsyth			continue;
894*37da2899SCharles.Forsyth		}
895*37da2899SCharles.Forsyth	}
896*37da2899SCharles.Forsyth	if(israw != w)
897*37da2899SCharles.Forsyth		raw(w);
898*37da2899SCharles.Forsyth}
899*37da2899SCharles.Forsyth
900*37da2899SCharles.Forsyth
901*37da2899SCharles.Forsythinput()
902*37da2899SCharles.Forsyth{
903*37da2899SCharles.Forsyth	fi := sys->fildes(0);
904*37da2899SCharles.Forsyth	b := array[1024] of byte;
905*37da2899SCharles.Forsythiloop: 	for(;;) {
906*37da2899SCharles.Forsyth		r := sys->read(fi, b, len b);
907*37da2899SCharles.Forsyth		if(r < 0) {
908*37da2899SCharles.Forsyth			print("stdin: %r");
909*37da2899SCharles.Forsyth			killgrp();
910*37da2899SCharles.Forsyth			exit;
911*37da2899SCharles.Forsyth		}
912*37da2899SCharles.Forsyth		for(i:=0; i<r; i++) {
913*37da2899SCharles.Forsyth			if(b[i] == byte echar) {
914*37da2899SCharles.Forsyth				menu(fi);
915*37da2899SCharles.Forsyth				continue iloop;
916*37da2899SCharles.Forsyth			}
917*37da2899SCharles.Forsyth		}
918*37da2899SCharles.Forsyth		if(r == 0) {
919*37da2899SCharles.Forsyth			b[0] = byte 4;	# ctrl-d
920*37da2899SCharles.Forsyth			r = 1;
921*37da2899SCharles.Forsyth		}
922*37da2899SCharles.Forsyth		if(tmode)
923*37da2899SCharles.Forsyth			sys->write(dfd, b, r);
924*37da2899SCharles.Forsyth		else
925*37da2899SCharles.Forsyth			sys->write(pifd, b, r);
926*37da2899SCharles.Forsyth	}
927*37da2899SCharles.Forsyth}
928*37da2899SCharles.Forsyth
929*37da2899SCharles.Forsythccfd: ref Sys->FD;
930*37da2899SCharles.Forsythisraw := 0;
931*37da2899SCharles.Forsyth
932*37da2899SCharles.Forsythraw(on: int)
933*37da2899SCharles.Forsyth{
934*37da2899SCharles.Forsyth	if(ccfd == nil) {
935*37da2899SCharles.Forsyth		ccfd = sys->open("/dev/consctl", Sys->OWRITE);
936*37da2899SCharles.Forsyth		if(ccfd == nil) {
937*37da2899SCharles.Forsyth			print("/dev/consctl: %r\n");
938*37da2899SCharles.Forsyth			return;
939*37da2899SCharles.Forsyth		}
940*37da2899SCharles.Forsyth	}
941*37da2899SCharles.Forsyth	if(on)
942*37da2899SCharles.Forsyth		sys->fprint(ccfd, "rawon");
943*37da2899SCharles.Forsyth	else
944*37da2899SCharles.Forsyth		sys->fprint(ccfd, "rawoff");
945*37da2899SCharles.Forsyth	israw = on;
946*37da2899SCharles.Forsyth}
947*37da2899SCharles.Forsyth
948*37da2899SCharles.Forsythkillgrp()
949*37da2899SCharles.Forsyth{
950*37da2899SCharles.Forsyth	pid := sys->pctl(0, nil);
951*37da2899SCharles.Forsyth	f := "/prog/"+string pid+"/ctl";
952*37da2899SCharles.Forsyth	fd := sys->open(f, Sys->OWRITE);
953*37da2899SCharles.Forsyth	if(fd == nil)
954*37da2899SCharles.Forsyth		print("%s: %r\n", f);
955*37da2899SCharles.Forsyth	else
956*37da2899SCharles.Forsyth		sys->fprint(fd, "killgrp");
957*37da2899SCharles.Forsyth}
958*37da2899SCharles.Forsyth
959*37da2899SCharles.Forsythkill(pid: int)
960*37da2899SCharles.Forsyth{
961*37da2899SCharles.Forsyth	f := "/prog/"+string pid+"/ctl";
962*37da2899SCharles.Forsyth	fd := sys->open(f, Sys->OWRITE);
963*37da2899SCharles.Forsyth	if(fd == nil)
964*37da2899SCharles.Forsyth		print("%s: %r\n", f);
965*37da2899SCharles.Forsyth	else
966*37da2899SCharles.Forsyth		sys->fprint(fd, "kill");
967*37da2899SCharles.Forsyth}
968*37da2899SCharles.Forsyth
969*37da2899SCharles.Forsyth
970*37da2899SCharles.Forsyth# Code for switching to previously unsupported bps rates:
971*37da2899SCharles.Forsyth
972*37da2899SCharles.Forsyth##define UTCR1	0x4
973*37da2899SCharles.Forsyth##define UTCR2	0x8
974*37da2899SCharles.Forsyth##define UTCR3	0xc
975*37da2899SCharles.Forsyth##define UTDR	0x14
976*37da2899SCharles.Forsyth##define UTSR0	0x1c
977*37da2899SCharles.Forsyth##define UTSR1	0x20
978*37da2899SCharles.Forsyth#
979*37da2899SCharles.Forsyth#TEXT _startup(SB), $-4
980*37da2899SCharles.Forsyth#	MOVW	$0x80000000,R2
981*37da2899SCharles.Forsyth#	ORR	$0x00050000,R2
982*37da2899SCharles.Forsyth#
983*37da2899SCharles.Forsyth#	MOVW	$0, R1
984*37da2899SCharles.Forsyth#	MOVW	R1, UTDR(R2)	/* send ack */
985*37da2899SCharles.Forsyth#
986*37da2899SCharles.Forsyth#wait:
987*37da2899SCharles.Forsyth#	MOVW	UTSR1(R2), R1
988*37da2899SCharles.Forsyth#	TST	$1, R1		/* TBY */
989*37da2899SCharles.Forsyth#	BNE	wait
990*37da2899SCharles.Forsyth#
991*37da2899SCharles.Forsyth#	MOVW	$0x90000000,R3
992*37da2899SCharles.Forsyth#	ORR	$0x00000010,R3
993*37da2899SCharles.Forsyth#	MOVW	(R4),R1
994*37da2899SCharles.Forsyth#	ADD	$0x5a000,R1	/* 100 ms */
995*37da2899SCharles.Forsyth#delay1:
996*37da2899SCharles.Forsyth#	MOVW	(R3),R1
997*37da2899SCharles.Forsyth#	SUB.S	$0x5a000, R1	/* 100 ms */
998*37da2899SCharles.Forsyth#	BLO	delay1
999*37da2899SCharles.Forsyth#
1000*37da2899SCharles.Forsyth#	MOVW	UTCR3(R2), R5	/* save utcr3 */
1001*37da2899SCharles.Forsyth#	MOVW	$0, R1
1002*37da2899SCharles.Forsyth#	MOVW	R1, UTCR3(R2)	/* disable xmt/rcv */
1003*37da2899SCharles.Forsyth#
1004*37da2899SCharles.Forsyth#	MOVW	R0, R1
1005*37da2899SCharles.Forsyth#	AND	$0xff, R1
1006*37da2899SCharles.Forsyth#	MOVW	R1, UTCR2(R2)
1007*37da2899SCharles.Forsyth#	MOVW	R0 >> 8, R1
1008*37da2899SCharles.Forsyth#	MOVW	R1, UTCR1(R2)
1009*37da2899SCharles.Forsyth#
1010*37da2899SCharles.Forsyth#	MOVW	$0xff, R1
1011*37da2899SCharles.Forsyth#	MOVW	R1, UTSR0(R2)	/* clear sticky bits */
1012*37da2899SCharles.Forsyth#
1013*37da2899SCharles.Forsyth#	MOVW	$3, R1
1014*37da2899SCharles.Forsyth#	MOVW	R1, UTCR3(R2)	/* enable xmt/rcv */
1015*37da2899SCharles.Forsyth#
1016*37da2899SCharles.Forsyth#	MOVW	$0, R0
1017*37da2899SCharles.Forsyth#sync:
1018*37da2899SCharles.Forsyth#	MOVW	R0, UTDR(R2)	/* send sync char */
1019*37da2899SCharles.Forsyth#syncwait:
1020*37da2899SCharles.Forsyth#	MOVW	UTSR1(R2), R1
1021*37da2899SCharles.Forsyth#	TST	$1, R1		/* TBY */
1022*37da2899SCharles.Forsyth#	BNE	syncwait
1023*37da2899SCharles.Forsyth#	TST	$2, R1		/* RNE */
1024*37da2899SCharles.Forsyth#	BEQ	sync
1025*37da2899SCharles.Forsyth#	MOVW	UTDR(R2), R0
1026*37da2899SCharles.Forsyth#	MOVW	R0, UTDR(R2)	/* echo rcvd char */
1027*37da2899SCharles.Forsyth#
1028*37da2899SCharles.Forsyth#	MOVW	$0xff, R1
1029*37da2899SCharles.Forsyth#	MOVW	R1, UTSR0(R2)	/* clear sticky bits */
1030*37da2899SCharles.Forsyth#	MOVW	R5, UTCR3(R2)	/* re-enable xmt/rcv and interrupts */
1031*37da2899SCharles.Forsyth#
1032*37da2899SCharles.Forsyth#	WORD	$0xef000011	/* exit */
1033*37da2899SCharles.Forsyth
1034*37da2899SCharles.Forsyth
1035*37da2899SCharles.Forsythbpscode := array[] of {
1036*37da2899SCharles.Forsyth	16re3a22102, 16re3822805, 16re3a11000, 16re5821014,
1037*37da2899SCharles.Forsyth	16re5921020, 16re3110001, big 16r1afffffc, 16re3a33209,
1038*37da2899SCharles.Forsyth	16re3833010, 16re5941000, 16re2811a5a, 16re5931000,
1039*37da2899SCharles.Forsyth	16re2511a5a, big 16r3afffffc, 16re592500c, 16re3a11000,
1040*37da2899SCharles.Forsyth	16re582100c, 16re1a11000, 16re20110ff, 16re5821008,
1041*37da2899SCharles.Forsyth	16re1a11420, 16re5821004, 16re3a110ff, 16re582101c,
1042*37da2899SCharles.Forsyth	16re3a11003, 16re582100c, 16re3a00000, 16re5820014,
1043*37da2899SCharles.Forsyth	16re5921020, 16re3110001, big 16r1afffffc, 16re3110002,
1044*37da2899SCharles.Forsyth	big 16r0afffff9, 16re5920014, 16re5820014, 16re3a110ff,
1045*37da2899SCharles.Forsyth	16re582101c, 16re582500c, 16ref000011,
1046*37da2899SCharles.Forsyth};
1047*37da2899SCharles.Forsyth
1048*37da2899SCharles.Forsythsa1100_setbps(bps: int)
1049*37da2899SCharles.Forsyth{
1050*37da2899SCharles.Forsyth	print("<sa1100_setbps %d>", bps);
1051*37da2899SCharles.Forsyth	nb := len bpscode*4;
1052*37da2899SCharles.Forsyth	b := array[nb] of byte;
1053*37da2899SCharles.Forsyth	for(i := 0; i < len bpscode; i++)
1054*37da2899SCharles.Forsyth		b[i*4:] = bint(int bpscode[i]);
1055*37da2899SCharles.Forsyth	rdi_write(b, 16r8080, nb);
1056*37da2899SCharles.Forsyth	reg := array[NREG] of int;
1057*37da2899SCharles.Forsyth	d := (3686400/(bps*16))-1;
1058*37da2899SCharles.Forsyth	reg[0] = d;
1059*37da2899SCharles.Forsyth	reg[R_PC] = 16r8080;
1060*37da2899SCharles.Forsyth	rdi_cpuwrite(reg, (1<<0)|(1<<R_PC));
1061*37da2899SCharles.Forsyth	sb := array[2] of byte;
1062*37da2899SCharles.Forsyth	sb[0] = byte 16r10;
1063*37da2899SCharles.Forsyth	sb[1] = byte 0;
1064*37da2899SCharles.Forsyth	sys->write(dfd, sb, 2);
1065*37da2899SCharles.Forsyth	rb := sreadn(1);
1066*37da2899SCharles.Forsyth	setbps(bps);
1067*37da2899SCharles.Forsyth	do rb = sreadn(1);
1068*37da2899SCharles.Forsyth	while(rb[0] != byte 0);
1069*37da2899SCharles.Forsyth	sb[0] = byte 16rff;
1070*37da2899SCharles.Forsyth	sys->write(dfd, sb, 1);
1071*37da2899SCharles.Forsyth	do rb = sreadn(1);
1072*37da2899SCharles.Forsyth	while(rb[0] != sb[0]);
1073*37da2899SCharles.Forsyth	getreply(0);
1074*37da2899SCharles.Forsyth}
1075*37da2899SCharles.Forsyth
1076*37da2899SCharles.Forsythaifload(fname: string, adr: int)
1077*37da2899SCharles.Forsyth{
1078*37da2899SCharles.Forsyth	out("");
1079*37da2899SCharles.Forsyth	if(adr < 0)
1080*37da2899SCharles.Forsyth		print("<aifload %s>\n", fname);
1081*37da2899SCharles.Forsyth	fd := sys->open(fname, Sys->OREAD);
1082*37da2899SCharles.Forsyth	if(fd == nil)
1083*37da2899SCharles.Forsyth		raise sprint("fail:%s:%r", fname);
1084*37da2899SCharles.Forsyth	d: Sys->Dir;
1085*37da2899SCharles.Forsyth	(nil, d) = sys->fstat(fd);
1086*37da2899SCharles.Forsyth	b := array[int d.length] of byte;
1087*37da2899SCharles.Forsyth	sys->read(fd, b, len b);
1088*37da2899SCharles.Forsyth	if(adr < 0) {
1089*37da2899SCharles.Forsyth		if(len b < 128)
1090*37da2899SCharles.Forsyth			raise sprint("fail:%s:not aif", fname);
1091*37da2899SCharles.Forsyth		tsize := intb(b[20:24]);
1092*37da2899SCharles.Forsyth		dsize := intb(b[24:28]);
1093*37da2899SCharles.Forsyth		bsize := intb(b[32:36]);
1094*37da2899SCharles.Forsyth		tbase := intb(b[40:44]);
1095*37da2899SCharles.Forsyth		dbase := intb(b[52:56]);
1096*37da2899SCharles.Forsyth		print("%ux/%ux: %ux+%ux+%ux\n", tbase, dbase, tsize, dsize, bsize);
1097*37da2899SCharles.Forsyth		rdi_write(b, tbase, tsize+dsize);
1098*37da2899SCharles.Forsyth		reg := array[NREG] of int;
1099*37da2899SCharles.Forsyth		reg[R_PC] = tbase+8;
1100*37da2899SCharles.Forsyth		rdi_cpuwrite(reg, 1<<R_PC);
1101*37da2899SCharles.Forsyth	} else
1102*37da2899SCharles.Forsyth		rdi_write(b, adr, int d.length);
1103*37da2899SCharles.Forsyth}
1104*37da2899SCharles.Forsyth
1105*37da2899SCharles.Forsyth
1106*37da2899SCharles.Forsythinit(nil: ref Draw->Context, argv: list of string)
1107*37da2899SCharles.Forsyth{
1108*37da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
1109*37da2899SCharles.Forsyth	str = load String String->PATH;
1110*37da2899SCharles.Forsyth
1111*37da2899SCharles.Forsyth	sys->pctl(Sys->NEWPGRP, nil);
1112*37da2899SCharles.Forsyth
1113*37da2899SCharles.Forsyth	port := df_port;
1114*37da2899SCharles.Forsyth	bps := df_bps;
1115*37da2899SCharles.Forsyth	usecmdmode := 0;
1116*37da2899SCharles.Forsyth	ofs := -1;
1117*37da2899SCharles.Forsyth	prog: string = nil;
1118*37da2899SCharles.Forsyth
1119*37da2899SCharles.Forsyth	argv = tl argv;
1120*37da2899SCharles.Forsyth	while(argv != nil) {
1121*37da2899SCharles.Forsyth		a := hd argv;
1122*37da2899SCharles.Forsyth		argv = tl argv;
1123*37da2899SCharles.Forsyth		if(len a >= 2 && a[0] == '-')
1124*37da2899SCharles.Forsyth			case a[1] {
1125*37da2899SCharles.Forsyth			'c' =>
1126*37da2899SCharles.Forsyth				usecmdmode = 1;
1127*37da2899SCharles.Forsyth			'O' =>
1128*37da2899SCharles.Forsyth				ofs = atoi(a[2:]);
1129*37da2899SCharles.Forsyth			'd' =>
1130*37da2899SCharles.Forsyth				debug = 1;
1131*37da2899SCharles.Forsyth			'p' =>
1132*37da2899SCharles.Forsyth				port = a[2:];
1133*37da2899SCharles.Forsyth			's' =>
1134*37da2899SCharles.Forsyth				bps = atoi(a[2:]);
1135*37da2899SCharles.Forsyth			'r' =>
1136*37da2899SCharles.Forsyth				nocr = 1;
1137*37da2899SCharles.Forsyth			'l' =>
1138*37da2899SCharles.Forsyth				raw(1);
1139*37da2899SCharles.Forsyth			'e' =>
1140*37da2899SCharles.Forsyth				if(a[2] == '^')
1141*37da2899SCharles.Forsyth					echar = a[3]&16r1f;
1142*37da2899SCharles.Forsyth				else
1143*37da2899SCharles.Forsyth					echar = a[2];
1144*37da2899SCharles.Forsyth			't' =>
1145*37da2899SCharles.Forsyth				tmode = 1;
1146*37da2899SCharles.Forsyth			'h' =>
1147*37da2899SCharles.Forsyth				print("usage: rdp [-crdlht] [-e<c>] [-O<ofs>] [-p<port>] [-s<bps>] [prog]\n");
1148*37da2899SCharles.Forsyth				return;
1149*37da2899SCharles.Forsyth			* =>
1150*37da2899SCharles.Forsyth				print("invalid option: %s\n", a);
1151*37da2899SCharles.Forsyth				return;
1152*37da2899SCharles.Forsyth			}
1153*37da2899SCharles.Forsyth		else
1154*37da2899SCharles.Forsyth			prog = a;
1155*37da2899SCharles.Forsyth	}
1156*37da2899SCharles.Forsyth
1157*37da2899SCharles.Forsyth	print("rdp 0.17 (port=%s, bps=%d)\n", port, bps);
1158*37da2899SCharles.Forsyth	dfd = sys->open(port, Sys->ORDWR);
1159*37da2899SCharles.Forsyth	if(dfd == nil) {
1160*37da2899SCharles.Forsyth		sys->print("open %s failed: %r\n", port);
1161*37da2899SCharles.Forsyth		return;
1162*37da2899SCharles.Forsyth	}
1163*37da2899SCharles.Forsyth	cfd = sys->open(port+"ctl", Sys->OWRITE);
1164*37da2899SCharles.Forsyth	if(cfd == nil)
1165*37da2899SCharles.Forsyth		sys->print("warning: open %s failed: %r\n", port+"ctl");
1166*37da2899SCharles.Forsyth
1167*37da2899SCharles.Forsyth	pfd := array[2] of ref Sys->FD;
1168*37da2899SCharles.Forsyth	sys->pipe(pfd);
1169*37da2899SCharles.Forsyth	ifd = pfd[1];
1170*37da2899SCharles.Forsyth	pifd = pfd[0];
1171*37da2899SCharles.Forsyth	(scc, sdc) = (chan of int, chan of (array of byte, int));
1172*37da2899SCharles.Forsyth	spawn serinp();
1173*37da2899SCharles.Forsyth	spawn input();
1174*37da2899SCharles.Forsyth	r := 1;
1175*37da2899SCharles.Forsyth	{
1176*37da2899SCharles.Forsyth		if(tmode)
1177*37da2899SCharles.Forsyth			terminal();
1178*37da2899SCharles.Forsyth		reset(r);
1179*37da2899SCharles.Forsyth		if(!p_isopen) {
1180*37da2899SCharles.Forsyth			rdi_open(bps);
1181*37da2899SCharles.Forsyth			rdi_info(16r180, (1<<0)|(1<<1)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8));
1182*37da2899SCharles.Forsyth		}
1183*37da2899SCharles.Forsyth		# print("\n<connection established>\n");
1184*37da2899SCharles.Forsyth		print("\n<contact has been made>\n");
1185*37da2899SCharles.Forsyth		if(usecmdmode) {
1186*37da2899SCharles.Forsyth			cmdmode();
1187*37da2899SCharles.Forsyth		} else {
1188*37da2899SCharles.Forsyth			if(prog != nil)
1189*37da2899SCharles.Forsyth				aifload(prog, -1);
1190*37da2899SCharles.Forsyth			else if(ofs != -1)
1191*37da2899SCharles.Forsyth				sbmodeofs(ofs);
1192*37da2899SCharles.Forsyth			else
1193*37da2899SCharles.Forsyth				sbmode();
1194*37da2899SCharles.Forsyth			reg := array[NREG] of int;
1195*37da2899SCharles.Forsyth			# rdi_cpuread(reg, (1<<R_PC)|(1<<R_CPSR));
1196*37da2899SCharles.Forsyth			# print("<execute at %ux; cpsr=%ux>\n", reg[R_PC], reg[R_CPSR]);
1197*37da2899SCharles.Forsyth			rdi_cpuread(reg, (1<<R_PC));
1198*37da2899SCharles.Forsyth			print("<execute at %ux>\n", reg[R_PC]);
1199*37da2899SCharles.Forsyth			rdi_execute();
1200*37da2899SCharles.Forsyth		}
1201*37da2899SCharles.Forsyth		rdi_close();
1202*37da2899SCharles.Forsyth
1203*37da2899SCharles.Forsyth		# Warning: this will make Linux emu crash...
1204*37da2899SCharles.Forsyth		killgrp();
1205*37da2899SCharles.Forsyth	}exception e{
1206*37da2899SCharles.Forsyth	"fail:*" =>
1207*37da2899SCharles.Forsyth		if(israw)
1208*37da2899SCharles.Forsyth			raw(0);
1209*37da2899SCharles.Forsyth		killgrp();
1210*37da2899SCharles.Forsyth		raise e;
1211*37da2899SCharles.Forsyth	"rdp:*" =>
1212*37da2899SCharles.Forsyth		out("");
1213*37da2899SCharles.Forsyth		if(debug)
1214*37da2899SCharles.Forsyth			print("<exception: %s>\n", e);
1215*37da2899SCharles.Forsyth		case e {
1216*37da2899SCharles.Forsyth		"rdp:error" =>	;
1217*37da2899SCharles.Forsyth		"rdp:tmode" =>
1218*37da2899SCharles.Forsyth			tmode = !tmode;
1219*37da2899SCharles.Forsyth			if(tmode)
1220*37da2899SCharles.Forsyth				print("<terminal mode>\n");
1221*37da2899SCharles.Forsyth			else
1222*37da2899SCharles.Forsyth				print("<rdp mode>\n");
1223*37da2899SCharles.Forsyth		"rdp:reset" =>
1224*37da2899SCharles.Forsyth			r = 0;
1225*37da2899SCharles.Forsyth		* =>
1226*37da2899SCharles.Forsyth			r = 1;
1227*37da2899SCharles.Forsyth		}
1228*37da2899SCharles.Forsyth	}
1229*37da2899SCharles.Forsyth}
1230*37da2899SCharles.Forsyth
1231