mirror of
https://github.com/aap/pdp6.git
synced 2026-01-18 01:02:44 +00:00
959 lines
13 KiB
C
959 lines
13 KiB
C
#include <fcntl.h>
|
|
#include <termios.h>
|
|
#include <unistd.h>
|
|
#include <setjmp.h>
|
|
|
|
#include "fe.h"
|
|
|
|
struct termios tiosaved;
|
|
char erasec, killc, intrc;
|
|
jmp_buf errjmp;
|
|
|
|
int
|
|
raw(int fd)
|
|
{
|
|
struct termios tio;
|
|
if(tcgetattr(fd, &tio) < 0) return -1;
|
|
tiosaved = tio;
|
|
cfmakeraw(&tio);
|
|
if(tcsetattr(fd, TCSAFLUSH, &tio) < 0) return -1;
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
reset(int fd)
|
|
{
|
|
if(tcsetattr(0, TCSAFLUSH, &tiosaved) < 0) return -1;
|
|
return 0;
|
|
}
|
|
|
|
#define ALT 033
|
|
|
|
char
|
|
tyi(void)
|
|
{
|
|
char c;
|
|
read(0, &c, 1);
|
|
return c;
|
|
}
|
|
|
|
#define CTL(c) ((c) & 037)
|
|
|
|
void
|
|
tyo_(char c)
|
|
{
|
|
write(1, &c, 1);
|
|
}
|
|
|
|
void
|
|
tyo(char c)
|
|
{
|
|
static char *alt = "◊";
|
|
static char *ctrl = "↑";
|
|
|
|
if(c < 040){
|
|
switch(c){
|
|
case ALT:
|
|
write(1, alt, strlen(alt));
|
|
return;
|
|
case CTL('J'):
|
|
write(1, &c, 1);
|
|
c = CTL('M');
|
|
case CTL('M'):
|
|
case CTL('H'):
|
|
case CTL('I'):
|
|
write(1, &c, 1);
|
|
break;
|
|
default:
|
|
write(1, ctrl, strlen(ctrl));
|
|
c += 0100;
|
|
write(1, &c, 1);
|
|
}
|
|
}else
|
|
write(1, &c, 1);
|
|
}
|
|
|
|
#define ADDRMASK 03777777
|
|
|
|
enum {
|
|
BUF_ERR = ~0,
|
|
BUF_EMPTY = ~0-1,
|
|
|
|
/* typeout modes */
|
|
MODE_NONE = 0,
|
|
MODE_NUM,
|
|
MODE_HALF,
|
|
MODE_SYM,
|
|
MODE_ASCII,
|
|
MODE_SIXBIT,
|
|
MODE_SQUOZE,
|
|
MODE_FLOAT,
|
|
|
|
/* flags */
|
|
CF = 1, // one altmode
|
|
CCF = 2, // two altmodes
|
|
|
|
/* fields */
|
|
F_A = 1,
|
|
F_I = 2,
|
|
F_AC = 4,
|
|
F_FW = 8,
|
|
|
|
/* line modes */
|
|
LM_COLON = 1,
|
|
LM_LOAD,
|
|
LM_DUMP,
|
|
LM_MOUNT,
|
|
LM_UNMOUNT
|
|
};
|
|
|
|
#define BUFLEN 200
|
|
|
|
char buf[BUFLEN+1];
|
|
char *bufstart;
|
|
int nbuf;
|
|
|
|
int flags;
|
|
char ch;
|
|
int base = 8;
|
|
hword dot;
|
|
hword addr;
|
|
int opened;
|
|
word q;
|
|
word number;
|
|
int hasnum;
|
|
int permmode = MODE_SYM;
|
|
int curmode;
|
|
struct Assembler
|
|
{
|
|
word fields[4];
|
|
int f;
|
|
|
|
word exp;
|
|
int op;
|
|
int gotexp;
|
|
};
|
|
struct Assembler as;
|
|
struct Assembler astack[8];
|
|
int asp;
|
|
hword starta;
|
|
int linemode;
|
|
|
|
void
|
|
typenum(word n)
|
|
{
|
|
word d;
|
|
d = n % base;
|
|
n /= base;
|
|
if(n)
|
|
typenum(n);
|
|
tyo(d + '0');
|
|
}
|
|
|
|
void
|
|
typestr(char *str)
|
|
{
|
|
while(*str)
|
|
tyo(*str++);
|
|
}
|
|
|
|
void
|
|
typestrnl(char *str)
|
|
{
|
|
while(*str){
|
|
if(*str == '\n')
|
|
tyo('\r');
|
|
tyo(*str++);
|
|
}
|
|
}
|
|
|
|
void
|
|
typestrnl_(char *str)
|
|
{
|
|
while(*str){
|
|
if(*str == '\n')
|
|
tyo_('\r');
|
|
tyo_(*str++);
|
|
}
|
|
}
|
|
|
|
void
|
|
err(char *str)
|
|
{
|
|
typestr(str);
|
|
longjmp(errjmp, 0);
|
|
}
|
|
|
|
void
|
|
num(void)
|
|
{
|
|
number = number*base + ch-'0';
|
|
hasnum = 1;
|
|
}
|
|
|
|
void
|
|
ins(void)
|
|
{
|
|
buf[nbuf++] = ch;
|
|
nbuf %= BUFLEN;
|
|
buf[nbuf] = '\0';
|
|
}
|
|
|
|
word
|
|
parsenum(void)
|
|
{
|
|
word w;
|
|
char *c;
|
|
|
|
w = 0;
|
|
for(c = bufstart; c < &buf[nbuf]; c++){
|
|
if(*c >= '0' && *c <= '9')
|
|
w = w*base + *c-'0';
|
|
else
|
|
return BUF_ERR;
|
|
w &= 0777777777777;
|
|
}
|
|
return w;
|
|
}
|
|
|
|
typedef struct Symbol Symbol;
|
|
struct Symbol
|
|
{
|
|
char *sym;
|
|
word value;
|
|
};
|
|
|
|
Symbol symtab[] = {
|
|
{ "SM", 01000000 },
|
|
{ "LED", 01001000 },
|
|
{ "SW", 01001001 },
|
|
|
|
/* some more instructions */
|
|
{ "HALT", 0254200000000 },
|
|
|
|
/* devices, decorated with % */
|
|
{ "%APR", 0 },
|
|
{ "%PI", 4 },
|
|
{ "%PTP", 0100 },
|
|
{ "%PTR", 0104 },
|
|
{ "%TTY", 0120 },
|
|
{ "%DIS", 0130 },
|
|
{ "%DC", 0200 },
|
|
{ "%UTC", 0204 },
|
|
{ "%UTS", 0210 },
|
|
|
|
#define X(str, name) { str, name },
|
|
PDP_REGS
|
|
PDP_REGS_TEST
|
|
#undef X
|
|
|
|
{ nil, 0 },
|
|
};
|
|
|
|
// for disasm
|
|
char *findacsym(word v) { return nil; }
|
|
char *findsymval(word v) { return nil; }
|
|
|
|
word
|
|
parsesym(void)
|
|
{
|
|
word i;
|
|
|
|
if(strcmp(bufstart, ".") == 0)
|
|
return dot;
|
|
|
|
for(i = 0; symtab[i].sym; i++)
|
|
if(strcasecmp(bufstart, symtab[i].sym) == 0)
|
|
return symtab[i].value;
|
|
|
|
for(i = 0; i < 0700; i++)
|
|
if(mnemonics[i] && strcasecmp(mnemonics[i], bufstart) == 0)
|
|
return i << 27;
|
|
for(i = 0; i < 8; i++)
|
|
if(strcasecmp(iomnemonics[i], bufstart) == 0)
|
|
return (word)0700<<27 | i<<23;
|
|
return BUF_ERR;
|
|
}
|
|
|
|
void
|
|
trimbuf(void)
|
|
{
|
|
bufstart = buf;
|
|
while(isspace(*bufstart)) bufstart++;
|
|
while(&buf[nbuf] > bufstart && isspace(buf[nbuf-1])) nbuf--;
|
|
buf[nbuf] = '\0';
|
|
}
|
|
|
|
/* parse input buffer, error if can't parse
|
|
* return 0 if empty */
|
|
int
|
|
parse(word *t)
|
|
{
|
|
word w;
|
|
|
|
// this should be unnecessary now
|
|
trimbuf();
|
|
|
|
w = parsenum();
|
|
if(bufstart >= &buf[nbuf])
|
|
return 0;
|
|
if((w = parsenum()) == BUF_ERR && (w = parsesym()) == BUF_ERR)
|
|
err("?U? ");
|
|
nbuf = 0;
|
|
*t = w;
|
|
return 1;
|
|
}
|
|
|
|
void
|
|
resetexp(void)
|
|
{
|
|
as.fields[0] = 0;
|
|
as.fields[1] = 0;
|
|
as.fields[2] = 0;
|
|
as.fields[3] = 0;
|
|
as.f = 0;
|
|
|
|
as.exp = 0;
|
|
as.op = 0;
|
|
as.gotexp = 0;
|
|
}
|
|
|
|
void
|
|
pushexp(void)
|
|
{
|
|
astack[asp] = as;
|
|
asp++;
|
|
if(asp >= 8)
|
|
err(" XXX ");
|
|
resetexp();
|
|
}
|
|
|
|
void
|
|
popexp(void)
|
|
{
|
|
if(asp < 0)
|
|
err(" XXX ");
|
|
asp--;
|
|
as = astack[asp];
|
|
}
|
|
|
|
/* combine word t into current expression */
|
|
void
|
|
combine(word t)
|
|
{
|
|
switch(as.op){
|
|
case '+':
|
|
default:
|
|
as.exp += t;
|
|
break;
|
|
case '-':
|
|
as.exp -= t;
|
|
break;
|
|
case '*':
|
|
as.exp *= t;
|
|
break;
|
|
case '|':
|
|
as.exp /= t;
|
|
break;
|
|
}
|
|
as.gotexp = 1;
|
|
as.op = 0;
|
|
}
|
|
|
|
/* assemble storage word and set *w
|
|
* if no word, don't change *w and return 0 */
|
|
int
|
|
endword(word *w)
|
|
{
|
|
word t;
|
|
|
|
if(!parse(&t)){
|
|
if(!as.gotexp)
|
|
return 0;
|
|
t = 0;
|
|
}
|
|
combine(t);
|
|
if(as.f & (F_FW|F_AC)){
|
|
// add to address field
|
|
as.fields[3] += as.exp;
|
|
as.f |= F_A;
|
|
}else{
|
|
as.fields[0] += as.exp;
|
|
as.f |= F_FW;
|
|
}
|
|
t = as.fields[0];
|
|
if(as.f & F_AC){
|
|
if((t & 0700000000000) == 0700000000000)
|
|
t += (as.fields[1]&0774)<<24;
|
|
else
|
|
t += (as.fields[1]&017)<<23;
|
|
}
|
|
if(as.f & F_I)
|
|
if((t & 020000000) == 0)
|
|
t += as.fields[2]&020000000;
|
|
if(as.f & F_A)
|
|
t = (t<) + ((t+as.fields[3])&RT);
|
|
t &= LT|RT;
|
|
*w = t;
|
|
resetexp();
|
|
return 1;
|
|
}
|
|
|
|
void
|
|
prword(int mode, word wd)
|
|
{
|
|
int i;
|
|
char c;
|
|
char s[7];
|
|
double f;
|
|
|
|
switch(mode){
|
|
case MODE_ASCII:
|
|
tyo(ALT);
|
|
tyo('0' + (wd&1));
|
|
tyo('"');
|
|
for(i = 0; i < 5; i++){
|
|
c = (wd >> ((7*(4-i))+1)) & 0177;
|
|
if(c < 040 || c == 0177){
|
|
tyo('^');
|
|
tyo(c ^ 0100);
|
|
}else
|
|
tyo(c);
|
|
}
|
|
tyo(ALT);
|
|
break;
|
|
|
|
case MODE_SIXBIT:
|
|
tyo(ALT);
|
|
tyo('1');
|
|
tyo('\'');
|
|
for(i = 0; i < 6; i++){
|
|
c = (wd >> (6*(5-i))) & 077;
|
|
tyo(c + 040);
|
|
}
|
|
tyo(ALT);
|
|
break;
|
|
|
|
case MODE_SQUOZE:
|
|
tyo(ALT);
|
|
typenum(unrad50(wd, s));
|
|
tyo('&');
|
|
typestr(s);
|
|
tyo(ALT);
|
|
break;
|
|
|
|
break;
|
|
|
|
case MODE_SYM:
|
|
typestr(disasm(wd));
|
|
break;
|
|
|
|
case MODE_HALF:
|
|
tyo('(');
|
|
typenum(wd&0777777);
|
|
tyo(')');
|
|
typenum((wd>>18)&0777777);
|
|
break;
|
|
|
|
case MODE_FLOAT:
|
|
f = pdptod(wd);
|
|
printf("%lf", f);
|
|
fflush(stdout);
|
|
break;
|
|
|
|
default:
|
|
typenum(wd);
|
|
}
|
|
}
|
|
|
|
void
|
|
typeout(int mode)
|
|
{
|
|
endword(&q);
|
|
prword(mode, q);
|
|
typestr(" ");
|
|
}
|
|
|
|
void
|
|
propen(hword a)
|
|
{
|
|
prword(curmode, a);
|
|
tyo('/');
|
|
}
|
|
|
|
void
|
|
aclose(int ins)
|
|
{
|
|
// this is a bit ugly...
|
|
// we don't want ^M to set Q if no location is open
|
|
word t;
|
|
t = q;
|
|
if(endword(&q) && opened && ins)
|
|
deposit(addr, q);
|
|
addr = q & ADDRMASK;
|
|
if(!opened)
|
|
q = t;
|
|
opened = 0;
|
|
}
|
|
|
|
void
|
|
aopen(int mode)
|
|
{
|
|
opened = 1;
|
|
q = examine(addr);
|
|
typestr(" ");
|
|
if(mode != MODE_NONE)
|
|
typeout(mode);
|
|
}
|
|
|
|
void
|
|
modechange(int mode)
|
|
{
|
|
curmode = mode;
|
|
if(flags & CCF){
|
|
permmode = mode;
|
|
typestr(" ");
|
|
}
|
|
}
|
|
|
|
void
|
|
runline(void)
|
|
{
|
|
/* TODO: this can be improved */
|
|
switch(linemode){
|
|
case LM_COLON:
|
|
coloncmd(buf);
|
|
break;
|
|
case LM_LOAD:
|
|
docmd("load", buf);
|
|
break;
|
|
case LM_DUMP:
|
|
docmd("dump", buf);
|
|
break;
|
|
case LM_MOUNT:
|
|
docmd("mount", buf);
|
|
break;
|
|
case LM_UNMOUNT:
|
|
docmd("unmount", buf);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
zerocore(void)
|
|
{
|
|
hword a;
|
|
for(a = 0; a < MAXMEM; a++)
|
|
deposit(a, 0);
|
|
typestr("\r\n");
|
|
}
|
|
|
|
void
|
|
quit(void)
|
|
{
|
|
reset(0);
|
|
putchar('\n');
|
|
|
|
deinit6();
|
|
exit(0);
|
|
}
|
|
|
|
int started;
|
|
|
|
int
|
|
threadmain(int argc, char *argv[])
|
|
{
|
|
char chu;
|
|
word t;
|
|
|
|
init6();
|
|
initcrt("soma");
|
|
// initnetmem("10.0.0.222", 10006);
|
|
|
|
raw(0);
|
|
erasec = tiosaved.c_cc[VERASE];
|
|
killc = tiosaved.c_cc[VKILL];
|
|
intrc = tiosaved.c_cc[VINTR];
|
|
|
|
setjmp(errjmp);
|
|
nbuf = 0;
|
|
opened = 0;
|
|
resetexp();
|
|
flags = 0;
|
|
curmode = permmode;
|
|
number = 0;
|
|
hasnum = 0;
|
|
linemode = 0;
|
|
|
|
for(;;){
|
|
if(hasinput(0)){
|
|
ch = tyi();
|
|
}else{
|
|
if(started && (!isrunning() || isstopped())){
|
|
t = examine(APR_PC);
|
|
/* TODO: maybe do something different on stop? */
|
|
typestrnl("\n");
|
|
typenum(t);
|
|
if(!isrunning())
|
|
typestr(">>");
|
|
else
|
|
typestr("<<");
|
|
t = examine(t);
|
|
prword(MODE_SYM, t);
|
|
typestr(" ");
|
|
|
|
/* show AC or E */
|
|
if((t&0700000000000) == 0700000000000){
|
|
t = t&RT;
|
|
}else{
|
|
t = t>>23 & 017;
|
|
}
|
|
dot = t;
|
|
prword(MODE_SYM, dot);
|
|
typestr("/ ");
|
|
t = examine(t);
|
|
prword(MODE_SYM, t);
|
|
q = t;
|
|
typestr(" ");
|
|
|
|
started = 0;
|
|
}
|
|
fe_svc();
|
|
// this was commented out, why?
|
|
usleep(1000);
|
|
continue;
|
|
}
|
|
|
|
chu = toupper(ch);
|
|
if(ch == erasec || ch == CTL('H') || ch == CTL('?')){
|
|
/* can't backspace in all cases */
|
|
if((flags & CF) || nbuf <= 0)
|
|
err("\r\n");
|
|
typestr("\b \b");
|
|
nbuf--;
|
|
}else if(ch == killc)
|
|
err("");
|
|
else if(ch == intrc)
|
|
break;
|
|
else if(linemode){
|
|
if(ch == '\r' || ch == '\n'){
|
|
typestrnl("\n");
|
|
runline();
|
|
err("");
|
|
}else{
|
|
tyo(ch);
|
|
ins();
|
|
}
|
|
}else{
|
|
tyo(ch);
|
|
|
|
if((flags & CF) == 0 &&
|
|
(ch >= 'A' && ch <= 'Z' ||
|
|
ch >= 'a' && ch <= 'z')){
|
|
ins();
|
|
}else switch(chu){
|
|
case ':':
|
|
linemode = LM_COLON;
|
|
nbuf = 0;
|
|
break;
|
|
case 'L':
|
|
tyo(' ');
|
|
linemode = LM_LOAD;
|
|
nbuf = 0;
|
|
break;
|
|
case 'Y':
|
|
tyo(' ');
|
|
linemode = LM_DUMP;
|
|
nbuf = 0;
|
|
break;
|
|
|
|
case '?':
|
|
typestrnl_(flags & CF ? colhelpstr : helpstr);
|
|
break;
|
|
|
|
case CTL('D'):
|
|
err("XXX? ");
|
|
break;
|
|
|
|
case '.': case '%': case '$':
|
|
ins();
|
|
break;
|
|
|
|
case '0': case '1': case '2': case '3':
|
|
case '4': case '5': case '6': case '7':
|
|
case '8': case '9':
|
|
if(flags & CF){
|
|
num();
|
|
goto keepflags;
|
|
}
|
|
ins();
|
|
break;
|
|
|
|
case 'F':
|
|
cpu_printflags();
|
|
break;
|
|
|
|
case 'G':
|
|
if(!endword(&t))
|
|
t = starta;
|
|
if(flags & CCF)
|
|
starta = t;
|
|
if(hasnum && number == 0)
|
|
cpu_setpc(t);
|
|
else
|
|
cpu_start(t);
|
|
started = 1;
|
|
break;
|
|
|
|
case 'R':
|
|
if(!endword(&t))
|
|
t = starta;
|
|
if(flags & CCF)
|
|
starta = t;
|
|
cpu_readin(t);
|
|
started = 1;
|
|
break;
|
|
|
|
case CTL('Z'):
|
|
nbuf = 0;
|
|
if(flags & CF)
|
|
cpu_stopmem();
|
|
else
|
|
cpu_stopinst();
|
|
break;
|
|
|
|
case 'P':
|
|
endword(&t);
|
|
cpu_cont();
|
|
started = 1;
|
|
break;
|
|
|
|
case CTL('N'):
|
|
endword(&t);
|
|
if(flags & CF)
|
|
cpu_nextmem();
|
|
else
|
|
cpu_nextinst();
|
|
started = 1;
|
|
break;
|
|
|
|
case 'X':
|
|
if(!endword(&t))
|
|
t = q;
|
|
cpu_exec(t);
|
|
typestrnl("\n");
|
|
break;
|
|
|
|
case 'I':
|
|
nbuf = 0;
|
|
cpu_ioreset();
|
|
break;
|
|
|
|
case 'Q':
|
|
combine(q);
|
|
break;
|
|
|
|
case 'Z':
|
|
if(flags & CCF)
|
|
zerocore();
|
|
else
|
|
err(" ?? ");
|
|
break;
|
|
|
|
case ALT:
|
|
if(flags & CF)
|
|
flags |= CCF;
|
|
flags |= CF;
|
|
goto keepflags;
|
|
|
|
/* expressions */
|
|
case '+':
|
|
case '-':
|
|
case '*':
|
|
case '|':
|
|
if(!parse(&t)){
|
|
if(ch == '-')
|
|
as.op = '-';
|
|
break;
|
|
}
|
|
combine(t);
|
|
as.op = ch;
|
|
break;
|
|
case '(':
|
|
if(parse(&t))
|
|
combine(t);
|
|
pushexp();
|
|
break;
|
|
case ')':
|
|
t = 0;
|
|
endword(&t);
|
|
popexp();
|
|
if(as.op == 0){
|
|
t = (t<)>>18 | (t&RT)<<18;
|
|
as.fields[0] += t;
|
|
as.gotexp = 1;
|
|
}else{
|
|
combine(t);
|
|
}
|
|
as.op = 0;
|
|
break;
|
|
|
|
/* word assembly */
|
|
case ' ':
|
|
if(!parse(&t))
|
|
break;
|
|
combine(t);
|
|
if(as.f & F_FW){
|
|
// add to address field
|
|
// if we have a full word already
|
|
as.fields[3] += as.exp;
|
|
as.f |= F_A;
|
|
}else{
|
|
as.fields[0] += as.exp;
|
|
as.f |= F_FW;
|
|
}
|
|
as.exp = 0;
|
|
break;
|
|
case ',':
|
|
if(!parse(&t))
|
|
break;
|
|
combine(t);
|
|
if(as.f & F_AC){
|
|
// add to address field
|
|
// if we have an AC already
|
|
as.fields[3] += as.exp;
|
|
as.f |= F_A;
|
|
}else{
|
|
as.fields[1] += as.exp;
|
|
as.f |= F_AC;
|
|
}
|
|
as.exp = 0;
|
|
break;
|
|
case '@':
|
|
as.fields[2] += 020000000;
|
|
as.f |= F_I;
|
|
as.gotexp = 1;
|
|
break;
|
|
|
|
/* opening */
|
|
case '/':
|
|
aclose(0);
|
|
dot = addr;
|
|
aopen(curmode);
|
|
break;
|
|
case '\\':
|
|
aclose(0);
|
|
aopen(curmode);
|
|
break;
|
|
case '[':
|
|
if(flags & CF){
|
|
tyo(' ');
|
|
linemode = LM_MOUNT;
|
|
nbuf = 0;
|
|
break;
|
|
}
|
|
aclose(0);
|
|
dot = addr;
|
|
aopen(MODE_NUM);
|
|
break;
|
|
case ']':
|
|
if(flags & CF){
|
|
tyo(' ');
|
|
linemode = LM_UNMOUNT;
|
|
nbuf = 0;
|
|
break;
|
|
}
|
|
aclose(0);
|
|
dot = addr;
|
|
aopen(MODE_SYM);
|
|
break;
|
|
case '!':
|
|
aclose(0);
|
|
dot = addr;
|
|
aopen(MODE_NONE);
|
|
break;
|
|
|
|
case CTL('I'):
|
|
typestrnl("\n");
|
|
aclose(1);
|
|
dot = addr;
|
|
propen(addr);
|
|
aopen(curmode);
|
|
break;
|
|
case '^':
|
|
typestrnl("\n");
|
|
aclose(1);
|
|
dot = (dot-1) & ADDRMASK;
|
|
addr = dot;
|
|
propen(addr);
|
|
aopen(curmode);
|
|
break;
|
|
case CTL('J'):
|
|
tyo('\r');
|
|
aclose(1);
|
|
dot = (dot+1) & ADDRMASK;
|
|
addr = dot;
|
|
propen(addr);
|
|
aopen(curmode);
|
|
break;
|
|
|
|
case CTL('M'):
|
|
tyo('\n');
|
|
aclose(1);
|
|
curmode = permmode;
|
|
break;
|
|
|
|
/* typeout */
|
|
case '_':
|
|
typeout(MODE_SYM);
|
|
break;
|
|
case '=':
|
|
typeout(MODE_NUM);
|
|
break;
|
|
case ';':
|
|
typeout(MODE_FLOAT);
|
|
break;
|
|
case '"':
|
|
if(flags & CF)
|
|
modechange(MODE_ASCII);
|
|
else
|
|
typeout(MODE_ASCII);
|
|
break;
|
|
case '\'':
|
|
if(flags & CF)
|
|
modechange(MODE_SIXBIT);
|
|
else
|
|
typeout(MODE_SIXBIT);
|
|
break;
|
|
case '&':
|
|
if(flags & CF)
|
|
modechange(MODE_SQUOZE);
|
|
else
|
|
typeout(MODE_SQUOZE);
|
|
break;
|
|
case 'S':
|
|
modechange(MODE_SYM);
|
|
break;
|
|
case 'C':
|
|
modechange(MODE_NUM);
|
|
break;
|
|
case 'H':
|
|
modechange(MODE_HALF);
|
|
break;
|
|
|
|
default:
|
|
err(" ?? ");
|
|
break;
|
|
}
|
|
}
|
|
flags = 0;
|
|
number = 0;
|
|
hasnum = 0;
|
|
keepflags:;
|
|
}
|
|
|
|
quit();
|
|
|
|
return 0;
|
|
}
|