mirror of
https://github.com/tschak909/platotermClassicMac.git
synced 2024-12-28 03:29:20 +00:00
988 lines
20 KiB
C
Executable File
988 lines
20 KiB
C
Executable File
/**
|
|
* PLATOTerm64 - A PLATO Terminal for the Commodore 64
|
|
* Based on Steve Peltz's PAD
|
|
*
|
|
* Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
|
|
* This file written by Steve Peltz. Copyright notice preserved.
|
|
* and this code has been used with permission, and can be considered
|
|
* public domain.
|
|
*
|
|
* protocol.c - Protocol decoder functions
|
|
*/
|
|
|
|
/* Copyright (c) 1990 by Steve Peltz */
|
|
|
|
#include "protocol.h"
|
|
|
|
#define true 1
|
|
#define false 0
|
|
|
|
#define BSIZE 64
|
|
|
|
static padBool EscFlag; /* Currently in an escape sequence */
|
|
static Mode PMode, /* Mode */
|
|
CMode; /* Command */
|
|
static unsigned short SubMode; /* Block/Line modes */
|
|
static DataType PType, /* Mode type */
|
|
CType; /* Current type */
|
|
static unsigned short Phase; /* Phase of current type */
|
|
static padWord theWord; /* Data received for various data types */
|
|
static padByte theChar;
|
|
static padByte rawChar;
|
|
static padByte lastChar;
|
|
static padRGB theColor;
|
|
static unsigned short LowX, /* Previous coordinates received */
|
|
HiX, LowY, HiY;
|
|
static padPt CurCoord; /* Current coordinate */
|
|
static padWord Margin; /* Margin for CR */
|
|
static padWord MemAddr; /* Load address for program data */
|
|
static unsigned short CharCnt; /* Current count for loading chars */
|
|
static charData Char; /* Character data */
|
|
static padByte charBuff[BSIZE];
|
|
static unsigned short charCount; /* Count of characters currently buffered */
|
|
static padPt charCoord;
|
|
|
|
extern unsigned char terminal_get_features(void);
|
|
extern unsigned char terminal_get_type(void);
|
|
extern unsigned char terminal_get_subtype(void);
|
|
extern unsigned char terminal_get_load_file(void);
|
|
extern unsigned char terminal_get_configuration(void);
|
|
extern unsigned short terminal_get_char_address(void);
|
|
extern padByte terminal_mem_read(padWord addr);
|
|
extern padByte terminal_ext_in(void);
|
|
|
|
extern void screen_wait(void);
|
|
extern void screen_beep(void);
|
|
extern void io_send_byte(unsigned char b);
|
|
extern void screen_block_draw(padPt* Coord1, padPt* Coord2);
|
|
extern void screen_dot_draw(padPt* Coord);
|
|
extern void screen_line_draw(padPt* Coord1, padPt* Coord2);
|
|
extern void screen_char_draw(padPt* Coord, unsigned char* ch, unsigned char count);
|
|
extern void screen_tty_char(padByte theChar);
|
|
extern void screen_foreground(padRGB* theColor);
|
|
extern void screen_background(padRGB* theColor);
|
|
extern void screen_paint(padPt* Coord);
|
|
extern void terminal_mem_load(padWord addr, padWord value);
|
|
extern void terminal_char_load(padWord charnum, charData theChar);
|
|
extern void terminal_mode_5(padWord value);
|
|
extern void terminal_mode_6(padWord value);
|
|
extern void terminal_mode_7(padWord value);
|
|
extern void touch_allow(padBool allow);
|
|
extern void terminal_ext_allow(padBool allow);
|
|
extern void terminal_set_ext_in(padWord device);
|
|
extern void terminal_set_ext_out(padWord device);
|
|
extern void terminal_ext_out(padByte value);
|
|
extern void screen_clear(void);
|
|
extern void terminal_set_tty(void);
|
|
extern void terminal_set_plato(void);
|
|
|
|
#ifdef PROTOCOL_DEBUG
|
|
extern void log(const char* format, ...);
|
|
#endif
|
|
|
|
static padByte PTAT0[128] = { /* PLATO to ASCII lookup table */
|
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* original mapping */
|
|
0x38, 0x39, 0x26, 0x60, 0x0a, 0x5e, 0x2b, 0x2d,
|
|
0x13, 0x04, 0x07, 0x08, 0x7b, 0x0b, 0x0d, 0x1a,
|
|
0x02, 0x12, 0x01, 0x03, 0x7d, 0x0c, 0x83, 0x85,
|
|
0x3c, 0x3e, 0x5b, 0x5d, 0x24, 0x25, 0x5f, 0x7c,
|
|
0x2a, 0x28, 0x40, 0x27, 0x1c, 0x5c, 0x23, 0x7e,
|
|
0x17, 0x05, 0x14, 0x19, 0x7f, 0x09, 0x1e, 0x18,
|
|
0x0e, 0x1d, 0x11, 0x16, 0x00, 0x0f, 0x87, 0x88,
|
|
0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
|
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
|
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
|
0x78, 0x79, 0x7a, 0x3d, 0x3b, 0x2f, 0x2e, 0x2c,
|
|
0x1f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
|
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
|
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
|
0x58, 0x59, 0x5a, 0x29, 0x3a, 0x3f, 0x21, 0x22
|
|
};
|
|
|
|
static padByte PTAT1[128] = {
|
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* flow control mapping */
|
|
0x38, 0x39, 0x26, 0x60, 0x09, 0x5e, 0x2b, 0x2d,
|
|
0x17, 0x04, 0x07, 0x08, 0x7b, 0x0b, 0x0d, 0x1a,
|
|
0x02, 0x12, 0x01, 0x03, 0x7d, 0x0c, 0x83, 0x85,
|
|
0x3c, 0x3e, 0x5b, 0x5d, 0x24, 0x25, 0x5f, 0x27,
|
|
0x2a, 0x28, 0x40, 0x7c, 0x1c, 0x5c, 0x23, 0x7e,
|
|
0x97, 0x84, 0x14, 0x19, 0x7f, 0x0a, 0x1e, 0x18,
|
|
0x0e, 0x1d, 0x05, 0x16, 0x9d, 0x0f, 0x87, 0x88,
|
|
0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
|
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
|
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
|
0x78, 0x79, 0x7a, 0x3d, 0x3b, 0x2f, 0x2e, 0x2c,
|
|
0x1f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
|
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
|
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
|
0x58, 0x59, 0x5a, 0x29, 0x3a, 0x3f, 0x21, 0x22
|
|
};
|
|
|
|
/* externally referenced variables */
|
|
|
|
padPt PLATOSize={512,512}; /* Logical screen size */
|
|
CharMem CurMem; /* Font to plot in */
|
|
padBool TTY, /* TTY mode */
|
|
FlowControl, /* Flow control on */
|
|
ModeBold, /* Character plotting conditions */
|
|
Rotate, Reverse;
|
|
DispMode CurMode; /* Current PLATO plotting mode */
|
|
padBool FastText; /* Indicate to main program if text optimizations can be done. */
|
|
padBool NoEcho=padF;
|
|
|
|
/*----------------------------------------------*
|
|
* InitPAD, InitTTY, InitPLATO *
|
|
* *
|
|
* Called to initialize PAD variables. *
|
|
* Calls back to external routines to *
|
|
* set up proper plotting conditions. *
|
|
*----------------------------------------------*/
|
|
|
|
void
|
|
InitPAD (void)
|
|
{
|
|
InitTTY ();
|
|
}
|
|
|
|
void
|
|
InitTTY (void)
|
|
{
|
|
charCount = 0;
|
|
EscFlag = false;
|
|
TTY = true;
|
|
FastText = true;
|
|
FlowControl = false;
|
|
terminal_set_tty();
|
|
}
|
|
|
|
void
|
|
InitPLATO (void)
|
|
{
|
|
if (TTY)
|
|
InitPLATOx ();
|
|
}
|
|
|
|
void
|
|
InitPLATOx (void)
|
|
{
|
|
charCount = 0;
|
|
EscFlag = false;
|
|
TTY = false;
|
|
terminal_set_plato ();
|
|
SetMode (mAlpha, tByte);
|
|
LowX = 0;
|
|
HiX = 0;
|
|
LowY = 0;
|
|
HiY = 0;
|
|
CurCoord.x = 0;
|
|
CurCoord.y = 0;
|
|
MemAddr = 0;
|
|
CharCnt = 0;
|
|
Margin = 0;
|
|
ModeBold = false;
|
|
Rotate = false;
|
|
Reverse = false;
|
|
FastText = true;
|
|
CurMem = M0;
|
|
CurMode = ModeRewrite;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------*
|
|
* Key *
|
|
* *
|
|
* Send a 10-bit internal key. If a keyset *
|
|
* key, translate, else send as escaped *
|
|
* sequence. *
|
|
*----------------------------------------------*/
|
|
|
|
void
|
|
Key (padWord theKey)
|
|
{
|
|
if (theKey >> 7)
|
|
{
|
|
io_send_byte (0x1b);
|
|
io_send_byte (0x40 | (theKey & 0x3f));
|
|
io_send_byte (0x60 | ((theKey >> 6) & 0x0f));
|
|
}
|
|
else
|
|
{
|
|
|
|
if (FlowControl == 0)
|
|
theKey = PTAT0[theKey];
|
|
else
|
|
theKey = PTAT1[theKey];
|
|
|
|
if (theKey & 0x80)
|
|
{
|
|
io_send_byte (0x1b);
|
|
io_send_byte (theKey & 0x7f);
|
|
}
|
|
else
|
|
io_send_byte (theKey);
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------*
|
|
* Touch *
|
|
* *
|
|
* Send a touch key (01yyyyxxxx). *
|
|
*----------------------------------------------*/
|
|
|
|
void Touch(padPt* where)
|
|
{
|
|
io_send_byte(0x1b);
|
|
io_send_byte(0x1f);
|
|
io_send_byte(0x40 + (where->x & 0x1f));
|
|
io_send_byte(0x40 + ((where->x >> 5) & 0x0f));
|
|
io_send_byte(0x40 + (where->y & 0x1f));
|
|
io_send_byte(0x40 + ((where->y >> 5) & 0x0f));
|
|
|
|
Key(0x100 | ((where->x >> 1) & 0xF0) |
|
|
((where->y >> 5) & 0x0F));
|
|
}
|
|
|
|
/*----------------------------------------------*
|
|
* Ext *
|
|
* *
|
|
* Send an external key (10xxxxxxxx). *
|
|
*----------------------------------------------*/
|
|
|
|
void
|
|
Ext (padWord theKey)
|
|
{
|
|
Key (0x200 | (theKey & 0xFF));
|
|
}
|
|
|
|
|
|
/*----------------------------------------------*
|
|
* Echo *
|
|
* *
|
|
* Send an echo key (001xxxxxx). *
|
|
*----------------------------------------------*/
|
|
|
|
void
|
|
Echo (padWord theKey)
|
|
{
|
|
if (NoEcho==padT)
|
|
return;
|
|
Key (0x080 | theKey);
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------*
|
|
* SetCommand, SetMode *
|
|
* *
|
|
* Set state machine variables. *
|
|
*----------------------------------------------*/
|
|
|
|
void
|
|
SetCommand (Mode theMode, DataType theType)
|
|
{
|
|
CMode = theMode;
|
|
CType = theType;
|
|
Phase = 0;
|
|
}
|
|
|
|
void
|
|
SetMode (Mode theMode, DataType theType)
|
|
{
|
|
PMode = theMode;
|
|
PType = theType;
|
|
SubMode = 0;
|
|
SetCommand (theMode, theType);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------*
|
|
* FixXY *
|
|
* *
|
|
* Move location by offset, then make sure *
|
|
* it is still on the screen. *
|
|
*----------------------------------------------*/
|
|
|
|
void
|
|
FixXY (short DX, short DY)
|
|
{
|
|
if (ModeBold)
|
|
{
|
|
DX = DX * 2;
|
|
DY = DY * 2;
|
|
}
|
|
if (Reverse)
|
|
DX = -DX;
|
|
if (Rotate)
|
|
{
|
|
CurCoord.x = CurCoord.x + DY;
|
|
CurCoord.y = CurCoord.y + DX;
|
|
}
|
|
else
|
|
{
|
|
CurCoord.x = CurCoord.x + DX;
|
|
CurCoord.y = CurCoord.y + DY;
|
|
}
|
|
|
|
if (CurCoord.x < 0)
|
|
CurCoord.x += PLATOSize.x;
|
|
else if (CurCoord.x >= PLATOSize.x)
|
|
CurCoord.x -= PLATOSize.x;
|
|
|
|
if (CurCoord.y < 0)
|
|
CurCoord.y += PLATOSize.y;
|
|
else if (CurCoord.y >= PLATOSize.y)
|
|
CurCoord.y -= PLATOSize.y;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------*
|
|
* Superx, Subx, etc. *
|
|
* *
|
|
* Various character positioning commands. *
|
|
*----------------------------------------------*/
|
|
|
|
void
|
|
Superx (void)
|
|
{
|
|
FixXY (0, 5);
|
|
}
|
|
|
|
void
|
|
Subx (void)
|
|
{
|
|
FixXY (0, -5);
|
|
}
|
|
|
|
void
|
|
Marginx (void)
|
|
{
|
|
if (Rotate)
|
|
Margin = CurCoord.y;
|
|
else
|
|
Margin = CurCoord.x;
|
|
}
|
|
|
|
void
|
|
BSx (void)
|
|
{
|
|
FixXY (-8, 0);
|
|
}
|
|
|
|
void
|
|
HTx (void)
|
|
{
|
|
FixXY (8, 0);
|
|
}
|
|
|
|
void
|
|
LFx (void)
|
|
{
|
|
FixXY (0, -16);
|
|
}
|
|
|
|
void
|
|
VTx (void)
|
|
{
|
|
FixXY (0, 16);
|
|
}
|
|
|
|
void
|
|
FFx (void)
|
|
{
|
|
CurCoord.y = 0;
|
|
CurCoord.x = 0;
|
|
LFx ();
|
|
}
|
|
|
|
void
|
|
CRx (void)
|
|
{
|
|
if (Rotate)
|
|
CurCoord.y = Margin;
|
|
else
|
|
CurCoord.x = Margin;
|
|
LFx ();
|
|
}
|
|
|
|
|
|
/*----------------------------------------------*
|
|
* LoadCoordx *
|
|
* *
|
|
* Assemble completed coordinate. *
|
|
*----------------------------------------------*/
|
|
|
|
void
|
|
LoadCoordx (padPt * SetCoord)
|
|
{
|
|
SetCoord->x = (HiX << 5) + LowX;
|
|
SetCoord->y = (HiY << 5) + LowY;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------*
|
|
* Blockx, Pointx, Linex, Alphax *
|
|
* *
|
|
* Plot the specified item at the *
|
|
* current location. *
|
|
*----------------------------------------------*/
|
|
|
|
void
|
|
Blockx (void)
|
|
{
|
|
padPt NewCoord;
|
|
|
|
if (SubMode == 0)
|
|
{
|
|
LoadCoordx (&CurCoord);
|
|
SubMode = 1;
|
|
}
|
|
else
|
|
{
|
|
LoadCoordx (&NewCoord);
|
|
screen_block_draw (&CurCoord, &NewCoord);
|
|
SubMode = 0;
|
|
CurCoord.y-=15;
|
|
CurCoord.x+=16;
|
|
}
|
|
}
|
|
|
|
void
|
|
Pointx (void)
|
|
{
|
|
LoadCoordx (&CurCoord);
|
|
screen_dot_draw (&CurCoord);
|
|
}
|
|
|
|
void
|
|
Linex (void)
|
|
{
|
|
padPt OldCoord;
|
|
|
|
if (SubMode == 0)
|
|
{
|
|
LoadCoordx (&CurCoord);
|
|
SubMode = 1;
|
|
}
|
|
else
|
|
{
|
|
OldCoord.y = CurCoord.y;
|
|
OldCoord.x = CurCoord.x;
|
|
LoadCoordx (&CurCoord);
|
|
screen_line_draw (&OldCoord, &CurCoord);
|
|
}
|
|
}
|
|
|
|
void
|
|
Alphax (void)
|
|
{
|
|
if (charCount == 0)
|
|
charCoord = CurCoord;
|
|
charBuff[charCount++] = theChar;
|
|
HTx ();
|
|
if (charCount >= BSIZE)
|
|
{
|
|
screen_char_draw (&charCoord, charBuff, charCount);
|
|
charCount = 0;
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------*
|
|
* LoadEchox *
|
|
* *
|
|
* Echo responses to system. *
|
|
*----------------------------------------------*/
|
|
|
|
void
|
|
LoadEchox (void)
|
|
{
|
|
theWord &= 0x7f;
|
|
switch (theWord)
|
|
{
|
|
|
|
case 0x52:
|
|
FlowControl=true;
|
|
if (FlowControl)
|
|
Echo (0x53); /* flow control on */
|
|
else
|
|
Echo (0x52); /* flow control not on */
|
|
break;
|
|
case 0x60: /* Inquire about ascii specific features. */
|
|
Echo (terminal_get_features());
|
|
break;
|
|
case 0x70:
|
|
Echo (terminal_get_type ()); /* terminal type */
|
|
break;
|
|
|
|
case 0x71:
|
|
Echo (terminal_get_subtype()); /* subtype */
|
|
break;
|
|
|
|
case 0x72:
|
|
Echo (terminal_get_load_file ()); /* load file */
|
|
break;
|
|
|
|
case 0x73:
|
|
Echo (terminal_get_configuration ()); /* configuration */
|
|
break;
|
|
|
|
case 0x7A:
|
|
Key (0x3FF); /* send backout */
|
|
break;
|
|
|
|
case 0x7B:
|
|
screen_beep ();
|
|
break; /* beep */
|
|
|
|
case 0x7D:
|
|
Echo (terminal_mem_read (MemAddr) & 0x7F);
|
|
break;
|
|
|
|
default:
|
|
Echo (theWord); /* normal echo */
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
LoadAddrx (void)
|
|
{
|
|
MemAddr = theWord;
|
|
CharCnt = 0;
|
|
}
|
|
|
|
void
|
|
LoadCharx (void)
|
|
{
|
|
Char[CharCnt] = theWord;
|
|
if (CharCnt < 7)
|
|
CharCnt++;
|
|
else
|
|
{
|
|
terminal_char_load ((((MemAddr - terminal_get_char_address ()) >> 4) & 0x7f), Char);
|
|
CharCnt = 0;
|
|
MemAddr += 16;
|
|
}
|
|
}
|
|
|
|
void
|
|
LoadMemx (void)
|
|
{
|
|
terminal_mem_load (MemAddr, theWord);
|
|
MemAddr += 2;
|
|
}
|
|
|
|
void
|
|
SSFx (void)
|
|
{
|
|
padByte device;
|
|
|
|
device = (theWord >> 10) & 0xFF;
|
|
if (device == 1)
|
|
{
|
|
terminal_ext_allow ((theWord >> 3) & 1);
|
|
touch_allow ((theWord >> 5) & 1);
|
|
}
|
|
else if ((theWord >> 9) & 1)
|
|
{
|
|
terminal_set_ext_in (device);
|
|
if (!((theWord >> 8) & 1))
|
|
Ext (terminal_ext_in ());
|
|
}
|
|
else
|
|
{
|
|
terminal_set_ext_out (device);
|
|
if (!((theWord >> 8) & 1))
|
|
terminal_ext_out (theWord & 0xFF);
|
|
}
|
|
}
|
|
|
|
void
|
|
Externalx (void)
|
|
{
|
|
terminal_ext_out ((theWord >> 8) & 0xFF);
|
|
terminal_ext_out (theWord & 0xFF);
|
|
}
|
|
|
|
void
|
|
GoMode (void)
|
|
{
|
|
switch (CMode)
|
|
{
|
|
case mBlock:
|
|
Blockx ();
|
|
break;
|
|
case mPoint:
|
|
Pointx ();
|
|
break;
|
|
case mLine:
|
|
Linex ();
|
|
break;
|
|
case mAlpha:
|
|
Alphax ();
|
|
break;
|
|
case mLoadCoord:
|
|
LoadCoordx (&CurCoord);
|
|
break;
|
|
case mLoadAddr:
|
|
LoadAddrx ();
|
|
break;
|
|
case mSSF:
|
|
SSFx ();
|
|
break;
|
|
case mExternal:
|
|
Externalx ();
|
|
break;
|
|
case mLoadEcho:
|
|
LoadEchox ();
|
|
break;
|
|
case mLoadChar:
|
|
LoadCharx ();
|
|
break;
|
|
case mLoadMem:
|
|
LoadMemx ();
|
|
break;
|
|
case mMode5:
|
|
terminal_mode_5 (theWord);
|
|
break;
|
|
case mMode6:
|
|
terminal_mode_6 (theWord);
|
|
break;
|
|
case mMode7:
|
|
terminal_mode_7 (theWord);
|
|
break;
|
|
case mFore:
|
|
screen_foreground(&theColor);
|
|
break;
|
|
case mBack:
|
|
screen_background(&theColor);
|
|
break;
|
|
case mPaint:
|
|
screen_paint(&CurCoord);
|
|
break;
|
|
}
|
|
CMode = PMode;
|
|
CType = PType;
|
|
Phase = 0;
|
|
}
|
|
|
|
void
|
|
GoWord (void)
|
|
{
|
|
switch (Phase)
|
|
{
|
|
case 0:
|
|
theWord = theChar & 0x3F;
|
|
Phase = 1;
|
|
break;
|
|
case 1:
|
|
theWord |= ((theChar & 0x3F) << 6);
|
|
Phase = 2;
|
|
break;
|
|
case 2:
|
|
theWord |= ((theChar & 0x3F) << 12);
|
|
GoMode ();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
GoCoord (void)
|
|
{
|
|
unsigned short CoordType, CoordValue;
|
|
|
|
CoordValue = theChar & 0x1F;
|
|
CoordType = ((theChar >> 5) & 3);
|
|
switch (CoordType)
|
|
{
|
|
case 1:
|
|
switch (Phase)
|
|
{
|
|
case 0:
|
|
HiY = CoordValue;
|
|
break;
|
|
case 1:
|
|
HiX = CoordValue;
|
|
break;
|
|
}
|
|
Phase = 1;
|
|
break;
|
|
case 2:
|
|
LowX = CoordValue;
|
|
GoMode ();
|
|
break;
|
|
case 3:
|
|
LowY = CoordValue;
|
|
Phase = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
GoColor (void)
|
|
{
|
|
switch (Phase)
|
|
{
|
|
case 0:
|
|
theColor.blue = (theChar & 0x3f);
|
|
break;
|
|
case 1:
|
|
theColor.blue |= (theChar & 0x03) << 6;
|
|
theColor.green = (theChar & 0x3c) >> 2;
|
|
break;
|
|
case 2:
|
|
theColor.green |= (theChar & 0x0f) << 4;
|
|
theColor.red = (theChar & 0x30) >> 4;
|
|
break;
|
|
case 3:
|
|
theColor.red |= (theChar & 0x3f) << 2;
|
|
break;
|
|
}
|
|
if (Phase < 3)
|
|
Phase++;
|
|
else
|
|
GoMode ();
|
|
}
|
|
|
|
void
|
|
GoPaint (void)
|
|
{
|
|
if (Phase == 0)
|
|
Phase = 1;
|
|
else
|
|
GoMode ();
|
|
|
|
}
|
|
|
|
void
|
|
DataChar (void)
|
|
{
|
|
switch (CType)
|
|
{
|
|
case tByte:
|
|
Alphax ();
|
|
break;
|
|
case tWord:
|
|
GoWord ();
|
|
break;
|
|
case tCoord:
|
|
GoCoord ();
|
|
break;
|
|
case tColor:
|
|
GoColor ();
|
|
break;
|
|
case tPaint:
|
|
GoPaint ();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
ShowPLATO (padByte *buff, unsigned short count)
|
|
{
|
|
while (count--)
|
|
{
|
|
theChar = *buff++;
|
|
if (lastChar==0xFF && theChar==0xFF)
|
|
{
|
|
lastChar=0;
|
|
}
|
|
else
|
|
{
|
|
rawChar=theChar;
|
|
theChar &=0x7F;
|
|
if (TTY)
|
|
{
|
|
if (!EscFlag)
|
|
screen_tty_char (theChar);
|
|
else if (theChar == 0x02)
|
|
InitPLATOx ();
|
|
}
|
|
else if (EscFlag)
|
|
{
|
|
switch (theChar)
|
|
{
|
|
case 0x03:
|
|
InitTTY ();
|
|
break;
|
|
|
|
case 0x0C:
|
|
screen_clear ();
|
|
break;
|
|
|
|
case 0x11:
|
|
CurMode = ModeInverse;
|
|
SetFast();
|
|
break;
|
|
case 0x12:
|
|
CurMode = ModeWrite;
|
|
SetFast();
|
|
break;
|
|
case 0x13:
|
|
CurMode = ModeErase;
|
|
SetFast();
|
|
break;
|
|
case 0x14:
|
|
CurMode = ModeRewrite;
|
|
SetFast();
|
|
break;
|
|
|
|
case 0x32:
|
|
SetCommand (mLoadCoord, tCoord);
|
|
break;
|
|
|
|
case 0x40:
|
|
Superx ();
|
|
break;
|
|
case 0x41:
|
|
Subx ();
|
|
break;
|
|
|
|
case 0x42:
|
|
CurMem = M0;
|
|
break;
|
|
case 0x43:
|
|
CurMem = M1;
|
|
break;
|
|
case 0x44:
|
|
CurMem = M2;
|
|
break;
|
|
case 0x45:
|
|
CurMem = M3;
|
|
break;
|
|
|
|
case 0x4A:
|
|
Rotate = false;
|
|
SetFast();
|
|
break;
|
|
case 0x4B:
|
|
Rotate = true;
|
|
SetFast();
|
|
break;
|
|
case 0x4C:
|
|
Reverse = false;
|
|
SetFast();
|
|
break;
|
|
case 0x4D:
|
|
Reverse = true;
|
|
SetFast();
|
|
break;
|
|
case 0x4E:
|
|
ModeBold = false;
|
|
SetFast();
|
|
break;
|
|
case 0x4F:
|
|
ModeBold = true;
|
|
SetFast();
|
|
break;
|
|
|
|
case 0x50:
|
|
SetMode (mLoadChar, tWord);
|
|
break;
|
|
case 0x51:
|
|
SetCommand (mSSF, tWord);
|
|
break;
|
|
case 0x52:
|
|
SetCommand (mExternal, tWord);
|
|
break;
|
|
case 0x53:
|
|
SetMode (mLoadMem, tWord);
|
|
break;
|
|
case 0x54:
|
|
SetMode (mMode5, tWord);
|
|
break;
|
|
case 0x55:
|
|
SetMode (mMode6, tWord);
|
|
break;
|
|
case 0x56:
|
|
SetMode (mMode7, tWord);
|
|
break;
|
|
case 0x57:
|
|
SetCommand (mLoadAddr, tWord);
|
|
break;
|
|
case 0x59:
|
|
SetCommand (mLoadEcho, tWord);
|
|
break;
|
|
|
|
case 0x5A:
|
|
Marginx ();
|
|
break;
|
|
|
|
case 0x61:
|
|
SetCommand (mFore, tColor);
|
|
break;
|
|
case 0x62:
|
|
SetCommand (mBack, tColor);
|
|
break;
|
|
case 0x63:
|
|
SetCommand (mPaint, tPaint);
|
|
break;
|
|
}
|
|
}
|
|
else if (theChar < 0x20)
|
|
{
|
|
if (charCount > 0)
|
|
{
|
|
screen_char_draw (&charCoord, charBuff, charCount);
|
|
charCount = 0;
|
|
}
|
|
switch (theChar)
|
|
{
|
|
case 0x00:
|
|
screen_wait();
|
|
case 0x08:
|
|
BSx ();
|
|
break;
|
|
case 0x09:
|
|
HTx ();
|
|
break;
|
|
case 0x0A:
|
|
LFx ();
|
|
break;
|
|
case 0x0B:
|
|
VTx ();
|
|
break;
|
|
case 0x0C:
|
|
FFx ();
|
|
break;
|
|
case 0x0D:
|
|
CRx ();
|
|
break;
|
|
|
|
case 0x19:
|
|
SetMode (mBlock, tCoord);
|
|
break;
|
|
case 0x1C:
|
|
SetMode (mPoint, tCoord);
|
|
break;
|
|
case 0x1D:
|
|
SetMode (mLine, tCoord);
|
|
break;
|
|
case 0x1F:
|
|
SetMode (mAlpha, tByte);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
DataChar ();
|
|
|
|
EscFlag = (theChar == 0x1B);
|
|
lastChar=rawChar;
|
|
}
|
|
}
|
|
if (charCount > 0)
|
|
{
|
|
screen_char_draw (&charCoord, charBuff, charCount);
|
|
charCount = 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* SetFast()
|
|
* Toggle fast text output if mode = write or erase, and no rotate or bold
|
|
*/
|
|
void SetFast(void)
|
|
{
|
|
FastText = (((CurMode == ModeWrite) || (CurMode == ModeErase)) && ((Rotate == padF) && (ModeBold == padF)));
|
|
}
|