Logitech Modula-2 v1.00

This commit is contained in:
davidly 2024-06-30 15:16:10 -07:00
parent 74ea73d98b
commit 0aa762a607
152 changed files with 7835 additions and 0 deletions

View File

@ -0,0 +1,26 @@
DEFINITION MODULE ASCII;
(*
Symbolic constants for non-printing ASCII characters
*)
EXPORT QUALIFIED nul, soh, stx, etx, eot, enq, ack, bel,
bs, ht, lf, vt, ff, cr, so, si,
dle, dc1, dc2, dc3, dc4, nak, syn, etb,
can, em, sub, esc, fs, gs, rs, us,
del;
CONST
nul = 00C; soh = 01C; stx = 02C; etx = 03C;
eot = 04C; enq = 05C; ack = 06C; bel = 07C;
bs = 10C; ht = 11C; lf = 12C; vt = 13C;
ff = 14C; cr = 15C; so = 16C; si = 17C;
dle = 20C; dc1 = 21C; dc2 = 22C; dc3 = 23C;
dc4 = 24C; nak = 25C; syn = 26C; etb = 27C;
can = 30C; em = 31C; sub = 32C; esc = 33C;
fs = 34C; gs = 35C; rs = 36C; us = 37C;
del = 177C;
END ASCII.


Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,51 @@
DEFINITION MODULE CardinalIO;
(*
Terminal input/output of CARDINALs in decimal and hex
Derived from the Lilith Modula-2 system developed by the
group of Prof. N. Wirth at ETH Zurich, Switzerland.
*)
EXPORT QUALIFIED ReadCardinal, WriteCardinal, ReadHex, WriteHex;
PROCEDURE ReadCardinal (VAR c: CARDINAL);
(*- Read an unsigned decimal number from the terminal.
out: c the value that was read.
The read terminates only on ESC, EOL, or blank, and the terminator
must be re-read, for example with Terminal.Read.
If the read encounters a non-digit, or a digit which would cause the
number to exceed the maximum CARDINAL value, the bell is sounded and
that character is ignored. No more than one leading '0' is allowed.
*)
PROCEDURE WriteCardinal (c: CARDINAL; w: CARDINAL);
(*- Write a CARDINAL in decimal format to the terminal.
in: c value to write,
w minimum field width.
The value of c is written, even if it takes more than w digits.
If it takes fewer digits, leading blanks are output to make the
field w characters wide.
*)
PROCEDURE ReadHex (VAR c: CARDINAL);
(*- Read a CARDINAL in hexadecimal format from the terminal.
[see ReadCardinal above]
*)
PROCEDURE WriteHex (c: CARDINAL; digits: CARDINAL);
(*- Write a CARDINAL in hexadecimal format to the terminal.
[see WriteCardinal above]
*)
END CardinalIO.
AL);
(*- Write a CARDINAL in hexadecimal format to the terminal.
[see WriteCardinal above]
*)
EN

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,61 @@
Modula-2/86 Linker V1.0 - (c) 1983 Logitech
Output file name: a:comp.LOD
++ Program map (13 modules included in this layer):
Modules are listed in order of module code execution.
+ MOD= System KEY= A78702280DFC FILE= A:System.LNK
CODE= 05B1 DATA= 07EF
PROC-TABLE= 0002
+ MOD= Keyboard KEY= A787026FE9FC FILE= A:Keyboard.LNK
CODE= 0594 DATA= 07E6
PROC-TABLE= 0002
+ MOD= Display KEY= A6ED00811F68 FILE= C:\m2lib\lnk\Display.LNK
CODE= 058C DATA= 07E6
PROC-TABLE= 0002
+ MOD= Termbase KEY= A787024FACBC FILE= A:Termbase.LNK
CODE= 0551 DATA= 07DF
PROC-TABLE= 0002
+ MOD= ASCII KEY= A6ED007F8F20 FILE= C:\m2lib\lnk\ASCII.LNK
CODE= 054F DATA= 07DF
PROC-TABLE= 0002
+ MOD= Terminal KEY= A02101346662 FILE= A:Terminal.LNK
CODE= 052D DATA= 07DE
PROC-TABLE= 0002
+ MOD= ProgMessage KEY= A7880049D782 FILE= C:\m2lib\lnk\ProgMess.LNK
CODE= 04ED DATA= 07DE
PROC-TABLE= 01CC
+ MOD= DiskFiles KEY= A02102DCA83E FILE= A:DiskFile.LNK
CODE= 03A2 DATA= 0620
PROC-TABLE= 0006
+ MOD= FileSystem KEY= A02102D58DCC FILE= A:FileSyst.LNK
CODE= 022C DATA= 0607
PROC-TABLE= 0007
+ MOD= Storage KEY= A6ED00830B7C FILE= C:\m2lib\lnk\Storage.LNK
CODE= 01AD DATA= 0606
PROC-TABLE= 0002
+ MOD= Program KEY= A021002B9F06 FILE= A:Program.LNK
CODE= 0062 DATA= 0600
PROC-TABLE= 0002
+ MOD= DiskDirectory KEY= A02102DE2F80 FILE= A:DiskDire.LNK
CODE= 0041 DATA= 0600
PROC-TABLE= 0002
+ MOD= Comint KEY= A6ED008351F4 FILE= a:comp.LNK
CODE= 0000 DATA= 05F8
PROC-TABLE= 004E
++ Base (0 modules assumed to be in base layers):
Length of code (in paragraphs): 05F8
Length of data (in paragraphs): 0207
 KEY= A02102DE2F80 FILE= A:DiskDire.LNK
CODE= 0041 DATA= 060B
PROC-TABLE= 0002
+ MOD= Comint KEY= A6ED008351F4 FILE= a:comp.LNK
CODE= 0000 DATA= 0603
PROC-TABLE= 004E
++ Base (0 m

Binary file not shown.

View File

@ -0,0 +1,182 @@
(****************************************
* *
* MODULA-2 Multi-Pass Compiler *
* **************************** *
* *
* Implementation for Intel 8086 *
* *
* Resident Compiler *
* *
* *
* M86CompPara: *
* *
* parameter module to configurate *
* the Modula-2 compiler *
* implementation module may be *
* changed by the user *
* *
* Version: *
* 1.0 Dec 14, 1983 *
* *
* *
* Copyright: *
* (C) 1983 *
* LOGITECH S.A. *
* CH-1143 Apples (Switzerland) *
* *
****************************************)
DEFINITION MODULE CompPara;
EXPORT QUALIFIED
CPpageLength, CPpageWidth, (* listing definition *)
CPffAtEnd, CPffAtBegin,
CPheader, CPdate,
CPfooter, CPfooterText,
CPpriorityLevels, (* interrupt system definition: 8259A *)
CPRTSfunctVector, (* interrupt vector to access to RTS functions *)
CPemulator, (* default settings of compiler options *)
CPinteractiv,
CPquery, CPautoquery,
CPdebug, CPversion,
CPlister, CPerrorLister,
CPafterPass1, CPafterPass2,(* defines moment of listing generation *)
CPstacktest, CPrangetest, (* default settings of program-source options *)
CParithmetictest;
VAR
(* the following variables are used to define the format of *)
(* the listing generated by the compiler *)
CPpageLength,
(* number of lines per page : initial value is 60 *)
(* valid range: 40..65535 (if out of range: 60 is taken) *)
CPpageWidth: CARDINAL;
(* number of characters per line : initial value is 79 *)
(* valid range: 50..150 (if out of range: 79 is taken) *)
(* the next two parameters are used to define the page eject *)
CPffAtEnd: BOOLEAN;
(* defines whether a formfeed at last character *)
(* is generated or not: initial value is TRUE *)
CPffAtBegin: BOOLEAN;
(* defines whether a formfeed at first character *)
(* is generated or not: initial value is FALSE *)
(* the next two parameters define the header of each page *)
CPheader: BOOLEAN;
(* defines whether a headerline is generated on each *)
(* page or not: initial value is TRUE *)
CPdate: BOOLEAN;
(* defines whether date in headerline is generated *)
(* or not: initial value is FALSE *)
(* a header line has the following format: *)
(* Modula-2/86 filename.ext Date Page n *)
(* e.g. *)
(* Modula-2/86 COMPPARA.DEF Nov 16'83 Page 1 *)
(* the next two parameters define the footer of each page *)
CPfooter: BOOLEAN;
(* defines whether a footerline is generated on each *)
(* page or not: initial value is FALSE *)
CPfooterText: ARRAY [0..149] OF CHAR;
(* string of pagewidth characters that defines the footerline *)
(* normally used for Copyright text: initially an empty string *)
(* definition of interrupt system: number of priority levels *)
CPpriorityLevels: CARDINAL;
(* initial value of distributed version is 8: *)
(* defined by the (8259A) interrupt controller(s) *)
(* definition of interface to Run-Time-Support system *)
CPRTSfunctVector: CARDINAL;
(* defines the interrupt vector to acces the RTS *)
(* RTS: Runtime Support: Assembley part of Modula-2/86 System *)
(* normally 228: may be only changed if RTS is changed *)
(* the following boolean variable defines whether code for an *)
(* 8087 coprocessoror an 8087 emulator is generated by the compiler *)
CPemulator: BOOLEAN; (* initial value is FALSE *)
(* the following options define the interactive behaviour of the compiler *)
CPinteractiv: BOOLEAN; (* initial value is TRUE *)
(* whether compiler may be stopped by typing a key *)
CPquery: BOOLEAN; (* initial value is FALSE *)
(* whether compiler asks for the symbol files of *)
(* the imported modules or tries to find them by *)
(* the default strategy: *)
(* build filename from module name by taking *)
(* the 8 first characters and the extension 'SYM' *)
CPautoquery: BOOLEAN; (* initial value is TRUE *)
(* whether compiler falls automatically in query mode *)
(* if it didn't find the file by the default mechanism *)
CPdebug: BOOLEAN; (* initial value is TRUE *)
(* whether compiler generates a reference file *)
(* that would be used by the debugger, or not *)
CPversion: BOOLEAN; (* initial value is FALSE *)
(* whether compiler displays version info or not *)
CPlister: BOOLEAN; (* initial value is FALSE *)
(* whether compiler generates a listing file or not *)
CPerrorLister: BOOLEAN; (* initial value is TRUE *)
(* whether compiler generates automatically an *)
(* error listing if errors occured or not *)
(* moment of listing generation in case of errors *)
(* if both variables are set to FALSE the listing *)
(* will be generated after pass3 *)
(* the functions of the different passes are: *)
(* pass1 checks syntactic of program *)
(* pass2 checks declaration parts (allocation) *)
(* pass3 checks bodys (compatibility test) *)
CPafterPass1: BOOLEAN; (* initial value: TRUE *)
(* whether compiler goes to lister if error detected *)
(* in pass1 and terminates compilation, or not *)
CPafterPass2: BOOLEAN; (* initial value: FALSE *)
(* whether compiler goes to lister if error detected *)
(* in pass2 and terminates compilation, or not *)
(* the following boolean variables are used to define the default *)
(* setting of the corresponding testcode options: *)
(* TRUE means: default is '+'; FALSE means: default is '-' *)
CPstacktest: BOOLEAN;
(* for option 'S': initial value is TRUE *)
CPrangetest: BOOLEAN;
(* for option 'R': initial value is TRUE *)
CParithmetictest: BOOLEAN;
(* for option 'T': initial value is TRUE *)
END CompPara.
ial value is TRUE *)
CParithmetic

Binary file not shown.

View File

@ -0,0 +1,177 @@
(*
Copyrigth (C) 1984 Logitech. All Rights Reserved.
Permission is hereby granted to registered users to use or
abstract the following program in the implementation of
customized versions. This permission does not include the
right to redistribute the source code of this program.
*)
(****************************************
* *
* MODULA-2 Multi-Pass Compiler *
* **************************** *
* *
* Implementation for Intel 8086 *
* *
* Resident Compiler *
* *
* *
* M86CompPara: *
* *
* parameter module to configurate *
* the Modula-2 compiler *
* implementation module may be *
* changed by the user *
* *
* Version: *
* 1.0 Jan 17, 1984 *
* *
* *
* Copyright: *
* (C) 1983 *
* LOGITECH S.A. *
* CH-1143 Apples (Switzerland) *
* *
****************************************)
IMPLEMENTATION MODULE CompPara;
BEGIN
(* the following variables are used to define the format of *)
(* the listing generated by the compiler *)
CPpageLength := 60;
(* number of lines per page : initial value is 60 *)
(* valid range: 40..65535 (if out of range: 60 is taken) *)
CPpageWidth := 79;
(* number of characters per line : initial value is 79 *)
(* valid range: 50..150 (if out of range: 79 is taken) *)
(* the next two parameters are used to define the page eject *)
CPffAtEnd := TRUE;
(* defines whether a formfeed at last character *)
(* is generated or not: initial value is TRUE *)
CPffAtBegin := FALSE;
(* defines whether a formfeed at first character *)
(* is generated or not: initial value is FALSE *)
(* the next two parameters define the header of each page *)
CPheader := TRUE;
(* defines whether a headerline is generated on each *)
(* page or not: initial value is TRUE *)
CPdate := FALSE;
(* defines whether date in headerline is generated *)
(* or not: initial value is FALSE *)
(* a header line has the following format: *)
(* Modula-2/86 Date filename.ext Page n *)
(* e.g. *)
(* Modula-2/86 Nov 16'83 COMPPARA.DEF Page 1 *)
(* the next two parameters define the footer of each page *)
CPfooter := FALSE;
(* defines whether a footerline is generated on each *)
(* page or not: initial value is FALSE *)
CPfooterText := "";
(* string of pagewidth characters that defines the footerline *)
(* normally used for Copyright text: initially an empty string *)
(* definition of interrupt system: number of priority levels *)
CPpriorityLevels := 8;
(* initial value of distributed version is 8: *)
(* defined by the (8259A) interrupt controller(s) *)
(* definition of interface to Run-Time-Support system *)
CPRTSfunctVector := 228;
(* defines the interrupt vector to acces the RTS *)
(* RTS: Runtime Support: Assembley part of Modula-2/86 System *)
(* normally 228: may be only changed if RTS is changed *)
CPEmulBaseVector := 18H;
(* defines the base interrupt vector to acces the emulator *)
(* normally 18H: may be only changed if emulator is changed *)
(* the following boolean variable defines whether code for an *)
(* 8087 coprocessor or an 8087 emulator is generated by the compiler *)
CPemulator := FALSE; (* initial value is FALSE *)
(* the following options define the interactive behaviour of the compiler *)
CPinteractiv := TRUE; (* initial value is TRUE *)
(* whether compiler may be stopped by typing a key *)
CPstatistic := TRUE; (* initial value is TRUE *)
(* whether compiler displays some statistic values *)
CPquery := FALSE; (* initial value is FALSE *)
(* whether compiler asks for the symbol files of *)
(* the imported modules or tries to find them by *)
(* the default strategy: *)
(* build filename from module name by taking *)
(* the 8 first characters and the extension 'SYM' *)
CPautoquery := TRUE; (* initial value is TRUE *)
(* whether compiler falls automatically in query mode *)
(* if it didn't find the file by the default mechanism *)
CPdebug := TRUE; (* initial value is TRUE *)
(* whether compiler generates a reference file *)
(* that would be used by the debugger, or not *)
CPversion := FALSE; (* initial value is FALSE *)
(* whether compiler displays version info or not *)
CPlister := FALSE; (* initial value is FALSE *)
(* whether compiler generates a listing file or not *)
CPerrorLister := TRUE; (* initial value is TRUE *)
(* whether compiler generates automatically an *)
(* error listing if errors occured or not *)
(* moment of listing generation in case of errors *)
(* if both variables are set to FALSE the listing *)
(* will be generated after pass3 *)
(* the functions of the different passes are: *)
(* pass1 checks syntactic of program *)
(* pass2 checks declaration parts (allocation) *)
(* pass3 checks bodys (compatibility test) *)
CPafterPass1 := TRUE; (* initial value: TRUE *)
(* whether compiler goes to lister if error detected *)
(* in pass1 and terminates compilation, or not *)
CPafterPass2 := TRUE; (* initial value: FALSE *)
(* whether compiler goes to lister if error detected *)
(* in pass2 and terminates compilation, or not *)
(* the following boolean variables are used to define the default *)
(* setting of the corresponding testcode options: *)
(* TRUE means: default is '+'; FALSE means: default is '-' *)
CPstacktest := TRUE;
(* for option 'S': initial value is TRUE *)
CPrangetest := TRUE;
(* for option 'R': initial value is TRUE *)
CPindextest := TRUE;
(* for option 'T': initial value is TRUE *)
END CompPara.


Binary file not shown.

View File

@ -0,0 +1,45 @@
DEFINITION MODULE Conversions;
(*
Convert from INTEGER and CARDINAL to string
Derived from the Lilith Modula-2 system developed by the
group of Prof. N. Wirth at ETH Zurich, Switzerland.
*)
EXPORT QUALIFIED ConvertOctal, ConvertHex,
ConvertCardinal, ConvertInteger;
PROCEDURE ConvertOctal(num, len: CARDINAL; VAR str: ARRAY OF CHAR);
(*- Convert number to right-justified octal representation
in: num value to be represented,
len minimum width of representation,
out: str result string.
If the representation of 'num' uses fewer than 'len' digits, blanks
are added on the left. If the representation will not fit in 'str',
it is truncated on the right.
*)
PROCEDURE ConvertHex(num, len: CARDINAL; VAR str: ARRAY OF CHAR);
(*- Convert number to right-justified hexadecimal representation.
[see ConvertOctal]
*)
PROCEDURE ConvertCardinal(num, len: CARDINAL; VAR str: ARRAY OF CHAR);
(*- Convert a CARDINAL to right-justified decimal representation.
[see ConvertOctal]
*)
PROCEDURE ConvertInteger(num: INTEGER; len: CARDINAL;
VAR str: ARRAY OF CHAR);
(*- Convert an INTEGER to right-justified decimal representation.
[see ConvertOctal]
Note that a leading '-' is generated if num < 0, but never a '+'.
*)
END Conversions.

[see Co

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,76 @@
DEFINITION MODULE DiskDirectory;
(*
Interface to directory functions of the underlying OS
Derived from the Lilith Modula-2 system developed by the
group of Prof. N. Wirth at ETH Zurich, Switzerland.
*)
EXPORT QUALIFIED
CurrentDrive, SelectDrive,
CurrentDirectory, ChangeDirectory,
MakeDir, RemoveDir,
ResetDiskSys, ResetDrive;
PROCEDURE CurrentDrive (VAR drive: CHAR);
(*- Returns the current default drive.
out: drive the default drive, given in character format.
*)
PROCEDURE SelectDrive (drive: CHAR; VAR done: BOOLEAN);
(*- Set default drive.
in: drive name of drive to make default, specified in char format.
out: done TRUE if operation was successful.
The default drive will be used by all routines referring to DK: .
*)
PROCEDURE CurrentDirectory (drive: CHAR; VAR dir: ARRAY OF CHAR);
(*- Gets the current directory for the specified drive.
in: drive 0C for the current drive, 1C for drive "A", etc.
out: dir current directory for that drive.
Under DOS 1.1, dir[0] will be set to nul (0C).
*)
PROCEDURE ChangeDirectory (dir: ARRAY OF CHAR; VAR done: BOOLEAN);
(*- Set the current directory
in: dir drive and directory path name.
out: done TRUE if successful; FALSE if the directory does not exist.
Under DOS 1.1, this function has no effect and 'done' is FALSE.
*)
PROCEDURE MakeDir (dir: ARRAY OF CHAR; VAR done: BOOLEAN);
(*- Create a sub-directory
in: dir drive, optional pathname and name of sub-directory to create.
out: done TRUE if successful; FALSE if path or drive does not exist.
Under DOS 1.1, this function has no effect and 'done' is FALSE.
*)
PROCEDURE RemoveDir (dir: ARRAY OF CHAR; VAR done: BOOLEAN);
(*- Remove a directory
in: dir drive and name of the sub-directory to remove.
out: done: TRUE if successful; FALSE if directory does not exist.
The specified directory must be empty or the procedure returns FALSE.
Under DOS 1.1, this function has no effect and 'done' is FALSE.
*)
PROCEDURE ResetDiskSys;
(*- MS-DOS disk reset
*)
PROCEDURE ResetDrive (d: CHAR): CARDINAL;
(* This function has no effect and always returns 255. It is part of this
definition module for reasons of compatibility with other implementations.
*)
END DiskDirectory.
It is part of this
definition module for reasons of compatibil

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,40 @@
DEFINITION MODULE DiskFiles;
(*
Interface to disk file functions of the underlying OS
Derived from the Lilith Modula-2 system developed by the
group of Prof. N. Wirth at ETH Zurich, Switzerland.
[Private module of the Modula-2 system]
*)
FROM FileSystem IMPORT File;
EXPORT QUALIFIED InitDiskSystem,
DiskFileProc, DiskDirProc;
PROCEDURE InitDiskSystem;
(*- Initialize mediums for further disk file operations
This procedure has to be imported by FileSystem. This has the side-effect,
that this module is referenced and will therefore be linked to the user
program.
*)
PROCEDURE DiskFilePROC (VAR f: File);
(*- low-level interface for disk operations within a file
This procedure is passed as a parameter to the procedure CreateMedium in
FileSystem.
*)
PROCEDURE DiskDirProc (VAR f: File; name: ARRAY OF CHAR);
(*- low-level interface for disk operations within a directory
This procedure is passed as a parameter to the procedure CreateMedium in
FileSystem.
*)
END DiskFiles.


Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,29 @@
DEFINITION MODULE Display;
(*
Low-level Console Output
Derived from the Lilith Modula-2 system developed by the
group of Prof. N. Wirth at ETH Zurich, Switzerland.
[Private module of the Modula-2 system]
*)
EXPORT QUALIFIED Write;
PROCEDURE Write (ch: CHAR);
(*- Display a character on the console.
in: ch character to be displayed.
The following codes are interpreted:
System.EOL (36C) = go to beginning of next line
ASCII.ff (14C) = clear screen and set cursor home
ASCII.del (177C) = erase the last character on the left
ASCII.bs (10C) = move 1 character to the left
ASCII.cr (15C) = go to beginning of current line
ASCII.lf (12C) = move 1 line down, same column
Write uses direct console I/O.
*)
END Display.


Binary file not shown.

View File

@ -0,0 +1,61 @@
(*
Copyrigth (C) 1984 Logitech. All Rights Reserved.
Permission is hereby granted to registered users to use or
abstract the following program in the implementation of
customized versions. This permission does not include the
right to redistribute the source code of this program.
*)
(*$T-*)
(*$R-*)
(******************************************************************)
(* *)
(* MODULA-2 / 86 Private module of the terminal sub-system *)
(* *)
(* DISPLAY: *)
(* IBM-PC under MSDOS 1.1 / 2.0 *)
(* History: *)
(* Dec 9, 82 First revision *)
(* April 83 Version 0.1 - 19.04.83 *)
(* Aug 83 Version 1.0 pass uninterpreted ctl-chars *)
(* Author: *)
(* Willy Steiger *)
(* LOGITECH SA. *)
(* CH-1143 Apples (Switzerland) *)
(* *)
(******************************************************************)
IMPLEMENTATION MODULE Display;
FROM SYSTEM IMPORT DOSCALL;
PROCEDURE Write (ch: CHAR);
(* the following code are interpreted:
14C = FF, clear page, cursor home
36C = EOL, go to beginning of next line (scrolls possibly)
177C = DEL, backspace one char and clear it
*)
BEGIN (* specifically for IBM-PC: *)
IF ch = 177C THEN (* Delete *)
DOSCALL (6, 10C); (* BackSpace *)
DOSCALL (6, ' ');
DOSCALL (6, 10C); (* BackSpace *)
ELSIF ch = 36C THEN (* EOL: end of line character in modula system *)
DOSCALL (6, 15C);
DOSCALL (6, 12C);
ELSIF ch = 14C THEN (* Form Feed: clear screen *)
(* Note: This sequence is not supported under DOS 1.1, nor is
* it interpreted by DOS 2.0 unless the ANSI Terminal features have
* been enabled with "DEVICE=ANSI.SYS" See Chapter 13 of the
* DOS 2.0 Manual.
*)
DOSCALL (6, 33C);
DOSCALL (6, '[');
DOSCALL (6, '2');
DOSCALL (6, 'J');
ELSE DOSCALL (6, ch);
END;
END Write;
END Display.


Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,48 @@
(*$S-*)
(*$R-*)
(*$T-*)
MODULE e;
FROM SYSTEM IMPORT WORD, BYTE, ADDRESS;
FROM NumberConversion IMPORT StringToCard;
FROM Strings IMPORT Assign;
FROM InOut IMPORT WriteLn, WriteInt, WriteCard, WriteString;
CONST
DIGITS = 200;
VAR
high, n, x : CARDINAL;
a : ARRAY [ 0..DIGITS ] OF CARDINAL;
BEGIN
high := DIGITS;
x := 0;
n := high - 1;
WHILE n > 0 DO
a[ n ] := 1;
n := n - 1;
END;
a[ 1 ] := 2;
a[ 0 ] := 0;
WHILE high > 9 DO
high := high - 1;
n := high;
WHILE 0 <> n DO
a[ n ] := x MOD n;
x := 10 * a[ n - 1 ] + x DIV n;
n := n - 1;
END;
WriteCard( x, 0 );
END;
WriteLn;
WriteString( "done" );
WriteLn;
END e.

View File

@ -0,0 +1,9 @@
MODULE Examp1;
FROM Terminal IMPORT WriteString, WriteLn, Read;
VAR ch: CHAR;
BEGIN
WriteString('The program worked! (Hit a key)');
WriteLn;
Read(ch);
END Examp1.


View File

@ -0,0 +1,47 @@
MODULE Examp2; (* Program Module to demonstrate basic file I/O *)
IMPORT InOut;
FROM InOut IMPORT
OpenInput, OpenOutput, CloseInput, CloseOutput, Read, Write, EOL;
IMPORT Terminal; (* get qualified access to Terminal routines *)
IMPORT CardinalIO;
CONST ESC = 33C;
VAR Ch: CHAR;
LinesToCopy, LinesCopied: CARDINAL;
BEGIN
(* Note that interaction with user is done via Terminal and CardinalIO,
* because InOut input/output is being redirected to files.
*)
REPEAT
Terminal.WriteString("enter input file:"); Terminal.WriteLn;
OpenInput(""); (* request input file, no default extension *)
UNTIL InOut.Done; (* keep trying until open is successful *)
REPEAT
Terminal.WriteString("Lines to copy> ");
CardinalIO.ReadCardinal(LinesToCopy); Terminal.WriteLn;
Terminal.Read(Ch); (* read terminator of ReadCardinal *)
UNTIL Ch <> ESC; (* keep asking until entry ends with ' ' or EOL *)
REPEAT
Terminal.WriteString("enter output file:"); Terminal.WriteLn;
OpenOutput(""); (* request output file, no default extension *)
UNTIL InOut.Done;
LinesCopied := 0;
LOOP
IF LinesCopied >= LinesToCopy THEN EXIT END;
Read(Ch); (* read from in file *)
IF NOT InOut.Done THEN EXIT END; (* check for EOF *)
Write(Ch); (* otherwise copy char *)
IF Ch = EOL THEN INC(LinesCopied) END;
END; (* LOOP *)
IF LinesCopied < LinesToCopy THEN
Terminal.WriteString("[Only ");
CardinalIO.WriteCardinal(LinesCopied,0);
Terminal.WriteString(" lines in file]"); Terminal.WriteLn;
END;
CloseOutput;
CloseInput;
END Examp2.


View File

@ -0,0 +1,20 @@
DEFINITION MODULE FileMessage;
(*
Write file status/response to the terminal
*)
FROM FileSystem IMPORT Response;
EXPORT QUALIFIED WriteResponse;
PROCEDURE WriteResponse (r: Response);
(*- Write a short description of a FileSystem response on the terminal.
in: r the response from some FileSystem operation.
The actual argument for 'r' is typically the field 'res' of a variable
of type 'File'. The printed message is up to 32 characters long.
*)
END FileMessage.


Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,29 @@
DEFINITION MODULE FileNames;
(*
Read a file specification from the terminal.
Derived from the Lilith Modula-2 system developed by the
group of Prof. N. Wirth at ETH Zurich, Switzerland.
*)
EXPORT QUALIFIED FNParts, FNPartSet, ReadFileName;
TYPE FNParts = (FNDrive, FNPath, FNName, FNExt);
FNPartSet = SET OF FNParts;
PROCEDURE ReadFileName(VAR resultFN: ARRAY OF CHAR;
defaultFN: ARRAY OF CHAR;
VAR ReadInName: FNPartSet);
(*- Read a file specification from terminal.
in: defaultFN default file specification,
out: resultFN the file specifications,
ReadInName which parts are in specification.
Reads until a <cr>, blank, <can>, or <esc> is typed.
After a call to ReadFileName, Terminal.Read must be called to
read the termination character.
The format of the specifications depends on the host operating system.
*)
END FileNames.


Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,362 @@
DEFINITION MODULE FileSystem;
(*
file manipulation routines
Derived from the Modula-2 system developed by the
group of Prof. N. Wirth, ETH Zurich, Switzerland.
*)
FROM SYSTEM IMPORT ADDRESS, WORD;
EXPORT QUALIFIED
(* file operations: *)
File, Response, Command,
Create, Close, Lookup, Rename, Delete,
SetRead, SetWrite, SetModify, SetOpen,
Doio, SetPos, GetPos, Length,
(* Streamlike I/O: *)
Flag, FlagSet,
Reset, Again,
ReadWord, ReadChar, ReadByte, ReadNBytes,
WriteWord, WriteChar, WriteByte, WriteNBytes,
(* Medium Handling: *)
FileProc, DirectoryProc,
MediumType, CreateMedium, RemoveMedium,
FileNameChar;
TYPE MediumHint = CARDINAL;
(*- medium index used in DiskFiles *)
MediumType = ARRAY [0..2] OF CHAR;
(*- medium name (A, B...) *)
Flag = (er, ef, rd, wr, ag, txt);
(*- status flag for file operations
er = error occured, ef = end-of-file reached, rd = in read mode, wr = in
write mode, ag = "Again" has been called after last read, txt = text-file
(the last access to the file was a 'WriteChar' or 'ReadChar').
*)
FlagSet = SET OF Flag;
(*- status flag set *)
Response = (done, notdone, notsupported, callerror, unknownmedium,
unknownfile, paramerror, toomanyfiles, eom, userdeverror);
(*- result of a file operation *)
Command = (create, close, lookup, rename, delete, setread, setwrite,
setmodify, setopen, doio, setpos, getpos, length);
(*- commands passed to DiskFiles *)
BuffAdd = POINTER TO ARRAY [0..0FFFEH] OF CHAR;
(*- file buffer pointer type *)
File = RECORD
bufa: BuffAdd; (* Buffer Address *)
buflength: CARDINAL;
(* size of buffer in bytes. In the current release
it is always a multiple of 128 *)
validlength: CARDINAL;
(* Number of valid bytes in the buffer. *)
bufind: CARDINAL;
(* Byte-Index of current position in the buffer *)
flags: FlagSet; (* status of the file *)
eof: BOOLEAN;
(* TRUE, if last access was past end of file *)
res: Response; (* result of last operation *)
lastRead:CARDINAL;(* the last read word or byte (char) *)
mt: MediumType;
(* selects the driver that supports that file *)
fHint: CARDINAL; (* internally used by the device-driver *)
mHint: MediumHint; (* internally used by medium-handler *)
CASE com: Command OF
lookup: new: BOOLEAN;
| setpos, getpos, length: highpos, lowpos: CARDINAL;
END;
END;
(*- file structure used for bookkeeping by DiskFiles *)
PROCEDURE Create (VAR f: File; mediumName: ARRAY OF CHAR);
(*- create a temporary file
in: mediumName name of medium to create file on, in char format
out: f initialized file structure
A temporary file is characterised by an empty name. To make the file
permanent, it has to be renamed with a non-empty name before closing it.
For subsequent operations on this file, it is referenced by "f".
*)
PROCEDURE Close (VAR f: File);
(*- Close a file
in: f structure referencing an open file
out: f the field f.res will be set appropriately.
Terminates the operations on file "f". If "f" is a temporary file, it will
be destroyed, whereas a file with a non-empty name remains on its medium
and is accessible through "Lookup". When closing a text-file after writing,
the end-of-file code 32C is written on the file (MS-DOS and CP/M convention).
*)
PROCEDURE Lookup (VAR f: File; filename: ARRAY OF CHAR; newFile: BOOLEAN);
(*- look for a file
in: filename drive and name of file to search for
newFile TRUE if file should be created if not found
out: f initialized file structure; f.res will be set
appropriately.
Searches the medium specified in "filename" for a file that matches the
name and type given in "filename". If the file is not found and "newFile"
is TRUE, a new (permanent) file with the given name and type is created.
If it is not found and "newFile" is FALSE, no action takes place and
"notdone" is returned in the result field of "f".
*)
PROCEDURE Rename (VAR f: File; newname: ARRAY OF CHAR);
(*- rename a file
in: f structure referencing an open file
newname filename to rename to, with device:name.type specified
out: f file name in f will be changed and the f.res field will
be set appropriately.
The medium, on which the files reside can not be changed with this command.
The medium name inside "newname" has to be the old one.
*)
PROCEDURE Delete (name: ARRAY OF CHAR; VAR f: File);
(*- delete a file
in: name name of file to delete, with dev:name.type specified
out: f the result field f.res will be set appropriately.
*)
PROCEDURE ReadWord (VAR f: File; VAR w: WORD);
(*- Returns the word at the current position in f
in: f structure referencing an open file
out: w word read from file
f the result field f.res will be set appropriately.
the file will be positioned at the next word when the read is done.
*)
PROCEDURE WriteWord (VAR f: File; w: WORD);
(*- Write one word to a file
in: f structure referencing an open file
w word to write
out: f the field f.res will be set appropriately.
*)
PROCEDURE ReadChar (VAR f: File; VAR ch: CHAR);
(*- Read one character from a file
in: f structure referencing an open file
out: ch charatcter read from file
f the result field f.res will be set appropriately.
the file will be positioned at the next character when the read is done.
*)
PROCEDURE WriteChar (VAR f: File; ch: CHAR);
(*- Write one character to a file
in: f structure referencing an open file
ch character to write
out: f the result field f.res will be set apporopriately.
*)
PROCEDURE ReadByte (VAR f: File; VAR b: CHAR);
(*- Read one byte from a file
in: f structure referencing an open file
out: b byte read from file
f the result field f.res will be set appropriately.
the file will be positioned at the next byte when the read is completed.
*)
PROCEDURE WriteByte (VAR f: File; b: CHAR);
(*- Write one byte to a file
in: f structure referencing an open file
b byte to write
out: f the result field f.res will be set appropriately.
*)
PROCEDURE ReadNBytes (VAR f: File; bufPtr: ADDRESS;
requestedBytes: CARDINAL; VAR read: CARDINAL);
(*- Read a specified number of bytes from a file
in: f structure referencing an open file
bufPtr pointer to buffer area to read bytes into
requestedBytes number of bytes to read
out: bufPtr^ bytes read from file
f the result field f.res will be set appropriately.
read the number of bytes actually read.
the file will be positioned at the next byte after the requested string.
*)
PROCEDURE WriteNBytes (VAR f: File; bufPtr: ADDRESS;
requestedBytes: CARDINAL; VAR written: CARDINAL);
(*- Write a specified number of bytes to a file
in: f structure referencing an open file
bufPtr pointer to string of bytes to write
requestedBytes number of bytes to write
out: f the result field f.res will be set appropriately.
written the number of bytes actually written
*)
PROCEDURE Again (VAR f: File);
(*- returns a character to the buffer to be read again
in: f structure referencing an open file
out: f the f.res field will be set appropriately.
This should be called after a read operation only (it has no effect
otherwise). It prevents the subsequent read from reading the next element;
the element just read before will be returned a second time. Multiple calls
to Again without a read in between have the same effect as one call to
Again. The position in the file is undefined after a call to Again (it is
defined again after the next read operation).
*)
PROCEDURE SetRead (VAR f: File);
(*- Set the file in reading-state, without changing the current position.
in: f structure referencing an open file
out: f f.res will be set appropriately.
Upon calling SetRead, the current position must be before the eof.
In reading-state, no writing is allowed.
*)
PROCEDURE SetWrite (VAR f: File);
(*- Sets the file in writing-state, without changing the current position.
in: f structure referencing an open file
out: f f.res will be set appropriately.
Upon calling SetWrite, the current position must be a legal position in
the file (including eof). In writing-state, no reading is allowed, and
a write always takes place at the eof. The current implementation does
not truncate the file.
*)
PROCEDURE SetModify (VAR f: File);
(*- Sets the file in modifying-state, without changing the current position.
in: f structure referencing an open file
out: f f.res will be set appropriately.
Upon calling SetModify, the current position must be before the eof.
In modifying-state, reading and writing are allowed. Writing is done
at the current position, overwriting whatever element is already there.
The file is not truncated.
*)
PROCEDURE SetOpen (VAR f: File);
(*- Set the file to opened-state, without changing the current position.
in: f structure referencing an open file
out: f f.res will be set appropriately.
The buffer content is written back on the file, if the file has been in
writing or modifying status. The new buffer content is undefined.
In opened-state, neither reading nor writing is allowed.
*)
PROCEDURE Reset (VAR f: File);
(*- Set the file to opened state and position it to the top of file.
in: f structure referencing an open file
out: f f.res will be set appropriately.
*)
PROCEDURE SetPos (VAR f: File; high, low: CARDINAL);
(*- Set the current position in file
in: f structure referencing an open file
high high part of the byte offset
low low part of the byte offset
out: f f.res will be set appropriately.
The file will be positioned (high*2^16 +low) bytes from top of file.
*)
PROCEDURE GetPos (VAR f: File; VAR high, low: CARDINAL);
(*- Return the current byte position in file
in: f structure referencing an open file
out: high high part of byte offset
low low part of byte offset
The actual position is (high*2^16 +low) bytes from the top of file.
*)
PROCEDURE Length (VAR f: File; VAR high, low: CARDINAL);
(*- Return the length of the file in bytes.
in: f structure referencing an open file.
out: high high part of byte offset
low ;pw part of byte offset
The actual length is (high*2^16 +low) bytes.
*)
PROCEDURE Doio (VAR f: File);
(*- Do various read/write operations on a file
in: f structure referencing an open file
out: f f.res will be set appropriately.
The exact effect of this command depends on the state of the file (flags):
opened = NOOP.
reading = reads the record that contains the current byte from the
file. The old content of the buffer is not written back.
writing = the buffer is written back. It is then assigned to the
record, that contains the current position. Its content
is not changed.
modifying = the buffer is written back and the record containing
the current position is read.
Note that 'Doio' does not need to be used when reading through the
'stream-like' I/O routines. Its use is limited to special applications.
*)
PROCEDURE FileNameChar (c: CHAR): CHAR;
(*- Check the character c for legality in an MS-DOS filename.
in: c charater to check
out: 0C for illegal characters and c otherwise; lowercase
letters are transformed into uppercase letters.
*)
TYPE FileProc = PROCEDURE (VAR File);
(*- Procedure type to be used for internal file operations
A procedure of this type will be called for the functions:
setread, setwrite, setmodify, setopen, doio,
setpos, getpos, length, setprotect, getprotect,
setpermanent, getpermanent.
*)
DirectoryProc = PROCEDURE (VAR File, ARRAY OF CHAR);
(*- Procedure type to be used for operations on an entire file
A procedure of this type will be called for the functions:
create, close, lookup, rename, delete.
*)
PROCEDURE CreateMedium (mt: MediumType;
fproc: FileProc; dproc: DirectoryProc;
VAR done: BOOLEAN);
(*- Install the medium "mt" in the file system
in: mt medium type to install
fproc procedure to handle internal file operations
dproc procedure to handle operations on an entire file
out done TRUE if medium was successfully installed.
Before accessing or creating a file on a medium, this medium has to be
announced to the file system by means of the routine CreateMedium.
FileSystem calls "fproc" and "dproc" to perform operations on a file of
this medium. Up to 24 mediums can be announced.
*)
PROCEDURE RemoveMedium (mt: MediumType; VAR done: BOOLEAN);
(*- Remove the medium "mt" from the file system
in: mt medium type to remove
out: done true if medium was successfully removed
Attempts to access a file on this medium result in an error (unknownmedium).
*)
END FileSystem.


Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,158 @@
DEFINITION MODULE InOut;
(*
Standard high-level formatted input/output
From the book 'Programming in Modula-2' by Prof. N. Wirth.
*)
FROM SYSTEM IMPORT WORD;
FROM FileSystem IMPORT File;
EXPORT QUALIFIED EOL, Done, in, out, termCH,
OpenInput, OpenOutput, CloseInput, CloseOutput,
Read, ReadString, ReadInt, ReadCard, ReadWrd,
Write, WriteLn, WriteString, WriteInt, WriteCard,
WriteOct, WriteHex, WriteWrd;
CONST EOL = 36C;
VAR Done: BOOLEAN;
(* Done is set by several procedures, TRUE if the
* operation was successful, FALSE otherwise. *)
termCH: CHAR;
(* terminating character from ReadString, ReadInt, ReadCard. *)
in, out: File;
(* The currently open input and output files, respectively.
* Use for exceptional cases only. *)
PROCEDURE OpenInput(defext: ARRAY OF CHAR);
(*- Accept a file name from the terminal and open it for input.
in: defext default filetype or 'extension'.
If the file name that is read ends with '.', then 'defext' is
appended to the file name.
If OpenInput succeeds, Done = TRUE and subsequent input is
taken from the file until CloseInput is called.
*)
PROCEDURE OpenOutput(defext: ARRAY OF CHAR);
(*- Accept a file name from the terminal and open it for output.
in: defext default filetype or 'extension'.
If the file name ends in '.', 'defext' is appended.
If OpenOutput succeeds, Done = TRUE and subsequent output is written
to the file until CloseOutput is called.
*)
PROCEDURE CloseInput;
(*- Close current input file and revert to terminal for input.
*)
PROCEDURE CloseOutput;
(*- Close current output file and revert to terminal for output.
*)
PROCEDURE Read(VAR ch: CHAR);
(*- Read the next character from the current input.
out: ch the character read. (EOL for end-of-line.)
Done = TRUE unless the input is at end of file.
*)
PROCEDURE ReadString(VAR s: ARRAY OF CHAR);
(*- Read a string from the current input.
out: s the string that was read, excluding terminator.
Leading blanks are accepted and thrown away, then characters
are read into 's' until a blank or control character is entered.
ReadString truncates the input string if it is too long for 's'.
The terminating character is left in 'termCH'.
If input is from the terminal, BS and DEL are allowed for editing.
*)
PROCEDURE ReadInt(VAR x: INTEGER);
(*- Read an INTEGER representation from the current input.
out: x the value read.
ReadInt is like ReadString, but the string is converted to an
INTEGER value if possible, using the syntax: ["+"|"-"] digit { digit }.
Done = TRUE if some conversion took place.
*)
PROCEDURE ReadCard(VAR x: CARDINAL);
(*- Read an unsigned decimal number from the current input.
out: x the value read.
ReadCard is like ReadInt, but the syntax is: digit { digit }.
*)
PROCEDURE ReadWrd(VAR w: WORD);
(*- Read a WORD value from the current input.
out: w the value read.
Done is TRUE if a WORD was read successfully.
(A WORD cannot be read from the terminal.)
Note that the meaning of WORD is system-dependent.
*)
PROCEDURE Write(ch: CHAR);
(*- Write a character to the current output.
in: ch character to write.
*)
PROCEDURE WriteLn; (*terminate line*)
(*- Write a new-line sequence to the current output.
*)
PROCEDURE WriteString(s: ARRAY OF CHAR);
(*- Write a string to the current output.
in: s string to write.
*)
PROCEDURE WriteInt(x: INTEGER; n: CARDINAL);
(*- Write an integer in right-justified decimal format.
in: x value to be output,
n minimum field width.
The decimal representation of 'x' (including '-' if x is negative)
is output, using at least n characters (but more if needed).
Leading blanks are output if necessary.
*)
PROCEDURE WriteCard(x,n: CARDINAL);
(*- Output a CARDINAL in decimal format.
in: x value to be output,
n minimum field width.
The decimal representation of the value 'x' is output, using
at least n characters (but more if needed). Leading blanks are
output if necessary.
*)
PROCEDURE WriteOct(x,n: CARDINAL);
(*- Output a CARDINAL in octal format.
in: x value to be output,
n minimum field width.
[see WriteCard above]
*)
PROCEDURE WriteHex(x,n: CARDINAL);
(*- Output a CARDINAL in hexadecimal format.
in: x value to be output,
n minimum field width.
Four uppercase hex digits are written, with leading blanks if
n > 4.
*)
PROCEDURE WriteWrd(w: WORD);
(*- Output a WORD
in: w WORD value to be output.
Note that the meaning of WORD is system-dependent, and that
WORDs cannot be written to the terminal.
*)
END InOut.


Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,7 @@
pause * Loading M2.EXE and examples onto current drive from drive B: *
copy b:m2.exe
copy b:examp*.mod
rem ****** BEFORE USING MODULA-2/86 PLEASE MAKE SURE THAT ****************
rem * You have a CONFIG.SYS file, and it includes 'FILES=12'. *
rem **********************************************************************


View File

@ -0,0 +1,11 @@
pause ** Creating Modula-2/86 directories on current drive **
mkdir \m2lod
mkdir \m2lib
mkdir \m2lib\def
mkdir \m2lib\mod
mkdir \m2lib\sym
mkdir \m2lib\lnk
mkdir \m2lib\ref
mkdir \m2lib\map
rem ** Now execute INSTALL2 to load Modula-2 system from diskettes **


View File

@ -0,0 +1,2 @@
copy a:installx.bat
installx

View File

@ -0,0 +1,18 @@
pause * Loading Modula-2/86 system onto current drive from drive A: *
pause Insert 'System' disk in drive A:
copy a:comppara.sym \m2lib\sym
copy a:*.def \m2lib\def
copy a:*.mod \m2lib\mod
pause Insert 'Compiler' disk in drive A:
copy a:*.lod \m2lod
copy a:*.sym \m2lib\sym
pause Insert 'Linker' disk in drive A:
copy a:*.lod \m2lod
copy a:*.lnk \m2lib\lnk
copy a:*.ref \m2lib\ref
rem ****** BEFORE USING MODULA-2/86 PLEASE MAKE SURE THAT ****************
rem * You have a CONFIG.SYS file, and it includes 'FILES=12' *
rem * You have an AUTOEXEC.BAT file, and it sets the search paths, *
rem * as described in the INSTALLATION section of the manual. *
rem **********************************************************************
del installx.bat

View File

@ -0,0 +1,30 @@
DEFINITION MODULE Keyboard;
(*
Default driver for terminal input.
Derived from the Lilith Modula-2 system developed by the
group of Prof. N. Wirth at ETH Zurich, Switzerland.
[Private module of the Modula-2 system]
*)
EXPORT QUALIFIED Read, KeyPressed;
PROCEDURE Read (VAR ch: CHAR);
(*- Read a character from the keyboard.
out: ch
If necessary, Read waits for a character to be entered.
Characters that have been entered are returned immediately,
with no editing or buffering.
- CTRL-C terminates the current program
- ASCII.cr is transformed into System.EOL
*)
PROCEDURE KeyPressed (): BOOLEAN;
(*- Test if a character is available from the keyboard.
*)
END Keyboard.


Binary file not shown.

View File

@ -0,0 +1,114 @@
(*
Copyrigth (C) 1984 Logitech. All Rights Reserved.
Permission is hereby granted to registered users to use or
abstract the following program in the implementation of
customized versions. This permission does not include the
right to redistribute the source code of this program.
*)
(*$T-*)
(*$R-*)
(*************************************************************)
(* *)
(* MODULA-2 / 86 Private Module of Terminal Sub-System *)
(* *)
(* Keyboard: *)
(* Reads the KBD, going through MSDOS *)
(* (direct console IO) *)
(* Version: *)
(* IBM-PC, MSDOS 1.1 / 2.0 *)
(* History: *)
(* Dec 6, 82 First revision *)
(* Feb 2, 84 V1.0 *)
(* Feb 28,84 access to command tail *)
(* Author: *)
(* Willy Steiger *)
(* LOGITECH SA. *)
(* CH-1143 Apples (Switzerland) *)
(* *)
(*************************************************************)
IMPLEMENTATION MODULE Keyboard;
FROM SYSTEM IMPORT DOSCALL, SWI, SETREG, GETREG;
FROM System IMPORT Status, Terminate, EOL, RegAX, RegBX, RegCX;
CONST
CtrlC = 3C;
KBDCR = 15C;
PROCEDURE KeyPressed (): BOOLEAN;
(* Returns TRUE, if a character has been entered,
FALSE otherwise.
*)
VAR result: CARDINAL;
BEGIN
IF ti < tailc THEN
RETURN TRUE
END;
DOSCALL (11, result);
RETURN (result <> 0);
END KeyPressed;
PROCEDURE Read (VAR ch: CHAR);
(* Waits until a character has been entered and returns it.
If Ctrl-C is entered, the program is stopped.
CR is transformed into System.EOL.
*)
VAR ready: BOOLEAN;
BEGIN
IF ti < tailc THEN
ch := tail[ti];
INC(ti)
ELSE
REPEAT
DOSCALL (6, 0FFH, ch, ready);
UNTIL ready;
END;
IF ch = CtrlC THEN Terminate (stopped); END;
IF ch = KBDCR THEN ch := EOL;
(* ASCII-cr is transformed in Modula-2 EOL character *)
END;
END Read;
TYPE PSP = RECORD
stuff: ARRAY [1..128] OF CHAR;
count: CHAR; (* really BYTE or SHORTCARD or whatever *)
text: ARRAY [0..127] OF CHAR
END;
VAR PSPPtr: RECORD
CASE BOOLEAN OF
TRUE: addr: POINTER TO PSP;
| FALSE: offset,base: CARDINAL;
END;
END;
tail: ARRAY [0..127] OF CHAR;
tailc,ti: [0..128];
BEGIN
SETREG(RegAX,0026H); (* RTS(38) - get Program Segment Prefix Pointer *)
SWI(228); (* rts call *)
GETREG(RegBX,PSPPtr.offset);
GETREG(RegCX,PSPPtr.base);
WITH PSPPtr.addr^ DO
tailc := ORD(count);
FOR ti := 0 TO tailc DO
tail[ti] := text[ti]
END; (* FOR *)
END; (* WITH *)
ti := 0;
WHILE (ti < tailc) AND (tail[ti] = ' ') DO
INC(ti) (* skip leading blanks *)
END;
WHILE (ti < tailc) AND (tail[ti] <> ' ') DO
INC(ti) (* skip program name *)
END;
IF (ti < tailc) AND (tail[ti] = ' ') THEN
INC(ti) (* skip one blank *)
END;
END Keyboard.


Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,475 @@
;**********************************************************************
;
; Copyrigth (C) 1984 Logitech. All Rights Reserved.
;
; Permission is hereby granted to registered users to use or
; abstract the following program in the implementation of
; customized versions. This permission does not include the
; right to redistribute the source code of this program.
;
;
; title 'Modula-2/86 Resident Loader'
;
; Author: Hugh McLarty
;
; Version: 0.0 03 August 83
; 8308.06 converted to MSDOS
;
; Introduction:
;
; This module loads Modula-2/86 'LOD' files into memory.
;
code segment public
data segment public
DOS equ 21h
currentVersion equ 1
targetSystem equ 0
NameLength equ 24 ; bytes of module name
KeyLength equ 6 ; bytes of module key
MDescr struc
MDname db NameLength dup (?) ; module name
MDkey db KeyLength dup (?) ; key
MDproc dw ? ; offset of procedure table
MDcode dw ? ; base of code
MDdata dw ? ; base of data
MDprogid dw ? ; 'owner' program id
MDnext dd ? ; forward link
MDprev dd ? ; backward link
MDescr ends
MDSize equ size MDescr
badStructure equ 1
badVersion equ 2
readEOF equ 3
TooBig equ 4 ; not enough memory
badCheck equ 5
; Object Record Tags:
FormatVersion equ 0
ProgramHeader equ 1
SCModHeader equ 2
ImportElement equ 3
FilledData equ 4
ProcedureCode equ 5
SCModInitCode equ 6
ModuleCode equ 7
SCModuleCall equ 8
RefExtData equ 9
RefExtCode equ 10
RefExtProc equ 11
RefOwnData equ 12
RefOwnCode equ 13
RefOwnProc equ 14
SCModuleEnd equ 15
ProgramEnd equ 16
LoadSP dw ? ; sp inside LoadProg
FileHandle dw ?
LdBufSize equ 512
LdBuf db LdBufSize dup (?) ; read buffer
LdCnt dw ? ; bytes left in buffer
LowSum db ? ; low byte of checksum
HiSum db ? ; high byte of checksum
Checksum equ word ptr LowSum
CodeSize dw ? ; code size in paragraphs
DataSize dw ? ; data size in paragraphs
LdProgId dw ? ; id of loading program?
SCMcnt dw ? ; number of SCM's to load
ProgCodeBase dw ? ; base of program code segment
ProgDataBase dw ? ; base of program data segment
ModCodeBase dw ? ; base of module code segment
ModDataBase dw ? ; base of module data segment
StartOff dw ? ; start address of program, ..
StartBase dw ? ; .. offset and segment.
StartPtr equ dword ptr StartOff
MDoff dw ?
MDbase dw ?
MDptr equ dword ptr MDoff
PrevOff dw ?
PrevBase dw ? ; previous module descrip. (init NIL)
PrevPtr equ dword ptr PrevOff
ModCodeSize dw ?
ModDataSize dw ?
LdMCB dw 3 dup (?) ; Memory Control Block
even
data ends
; LoadProg - load from file
; in: AX prog id to use
; BX file handle of already opened file
; CX:DX most recent entry in module 'tree'
;
; out: BX status
; ES:DI start address
; CX:DX last module entry added
;
public LoadProg
extrn Alloc_Mem:NEAR
assume CS:code,DS:data
LoadProg proc near
mov LdProgId,ax ; save prog id for module descriptors
mov LoadSP,sp ; save stack pointer
mov PrevBase,cx ; current 'top' of module table
mov PrevOff,dx
call InitInput ; initialize for reading from FCB
mov Checksum,0 ; reset checksum
call ReadFormatVersion
call ReadProgHdr
call AllocateProgMem ; allocate code, data, module table
call LoadSCM ; load first module
les bx,MDptr ; point to its descriptor
mov bx,ES:MDproc[bx] ; get offset to procedure table
mov ES,StartBase
mov ax,ES:word ptr 2[bx] ; get offset to procedure 0
mov StartOff,ax ; which is offset of start address
dec SCMcnt ; more modules to load?
jz SCMend ; guess not.
SCMloop:
add MDoff,MDSize ; allocate a new module descriptor
call LoadSCM ; load one SCM
dec SCMcnt ; more?
jnz SCMloop ; yes, load them too (why not)
SCMend: call ReadProgEnd ; process ProgramEnd
les di,StartPtr
mov cx,MDbase
mov dx,MDoff ; pointer to last module entry
xor bx,bx ; if no error, return BX=0
LoadFU: mov sp,LoadSP ; reset stack pointer
ret
LoadProg endp
ReadFormatVersion proc near
call GetByte ; record tag
cmp al,FormatVersion
je RFV2
mov bx,badStructure
jmp LoadFU
;
RFV2: call GetByte ; object file format
cmp al,currentVersion
je RFV4 ; right version
mov bx,badVersion
jmp LoadFU
;
RFV4: call GetByte ; read target system
cmp al,targetSystem
je RFV6
mov bx,badVersion
jmp LoadFU
;
RFV6: jmp CheckChecksum
ReadFormatVersion endp
ReadProgHdr proc near
call GetByte
cmp al,ProgramHeader
je RPH2
mov bx,badStructure
jmp LoadFU
;
RPH2: call GetWord
mov CodeSize,ax
call GetWord
mov DataSize,ax
call GetWord
mov SCMcnt,ax
jmp CheckChecksum
ReadProgHdr endp
AllocateProgMem proc near
mov ax,MDSize ; size of a module descriptor
mul SCMcnt ; times number of modules..
add ax,15
mov cl,4
shr ax,cl ; convert to paragraphs
add ax,CodeSize ; add paragraphs of code..
add ax,DataSize ; and paragraphs of data
call Alloc_Mem ; allocate memory, base => AX
test bx,bx ; got it?
jz GotMem ; yes
mov bx,TooBig ; nope.
jmp LoadFU
;
GotMem: mov ProgCodeBase,ax ; start of code segment
mov ModCodeBase,ax ; start of first module
mov StartBase,ax ; save base of start address
add ax,CodeSize
mov ProgDataBase,ax ; start of data segment
mov ModDataBase,ax ; data of first module
add ax,DataSize
mov MDbase,ax ; base of module descriptor table
mov MDoff,0 ; initial offset
ret
AllocateProgMem endp
; LoadSCM - load one module
;
LoadSCM proc near
call ReadSCMHdr
call GetByte ; next field tag..
cmp al,ModuleCode ; ModuleCode record?
je LdSCM2 ; yes
mov bx,badStructure
jmp LoadFU
;
LdSCM2: call RestModCode ; yes, process rest of record
call ReadFixups ; process rest of module (fixups & end)
ret
LoadSCM endp
; ReadSCMhdr - process an SCModHeader record
; out: ModName module name
; ModKey module key
ReadSCMhdr proc near
call GetByte
cmp al,SCModHeader
je RSCMH2
mov bx,badStructure
jmp LoadFU
;
RSCMH2: les di,MDptr
mov ax,ModCodeBase
mov ES:MDcode[di],ax ; code-base for this module
mov ax,ModDataBase
mov ES:MDdata[di],ax ; data base for this module
mov ax,LdProgId
mov ES:MDprogid[di],ax ; owner-program id for this module
;;;;;;;;add di,offset MDname ; DOESN'T WORK!!!
MOV AX, OFFSET MDname
ADD DI, AX
mov ax,NameLength
call GetNBytes ; read module name
les di,MDptr
;;;;;;;;add di,offset MDkey ; DOESN'T WORK
MOV AX, OFFSET MDkey
ADD DI, AX
mov ax,KeyLength
call GetNBytes ; read module key
call GetWord
les di,MDptr
mov ES:MDproc[di],ax ; offset of procedure table
call GetWord
mov ModCodeSize,ax ; bytes of code
call GetWord
mov ModDataSize,ax ; bytes of data
call GetWord ; (internal use by compiler)
jmp CheckChecksum
ReadSCMhdr endp
; RestModCode - read the rest of a ModuleCode record
; (called after the tag has been read)
RestModCode proc near
call GetWord ; length of code (bytes)
mov ES,ModCodeBase ; base
mov di,0 ; offset
call GetNBytes ; read AX bytes at ES:0000
jmp CheckChecksum
RestModCode endp
; ReadFixups - process fixup records until SCModuleEnd record is processed
;
ReadFixups proc near
call GetByte
cmp al,RefOwnCode
jne RFIX2
call GetWord ; offset of fixup (current module)
push ax
call GetWord ; 'bias' (paragraphs from codebase)
add ax,ProgCodeBase ; compute fixup value
pop bx ; fixup offset..
mov ES,ModCodeBase ; fixup base: current module
mov ES:[bx],ax
call CheckChecksum
jmp short ReadFixups
;
RFIX2: cmp al,SCModuleEnd
je RFIX4
mov bx,badStructure
jmp LoadFU
; end of module:
RFIX4: mov ax,ModCodeSize ; adjust base-of-module-code
add ax,15 ; paragraph pointer by size
mov cl,4 ; of module code, rounded up
shr ax,cl ; and converted to paragraphs.
add ModCodeBase,ax
mov ax,ModDataSize
add ax,15
mov cl,4
shr ax,cl
add ModDataBase,ax
call LinkModuleDescriptor
jmp CheckChecksum
ReadFixups endp
LinkModuleDescriptor proc near
les di,PrevPtr
cmp di,0Fh
jne LMD2
mov ax,ES
cmp ax,0FFFFh
je LMD4 ; IF PrevPtr <> NIL THEN..
LMD2: mov ax,MDoff
mov ES:MDnext[di],ax
mov ax,MDbase
mov ES:MDnext+2[di],ax ; PrevPtr^.next := MDptr
LMD4: les di,MDptr ; END
mov ES:MDnext[di],0Fh
mov ES:MDnext+2[di],0FFFFh ; MDptr^.next := NIL
mov ax,PrevOff
mov ES:MDprev[di],ax
mov ax,PrevBase
mov ES:MDprev+2[di],ax ; MDptr^.prev := PrevPtr
mov PrevOff,di
mov PrevBase,ES ; PrevPtr := MDptr
ret
LinkModuleDescriptor endp
ReadProgEnd proc near
call GetByte
cmp al,ProgramEnd
je RPE2
mov bx,badStructure
jmp LoadFU
;
RPE2: jmp CheckChecksum
ReadProgEnd endp
; GetWord - get next word from object record (update checksum)
; out: AX data word
; BX status/error code
; <CC> set for BX
GetWord proc near
call GetByte ; read lo byte
mov ah,al
call GetByte ; read hi byte
xchg ah,al ; shuffle into position
ret
GetWord endp
; GetNBytes - get multiple bytes into memory (with Checksum)
; in: AX byte count (must be > 0!)
; ES:DI where to put the bytes
; out: CX =0
; ES:DI points past last byte read
GetNBytes proc near
mov cx,ax
mov dx,Checksum ; move checksum into reg for speed
NBcont: mov bx,LdCnt ; ditto for bytes-left-in-buffer
cld ; make sure direction flag is forward
xor ah,ah ; extend each byte to cardinal
NBytes: lodsb ; fetch next byte from buffer
sub bx,1
jc NBfill ; refill buffer
add dx,ax ; update checksum
stosb ; place byte into memory
loop NBytes ; and repeat N times
mov LdCnt,bx ; bring memory variables up to date
mov Checksum,dx
ret
;
NBfill: call ReadSeq ; read next buffer sequentially
jmp short NBcont
GetNBytes endp
; GetByte - get next byte from object record (updates checksum)
; out: AL data byte
; BX status/error code
; note: CX, DX, DI, ES preserved
GetByte proc near
call ReadByte ; read one raw
add LowSum,al ; update checksum
adc HiSum,0
ret
GetByte endp
CheckChecksum proc near
call ReadWord ; read record checksum field
cmp ax,Checksum ; checksum checks?
jne Struct ; no
ret
;
Struct: mov bx,badCheck ; no
jmp LoadFU ; short-circuit exit
CheckChecksum endp
ReadWord proc near
call ReadByte ; read low byte
mov ah,al ; save it
call ReadByte ; read high byte
xchg ah,al ; swap into position
ret
ReadWord endp
; ReadByte - get next raw byte from input file
; out: AL next byte
; BX status/error code
; note: AH, CX, DX, DI, ES preserved
;
ReadByte proc near
cld
lodsb ; yes: pull next byte from buffer
sub LdCnt,1 ; anything left in buffer?
jc ReadB2 ; no, refill buffer
ret
;
ReadB2: call ReadSeq
jmp short ReadByte ; try again
ReadByte endp
InitInput proc near
mov FileHandle,bx
InitInput endp ; fall through to read first block
; ReadSeq - read next sequential block into buffer
;
; out: BX status/error code
; SI points to start of buffer
; LdCnt number of bytes read
; note: AX, CX, DX, DI, ES are preserved
ReadSeq proc near
push ax ; just to be polite
push cx
push dx
push di
push ES
push DS
mov bx,FileHandle
mov cx,LdBufSize
mov dx,offset LdBuf
mov ah,3FH
int DOS ; sequential read
pop DS
cmp ax,LdBufSize ; full record?
je RstBuf ; yes
cmp ax,0 ; partial record?
jne RstBuf ; yes
mov bx,readEOF ; no, EOF, which should never happen!
jmp LoadFU
;
RstBuf: mov si,offset LdBuf ; reset buffer scanner
mov LdCnt,LdBufSize ; and buffer count
pop ES
pop di
pop dx
pop cx
pop ax
ret
ReadSeq endp
code ends
end


BIN
Logitech Modula-2 v1/M2.EXE Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,41 @@
DEFINITION MODULE MathLib0;
(*
Real Math Functions
From the book 'Programming in Modula-2' by Prof. N. Wirth.
*)
EXPORT QUALIFIED sqrt, exp, ln, sin, cos, arctan, real, entier;
PROCEDURE sqrt(x: REAL): REAL;
(* x must be positive *)
PROCEDURE exp(x: REAL): REAL;
(* returns e^x where e = 2.71828.. *)
PROCEDURE ln(x: REAL): REAL;
(* returns natural logarithm with base e = 2.71828.. of x *)
(* x must be positive and not zero *)
PROCEDURE sin(x: REAL): REAL;
(* returns sin(x) where x is given in radians *)
PROCEDURE cos(x: REAL): REAL;
(* returns cos(x) where x is given in radians *)
PROCEDURE arctan(x: REAL): REAL;
(* returns arctan(x) in radians *)
PROCEDURE real(x: INTEGER): REAL;
(* type conversion from INTEGER to REAL *)
PROCEDURE entier(x: REAL): INTEGER;
(* returns the integral part of x. *)
(* If this cannot be represented in an INTEGER, *)
(* the result is undefined. *)
END MathLib0.


Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,106 @@
DEFINITION MODULE NumberConversion;
(*
Conversion between numbers and strings
The routines that convert a string to a number:
- skip leading blanks,
- accept always a '+' sign and for integers
also a '-' sign
- skip blanks between sign and number
Done is TRUE if the conversion is successful
The routines that convert a number to a string:
- if the string is too small the number is truncated
- if the number has less digits than width,leading
blanks are added
*)
EXPORT QUALIFIED MaxBase, BASE,
StringToCard, StringToInt, StringToNum,
CardToString, IntToString, NumToString;
CONST MaxBase = 16;
TYPE BASE = [2..MaxBase];
PROCEDURE StringToCard(
str: ARRAY OF CHAR;
VAR num: CARDINAL;
VAR done: BOOLEAN
);
(*- Convert a string to a CARDINAL number.
in: str string to convert
out: num converted number
done TRUE if successful conversion,
FALSE if number out of range,
or contents of string non numeric.
*)
PROCEDURE StringToInt(
str: ARRAY OF CHAR;
VAR num: INTEGER;
VAR done: BOOLEAN
);
(*- Convert a string to an INTEGER number.
in: str string to convert
out: num converted number
done TRUE if successful conversion,
FALSE if number out of range,
or contents of string non numeric.
*)
PROCEDURE StringToNum(
str: ARRAY OF CHAR;
base: BASE;
VAR num: CARDINAL;
VAR done: BOOLEAN
);
(*- Convert a string to a CARDINAL number.
in: str string to convert
base the base of the number represented in the string
out: num converted number
done TRUE if successful conversion,
FALSE or number out of range,
or contents of string not within base.
*)
PROCEDURE CardToString(
num: CARDINAL;
VAR str: ARRAY OF CHAR;
width: CARDINAL
);
(*- Convert a CARDINAL number to a string.
in: num number to convert
out: str returned string representation of the number
in: width width of the returned string
*)
PROCEDURE IntToString(
num: INTEGER;
VAR str: ARRAY OF CHAR;
width: CARDINAL
);
(*- Convert an INTEGER number to a string.
in: num number to convert
out: str returned string representation of the number
in: width width of the returned string
*)
PROCEDURE NumToString(
num: CARDINAL;
base: BASE;
VAR str: ARRAY OF CHAR;
width: CARDINAL
);
(*- Convert a number to the string representation in the specified base.
in: num number to convert
in: base the base of conversion
out: str returned string representation of the number
in: width width of the returned string
*)
END NumberConversion.


Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,52 @@
DEFINITION MODULE Options;
(*
Read a file specification, with options, from the terminal
Derived from the Lilith Modula-2 system developed by the
group of Prof. N. Wirth at ETH Zurich, Switzerland.
*)
EXPORT QUALIFIED NameParts, NamePartSet, Termination,
FileNameAndOptions, GetOption;
TYPE Termination = (norm, empty, can, esc);
NameParts = (NameDrive, NamePath, NameName, NameExt);
NamePartSet = SET OF NameParts;
PROCEDURE FileNameAndOptions(default: ARRAY OF CHAR;
VAR name: ARRAY OF CHAR;
VAR term: Termination;
acceptOption: BOOLEAN;
VAR ReadInName: NamePartSet);
(*- Read file name and options from terminal.
in: default the file specification to use if one is not entered,
acceptOption if TRUE, allow options to be entered,
out: name the file specification,
term how the read ended,
ReadInName which parts of specification are present.
'term' returns the status of the input termination:
norm : normally terminated
empty : normally terminated, but name is empty
can : <can> is typed, input line cancelled
esc : <esc> is typed, no file specified.
Input is terminated by a <cr>, blank, <can>, or <esc>.
<bs> and <del> are allowed while entering the file name.
*)
PROCEDURE GetOption(VAR optStr: ARRAY OF CHAR; VAR length: CARDINAL);
(*- Get another option from the last call to FileNameAndOptions.
out: optStr text of the option,
length length of optStr.
Calls to GetOption return the options from the last call to
FileNameAndOptions, in the order they were entered. When there are
no more options, a length of 0 is returned.
*)
END Options.


Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,338 @@
;******************************************************
;
; Copyrigth (C) 1984 Logitech. All Rights Reserved.
;
; Permission is hereby granted to registered users to use or
; abstract the following program in the implementation of
; customized versions. This permission does not include the
; right to redistribute the source code of this program.
;
;
; Modula-2/86 Run Time Support package
;
; PMD.ASM - Post Mortem Dump module
;
;
include RTS.INC
code segment public
extrn RTS_DS:word ; really belongs here!
extrn GET_CURR_DISK:near
extrn SELECT_DISK:near
extrn DELETE_FILE:near
extrn MAKE_FILE:near
extrn SET_DEFAULT_DMA:near
extrn NORM_ADDR:near
extrn SEQ_WRITE:near
extrn CLOSE_FILE:near
extrn DELETE_FILE:near
extrn WRITE_LN:near
extrn WRITE_MSG:near
data segment public
; Variables for Post Mortem Dump:
DUMP_NAME DB 'MEMORY.PMD',0
NO_DUMP DB 'Post Mortem Dump failed', 0DH,0AH, '$'
PARAG_IN_REC DB 0 ; paragraph counter for PMD
even
DUMP_LOW_START dw ? ; first paragraph of 'low' dump area
DUMP_LOW_END dw ? ; last paragraph of same
DUMP_HIGH_START dw ?
DUMP_HIGH_END dw ?
TEMP_W dd ?
extrn START_MEM:word, MEM_SIZE:word
extrn SAVED_DISK:byte
extrn RTS_DISK:byte
extrn CUR_PROCESS:byte ;:ProcessDescriptor
extrn RTS_PROCESS:byte ;:ProcessDescriptor
extrn CUR_P_PTR:dword
extrn FILE_HANDLE:word
extrn FILE_SPEC:byte
data ends
public P_M_DUMP
assume CS:code, DS:data
P_M_DUMP proc NEAR
;========
; Entry point for Post Mortem Dump
; When arriving here, we assume the relevant
; registers to be saved in the process descriptor.
; Before dumping memory, we are going to
; write the copy of the P.D. back into the
; workspace of the process:
Les di, CUR_P_PTR
Mov si, offset CUR_PROCESS
Mov cx, (size ProcessDescriptor)/2
Rep Movsw
; Now, we create the file on the same disk
; where the resident part was found. Therefore,
; we have first to save the currrent disk:
call GET_CURR_DISK
; set up the filespec:
MOV AL, RTS_DISK
add al,'A'
PUSH DS
POP ES
MOV SI, OFFSET DUMP_NAME
MOV DI, offset FILE_SPEC
mov byte ptr[di],al
inc di
mov byte ptr[di],':'
inc di
MOV CX, 11 ; Drive, Name, Typ and Extent
REP MOVSB
CALL DELETE_FILE ; Delete the old DUMP-file
CALL MAKE_FILE ; and create the new-one
JNB D_FILE_MADE ; yes
JMP AFTER_DUMP ; no, dump fails
D_FILE_MADE:
mov FILE_HANDLE,ax
CALL SET_DEFAULT_DMA
; Fill the header record:
MOV AX, 0 ; First fill with zeroes
MOV DI, DEFAULT_DMA
PUSH DS
POP ES
MOV CX, 64
REP STOSW
; Now put the info required by the debugger:
MOV DI, DEFAULT_DMA
; addr of MAIN process descr:
MOV word ptr [DI], OFFSET RTS_PROCESS
MOV word ptr 2[DI], DS
; addr of descriptor of terminating process:
LES SI, CUR_P_PTR
MOV [DI]+4, SI
MOV [DI]+6, ES
; start and end of interrupt vector table:
MOV WORD PTR [DI]+16, 0
MOV WORD PTR [DI]+18, 3FH
; paragraph address of RESIDENT:
mov ax, RTS_DS
mov DUMP_LOW_START, ax
mov [di]+20, ax
; end of lower memory area:
MOV BX, RTS_PROCESS.PD_HEAP_TOP + 2
MOV AX, RTS_PROCESS.PD_HEAP_TOP
CALL NORM_ADDR
INC BX ; next paragraph
MOV DUMP_LOW_END, BX ; just save it
MOV [DI]+22, BX ; top of main heap (parag)
; start of higher memory area:
MOV BX, RTS_PROCESS.PD_SS
MOV AX, RTS_PROCESS.PD_SP
CALL NORM_ADDR
MOV DUMP_HIGH_START, BX ; just save it
MOV [DI]+24, BX ; top of main stack (parag)
; last paragraph of memory:
mov bx, START_MEM
dec bx
add bx, MEM_SIZE
MOV DUMP_HIGH_END, BX ; just save it
MOV [DI]+26, BX
; Send the first record to the file:
CALL SEQ_WRITE
CMP AL, 80H
JNE DUMP_BAD
; Now dump the memory:
; We dump 3 memory areas: the interrupt vectors (0..3FFH), the 'low'
; memory from start of RESIDENT to heaptop of main and the 'high'
; memory starting at stacktop of main to end of memory.
; These 3 areas are dumped paragraph-wise.
MOV PARAG_IN_REC, 0 ; counter = 0
MOV CX, 0 ; start of first area
MOV BX, 03FH ; end of first area
CALL DUMP_PART
CMP AL, 0
JNE DUMP_BAD ; there was an error
MOV CX, DUMP_LOW_START ; start of second area
MOV BX, DUMP_LOW_END ; end of second area
CALL DUMP_PART
CMP AL, 0
JNE DUMP_BAD ; there was an error
MOV CX, DUMP_HIGH_START ; start of third area
MOV BX, DUMP_HIGH_END ; end of third area
CALL DUMP_PART
CMP AL, 0
JNE DUMP_BAD ; there was an error
CMP PARAG_IN_REC, 0
JE CLOSE_DUMP
CALL SET_DEFAULT_DMA ; We have to write the buffer
CALL SEQ_WRITE
CMP AL, 80H
JNE DUMP_BAD
CLOSE_DUMP:
MOV AX, 0 ; to indicate 'no error'
DUMP_BAD:
PUSH AX
; Close the file:
CALL CLOSE_FILE
POP AX
AFTER_DUMP:
; Dump is made. AX contains 0 for successfull
; dump and > 0 if an error occured:
CMP AX, 0
JE DUMP_OK
CALL WRITE_LN
MOV DX, OFFSET NO_DUMP
CALL WRITE_MSG
CALL DELETE_FILE
DUMP_OK:
; Restore the disk of before the dump:
MOV DL, SAVED_DISK
CALL SELECT_DISK
RET
P_M_DUMP endp
DUMP_PARTIAL_REC proc NEAR
; The variable 'PARAG_IN_REC' gives the number of paragraphs that
; are already in the record at CPM_DMA. It is updated here.
; AX holds the number of paragraphs to dump at entry and the
; remaining-ones at exit.
; CX is paragraph address of memory to dump and is updated here.
; When the record can be filled completely, it is written to the
; file (DEFAULT_FCB). BL returns 0 if no error, 0FFH otherwise.
CMP AX, 8
JB DO_PARTIAL_DUMP
JZ GOOD_PARTIAL_DUMP
; nothing to dump
CMP PARAG_IN_REC, 0
JZ GOOD_PARTIAL_DUMP
; This means: nothing in the
; buffer and more than 8
; paragraphs to dump.
DO_PARTIAL_DUMP:
; There are some paragraphs to copy:
MOV BX, 8
SUB BL, PARAG_IN_REC
; BX= number of par. to copy
CMP AX, BX
JAE ENOUGH_TO_FILL
MOV BX, AX
MOV AX, 0
JMP SHORT PARTIAL_DUMP
ENOUGH_TO_FILL:
SUB AX, BX
PARTIAL_DUMP:
; AX = remaining paragraphs to dump later.
; BX = number of paragraphs to copy in buffer.
; CX = paragraph addr of area to copy (offset=0).
MOV TEMP_W, AX
MOV TEMP_W+2, BX
MOV ES, RTS_DS
MOV DI, DEFAULT_DMA ; offset of buffer
MOV AL, PARAG_IN_REC
MOV AH, 0
MOV DS, CX
MOV CL, 4
SHL AX, CL ; offset inside buffer
ADD DI, AX ; (ES,DI) = dest addr
MOV SI, 0 ; source offset
MOV CX, 4
SHL BL, CL
MOV CL, BL
; number of bytes to copy
REP MOVSB
; Now, the paragraphs to copy are in the
; buffer, update counters and pointers:
MOV CX, DS
MOV DS, RTS_DS
MOV AX, TEMP_W+2 ; number of copied paragraphs
ADD PARAG_IN_REC, AL
ADD AX, CX
MOV TEMP_W+2, AX
MOV CX, AX
MOV AX, TEMP_W
CMP PARAG_IN_REC, 8
JB GOOD_PARTIAL_DUMP
; The buffer is full, we write it on the file:
CALL SET_DEFAULT_DMA
CALL SEQ_WRITE
CMP AL, 80H
JNE BAD_PARTIAL_DUMP
MOV AX, TEMP_W
MOV CX, TEMP_W+2
MOV PARAG_IN_REC, 0
GOOD_PARTIAL_DUMP:
MOV BL, 0
RET
BAD_PARTIAL_DUMP:
MOV BL, 0FFH
RET
DUMP_PARTIAL_REC endp
DUMP_PART proc NEAR
; Dumps a part of the memory to an open
; disk file, using the DEFAULT_FCB.
; Upon entry:
; CX holds addr of first paragraph to
; dump, BX is addr of last paragraph
; to dump (BX=CX means 1 par. to dump).
; Upon exit:
; AL=0 if no error occured while writing,
; AL=1 otherwise.
MOV AX, BX
INC AX
SUB AX, CX
JA DUMP_SIZE_OK
RET
; endaddr < startaddr
DUMP_SIZE_OK:
CALL DUMP_PARTIAL_REC
; needed to fill partially filled
; buffer, as remainder from dumping
; the previous area.
CMP BL, 0
JZ DUMP_NEXT_REC
MOV AL, 0FFH
RET
DUMP_NEXT_REC:
;;;;;; start of LOOP ;;;;;;;
; AX holds number of paragraphs to dump
; CX holds first paragr-addr
CMP AX, 8
JB DUMP_LAST_REC
MOV TEMP_W, AX
MOV TEMP_W+2, CX
push DS
mov DS,cx
mov dx,0
mov ah, 01Ah
int OS ; Set disk transfer address (DS:DX)
pop DS
CALL SEQ_WRITE ; Write next record
CMP AL, 80H
JE DUMP_REC_OK
RET
;
DUMP_REC_OK:
MOV AX, TEMP_W ; The next record is written,
SUB AX, 8 ; update counter and address.
MOV CX, TEMP_W+2
ADD CX, 8
JMP SHORT DUMP_NEXT_REC
;;;;; End of LOOP ;;;;;;;
DUMP_LAST_REC:
CALL DUMP_PARTIAL_REC ; copy the remaining paragraphs
; in the buffer.
MOV AL, BL ; error flag
RET
DUMP_PART endp
code ends
end


View File

@ -0,0 +1,66 @@
DEFINITION MODULE Processes;
(*
(pseudo-) concurrent programming with SEND/WAIT
From the book 'Programming in Modula-2' by Prof. N. Wirth.
*)
EXPORT QUALIFIED SIGNAL, SEND, WAIT,
StartProcess, Awaited, Init;
TYPE SIGNAL;
(* SIGNAL's are the means of synchronization between processes. *)
PROCEDURE StartProcess (P: PROC; n: CARDINAL);
(*- Start up a new process.
in: P top-level procedure that will execute in this process.
n number of bytes of workspace to be allocated to it.
Allocates (from Storage) a workspace of n bytes, and creates a process
executing procedure P in that workspace. Control is given to the new process.
Caution: The caller must ensure that the workspace size is sufficient for P.
Errors: StartProcess may fail due to insufficient memory.
*)
PROCEDURE SEND (VAR s: SIGNAL);
(*- Send a signal
in: s the signal to be sent. [Must have been Init'd]
out: s the signal with one less process waiting for it.
If no process is waiting for s, SEND has precisely no effect. Otherwise,
some process which is waiting for s is given control and allowed to
continue from WAIT.
*)
PROCEDURE WAIT (VAR s: SIGNAL);
(*- Wait for some other process to send a signal.
in: s the signal to wait for. [Must have been Init'd]
The current process waits for the signal s. At some later time, a
SEND(s) by some other process can cause this process to return from WAIT.
Errors: If all other processes are waiting, WAIT terminates the program.
*)
PROCEDURE Awaited (s:SIGNAL): BOOLEAN;
(*- Test whether any process is waiting for a signal.
in: s the signal of interest. [Must have been Init'd]
out: TRUE if and only if at least one process is waiting for s.
*)
PROCEDURE Init (VAR s: SIGNAL);
(*- Initialize a SIGNAL object.
in: s the signal to be initialized
out: s the initialized signal (ready to be used as above)
An object of type SIGNAL must be initialized with this procedure before
it can be used with any of the other operations. After Init(S), Awaited(S)
is FALSE.
*)
END Processes.


Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,20 @@
DEFINITION MODULE ProgMessage;
(*
Write program status message to the terminal
*)
FROM System IMPORT Status;
EXPORT QUALIFIED WriteStatus;
PROCEDURE WriteStatus (st: Status);
(*- Write a short description of a program status on the terminal.
in: st a Status, as returned by Program.Call
The message may be up to 32 characters long.
*)
END ProgMessage.


Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More