Reorganise system and runtime library modules for both O2 and OC builds.

This commit is contained in:
David Brown 2016-10-01 17:26:44 +01:00
parent c924a33a05
commit c2567a2600
223 changed files with 1521 additions and 4039 deletions

View file

@ -19,7 +19,7 @@ BEGIN
error := Platform.Write(Platform.StdOut, SYSTEM.ADR(str), l)
END String;
PROCEDURE Int*(x: HUGEINT; n: LONGINT);
PROCEDURE Int*(x, n: HUGEINT);
CONST zero = ORD('0');
VAR s: ARRAY 22 OF CHAR; i: INTEGER; negative: BOOLEAN;
BEGIN

View file

@ -389,7 +389,7 @@ END ReadBuf;
PROCEDURE -writefile(fd: LONGINT; p: SYSTEM.ADDRESS; l: LONGINT): SYSTEM.ADDRESS
PROCEDURE -writefile(fd: LONGINT; p: SYSTEM.ADDRESS; l: SYSTEM.ADDRESS): SYSTEM.ADDRESS
"write(fd, (void*)(address)(p), l)";
PROCEDURE Write*(h: FileHandle; p: SYSTEM.ADDRESS; l: LONGINT): ErrorCode;

219
src/runtime/SYSTEM.c Normal file
View file

@ -0,0 +1,219 @@
/*
* The body prefix file of the voc(jet backend) runtime system, Version 1.0
*
* Copyright (c) Software Templ, 1994, 1995
*
* Module SYSTEM is subject to change any time without prior notification.
* Software Templ disclaims all warranties with regard to module SYSTEM,
* in particular shall Software Templ not be liable for any damage resulting
* from inappropriate use or modification of module SYSTEM.
*
* Version 1.1 jt, 24.11.95 fixes for correct pointer arithmetic on Cray computers
* jt 31.1.2007 ANSI prototypes for malloc and exit in order to avoid cc warnings
*
*/
#include "SYSTEM.h"
#include "stdarg.h"
#include <signal.h>
// Procedure verions of SYSTEM.H versions used when a multiply accessed
// parameter has side effects.
int64 SYSTEM_DIV(int64 x, int64 y)
{
if (x == 0) return 0;
if (x >= 0)
if (y >= 0) {return x/y;}
else {return -((x-y-1)/(-y));}
else
if (y >= 0) {return -((y-x-1)/y);}
else {return (-x)/(-y);}
}
int64 SYSTEM_MOD(int64 x, int64 y)
{
if (x == 0) return 0;
if (x >= 0)
if (y >= 0) {return x % y;}
else {return (y+1) + ((x-1) % (-y));}
else
if (y >= 0) {return (y-1) - ((-x-1) % y);}
else {return -((-x) % (-y));}
}
LONGINT SYSTEM_ENTIER(double x)
{
LONGINT y;
if (x >= 0)
return (LONGINT)x;
else {
y = (LONGINT)x;
if (y <= x) return y; else return y - 1;
}
}
void SYSTEM_INHERIT(address *t, address *t0)
{
t -= __TPROC0OFF;
t0 -= __TPROC0OFF;
while (*t0 != __EOM) {*t = *t0; t--; t0--;}
}
void SYSTEM_ENUMP(void *adr, address n, void (*P)())
{
while (n > 0) {
P((address)(*((void**)(adr))));
adr = ((void**)adr) + 1;
n--;
}
}
void SYSTEM_ENUMR(void *adr, address *typ, address size, address n, void (*P)())
{
address *t, off;
typ++;
while (n > 0) {
t = typ;
off = *t;
while (off >= 0) {P(*(address*)((char*)adr+off)); t++; off = *t;}
adr = ((char*)adr) + size;
n--;
}
}
extern void Heap_Lock();
extern void Heap_Unlock();
SYSTEM_PTR SYSTEM_NEWARR(address *typ, address elemsz, int elemalgn, int nofdim, int nofdyn, ...)
{
address nofelems, size, dataoff, n, nptr, *x, *p, nofptrs, i, *ptab, off;
va_list ap;
va_start(ap, nofdyn);
nofelems = 1;
while (nofdim > 0) {
nofelems = nofelems * va_arg(ap, address); nofdim--;
if (nofelems <= 0) __HALT(-20);
}
va_end(ap);
dataoff = nofdyn * sizeof(address);
if (elemalgn > sizeof(address)) {
n = dataoff % elemalgn;
if (n != 0) dataoff += elemalgn - n;
}
size = dataoff + nofelems * elemsz;
Heap_Lock();
if (typ == NIL) {
/* element typ does not contain pointers */
x = Heap_NEWBLK(size);
}
else if (typ == (address*)POINTER__typ) {
/* element type is a pointer */
x = Heap_NEWBLK(size + nofelems * sizeof(address));
p = (address*)(address)x[-1];
p[-nofelems] = *p; /* build new type desc in situ: 1. copy block size; 2. setup ptr tab; 3. set sentinel; 4. patch tag */
p -= nofelems - 1; n = 1; /* n =1 for skipping the size field */
while (n <= nofelems) {*p = n*sizeof(address); p++; n++;}
*p = - (nofelems + 1) * sizeof(address); /* sentinel */
x[-1] -= nofelems * sizeof(address);
}
else {
/* element type is a record that contains pointers */
ptab = typ + 1; nofptrs = 0;
while (ptab[nofptrs] >= 0) {nofptrs++;} /* number of pointers per element */
nptr = nofelems * nofptrs; /* total number of pointers */
x = Heap_NEWBLK(size + nptr * sizeof(address));
p = (address*)(address)x[- 1];
p[-nptr] = *p; /* build new type desc in situ; 1. copy block size; 2. setup ptr tab; 3. set sentinel; 4. patch tag */
p -= nptr - 1; n = 0; off = dataoff;
while (n < nofelems) {i = 0;
while (i < nofptrs) {*p = off + ptab[i]; p++; i++;}
off += elemsz; n++;
}
*p = - (nptr + 1) * sizeof(address); /* sentinel */
x[-1] -= nptr * sizeof(address);
}
if (nofdyn != 0) {
/* setup len vector for index checks */
va_start(ap, nofdyn);
p = x;
while (nofdyn > 0) {*p = va_arg(ap, address); p++, nofdyn--;}
va_end(ap);
}
Heap_Unlock();
return x;
}
typedef void (*SystemSignalHandler)(INTEGER); // = Platform_SignalHandler
#ifndef _WIN32
SystemSignalHandler handler[3] = {0};
// Provide signal handling for Unix based systems
void signalHandler(int s) {
if (s >= 2 && s <= 4) handler[s-2](s);
// (Ignore other signals)
}
void SystemSetHandler(int s, address h) {
if (s >= 2 && s <= 4) {
int needtosetsystemhandler = handler[s-2] == 0;
handler[s-2] = (SystemSignalHandler)h;
if (needtosetsystemhandler) {signal(s, signalHandler);}
}
}
#else
// Provides Windows callback handlers for signal-like scenarios
#include "WindowsWrapper.h"
SystemSignalHandler SystemInterruptHandler = 0;
SystemSignalHandler SystemQuitHandler = 0;
BOOL ConsoleCtrlHandlerSet = FALSE;
BOOL WINAPI SystemConsoleCtrlHandler(DWORD ctrlType) {
if ((ctrlType == CTRL_C_EVENT) || (ctrlType == CTRL_BREAK_EVENT)) {
if (SystemInterruptHandler) {
SystemInterruptHandler(2); // SIGINT
return TRUE;
}
} else { // Close, logoff or shutdown
if (SystemQuitHandler) {
SystemQuitHandler(3); // SIGQUIT
return TRUE;
}
}
return FALSE;
}
void EnsureConsoleCtrlHandler() {
if (!ConsoleCtrlHandlerSet) {
SetConsoleCtrlHandler(SystemConsoleCtrlHandler, TRUE);
ConsoleCtrlHandlerSet = TRUE;
}
}
void SystemSetInterruptHandler(address h) {
EnsureConsoleCtrlHandler();
SystemInterruptHandler = (SystemSignalHandler)h;
}
void SystemSetQuitHandler(address h) {
EnsureConsoleCtrlHandler();
SystemQuitHandler = (SystemSignalHandler)h;
}
#endif

343
src/runtime/SYSTEM.h Normal file
View file

@ -0,0 +1,343 @@
#ifndef SYSTEM__h
#define SYSTEM__h
// 64 bit system detection
#if (__SIZEOF_POINTER__ == 8) || defined (_LP64) || defined(__LP64__) || defined(_WIN64)
#define __o_64
#endif
// Temporary while bootstrapping and clearing up SYSTEM.c.
#ifndef LONGINT
#if defined (__o_64)
#define INTEGER int32
#define LONGINT int64
#define SET uint64
#else
#define INTEGER int16
#define LONGINT int32
#define SET uint32
#endif
#endif
// Declare memcpy in a way compatible with C compilers intrinsic
// built in implementations.
#if defined (__o_64)
#if defined(_WIN64)
typedef unsigned long long size_t;
#else
typedef unsigned long size_t;
#endif
#else
typedef unsigned int size_t;
#endif
#define _SIZE_T_DECLARED // For FreeBSD
#define _SIZE_T_DEFINED_ // For OpenBSD
void *memcpy(void *dest, const void *source, size_t size);
// Declare fixed size versions of basic intger types
#if defined (__o_64) && !defined(_WIN64)
// LP64
typedef long int64;
typedef unsigned long uint64;
#else
// ILP32 or LLP64
typedef long long int64;
typedef unsigned long long uint64;
#endif
typedef int int32;
typedef unsigned int uint32;
typedef short int int16;
typedef unsigned short int uint16;
typedef signed char int8;
typedef unsigned char uint8;
// The compiler uses 'import' and 'export' which translate to 'extern' and
// nothing respectively.
#define import extern
#define export
// Known constants
#define NIL ((void*)0)
#define __MAXEXT 16
#define POINTER__typ ((address*)(1)) // not NIL and not a valid type
// Oberon types
typedef int8 BOOLEAN;
typedef int8 SYSTEM_BYTE;
typedef uint8 CHAR;
typedef float REAL;
typedef double LONGREAL;
typedef void* SYSTEM_PTR;
// 'address' is a synonym for an int of pointer size
#if defined (__o_64)
#define address int64
#else
#define address int32
#endif
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// OS Memory allocation interfaces are in PlatformXXX.Mod
extern address Platform_OSAllocate (address size);
extern void Platform_OSFree (address addr);
// Assertions and Halts
extern void Platform_Halt(LONGINT x);
extern void Platform_AssertFail(LONGINT x);
#define __HALT(x) Platform_Halt(x)
#define __ASSERT(cond, x) if (!(cond)) Platform_AssertFail((LONGINT)(x))
// Index checking
static inline int64 __XF(uint64 i, uint64 ub) {if (i >= ub) {__HALT(-2);} return i;}
#define __X(i, ub) (((i)<(ub))?i:(__HALT(-2),0))
// Range checking, and checked SHORT and CHR functions
static inline int64 __RF(uint64 i, uint64 ub) {if (i >= ub) {__HALT(-8);} return i;}
#define __R(i, ub) (((i)<(ub))?i:(__HALT(-8),0))
#define __SHORT(x, ub) ((int)((uLONGINT)(x)+(ub)<(ub)+(ub)?(x):(__HALT(-8),0)))
#define __SHORTF(x, ub) ((int)(__RF((x)+(ub),(ub)+(ub))-(ub)))
#define __CHR(x) ((CHAR)__R(x, 256))
#define __CHRF(x) ((CHAR)__RF(x, 256))
// Signal handling in SYSTEM.c
#ifndef _WIN32
extern void SystemSetHandler(int s, address h);
#else
extern void SystemSetInterruptHandler(address h);
extern void SystemSetQuitHandler (address h);
#endif
// String comparison
static inline int __str_cmp(CHAR *x, CHAR *y){
LONGINT i = 0;
CHAR ch1, ch2;
do {ch1 = x[i]; ch2 = y[i]; i++;
if (!ch1) return -(int)ch2;
} while (ch1==ch2);
return (int)ch1 - (int)ch2;
}
#define __STRCMP(a,b) __str_cmp((CHAR*)(a), (CHAR*)(b))
// Inline string, record and array copy
#define __COPY(s, d, n) {char*_a=(void*)s,*_b=(void*)d; LONGINT _i=0,_t=n-1; \
while(_i<_t&&((_b[_i]=_a[_i])!=0)){_i++;};_b[_i]=0;}
#define __DUP(x, l, t) x=(void*)memcpy((void*)Platform_OSAllocate(l*sizeof(t)),x,l*sizeof(t))
#define __DUPARR(v, t) v=(void*)memcpy(v##__copy,v,sizeof(t))
#define __DEL(x) Platform_OSFree((address)x)
/* SYSTEM ops */
#define __VAL(t, x) (*(t*)&(x))
#define __GET(a, x, t) x=*(t*)(address)(a)
#define __PUT(a, x, t) *(t*)(address)(a)=x
#define __LSHL(x, n, s) ((int##s)((uint##s)(x)<<(n)))
#define __LSHR(x, n, s) ((int##s)((uint##s)(x)>>(n)))
#define __LSH(x, n, s) ((n)>=0? __LSHL(x, n, s): __LSHR(x, -(n), s))
#define __ROTL(x, n, s) ((int##s)((uint##s)(x)<<(n)|(uint##s)(x)>>(s-(n))))
#define __ROTR(x, n, s) ((int##s)((uint##s)(x)>>(n)|(uint##s)(x)<<(s-(n))))
#define __ROT(x, n, s) ((n)>=0? __ROTL(x, n, s): __ROTR(x, -(n), s))
#define __ASHL(x, n) ((int64)(x)<<(n))
#define __ASHR(x, n) ((int64)(x)>>(n))
#define __ASH(x, n) ((n)>=0?__ASHL(x,n):__ASHR(x,-(n)))
static inline int64 SYSTEM_ASH(int64 x, int64 n) {return __ASH(x,n);}
#define __ASHF(x, n) SYSTEM_ASH((int64)(x), (int64)(n))
#define __MOVE(s, d, n) memcpy((char*)(address)(d),(char*)(address)(s),n)
extern int64 SYSTEM_DIV(int64 x, int64 y);
#define __DIVF(x, y) SYSTEM_DIV(x, y)
#define __DIV(x, y) (((x)>0 && (y)>0) ? (x)/(y) : __DIVF(x, y))
extern int64 SYSTEM_MOD(int64 x, int64 y);
#define __MODF(x, y) SYSTEM_MOD(x, y)
#define __MOD(x, y) (((x)>0 && (y)>0) ? (x)%(y) : __MODF(x, y))
extern LONGINT SYSTEM_ENTIER (double x);
#define __ENTIER(x) SYSTEM_ENTIER(x)
#define __ABS(x) (((x)<0)?-(x):(x))
static inline int32 SYSTEM_ABS64(int64 i) {return i >= 0 ? i : -i;}
static inline int64 SYSTEM_ABS32(int32 i) {return i >= 0 ? i : -i;}
#define __ABSF(x) ((sizeof(x) <= 4) ? SYSTEM_ABS32(i) : SYSTEM_ABS64(i))
static inline double SYSTEM_ABSD(double i) {return i >= 0.0 ? i : -i;}
#define __ABSFD(x) SYSTEM_ABSD(x)
#define __CAP(ch) ((CHAR)((ch)&0x5f))
#define __ODD(x) ((x)&1)
#define __IN(x, s, size) (((unsigned int)(x))<size && ((((uint##size)(s))>>(x))&1))
// todo tested versions of SETOF and SETRNG: check that x, l and h fit size
#define __SETOF(x, size) ((uint##size)1<<(x))
#define __SETRNG(l, h, size) ((~(uint##size)0<<(l))&~(uint##size)0>>(size-1-(h)))
#define __MASK(x, m) ((x)&~(m))
#define __BIT(x, n) (*(uint64*)(x)>>(n)&1)
// Runtime checks
#define __RETCHK __retchk: __HALT(-3); return 0;
#define __CASECHK __HALT(-4)
#define __WITHCHK __HALT(-7)
#define __IS(tag, typ, level) (*(tag-(__BASEOFF-level))==(address)typ##__typ)
#define __TYPEOF(p) (*(((address**)(p))-1))
#define __ISP(p, typ, level) __IS(__TYPEOF(p),typ,level)
#define __GUARDP(p, typ, level) ((typ*)(__ISP(p,typ,level)?p:(__HALT(-5),p)))
#define __GUARDR(r, typ, level) (*((typ*)(__IS(r##__typ,typ,level)?r:(__HALT(-5),r))))
#define __GUARDA(p, typ, level) ((struct typ*)(__IS(__TYPEOF(p),typ,level)?p:(__HALT(-5),p)))
#define __GUARDEQR(p, dyntyp, typ) if(dyntyp!=typ##__typ) __HALT(-6);*(p)
#define __GUARDEQP(p, typ) if(__TYPEOF(p)!=typ##__typ)__HALT(-6);*(p)
// Module entry/registration/exit
extern void Heap_REGCMD();
extern SYSTEM_PTR Heap_REGMOD();
extern void Heap_REGTYP();
extern void Heap_INCREF();
#define __DEFMOD static void *m; if (m!=0) {return m;}
#define __REGCMD(name, cmd) Heap_REGCMD(m, (CHAR*)name, cmd)
#define __REGMOD(name, enum) if (m==0) {m = Heap_REGMOD((CHAR*)name,enum);}
#define __ENDMOD return m
#define __MODULE_IMPORT(name) Heap_INCREF(name##__init())
// Main module initialisation, registration and finalisation
extern void Platform_Init(INTEGER argc, address argv);
extern void Heap_FINALL();
#define __INIT(argc, argv) static void *m; Platform_Init((INTEGER)argc, (address)&argv);
#define __REGMAIN(name, enum) m = Heap_REGMOD((CHAR*)name,enum)
#define __FINI Heap_FINALL(); return 0
// Memory allocation
extern SYSTEM_PTR Heap_NEWBLK (address size);
extern SYSTEM_PTR Heap_NEWREC (address tag);
extern SYSTEM_PTR SYSTEM_NEWARR(LONGINT*, LONGINT, int, int, int, ...);
#define __SYSNEW(p, len) p = Heap_NEWBLK((address)(len))
#define __NEW(p, t) p = Heap_NEWREC((address)t##__typ)
#define __NEWARR SYSTEM_NEWARR
/* Type handling */
extern void SYSTEM_INHERIT(address *t, address *t0);
extern void SYSTEM_ENUMP (void *adr, address n, void (*P)());
extern void SYSTEM_ENUMR (void *adr, address *typ, address size, address n, void (*P)());
#define __TDESC(t, m, n) \
static struct t##__desc { \
address tproc[m]; /* Proc for each ptr field */ \
address tag; \
address next; /* Module table type list points here */ \
address level; \
address module; \
char name[24]; \
address basep[__MAXEXT]; /* List of bases this extends */ \
address reserved; \
address blksz; /* xxx_typ points here */ \
address ptr[n+1]; /* Offsets of ptrs up to -ve sentinel */ \
} t##__desc
#define __BASEOFF (__MAXEXT+1) // blksz as index to base.
#define __TPROC0OFF (__BASEOFF+24/sizeof(address)+5) // blksz as index to tproc IFF m=1.
#define __EOM 1
#define __TDFLDS(name, size) {__EOM}, 1, 0, 0, 0, name, {0}, 0, size
#define __ENUMP(adr, n, P) SYSTEM_ENUMP(adr, (address)(n), P)
#define __ENUMR(adr, typ, size, n, P) SYSTEM_ENUMR(adr, typ, (address)(size), (address)(n), P)
#define __INITYP(t, t0, level) \
t##__typ = (address*)&t##__desc.blksz; \
memcpy(t##__desc.basep, t0##__typ - __BASEOFF, level*sizeof(address)); \
t##__desc.basep[level] = (address)t##__typ; \
t##__desc.module = (address)m; \
if(t##__desc.blksz!=sizeof(struct t)) __HALT(-15); \
t##__desc.blksz = (t##__desc.blksz+5*sizeof(address)-1)/(4*sizeof(address))*(4*sizeof(address)); \
Heap_REGTYP(m, (address)&t##__desc.next); \
SYSTEM_INHERIT(t##__typ, t0##__typ)
// Oberon-2 type bound procedures support
#define __INITBP(t, proc, num) *(t##__typ-(__TPROC0OFF+num))=(address)proc
#define __SEND(typ, num, funtyp, parlist) ((funtyp)((address)*(typ-(__TPROC0OFF+num))))parlist
#endif

View file

@ -0,0 +1,10 @@
// WindowsWrapper.h
//
// Includes Windows.h while avoiding conflicts with Oberon types.
#define BOOLEAN _BOOLEAN
#define CHAR _CHAR
#include <windows.h>
#undef BOOLEAN
#undef CHAR

342
src/runtime/vt100.Mod Normal file
View file

@ -0,0 +1,342 @@
MODULE vt100;
IMPORT Out, Strings;
(* reference http://en.wikipedia.org/wiki/ANSI_escape_code
& http://misc.flogisoft.com/bash/tip_colors_and_formatting
*)
CONST
Escape* = 1BX;
SynchronousIdle* = 16X;
LeftCrotchet* = '[';
(* formatting *)
Bold* = "1m";
Dim* = "2m";
Underlined* = "4m";
Blink* = "5m"; (* does not work with most emulators, works in tty and xterm *)
Reverse* = "7m"; (* invert the foreground and background colors *)
Hidden* = "8m"; (* useful for passwords *)
(* reset *)
ResetAll* = "0m";
ResetBold* = "21m";
ResetDim* = "22m";
ResetUnderlined* = "24m";
ResetBlink* = "25m";
ResetReverse* = "27m";
ResetHidden* = "28m";
(* foreground colors *)
Black* = "30m";
Red* = "31m";
Green* = "32m";
Yellow* = "33m";
Blue* = "34m";
Magenta* = "35m";
Cyan* = "36m";
LightGray* = "37m";
Default* = "39m";
DarkGray* = "90m";
LightRed* = "91m";
LightGreen* = "92m";
LightYellow* = "93m";
LightBlue* = "94m";
LightMagenta* = "95m";
LightCyan* = "96m";
White* = "97m";
(* background colors *)
BBlack* = "40m";
BRed* = "41m";
BGreen* = "42m";
BYellow* = "43m";
BBlue* = "44m";
BMagenta* = "45m";
BCyan* = "46m";
BLightGray* = "47m";
BDefault* = "49m";
BDarkGray* = "100m";
BLightRed* = "101m";
BLightGreen* = "102m";
BLightYellow* = "103m";
BLightBlue* = "104m";
BLightMagenta*= "105m";
BLightCyan* = "106m";
BWhite* = "107m";
VAR
CSI* : ARRAY 5 OF CHAR;
tmpstr : ARRAY 32 OF CHAR;
(* IntToStr routine taken from
https://github.com/romiras/Oberon-F-components/blob/master/Ott/Mod/IntStr.cp
and modified to work on 64bit system,
in order to avoid using oocIntStr, which has many dependencies *)
PROCEDURE Reverse0 (VAR str : ARRAY OF CHAR; start, end : INTEGER);
(* Reverses order of characters in the interval [start..end]. *)
VAR
h : CHAR;
BEGIN
WHILE start < end DO
h := str[start]; str[start] := str[end]; str[end] := h;
INC(start); DEC(end)
END
END Reverse0;
PROCEDURE IntToStr*(int: LONGINT; VAR str: ARRAY OF CHAR);
(* Converts the value of `int' to string form and copies the possibly truncated
result to `str'. *)
VAR
b : ARRAY 21 OF CHAR;
s, e: INTEGER;
maxLength : SHORTINT; (* maximum number of digits representing a LONGINT value *)
BEGIN
IF SIZE(LONGINT) = 4 THEN maxLength := 11 END;
IF SIZE(LONGINT) = 8 THEN maxLength := 20 END;
(* build representation in string 'b' *)
IF int = MIN(LONGINT) THEN (* smallest LONGINT, -int is an overflow *)
IF SIZE(LONGINT) = 4 THEN
b := "-2147483648";
e := 11
ELSE (* SIZE(LONGINT) = 8 *)
b := "-9223372036854775808";
e := 20
END
ELSE
IF int < 0 THEN (* negative sign *)
b[0] := "-"; int := -int; s := 1
ELSE (* no sign *)
s := 0
END;
e := s; (* 's' holds starting position of string *)
REPEAT
b[e] := CHR(int MOD 10+ORD("0"));
int := int DIV 10;
INC(e)
UNTIL int = 0;
b[e] := 0X;
Reverse0(b, s, e-1);
END;
COPY(b, str) (* truncate output if necessary *)
END IntToStr;
PROCEDURE EscSeq0 (letter : ARRAY OF CHAR);
VAR
cmd : ARRAY 9 OF CHAR;
BEGIN
COPY(CSI, cmd);
Strings.Append (letter, cmd);
Out.String (cmd);
END EscSeq0;
PROCEDURE EscSeq (n : INTEGER; letter : ARRAY OF CHAR);
VAR nstr : ARRAY 2 OF CHAR;
cmd : ARRAY 7 OF CHAR;
BEGIN
IntToStr (n, nstr);
COPY(CSI, cmd);
Strings.Append (nstr, cmd);
Strings.Append (letter, cmd);
Out.String (cmd);
END EscSeq;
PROCEDURE EscSeqSwapped (n : INTEGER; letter : ARRAY OF CHAR);
VAR nstr : ARRAY 2 OF CHAR;
cmd : ARRAY 7 OF CHAR;
BEGIN
IntToStr (n, nstr);
COPY(CSI, cmd);
Strings.Append (letter, cmd);
Strings.Append (nstr, cmd);
Out.String (cmd);
END EscSeqSwapped;
PROCEDURE EscSeq2(n, m : INTEGER; letter : ARRAY OF CHAR);
VAR nstr, mstr : ARRAY 5 OF CHAR;
cmd : ARRAY 12 OF CHAR;
BEGIN
IntToStr(n, nstr);
IntToStr(m, mstr);
COPY (CSI, cmd);
Strings.Append (nstr, cmd);
Strings.Append (';', cmd);
Strings.Append (mstr, cmd);
Strings.Append (letter, cmd);
Out.String (cmd);
END EscSeq2;
(* Cursor up
moves cursor n cells in the given direction. if the cursor is already at the edge of the screen, this has no effect *)
PROCEDURE CUU*(n : INTEGER);
BEGIN
EscSeq (n, 'A');
END CUU;
(* Cursor down
moves cursor n cells in the given direction. if the cursor is already at the edge of the screen, this has no effect *)
PROCEDURE CUD*(n : INTEGER);
BEGIN
EscSeq (n, 'B');
END CUD;
(* Cursor forward
moves cursor n cells in the given direction. if the cursor is already at the edge of the screen, this has no effect *)
PROCEDURE CUF*(n : INTEGER);
BEGIN
EscSeq (n, 'C');
END CUF;
(* Cursor back
moves cursor n cells in the given direction. if the cursor is already at the edge of the screen, this has no effect *)
PROCEDURE CUB*(n : INTEGER);
BEGIN
EscSeq (n, 'D');
END CUB;
(* Curnser Next Line
moves cursor to beginning of the line n lines down *)
PROCEDURE CNL*( n: INTEGER);
BEGIN
EscSeq (n, 'E');
END CNL;
(* Cursor Previous Line
Moves cursor to beginning of the line n lines down *)
PROCEDURE CPL*( n : INTEGER);
BEGIN
EscSeq (n, 'F');
END CPL;
(* Cursor Horizontal Absolute
Moves the cursor to column n *)
PROCEDURE CHA*( n : INTEGER);
BEGIN
EscSeq (n, 'G');
END CHA;
(* Cursor position, moves cursor to row n, column m *)
PROCEDURE CUP*(n, m : INTEGER);
BEGIN
EscSeq2 (n, m, 'H');
END CUP;
(* Erase Display
if n = 0 then clears from cursor to end of the screen
if n = 1 then clears from cursor to beginning of the screen
if n = 2 then clears entire screen *)
PROCEDURE ED* (n : INTEGER);
BEGIN
EscSeq(n, 'J');
END ED;
(* Erase in Line
Erases part of the line. If n is zero, clear from cursor to the end of the line. If n is one, clear from cursor to beginning of the line. If n is two, clear entire line. Cursor position does not change *)
PROCEDURE EL*( n : INTEGER);
BEGIN
EscSeq(n, 'K');
END EL;
(* Scroll Up
Scroll whole page up by n lines. New lines are added at the bottom *)
PROCEDURE SU*( n : INTEGER);
BEGIN
EscSeq(n, 'S')
END SU;
(* Scroll Down
Scroll whole page down by n (default 1) lines. New lines are added at the top *)
PROCEDURE SD*( n : INTEGER);
BEGIN
EscSeq(n, 'T');
END SD;
(* Horizontal and Vertical Position,
Moves the cursor to row n, column m. Both default to 1 if omitted. Same as CUP *)
PROCEDURE HVP*(n, m : INTEGER);
BEGIN
EscSeq2 (n, m, 'f');
END HVP;
(* Select Graphic Rendition
Sets SGR parameters, including text color. After CSI can be zero or more parameters separated with ;. With no parameters, CSI m is treated as CSI 0 m (reset / normal), which is typical of most of the ANSI escape sequences *)
PROCEDURE SGR*( n : INTEGER);
BEGIN
EscSeq(n, 'm');
END SGR;
PROCEDURE SGR2*( n, m : INTEGER);
BEGIN
EscSeq2(n, m, 'm');
END SGR2;
(* Device Status Report
Reports the cursor position (CPR) to the application as (as though typed at the keyboard) ESC[n;mR, where n is the row and m is the column.) *)
PROCEDURE DSR*(n : INTEGER);
BEGIN
EscSeq(6, 'n');
END DSR;
(* Save Cursor Position *)
PROCEDURE SCP*;
BEGIN
EscSeq0('s');
END SCP;
(* Restore Cursor Position *)
PROCEDURE RCP*;
BEGIN
EscSeq0('u');
END RCP;
(* Hide the cursor *)
PROCEDURE DECTCEMl*;
BEGIN
EscSeq0("?25l")
END DECTCEMl;
(* shows the cursor *)
PROCEDURE DECTCEMh*;
BEGIN
EscSeq0("?25h")
END DECTCEMh;
PROCEDURE SetAttr*(attr : ARRAY OF CHAR);
VAR tmpstr : ARRAY 16 OF CHAR;
BEGIN
COPY(CSI, tmpstr);
Strings.Append(attr, tmpstr);
Out.String(tmpstr);
END SetAttr;
BEGIN
(* init CSI sequence *)
COPY(Escape, CSI);
Strings.Append(LeftCrotchet, CSI);
(*
EraseDisplay;
GotoXY (0, 0);
COPY(CSI, tmpstr);
Strings.Append(Green, tmpstr);
Strings.Append("hello", tmpstr);
Out.String(tmpstr); Out.Ln;
*)
END vt100.