📄 mterm.c
字号:
xy_flag = -1;
if(c == 0x1B) { /* Begin escape sequence */
state = 1;
parms[0] = parms[1] = value = parm = 0; }
else switch(state) {
case 1 : /* Escape already received */
if(c == '[') {
state = 2;
break; }
state = 0;
case 0 : /* No special processing */
vputc(c);
break;
case 2 : /* Waiting for numeric parms */
if(isdigit(c)) {
value = (value * 10) + (c - '0');
break; }
parms[parm++] = value; /* More to come */
if(c == ';') {
value = 0;
break; }
state = 0;
switch(c) {
case 'H' : /* Cursor position (1) */
case 'f' : /* Cursor position (2) */
if(y = parms[0])
--y;
if(x = parms[1])
--x;
vgotoxy(x, y);
break;
case 'J' : /* Erase in display */
x = V_XY;
value ? vclscr() : vcleos();
V_XY = x;
break;
case 'K' : /* Erase in line */
x = V_XY;
if(value)
V_XY &= 0xff00;
vcleol();
V_XY = x;
break;
case 'm' : /* Select attributes */
x = 0;
do {
V_ATTR = (y = parms[x]) ? (y == 4) ?
UNDERLINE : REVERSE : NORMAL; }
while(++x < parm); } } }
else if(xy_flag) { /* Cursor has moved */
vupdatexy();
xy_flag = 0; }
/* Process any input from the keyboard */
if(c = vtstc()) {
if(c & 0x80) { /* Special function key */
if(!(ptr = ansi_keys[c & 0x7f]))
return;
while(*ptr)
Cputc(*ptr++); }
else
Cputc((c == '\n') ? '\r' : c); } }
}
/*
* Receive a file in XMODEM protocol
*/
download()
{
char rbuffer[BLOCK_SIZE], *error_text, *old_error, ochr;
int r, rx_block_num, error_count;
FILE *fp;
if(vgets(FILCOL,MSGROW,"Write to file? ",dfile,FILSIZ) || !*dfile)
return;
if(!(fp = openf(dfile, -1)))
return;
info_box("Download to file", dfile);
error_text = old_error = rx_block_num = 1;
error_count = RETRYS;
do {
if(vtstc() == 0x1b) { /* Console escape */
ochr = CAN;
error_text = "CANCELED";
error_count = 0; }
else if((r = get_record(rbuffer)) == (rx_block_num & 255)) {
error_count = RETRYS;
fput(rbuffer, BLOCK_SIZE, fp);
vgotoxy(SUBCOL+23, MENROW+5);
vprintf("%u", rx_block_num++);
error_text = "RX PACKET";
ochr = ACK; }
else {
switch(r) {
case -1 : /* Timeout */
error_text = "TIMEOUT";
ochr = NAK;
break;
case -2 : /* Bad block */
error_text = "BAD BLOCK#";
while(Cgett(RX_TIMEOUT) != -1);
ochr = NAK;
break;
case -3 : /* Bad checksum */
error_text = "BAD CHKSUM";
ochr = NAK;
break;
case -4 : /* End of file */
error_text = "DONE";
ochr = ACK;
break;
case -5 : /* Cancel */
error_text = "ABORTED";
ochr = ACK;
break;
default: /* Block out of sequence */
error_text = "WRONG BLK";
ochr = NAK; }
--error_count; }
Cputc(ochr);
/* Update status message */
if(error_text != old_error)
transfer_status(old_error = error_text); }
while((r > -3) && error_count);
message("Download ended (Press ENTER)");
fclose(fp);
while(vgetc() != '\n');
vclear_box(SUBCOL, MENROW+1, 50, 8);
}
/*
* Read a record in the XMODEM protocol, return the block number
* (0-255) if successful, or one of the following return codes:
* -1 = Timeout
* -2 = Bad block number
* -3 = Bad block checksum
* -4 = End of file
* -5 = Canceled by remote
*/
get_record(rbuffer)
char rbuffer[];
{
int c, i, block_num, check_sum;
check_sum = 0;
i = -2;
switch(Cgett(SOH_TIMEOUT)) {
case SOH : /* Receive packet */
for(;;) {
if((c = Cgett(RX_TIMEOUT)) == -1) /* receive timeout */
break;
if(i == -2) /* first block number */
block_num = c;
else if(i == -1) { /* second block number */
if((255 & ~c) != block_num)
return -2; }
else if(i == BLOCK_SIZE) /* checksum at end */
return (check_sum & 0xff) == c ? block_num : -3;
else /* data character */
check_sum += (rbuffer[i] = c);
++i; }
case -1 : /* timeout on waiting for packet */
return -1;
case EOT : /* end of file encountered */
return -4;
case CAN : /* cancel protocol */
return -5; }
}
/*
* Transmit a file in XMODEM protocol
*/
upload()
{
int i, c, tx_block_num, error_count;
char buffer[BLOCK_SIZE], *error_text, *old_error;
FILE *fp;
if(vgets(FILCOL,MSGROW,"Read from file? ",ufile,FILSIZ) || !*ufile)
return;
if(!(fp = openf(ufile, 0)))
return;
info_box("Upload from file", ufile);
tx_block_num = old_error = error_text = 1;
error_count = RETRYS;
/* Transmit the file data */
while(i = fget(buffer, BLOCK_SIZE, fp)) {
while(i < 128)
buffer[i++] = -1;
error_text = "TX PACKET";
while(i = send_record(buffer, tx_block_num)) {
switch(i) {
case -1 :
error_text = "TIMEOUT";
break;
case -3 :
error_text = "RECV NAK";
break;
case -5 :
error_text = "ABORTED"; }
transfer_status(old_error = error_text);
if((i < -3) || !error_count--)
break; }
if(vtstc() == 0x1b) { /* Console escape */
i = -5;
error_text = "CANCELED"; }
if(i) { /* Error exit */
Cputc(CAN);
break; }
error_count = RETRYS;
vgotoxy(SUBCOL+23, MENROW+5);
vprintf("%u", tx_block_num++);
if(error_text != old_error)
transfer_status(old_error = error_text); }
/* Send the end of file indicator */
error_count = RETRYS;
if(!i) for(;;) {
Cputc(EOT);
if((c = Cgett(ACK_TIMEOUT)) == ACK) {
error_text = "DONE";
break; }
if(c == CAN) {
error_text = "ABORTED";
break; }
if(((c == -1) || (c == NAK)) && !error_count--) {
error_text = "TIMEOUT";
break; } }
transfer_status(error_text);
message("Upload ended (Press ENTER)");
fclose(fp);
while(vgetc() != '\n');
vclear_box(SUBCOL, MENROW+1, 50, 8);
}
/*
* Send an record in XMODEM protocol, return 0 if successful
* Otherwise, return one of the following:
* -1 = Timeout
* -2 = Bad block number (N/A)
* -3 = Bad block (NAK RECEIVED)
* -4 = End of file (N/A)
* -5 = Canceled by remote
*/
send_record(buffer, block_num)
char *buffer;
int block_num;
{
int i, check_sum;
char *ptr;
check_sum = 0;
ptr = buffer;
while(Ctestc() != -1); /* purge any received data */
Cputc(SOH);
Cputc(block_num);
Cputc(~block_num);
for(i=0; i < BLOCK_SIZE; ++i) {
Cputc(*buffer);
check_sum += *buffer++; }
Cputc(check_sum);
for(;;) switch(Cgett(ACK_TIMEOUT)) {
case ACK : /* Packet received ok */
return 0;
case NAK : /* Rejected */
return -3;
case CAN : /* Remote cancel */
return -5;
case -1 : /* Timeout */
return -1; }
}
/*
* Wait for a character from the modem (with timeout)
*/
Cgett(timeout)
unsigned timeout;
{
int h, m, s, old_s;
if((h = Ctestc()) != -1) /* Very fast if characters buffered */
return h;
get_time(&h, &m, &old_s);
do {
do {
if((h = Ctestc()) != -1)
return h;
get_time(&h,&m,&s); }
while(s == old_s);
old_s = s; }
while(--timeout);
return -1;
}
/*
* Main program, either TSR or execute main tty program menu
*/
main(argc, argv)
int argc;
int *argv[];
{
vopen();
vputs("MICRO-Terminal: (Press CTRL-HOME or CTRL-END to exit):\n");
save_screen();
/* If RAM-resident, print startup message & TSR */
if((argc > 1) && (*argv[1] == 't-')) {
draw_title();
printf("\n\n\nRam-Resident MICRO-Terminal installed\nPress BOTH SHIFTS to POP UP\n");
vcursor_line();
tsr(&tty_main, L_SHIFT+R_SHIFT, 2000); }
/* Not RAM-resident, execute the program */
vclscr(); /* Return to blank screen */
tty_main();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -