implement Rdp;include "sys.m"; sys: Sys; print, sprint: import sys;include "draw.m";include "string.m"; str: String; df_port: con "/dev/eia0";df_bps: con 38400; Rdp: module{ init: fn(nil: ref Draw->Context, arg: list of string);}; dfd: ref sys->FD;cfd: ref sys->FD;ifd: ref sys->FD;pifd: ref sys->FD;p_isopen := 0; R_R15: con 15;R_PC: con 16;R_CPSR: con 17;R_SPSR: con 18;NREG: con 19; debug := 0;nocr := 0;tmode := 0;# echar := 16r1c; # ctrl-\echar := 16r1d; # ctrl-] (because Tk grabs the ctrl-\ ) bint(x: int): array of byte{ b := array[4] of byte; b[0] = byte x; b[1] = byte (x>>8); b[2] = byte (x>>16); b[3] = byte (x>>24); return b;} intb(b: array of byte): int{ return int b[0] | (int b[1] << 8) | (int b[2] << 16) | (int b[3] << 24);} statusmsg(n: int): string{ m: string; case n { 0 => m = nil; 1 => m = "Reset"; 2 => m = "Undefined instruction"; 3 => m = "Software interrupt"; 4 => m = "Prefetch abort"; 5 => m = "Data abort"; 6 => m = "Address exception"; 7 => m = "IRQ"; 8 => m = "FIQ"; 9 => m = "Error"; 10 => m = "Branch Through 0"; 253 => m = "Insufficient privilege"; 254 => m = "Unimplemented message"; 255 => m = "Undefined message"; * => m = sprint("Status %d", n); } return m;} sdc: chan of (array of byte, int);scc: chan of int; serinp(){ b: array of byte = nil; save: array of byte = nil; x := 0; for(;;) { m := <- scc; if(m == 0) { save = b[0:x]; continue; } b = nil; t: int; do { alt { m = <- scc => if(m == 0) print("<strange error>\n"); b = nil; * => ; } if(b == nil) { if(m >= 0) t = m; else t = -m; x = 0; b = array[t] of byte; } if(save != nil) { r := len save; if(r > (t-x)) r = t-x; b[x:] = save[0:r]; save = save[r:]; if(len save == 0) save = nil; x += r; continue; } r := sys->read(dfd, b[x:], t-x); if(r < 0) sdc <-= (array of byte sprint("fail:%r"), -1); if(r == 0) sdc <-= (array of byte "fail:hangup", -1); if(debug) { if(r == 1) print("<%ux>", int b[x]); else print("<%ux,%ux...(%d)>", int b[x], int b[x+1], r); } x += r; } while(m >= 0 && x < t); sdc <-= (b, x); }} sreadn(n: int): array of byte{ b: array of byte; if(n == 0) return array[0] of byte; scc <-= n; (b, n) = <- sdc; if(n < 0) raise string b; return b[0:n];} # yes, it's kind of a hack...fds := array[32] of ref Sys->FD; oscmd(){ arg := array[4] of int; buf := array[4] of array of byte; b := sreadn(5); op := intb(b[:4]); argd := int b[4]; for(i := 0; i<4; i++) { t := (argd >> (i*2))&3; case t { 0 => ; 1 => arg[i] = int sreadn(1)[0]; 2 => arg[i] = intb(sreadn(4)); 3 => c := int sreadn(1)[0]; if(c < 255) { buf[i] = array[c] of byte; if(c <= 32) { buf[i][0:] = sreadn(c); } else arg[i] = intb(sreadn(4)); } else { b: array of byte; b = sreadn(8); c = intb(b[:4]); arg[i] = intb(b[4:8]); buf[i] = array[c] of byte; } } } for(i = 0; i<4; i++) if(buf[i] != nil && len buf[i] > 32) rdi_read(arg[i], buf[i], len buf[i]); r := 0; case op { 0 or 2 => ; * => out(""); } case op { 0 => if(debug) print("SWI_WriteC(%d)\n", arg[0]); out(string byte arg[0]); 2 => if(debug) print("SWI_Write0(<%d>)\n", len buf[0]); out(string buf[0]); 4 => if(debug) print("SWI_ReadC()\n"); sys->read(ifd, b, 1); r = int b[0]; 16r66 => fname := string buf[0]; if(debug) print("SWI_Open(%s, %d)\n", fname, arg[1]); fd: ref Sys->FD; case arg[1] { 0 or 1 => fd = sys->open(fname, Sys->OREAD); 2 or 3 => fd = sys->open(fname, Sys->ORDWR); 4 or 5 => fd = sys->open(fname, Sys->OWRITE); if(fd == nil) fd = sys->create(fname, Sys->OWRITE, 8r666); 6 or 7 => fd = sys->open(fname, Sys->OWRITE|Sys->OTRUNC); if(fd == nil) fd = sys->create(fname, Sys->OWRITE, 8r666); 8 or 9 => fd = sys->open(fname, Sys->OWRITE); if(fd == nil) fd = sys->create(fname, Sys->OWRITE, 8r666); else sys->seek(fd, big 0, Sys->SEEKEND); 10 or 11 => fd = sys->open(fname, Sys->ORDWR); if(fd == nil) fd = sys->create(fname, Sys->ORDWR, 8r666); else sys->seek(fd, big 0, Sys->SEEKEND); } if(fd != nil) { r = fd.fd; if(r >= len fds) { print("<fd %d out of range 1-%d>\n", r, len fds); r = 0; } else fds[r] = fd; } 16r68 => if(debug) print("SWI_Close(%d)\n", arg[0]); if(arg[0] <= 0 || arg[0] >= len fds) r = -1; else { if(fds[arg[0]] != nil) fds[arg[0]] = nil; else r = -1; } 16r69 => if(debug) print("SWI_Write(%d, <%d>)\n", arg[0], len buf[1]); if(arg[0] <= 0 || arg[0] >= len fds) r = -1; else r = sys->write(fds[arg[0]], buf[1], len buf[1]); r = arg[2]-r; 16r6a => if(debug) print("SWI_Read(%d, 0x%ux, %d)\n", arg[0], arg[1], arg[2]); if(arg[0] <= 0 || arg[0] >= len fds) r = -1; else { d := array[arg[2]] of byte; r = sys->read(fds[arg[0]], d, arg[2]); if(r > 0) rdi_write(d, arg[1], r); } r = arg[2]-r; 16r6b => if(debug) print("SWI_Seek(%d, %d)\n", arg[0], arg[1]); if(arg[0] <= 0 || arg[0] >= len fds) r = -1; else r = int sys->seek(fds[arg[0]], big arg[1], 0); 16r6c => if(debug) print("SWI_Flen(%d)\n", arg[0]); if(arg[0] <= 0 || arg[0] >= len fds) r = -1; else { d: Sys->Dir; (r, d) = sys->fstat(fds[arg[0]]); if(r >= 0) r = int d.length; } 16r6e => if(debug) print("SWI_IsTTY(%d)\n", arg[0]); r = 0; # how can we detect if it's a TTY? * => print("unsupported: SWI 0x%ux\n", op); } b = array[6] of byte; b[0] = byte 16r13; if(debug) print("r0=%d\n", r); if(r >= 0 && r <= 16rff) { b[1] = byte 1; b[2] = byte r; sys->write(dfd, b, 3); } else { b[1] = byte 2; b[2:] = bint(r); sys->write(dfd, b, 6); }} terminal(){ b := array[1024] of byte; c := 3; # num of invalid chars before resetting tmode = 1; for(;;) { n: int; b: array of byte; alt { scc <-= -8192 => (b, n) = <- sdc; (b, n) = <- sdc => ; } if(n < 0) raise string b; c -= out(string b[:n]); if(c < 0) { scc <-= 0; raise "rdp:tmode"; } if(!tmode) { return; } }} getreply(n: int): (array of byte, int){ loop: for(;;) { c := int sreadn(1)[0]; case c { 16r21 => oscmd(); 16r7f => raise "rdp:reset"; 16r5f => break loop; * => print("<%ux?>", c); scc <-= 0; raise "rdp:tmode"; } } b := sreadn(n+1); s := int b[n]; if(s != 0) { out(""); print("[%s]\n", statusmsg(s)); } return (b[:n], s);} outstr: string;tpid: int; timeout(t: int, c: chan of int){ tpid = sys->pctl(0, nil); if(t > 0) sys->sleep(t); c <-= 0; tpid = 0;} bsc: chan of string; bufout(){ buf := ""; tc := chan of int; n: int; s: string; for(;;) { alt { n = <- tc => print("%s", buf); buf = ""; s = <- bsc => #if(tpid) { # kill(tpid); # tpid = 0; #} if((len buf+len s) >= 1024) { print("%s", buf); buf = s; } if(s == "" || debug) { print("%s", buf); buf = ""; } else { buf += s; if(tpid == 0) spawn timeout(300, tc); } } }} out(s: string): int{ if(bsc == nil) { bsc = chan of string; spawn bufout(); } c := 0; if(nocr || tmode) { n := ""; for(i:=0; i<len s; i++) { if(!(nocr && s[i] == '\r')) n[len n] = s[i]; if(s[i] >= 16r7f) c++; } bsc <-= n; } else bsc <-= s; return c;} reset(r: int){ out(""); if(debug) print("reset(%d)\n", r); p_isopen = 0; b := array of byte sprint("b9600"); sys->write(cfd, b, len b); if(r) { b[0] = byte 127; sys->write(dfd, b, 1); print("<sending reset>"); } ok := 0; s := ""; for(;;) { n: int; b: array of byte; scc <-= -8192; (b, n) = <- sdc; if(n < 0) raise string b; for(i := 0; i<n; i++) { if(b[i] == byte 127) { if(!ok) print("\n"); ok = 1; s = ""; continue; } if(b[i] == byte 0) { if(ok && i == n-1) { out(s); out(""); return; } else { s = ""; continue; } } if(b[i] < byte 127) s += string b[i:i+1]; else ok = 0; } }} sa1100_reset(){ rdi_write(bint(1), int 16r90030000, 4);} setbps(bps: int){ # for older Emu's using setserial hacks... if(bps > 38400) sys->write(cfd, array of byte "b38400", 6); out(""); print("<bps=%d>\n", bps);Lines 1–500 of 1230. Load more
implement Rdp; include "sys.m"; sys: Sys; print, sprint: import sys; include "draw.m"; include "string.m"; str: String; df_port: con "/dev/eia0"; df_bps: con 38400; Rdp: module { init: fn(nil: ref Draw->Context, arg: list of string); }; dfd: ref sys->FD; cfd: ref sys->FD; ifd: ref sys->FD; pifd: ref sys->FD; p_isopen := 0; R_R15: con 15; R_PC: con 16; R_CPSR: con 17; R_SPSR: con 18; NREG: con 19; debug := 0; nocr := 0; tmode := 0; # echar := 16r1c; # ctrl-\ echar := 16r1d; # ctrl-] (because Tk grabs the ctrl-\ ) bint(x: int): array of byte { b := array[4] of byte; b[0] = byte x; b[1] = byte (x>>8); b[2] = byte (x>>16); b[3] = byte (x>>24); return b; } intb(b: array of byte): int { return int b[0] | (int b[1] << 8) | (int b[2] << 16) | (int b[3] << 24); } statusmsg(n: int): string { m: string; case n { 0 => m = nil; 1 => m = "Reset"; 2 => m = "Undefined instruction"; 3 => m = "Software interrupt"; 4 => m = "Prefetch abort"; 5 => m = "Data abort"; 6 => m = "Address exception"; 7 => m = "IRQ"; 8 => m = "FIQ"; 9 => m = "Error"; 10 => m = "Branch Through 0"; 253 => m = "Insufficient privilege"; 254 => m = "Unimplemented message"; 255 => m = "Undefined message"; * => m = sprint("Status %d", n); } return m; } sdc: chan of (array of byte, int); scc: chan of int; serinp() { b: array of byte = nil; save: array of byte = nil; x := 0; for(;;) { m := <- scc; if(m == 0) { save = b[0:x]; continue; } b = nil; t: int; do { alt { m = <- scc => if(m == 0) print("<strange error>\n"); b = nil; * => ; } if(b == nil) { if(m >= 0) t = m; else t = -m; x = 0; b = array[t] of byte; } if(save != nil) { r := len save; if(r > (t-x)) r = t-x; b[x:] = save[0:r]; save = save[r:]; if(len save == 0) save = nil; x += r; continue; } r := sys->read(dfd, b[x:], t-x); if(r < 0) sdc <-= (array of byte sprint("fail:%r"), -1); if(r == 0) sdc <-= (array of byte "fail:hangup", -1); if(debug) { if(r == 1) print("<%ux>", int b[x]); else print("<%ux,%ux...(%d)>", int b[x], int b[x+1], r); } x += r; } while(m >= 0 && x < t); sdc <-= (b, x); } } sreadn(n: int): array of byte { b: array of byte; if(n == 0) return array[0] of byte; scc <-= n; (b, n) = <- sdc; if(n < 0) raise string b; return b[0:n]; } # yes, it's kind of a hack... fds := array[32] of ref Sys->FD; oscmd() { arg := array[4] of int; buf := array[4] of array of byte; b := sreadn(5); op := intb(b[:4]); argd := int b[4]; for(i := 0; i<4; i++) { t := (argd >> (i*2))&3; case t { 0 => ; 1 => arg[i] = int sreadn(1)[0]; 2 => arg[i] = intb(sreadn(4)); 3 => c := int sreadn(1)[0]; if(c < 255) { buf[i] = array[c] of byte; if(c <= 32) { buf[i][0:] = sreadn(c); } else arg[i] = intb(sreadn(4)); } else { b: array of byte; b = sreadn(8); c = intb(b[:4]); arg[i] = intb(b[4:8]); buf[i] = array[c] of byte; } } } for(i = 0; i<4; i++) if(buf[i] != nil && len buf[i] > 32) rdi_read(arg[i], buf[i], len buf[i]); r := 0; case op { 0 or 2 => ; * => out(""); } case op { 0 => if(debug) print("SWI_WriteC(%d)\n", arg[0]); out(string byte arg[0]); 2 => if(debug) print("SWI_Write0(<%d>)\n", len buf[0]); out(string buf[0]); 4 => if(debug) print("SWI_ReadC()\n"); sys->read(ifd, b, 1); r = int b[0]; 16r66 => fname := string buf[0]; if(debug) print("SWI_Open(%s, %d)\n", fname, arg[1]); fd: ref Sys->FD; case arg[1] { 0 or 1 => fd = sys->open(fname, Sys->OREAD); 2 or 3 => fd = sys->open(fname, Sys->ORDWR); 4 or 5 => fd = sys->open(fname, Sys->OWRITE); if(fd == nil) fd = sys->create(fname, Sys->OWRITE, 8r666); 6 or 7 => fd = sys->open(fname, Sys->OWRITE|Sys->OTRUNC); if(fd == nil) fd = sys->create(fname, Sys->OWRITE, 8r666); 8 or 9 => fd = sys->open(fname, Sys->OWRITE); if(fd == nil) fd = sys->create(fname, Sys->OWRITE, 8r666); else sys->seek(fd, big 0, Sys->SEEKEND); 10 or 11 => fd = sys->open(fname, Sys->ORDWR); if(fd == nil) fd = sys->create(fname, Sys->ORDWR, 8r666); else sys->seek(fd, big 0, Sys->SEEKEND); } if(fd != nil) { r = fd.fd; if(r >= len fds) { print("<fd %d out of range 1-%d>\n", r, len fds); r = 0; } else fds[r] = fd; } 16r68 => if(debug) print("SWI_Close(%d)\n", arg[0]); if(arg[0] <= 0 || arg[0] >= len fds) r = -1; else { if(fds[arg[0]] != nil) fds[arg[0]] = nil; else r = -1; } 16r69 => if(debug) print("SWI_Write(%d, <%d>)\n", arg[0], len buf[1]); if(arg[0] <= 0 || arg[0] >= len fds) r = -1; else r = sys->write(fds[arg[0]], buf[1], len buf[1]); r = arg[2]-r; 16r6a => if(debug) print("SWI_Read(%d, 0x%ux, %d)\n", arg[0], arg[1], arg[2]); if(arg[0] <= 0 || arg[0] >= len fds) r = -1; else { d := array[arg[2]] of byte; r = sys->read(fds[arg[0]], d, arg[2]); if(r > 0) rdi_write(d, arg[1], r); } r = arg[2]-r; 16r6b => if(debug) print("SWI_Seek(%d, %d)\n", arg[0], arg[1]); if(arg[0] <= 0 || arg[0] >= len fds) r = -1; else r = int sys->seek(fds[arg[0]], big arg[1], 0); 16r6c => if(debug) print("SWI_Flen(%d)\n", arg[0]); if(arg[0] <= 0 || arg[0] >= len fds) r = -1; else { d: Sys->Dir; (r, d) = sys->fstat(fds[arg[0]]); if(r >= 0) r = int d.length; } 16r6e => if(debug) print("SWI_IsTTY(%d)\n", arg[0]); r = 0; # how can we detect if it's a TTY? * => print("unsupported: SWI 0x%ux\n", op); } b = array[6] of byte; b[0] = byte 16r13; if(debug) print("r0=%d\n", r); if(r >= 0 && r <= 16rff) { b[1] = byte 1; b[2] = byte r; sys->write(dfd, b, 3); } else { b[1] = byte 2; b[2:] = bint(r); sys->write(dfd, b, 6); } } terminal() { b := array[1024] of byte; c := 3; # num of invalid chars before resetting tmode = 1; for(;;) { n: int; b: array of byte; alt { scc <-= -8192 => (b, n) = <- sdc; (b, n) = <- sdc => ; } if(n < 0) raise string b; c -= out(string b[:n]); if(c < 0) { scc <-= 0; raise "rdp:tmode"; } if(!tmode) { return; } } } getreply(n: int): (array of byte, int) { loop: for(;;) { c := int sreadn(1)[0]; case c { 16r21 => oscmd(); 16r7f => raise "rdp:reset"; 16r5f => break loop; * => print("<%ux?>", c); scc <-= 0; raise "rdp:tmode"; } } b := sreadn(n+1); s := int b[n]; if(s != 0) { out(""); print("[%s]\n", statusmsg(s)); } return (b[:n], s); } outstr: string; tpid: int; timeout(t: int, c: chan of int) { tpid = sys->pctl(0, nil); if(t > 0) sys->sleep(t); c <-= 0; tpid = 0; } bsc: chan of string; bufout() { buf := ""; tc := chan of int; n: int; s: string; for(;;) { alt { n = <- tc => print("%s", buf); buf = ""; s = <- bsc => #if(tpid) { # kill(tpid); # tpid = 0; #} if((len buf+len s) >= 1024) { print("%s", buf); buf = s; } if(s == "" || debug) { print("%s", buf); buf = ""; } else { buf += s; if(tpid == 0) spawn timeout(300, tc); } } } } out(s: string): int { if(bsc == nil) { bsc = chan of string; spawn bufout(); } c := 0; if(nocr || tmode) { n := ""; for(i:=0; i<len s; i++) { if(!(nocr && s[i] == '\r')) n[len n] = s[i]; if(s[i] >= 16r7f) c++; } bsc <-= n; } else bsc <-= s; return c; } reset(r: int) { out(""); if(debug) print("reset(%d)\n", r); p_isopen = 0; b := array of byte sprint("b9600"); sys->write(cfd, b, len b); if(r) { b[0] = byte 127; sys->write(dfd, b, 1); print("<sending reset>"); } ok := 0; s := ""; for(;;) { n: int; b: array of byte; scc <-= -8192; (b, n) = <- sdc; if(n < 0) raise string b; for(i := 0; i<n; i++) { if(b[i] == byte 127) { if(!ok) print("\n"); ok = 1; s = ""; continue; } if(b[i] == byte 0) { if(ok && i == n-1) { out(s); out(""); return; } else { s = ""; continue; } } if(b[i] < byte 127) s += string b[i:i+1]; else ok = 0; } } } sa1100_reset() { rdi_write(bint(1), int 16r90030000, 4); } setbps(bps: int) { # for older Emu's using setserial hacks... if(bps > 38400) sys->write(cfd, array of byte "b38400", 6); out(""); print("<bps=%d>\n", bps);