DeSmet C88 v2.4

This commit is contained in:
davidly 2024-06-30 14:24:37 -07:00
parent 15a91f0338
commit 665e4e64a5
51 changed files with 3138 additions and 0 deletions

BIN
DeSmet C88 v24/ASM88.EXE Normal file

Binary file not shown.

BIN
DeSmet C88 v24/BIND.EXE Normal file

Binary file not shown.

159
DeSmet C88 v24/BUF128.A Normal file
View File

@ -0,0 +1,159 @@
;
; buf128: a 128 character type-ahead buffer for the IBM-PC
;
; This program works by intercepting the calls to the BIOS
; interrupt routines at 9 for the keystroke interrupts and
; 16H for the program requests
; Everything is kept in CS.
;
; Caution: buf128 must be linked with the -A option, e.g.
; BIND B:BUF128 -A
cseg
public main_,key_int,request,buffer,head,tail
KEYINT: equ 24H ; int 9 vector offset
REQINT: equ 58H ; int 16H vector offset
B_HEAD: equ 1AH ; offset to BUFFER_HEAD
B_TAIL: equ 1CH ; offset to BUFFER_TAIL
KB_FLAG: equ 17H ; offset to KB_FLAG
main_: jmp init_code
;
buffer: dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
head: dw buffer
tail: dw buffer
;
; the keystroke interrupt routine. Interrcept the key interrupt, run
; it through the standard key input routine, and remove it from the buffer.
;
key_int:
cli
pushf ; simulate an interrupt
;
; long call to F000:E987
;
db 9AH
dw 0E987H
dw 0F000H
;
push bx
push es
mov bx,40H ; BIOS data segment
mov es,bx
mov bx, es:[B_HEAD] ; pointer to datum
cmp bx, es:[B_TAIL] ; test for character
je k_esbx
mov es:[B_TAIL], bx ; clear the buffer
mov bx, es:[bx]
push si
mov si, cs:tail
push si ; save tail value
add si,2 ; test for full
cmp si, offset buffer+256
jb k_over1
mov si, offset buffer
k_over1:
cmp si, cs:head
pop si
je k_siesbx ; jump if buffer full
mov cs:[si], bx ; store the character
add si,2
cmp si, offset buffer+256
jb k_over2
mov si, offset buffer
k_over2:
mov cs:tail, si
k_siesbx:
pop si
k_esbx:
pop es ; no character, return
pop bx
iret
;
; The request interrupt routine.
;
; simulate the BIOS routine
; ah = 0 read next char
; ah = 1 set Z flag on character status, ZF=1 if no char
; ZF=0 and AX = char if char ready
; ah = 2 shift status
request:
sti
or ah,ah
jz do_read
dec ah
jz do_stat
dec ah
jz do_shift
iret
do_read: ; return the next character
sti
nop
cli
mov ax,cs:head
cmp ax,cs:tail
je do_read ; loop until a character
push bx
mov bx,ax
mov ax, cs:[bx] ; ax gets the character
add bx,2
cmp bx, offset buffer+256
jb r_over
mov bx, offset buffer
r_over:
cmp bx, cs:tail
mov cs:head, bx ; new head
pop bx
iret
do_stat: ; return key status
cli
push bx
mov bx,cs:head
cmp bx,cs:tail
mov ax,cs:[bx]
pop bx
sti
lret 2 ; throw out the flags
do_shift:
push es
mov ax,40H ; BIOS data segment
mov es,ax
mov al, es:[KB_FLAG]
pop es
iret
init_code: cli ; turn off interrupts for now
mov ax,0
mov es,ax ; segment base for vectors
mov es:[KEYINT], offset key_int
mov es:[KEYINT+2], cs
mov es:[REQINT], offset request
mov es:[REQINT+2], cs
mov cs:head, offset buffer
mov cs:tail, offset buffer
sti
mov ds:byte[1], 27H ; change PCB terminate to resident
push ds
mov dx,0
push dx
mov dx, offset init_code+100H
lret ; long return to the int 27H
end


BIN
DeSmet C88 v24/BUF128.EXE Normal file

Binary file not shown.

BIN
DeSmet C88 v24/BUGS!.EXE Normal file

Binary file not shown.

BIN
DeSmet C88 v24/C88.EXE Normal file

Binary file not shown.

231
DeSmet C88 v24/CB.C Normal file
View File

@ -0,0 +1,231 @@
/* CBCHECK.C -- Dumb Curley Brace Checker for C Programs
Usage: A>cbcheck program
This program really checks indentation. It ignores
#include and #define and has a lot of other
limitations. If it does not work for your style
of programs, change it. */
#define TAB 9
#define LF 10
#define CR 13
#define CONTZ 26
char *nextin,*line_start,lastch,switch_level;
int indentat[10],line,numcb;
main(argc,argv)
int argc;
char *argv[]; {
int ch;
char col;
if (argc < 2) error("no file name","");
read_file(argv[1]);
while (1) {
line_start=nextin;
line++;
col=countcol();
if (index("{}/#\r\n",*nextin) == 0 && (lastch == '{' || lastch == ';')
&& col != indentat[numcb] && switch_level == 0) {
if (indentat[numcb]) lerror("questionable indent");
indentat[numcb]=col;
}
if (skipl() == -1) break;
}
printf("%d lines",line);
}
/* READ_FILE -- open the input file and read. */
read_file(fil)
char *fil; {
int i,filenum;
unsigned max,numin;
char filename[65];
/* get the file name. default is .C */
strcpy(filename,fil);
i=0;
while (filename[i] && filename[i] != '.') i++;
if (filename[i] == 0) strcat(filename,".C");
/* open the filename */
if ((filenum=open(filename,0)) == -1) error("cannot open",filename);
/* read file in */
nextin=_memory(); /* first free memory */
max=_showsp()-nextin-1000; /* size of memory */
if ((numin=read(filenum,nextin,max)) == -1)
error("cannot read",filename);
if (numin == max) error("file too big","");
nextin[numin]=CONTZ; /* plant a control Z for EOF */
close(filenum);
}
/* COUNTCOL -- count indentation */
countcol() {
int col;
col=0;
while (*nextin == ' ' || *nextin == TAB) {
if (*nextin == ' ') col++; else col+=4;
nextin++;
}
return col;
}
/* SKIPL -- skip the rest of the line. take care of comments etc. */
skipl() {
lastch=0;
while (*nextin != LF) {
if (*nextin != CR) lastch=*nextin;
switch (*nextin++) {
/* control Z means EOF */
case CONTZ: return -1;
/* " means string */
case '"': while (*nextin != '"') {
if (*nextin == '\\') {
nextin++;
if (*nextin == CR) {
nextin++;
line++;
}
}
if (*nextin == LF || *nextin == CONTZ) {
lerror("missing \"");
nextin--;
break;
}
nextin++;
}
nextin++;
break;
/* ' means character constant */
case '\'': skip_char();
break;
/* / may mean comment */
case '/': if (*nextin == '*') {
while (*++nextin != '*' || *++nextin != '/') {
if (*nextin == LF) line++;
if (*nextin == '/' && *(nextin+1) == '*')
lerror("comments may be nested");
if (*nextin == CONTZ) {
lerror("missing */");
nextin--;
break;
}
}
nextin++;
}
break;
/* a switch statement adds extra indentation */
case 's': if ((*(nextin-2) == ' ' || *(nextin-2) == TAB)
&& *nextin == 'w' && *++nextin == 'i' &&
*++nextin == 't' && *++nextin == 'c' &&
*++nextin == 'h' && (*++nextin == '(' ||
*nextin == ' ')) {
if (switch_level == 0) switch_level=numcb;
}
break;
/* { adds to curley brace count */
case '{': numcb++;
break;
/* } subtracts form curley brace count */
case '}': if (numcb) {
numcb--;
if (switch_level == numcb) switch_level=0;
}
else lerror("too many '}'s");
break;
}
}
nextin++;
return *nextin == CONTZ ? -1: 1;
}
/* SKIP_CHAR -- skip a character constant. */
skip_char() {
while (*nextin != '\'') {
if (*nextin == '\\') nextin++;
if (*nextin == LF || *nextin == CONTZ) {
lerror("missing '");
return;
}
nextin++;
}
nextin++;
}
/* LERROR -- print an line error */
lerror(str)
char *str; {
char *ptr,col;
printf("%5d ",line);
col=0;
do {
if (*line_start != TAB) {
putchar(*line_start);
col++;
}
else do {
putchar(' ');
}
while (++col % 4);
}
while (*line_start != CONTZ && *line_start++ != LF);
puts("error: ");
puts(str);
puts("\n");
}
/* ERROR -- print an error and bail out */
error(stra,strb)
char *stra,*strb; {
puts("error: ");
puts(stra);
puts(" ");
puts(strb);
exit(2);
}

BIN
DeSmet C88 v24/CLIST.EXE Normal file

Binary file not shown.

BIN
DeSmet C88 v24/COMPARE.EXE Normal file

Binary file not shown.

BIN
DeSmet C88 v24/COMPARE.O Normal file

Binary file not shown.

677
DeSmet C88 v24/CONFIG.C Normal file
View File

@ -0,0 +1,677 @@
/* CONFIG.C -- Configuration file for SEE editor. */
/* This routine must be modified to match your terminal. If you have a
supported terminal, you need only set the appropriate define to 1
and the others to 0. The supported terminals are: */
#define ANSI 1 /* DEC Rainbow 100. OK for other ANSI terminals also. */
#define H1500 0 /* Hazeltine 1500. */
#define VT52 0 /* DEC VT-52 compatable. */
#define Z100 0 /* Zenith Z-100 by Daniel Herteg, Jr. */
/*
After modifying this routine, it must be compiled and linked to form
a new SEE and D88. Assuming that the C compiler is on drive A: and
that CONFIG.C and the other header and object files are on drive B:,
the commands required are:
A>c88 b:config
A>bind b:see b:config
A>bind b:d88 b:d88rest b:config
or, if under CP/M
A>bind b:cpmd88 b:d88rest b:config -s1000 -h -od88
B:SEE.EXE/CMD is the new version of SEE.
B:D88.EXE/CMD is the new version of D88.
A CP/M bind of SEE will report _PCB_ unresolved. This is OK.
The bind of D88 will report the three externals FLIPINIT_, SCR_SAVE_
and SCR_REST_ as unresolved. This is OK, but the screen flipping feature
of D88 will be dissabled. If you can read your screen and want the
screen flip feature, modify FLIP.A for your terminal and add b:flip
to the bind list for D88.
If your system is rom compatable with the IBM PC (Sanyo etc.),
assemble pcio.a instead of modifying config.c. Pcio.a is on disk 2.
A>asm88 b:pcio
Use pcio in the bind list instead of config.
The source compare program cannot be configured with config.c as
it needs the partial scroll routines found in pcio.a. If you cannot
use pcio.a, the following routines must be added to config.c to configure
compare.
SCR_SCRUP_ Scroll the screen up. The window is scrolled up nline lines.
A zero nline will clear the window. Top left of the screen in 0,0.
Usage: scr_scrup(nline,fromrow,fromcol,torow,tocol);
SCR_SCRDN_ scroll the screen down. the window is scrolled down nline lines.
A zero nline will clear the window. Top left of the screen in 0,0.
Usage: scr_scrdn(nline,fromrow,fromcol,torow,tocol);
note that ci() and co() are used instead of getchar() and putchar().
the former will not cancel if the user inadvertantly hits control c. */
/* control key translations. these are the codes that D88 and SEE expect. */
#define up_char 30
#define down_char 31
#define left_char 29
#define right_char 28
#define bol_char 200
#define eol_char 201
#define pageup_char 202
#define pagedown_char 203
#define bof_char 204
#define eof_char 205
#define Ins_char 206
#define Del_char 207
#define NextWord_char 208
#define PrevWord_char 209
/* Macro Keys */
#define F1 210
#define F2 211
#define F3 212
#define F4 213
#define F5 214
#define F6 215
#define F7 216
#define F8 217
#define F9 218
#define F10 219
#define RUBOUT 0x7f
#define BS 8
#define ESC 0x1B
#define FALSE 0
int scr_cols=80; /* number of screen columns */
int scr_rows=24; /* number of screen rows */
char scr_scrolldown=FALSE; /* FALSE if screen can be scrolled up. If true
scr_scdn() will not be called. */
char scr_scrollup=FALSE; /* TRUE if up scrolling (scr_scup()) causes the
top lines to be overwritten by the next lines.
This is only false for terminals that
support partial scrolling, i.e. have
delete line functions. */
char scr_window_top=2; /* Top line of scroll window. Must default to 2
for SEE. */
char scr_attr=7; /* default screen attributes. */
char see_mode; /* true if in Insert or eXchange mode */
/* A N S I */
#if ANSI
/* ANSI Configuration for SEE editor.
This is the ANSI version of the configuration file for SEE. It was
written for the DEC Rainbow and may have to be changed for other
terminals claiming ANSI compatability. The keys used are:
<arrow> move the cursor.
Do used as terminator instead of ESCAPE.
PF1 jump to start of line.
PF2 jump to end of line.
PF3 jump to start of file.
PF4 jump to end of file.
Insert Enter insert mode (like I) or flip between
insert and exchange mode.
Remove delete character under the cursor.
<= delete previuos character.
*/
/* hidig and lowdig are used to convert binary 0 to 79 to ascii 1 to 80 */
char hidig[]={
0,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,2,
2,2,2,2,2,2,2,2,2,3,
3,3,3,3,3,3,3,3,3,4,
4,4,4,4,4,4,4,4,4,5,
5,5,5,5,5,5,5,5,5,6,
6,6,6,6,6,6,6,6,6,7,
7,7,7,7,7,7,7,7,7,8};
char lowdig[]={
1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0};
#define SCR_ROWCOL "\\e[%c%c;%c%cH", hidig[row]+'0', lowdig[row]+'0', hidig[col]+'0', lowdig[col]+'0'
#define SCR_CLR "\\e[2J"
#define SCR_CLRL "\\e[K"
#define SCR_CLS "\\e[J"
#define SCR_SCUP "\\e[M"
#define SCR_SCDN "\\e[L"
/* SCR_CI -- Input a character and translate function keys. */
scr_ci() {
char chr;
int i;
if ((chr=ci()) == ESC) { /* ESCAPE starts special keys */
/* ESC O starts the PF keys */
if ((chr=ci()) == 'O') {
switch (chr=ci()) {
case 'P': chr=bol_char; /* PF1 key */
break;
case 'Q': chr=eol_char; /* PF2 key */
break;
case 'R': chr=bof_char; /* PF3 key */
break;
case 'S': chr=eof_char; /* PF4 key */
}
return chr;
}
if (chr == '[') {
switch (chr=ci()) {
case 'A': chr=up_char;
break;
case 'B': chr=down_char;
break;
case 'C': chr=right_char;
break;
case 'D': chr=left_char;
break;
case '2': if ((chr=ci()) == '9') {
chr=ESC; /* use Do for ESC */
ci(); /* eat the tilde */
}
else chr=Ins_char;
break;
case '3': chr=Del_char;
ci();
break;
case '5': chr=pageup_char;
ci();
break;
case '6': chr=pagedown_char;
ci();
}
}
}
else if (chr == RUBOUT) chr=BS; /* make rubout into a BS */
return chr;
}
#endif
/* H A Z E L T I N E 1 5 0 0 */
#if H1500
/* H1500 Configuration for SEE editor. */
#define SCR_ROWCOL "\176\21%c%c", col, row
#define SCR_CLR "\176\34"
#define SCR_CLRL "\176\17"
#define SCR_CLS "\176\30"
#define SCR_SCUP "\176\23"
#define SCR_SCDN "\176\32"
/* The Hazeltine 1500 has neither cursor movement keys nor function keys.
Consequently, control keys must be used. The choice of key for a
particular function is a matter of preference. */
/* keyxlat defines the key codes that can be used at any time. */
struct {char inkey,means; } keyxlat[]={
{15,up_char}, /* control O means up */
{16,down_char}, /* control P means down */
{11,left_char}, /* control K means left */
{12,right_char}, /* control L means right */
{26,bol_char}, /* control Z means go to beginning of line */
{24,eol_char}, /* control X means go to end of line */
{17,pageup_char}, /* control Q means page up */
{1,pagedown_char}, /* control A means page down */
{23,bof_char}, /* control W means go to top of file */
{19,eof_char}, /* control S means go to end of file */
/* no insert char as I will enter insert */
{4,Del_char}, /* control D for delete a char */
{0,0}}; /* no next or previous word */
/* cmdxlat defines alternate command codes that can be used when SEE
is not in insert or exchange mode. */
struct {char inkey,means; } cmdxlat[]={
{'@',up_char}, /* @ means up */
{';',down_char}, /* ; means down */
{',',left_char}, /* , means left */
{'.',right_char}, /* . means right */
{':',bol_char}, /* : means go to beginning of line */
{']',eol_char}, /* ] means go to end of line */
{'[',pageup_char}, /* [ means page up */
{'_',pagedown_char},/* _ means page down */
{0,0}};
extern char see_mode; /* true is in insert or exchange mode */
/* SCR_CI -- Input a character and translate function keys. */
scr_ci() {
char chr;
int i;
chr=ci(); /* get next character */
for (i=0; keyxlat[i].inkey; i++)
if (chr == keyxlat[i].inkey) {
chr=keyxlat[i].means;
break;
}
if (!see_mode) { /* if not in exchange or insert mode, accept alternate
command codes. */
for (i=0; cmdxlat[i].inkey; i++)
if (chr == cmdxlat[i].inkey) {
chr=cmdxlat[i].means;
break;
}
}
return chr;
}
#endif
/* V T 5 2 */
#if VT52
/* VT52 Configuration for SEE editor.
This is the CP/M-86 VT52 version of the configuration file for SEE.
The input control characters are:
^E = up
^X = down
^S = left
^D = right
^Q = go to beginning of line
^Z = go to end of line
^R = page up
^C = page down
^T = go to top of file
^B = go to end of file
^V = Insert/Xchg Toggle
^G = delete a char
^A = prev word
^F = next word
The alternate command codes that can be used when SEE is not in
insert or exchange mode are:
@ = up
; = down
, = left
. = right
: = go to beginning of line
] = go to end of line
[ = page up
_ = page down
*/
#define SCR_ROWCOL "\\eY%c%c", row + 0x20, col + 0x20
#define SCR_CLR "\\eE"
#define SCR_CLRL "\\eK"
#define SCR_CLS "\\eJ"
#define SCR_SCUP "\\eM"
#define SCR_SCDN "\\eL"
struct {char inkey,means; } keyxlat[]={
{05,up_char}, /* ^E = up */
{24,down_char}, /* ^X = down */
{19,left_char}, /* ^S = left */
{04,right_char}, /* ^D = right */
{17,bol_char}, /* ^Q = go to beginning of line */
{26,eol_char}, /* ^Z = go to end of line */
{18,pageup_char}, /* ^R = page up */
{03,pagedown_char}, /* ^C = page down */
{20,bof_char}, /* ^T = go to top of file */
{02,eof_char}, /* ^B = go to end of file */
{22,Ins_char}, /* ^V = Insert/Xchg Toggle */
{07,Del_char}, /* ^G = delete a char */
{01,NextWord_char}, /* ^A = prev word */
{06,PrevWord_char}, /* ^F = next word */
{0,0}};
/* cmdxlat defines alternate command codes that can be used when SEE
is not in insert or exchange mode. */
struct {char inkey,means; } cmdxlat[]={
{'@',up_char}, /* @ = up */
{';',down_char}, /* ; = down */
{',',left_char}, /* , = left */
{'.',right_char}, /* . = right */
{':',bol_char}, /* : = go to beginning of line */
{']',eol_char}, /* ] = go to end of line */
{'[',pageup_char}, /* [ = page up */
{'_',pagedown_char},/* _ = page down */
{0,0}};
/* SCR_CI -- Input a character and translate function keys. */
scr_ci() {
char chr;
int i;
chr=ci(); /* get next character */
for (i=0; keyxlat[i].inkey; i++)
if (chr == keyxlat[i].inkey) {
chr=keyxlat[i].means;
break;
}
if (!see_mode) { /* if not in exchange or insert mode, accept alternate
command codes. */
for (i=0; cmdxlat[i].inkey; i++)
if (chr == cmdxlat[i].inkey) {
chr=cmdxlat[i].means;
break;
}
}
return chr;
}
#endif
/* --------------------- ZENITH Z-100 ------------------------- */
#if Z100
/* Z100 Configuration for SEE editor.
The input control characters are:
Keypad 8 = up
Keypad 2 = down
Keypad 4 = left
Keypad 6 = right
Keypad 7 = go to beginning of line
Keypad 1 = go to end of line
Keypad 9 = page up
Keypad 6 = page down
Shift Keypad 7 = go to top of file
Shift Keypad 1 = go to end of file
Keypad 0 = Insert/Xchg Toggle
Keypad . = delete a char
Shift Keypad 4 = prev word
Shift Keypad 6 = next word
Up Arrow = up
Down Arrow = down
Left Arrow = left
Right Arrow = right
DELETE Key = delete a char
I CHR Key = Insert/Xchg Toggle
HOME Key = go to beginning of line
ENTER Key = ESCAPE
F1 - F10 = Macro Keys
NOTE: No alternate command codes are used.
*/
#define SCR_CLR "\\eE"
#define SCR_CLRL "\\eK"
#define SCR_CLS "\\eJ"
#define SCR_CURSOFF "\\ex5"
#define SCR_CURSON "\\ey5"
#define SCR_ROWCOL "\\eY%c%c", row + 0x20, col + 0x20
#define SCR_SCDN "\\eL"
#define SCR_SCUP "\\eM"
#define SCR_SETUP1 "\\ey?"
#define SCR_SETUP2 "\\ey@"
#define SCR_SETUP3 "\\ey1"
struct {char inkey,means; } keyxlat[]={
{0xB8,up_char}, /* Keypad 8 = up */
{0xB2,down_char}, /* Keypad 2 = down */
{0xB4,left_char}, /* Keypad 4 = left */
{0xB6,right_char}, /* Keypad 6 = right */
{0xB7,bol_char}, /* Keypad 7 = go to beginning of line */
{0xB1,eol_char}, /* Keypad 1 = go to end of line */
{0xB9,pageup_char}, /* Keypad 9 = page up */
{0xB3,pagedown_char}, /* Keypad 3 = page down */
{0xF7,bof_char}, /* Shift Keypad 7 = go to top of file */
{0xF1,eof_char}, /* Shift Keypad 1 = go to end of file */
{0xB0,Ins_char}, /* Keypad 0 = Insert/Xchg Toggle */
{0xAE,Del_char}, /* Keypad . = delete a char */
{0xF6,NextWord_char}, /* Shift Keypad 6 = next word */
{0xF4,PrevWord_char}, /* Shift Keypad 4 = prev word */
{0xA5,up_char}, /* Up Arrow = up */
{0xA6,down_char}, /* Down Arrow = down */
{0xA8,left_char}, /* Left Arrow = left */
{0xA7,right_char}, /* Right Arrow = right */
{0xA3,Ins_char}, /* I CHR Key = Insert/Xchg Toggle */
{0x7F,Del_char}, /* DELETE Key = delete a char */
{0x8D,ESC}, /* ENTER Key = ESCAPE */
{0xA9,bol_char}, /* HOME Key = go to beginning of line */
{0x97,F1}, /* F1 = Macro # 1 */
{0x98,F2}, /* F2 = Macro # 2 */
{0x99,F3}, /* F3 = Macro # 3 */
{0x9A,F4}, /* F4 = Macro # 4 */
{0x9B,F5}, /* F5 = Macro # 5 */
{0x9C,F6}, /* F6 = Macro # 6 */
{0x9D,F7}, /* F7 = Macro # 7 */
{0x9E,F8}, /* F8 = Macro # 8 */
{0x9F,F9}, /* F9 = Macro # 9 */
{0xA0,F10}, /* F10 = Macro # 10 */
{0,0}};
/* SCR_CI -- Input a character and translate function keys. */
scr_ci()
{
char chr;
int i;
chr=ci(); /* get next character */
for (i=0; keyxlat[i].inkey; i++)
if (chr == keyxlat[i].inkey)
chr = keyxlat[i].means;
return chr;
}
/* SCR_CURSOFF -- Turn Cursor Off */
scr_cursoff() {
scr_putf(SCR_CURSOFF);
}
/* SCR_CURSON -- Turn Cursor On */
scr_curson() {
scr_putf(SCR_CURSON);
}
#endif
/*SCR_ROWCOL -- Move cursor to selected position. The top left corner of
the screen is (0,0) */
scr_rowcol(row,col)
char row,col; {
scr_putf(SCR_ROWCOL);
}
/* SCR_CLR -- Clear screen. */
scr_clr() {
scr_putf(SCR_CLR);
}
/* SCR_CLRL -- Clear rest of line. */
scr_clrl() {
scr_putf(SCR_CLRL);
}
/* SCR_CLS -- Clear rest of screen. */
scr_cls() {
scr_putf(SCR_CLS);
}
/* SCR_SCUP -- Scroll the screen up.
if scr_scrollup is true, the top two lines of the
screen must be preserved. */
scr_scup() {
scr_rowcol(scr_window_top,0); /* go to start of window */
scr_putf(SCR_SCUP);
}
/* SCR_SCDN -- Scroll the screen down.
If scr_scrolldown is true, this routine is not called. */
scr_scdn() {
scr_rowcol(2,0); /* go to start of third line. */
scr_putf(SCR_SCDN);
}
/* SCR_CO -- Output a character. */
scr_co(chr)
char chr; {
co(chr);
}
/* SCR_CSTS -- return a non-zero value if key ready. */
scr_csts() {
if (csts()) return scr_ci();
return 0;
}
/* SCR_SETUP -- called first to do any required initilization. */
scr_setup() {
#if Z100
scr_putf(SCR_SETUP1);
scr_putf(SCR_SETUP2);
scr_putf(SCR_SETUP3);
#endif
}
/* SCR_TERM -- called last to do any required termination. */
scr_term() { ; }
/* SCR_MARK -- mark the current character fot the block and delete
command.
usage: scr_mark(current char); */
scr_mark(chr)
char chr; {
scr_co('X');
}
/* SCR_SET_CURSOR -- set physical cursor to logical cursor. does
nothing on a normal character but must reset
physical cursor on a memory mapped terminal
like the PC. */
scr_set_cursor() {
}
/* SCR_PUTF -- write a formatted string to the display
*
* In general scr_putf(cp, cv) outputs the char's pointed to
* by cp, with the following exceptions:
*
* "\e" is translated to ESC
*
* "%c" selects the next char value, cv, a la printf().
*
* Thus scr_putf("\\eY%c;%cH", row + 32, col + 32);
* will write 'ESC','Y','!',';','4','H'
* for row == 1 amd col == 20
*
* Note that if the string ends with a '\' or a '%', the
* routine will continue outputing until it finds a NULL
*/
static scr_putf(cp, cv)
char *cp;
int cv;
{
char c;
int *cvp;
cvp = &cv;
while(*cp)
switch(c = *cp++)
{
case '\\': co((c = *cp++) == 'e' ? ESC : c);
break;
case '%': co((c = *cp++) == 'c' ? *cvp++ : c);
break;
default: co(c);
}
}

BIN
DeSmet C88 v24/CSTDIO.S Normal file

Binary file not shown.

BIN
DeSmet C88 v24/CSTDIO7.S Normal file

Binary file not shown.

BIN
DeSmet C88 v24/D88.EXE Normal file

Binary file not shown.

BIN
DeSmet C88 v24/D88.O Normal file

Binary file not shown.

BIN
DeSmet C88 v24/D88REST.O Normal file

Binary file not shown.

89
DeSmet C88 v24/DUMP.C Normal file
View File

@ -0,0 +1,89 @@
/* dump.c core style dump of a file */
/* usage: A>DUMP B:BLIP.O */
char buffer[4096];
main(argc,argv)
int argc;
char *argv[]; {
unsigned i,numin,tot,file;
char *cfrom;
if (argc < 2) {
puts("Missing Filename\n");
}
tot=0;
if ((file=open(argv[1],0)) == -1) {
puts("Cannot Open ");
puts(argv[1]);
exit(1);
}
/* read and dump 4k at a time */
do {
numin=read(file,buffer,4096);
if (numin == -1) {
puts("Cannot Read ");
puts(argv[1]);
exit(1);
}
cfrom=0;
while (cfrom < numin) {
/* print the offset in hex */
ohw(cfrom+tot);
putchar(' ');
/* print 16 bytes in hex */
for (i=0; i < 16; i++) {
putchar(' ');
ohb(buffer[cfrom++]);
}
cfrom-=16;
puts(" *");
/* print the bytes in ascii */
for (i=0; i < 16; i++) {
putchar((buffer[cfrom] >= ' ' && buffer[cfrom] < 0x7f)
? buffer[cfrom]: '.');
cfrom++;
}
puts("*\n");
}
tot+=numin;
}
while (numin == 4096);
}
/* print a word in hex */
ohw(wrd)
unsigned wrd; {
ohb(wrd>>8);
ohb(wrd);
}
/* print a byte in hex */
ohb(byt)
char byt; {
onib(byt>>4);
onib(byt);
}
/* print a nibble as a hex character */
onib(nib)
char nib; {
nib&=15;
putchar((nib >= 10) ? nib-10+'A': nib+'0');
}


BIN
DeSmet C88 v24/DUMP.EXE Normal file

Binary file not shown.

35
DeSmet C88 v24/E.C Normal file
View File

@ -0,0 +1,35 @@
#include <stdio.h>
#ifndef MWC
#include <string.h>
#include <stdlib.h>
#endif
#define DIGITS_TO_FIND 200 /*9009*/
int main() {
int N = DIGITS_TO_FIND;
int x = 0;
int a[ DIGITS_TO_FIND ];
int n;
for (n = N - 1; n > 0; --n) {
a[n] = 1;
}
a[1] = 2, a[0] = 0;
while (N > 9) {
n = N--;
while (--n) {
a[n] = x % n;
x = 10 * a[n-1] + x/n;
}
printf("%d", x);
}
printf( "\ndone\n" );
return 0;
}

BIN
DeSmet C88 v24/EXEC.O Normal file

Binary file not shown.

139
DeSmet C88 v24/FLIP.A Normal file
View File

@ -0,0 +1,139 @@
; FLIP.A -- code to flip the screen. This version for the PC.
VIDEO equ 10h
dseg
public flipok_
flipok_ db 1 ;flag to say flip is supported
screen_save dw 0
screen_at dw 0
screen_len dw 0
curmode db 0
curpage db 0
curloc dw 0
addr_6845 dw 3D4H
cseg
public scr_clr_
; FLIPINIT -- initilize for flipping the screen.
; paragraphs needed for screen image = flipinit();
public flipinit_
flipinit_:
push bp
mov screen_save,ds
mov ah,15
int VIDEO
cmp al,7 ;monocrome ?
jz monoinit
mov screen_at,0b800h ;16k screen at b800
mov screen_len,1024*8
mov ax,1024 ;paragraphs needed to save
pop bp
ret
monoinit:
mov addr_6845,03b4h ;base of 6845
mov screen_at,0b000h ;4k screen at b000
mov screen_len,1024*2
mov ax,256 ;paras needed to save
pop bp
ret
; SCR_SAVE -- save the screen. use screen_at.
public scr_save_
scr_save_:
push bp
mov bp,sp
mov ah,15
int VIDEO
mov curmode,al
mov curpage,bh
mov ah,3
int VIDEO
mov curloc,dx
call disable_video
push ds
mov es,screen_save ;save the screen
mov cx,screen_len
mov ds,screen_at ;from here
xor si,si
mov di,si
cld
rep movsw
pop ds
call enable_video
mov al,curmode
cmp al,7 ;dont set monocrome mode
jz clear_only
cmp al,3
jz clear_only
mov ah,0
mov al,3
int VIDEO
jmp saved
clear_only:
call scr_clr_
saved: pop bp
ret
; SCR_REST -- restore the screen. use screen_at.
public scr_rest_
scr_rest_:
push bp
mov bp,sp
mov al,curmode
cmp al,7
jz dorest
mov ah,0
int VIDEO ;restore the mode
dorest:
call disable_video
push ds
mov es,screen_at ;restore the screen
mov cx,screen_len
mov ds,screen_save ;to here
xor si,si
mov di,si
cld
rep movsw
pop ds
call enable_video
mov ah,5
mov al,curpage
int VIDEO
mov ah,2
mov bh,curpage
mov dx,curloc
int VIDEO
pop bp
ret
disable_video: ; turn the screen refresh off
mov dx,addr_6845
add dx,4
mov al,25H
out dx,al ; disable video
ret
enable_video: ; set crt mode
mov dx,addr_6845
add dx,4
mov bx,40H
mov es,bx
mov al,es:[65H] ; crt_mode_set
out dx,al ; restore video
ret

BIN
DeSmet C88 v24/FLIP.O Normal file

Binary file not shown.

BIN
DeSmet C88 v24/GEN.EXE Normal file

Binary file not shown.

72
DeSmet C88 v24/LATER.C Normal file
View File

@ -0,0 +1,72 @@
/* LATER.C -- Exit with a 1 if any file has a higher create
date than the last or if the last file does not exist.
A 2 is returned if any other files do not exist.
Later only works on MS-DOS V2.0.
A>LATER FILE1.C FILE1.O
Later will set completion code to 1 if FILE1.C was
created after FILE1.O.
A>LATER FILE1.C FILE1.H FILE1.O
Later will set completion code to 1 if FILE1.C or
FILE1.H was created after FILE1.O. */
main(argc,argv)
int argc;
char *argv[]; {
unsigned ifile,ofile,i;
long odate,dateof();
puts("LATER V1.0 ");
if (argc < 3 ) {
puts("need two or more arguments");
exit(0);
}
if ((ofile=open(argv[argc-1],0)) == -1)
exit(1); /* the last file does not exist */
odate=dateof(ofile);
close(ofile);
/* for each file see if it is later than the last one */
for (i=1; i < argc-1; i++) {
if ((ifile=open(argv[i],0)) == -1) {
puts(argv[i]);
puts(" does not exist");
exit(2); /* an early file does not exist */
}
if (dateof(ifile) > odate) exit(1); /* found a later file */
close(ifile);
}
/* none of the files are later. set completion code of zero */
exit(0);
}
/* return a long encoding the date and time of a file */
long dateof(fil)
int fil; {
static long ret_dt;
#asm
mov bx,[bp+4] ;file handle is here. only argument.
and bx,0ffh ;low byte of file id is MS-DOS handle.
mov al,0 ;code to retrieve date and time.
mov ah,57h ;dos code for get file date and time.
int 21h ;call dos.
mov word dateof_ret_dt_+2,dx;store date in high word of ret_dt.
mov word dateof_ret_dt_,cx ;store time in low word of ret_dt.
;note: "dateof_" is added to name
;because ret_dt is static.
#
return ret_dt;
}

BIN
DeSmet C88 v24/LIB88.EXE Normal file

Binary file not shown.

253
DeSmet C88 v24/LIFE.C Normal file
View File

@ -0,0 +1,253 @@
/* LIFE.C The much implemented game of Life invented by John Conway
This version was written to illustrate the use of the C88
screen and keyboard interface. Use C option for color display.
To generate:
A>C88 B:LIFE
A>ASM88 B:PCIO
A>BIND B:LIFE B:PCIO */
/*
global constant and data declarations
*/
#define ROWS 24
#define COLS 80
/* control key translations */
#define up_char 30
#define down_char 31
#define left_char 29
#define right_char 28
#define bol_char 200
#define eol_char 201
#define pageup_char 202
#define pagedown_char 203
#define bof_char 204
#define eof_char 205
#define Ins_char 206
#define Del_char 207
#define NextWord_char 208
#define PrevWord_char 209
/* function keys */
#define M1 210
#define M2 211
#define M3 212
#define M4 213
#define M5 214
#define M6 215
#define M7 216
#define M8 217
#define M9 218
#define M10 219
char world[ROWS][COLS],create_mode=1,quit_flag;
int population,generation,crow,ccol;
char color_opt,color;
main(argc,argv)
int argc;
char *argv[]; {
if (argc > 1 && toupper(*argv[1]) == 'C') color_opt=1;
scr_setup();
scr_clr();
instruct();
setup();
do {
generation++;
cycle();
screen();
}
while (population && !quit_flag);
scr_rowcol(ROWS,10);
if (population == 0)
puts("Nobody left, sorry about that. ");
else puts("bye ");
scr_curson();
}
instruct() { /* print instructions */
puts(" The game of Life by John Conway\n\n");
puts(" Use LIFE C with color monitor.\n");
puts(" If started with a number, a random pattern starts the game.\n\n");
puts(" Otherwise, move the cursor with the four arrow keys to create life.\n\n");
puts(" DEL changes cursor movement to mean that cells are deleted\n\n");
puts(" INS flips back to create mode.\n\n");
puts(" The '+' key will toggle the game on or off.\n\n");
puts(" Hit ESC to bail out.\n\n");
puts(" Enter starting number of cells or hit CR ");
}
setup() {
int rnumber;
int i,row,col,seed,rnum;
char ch;
rnumber=0;
while (1) {
while ((ch=scr_csts()) == 0) seed++;
if (ch < '0' || ch > '9') break;
scr_co(ch);
rnumber*=10;
rnumber+=ch-'0';
}
scr_cursoff();
scr_clr();
scr_rowcol(ROWS,20); /* print population message */
puts("Generation 0 Population 0");
srand(seed); /* initilize random number generator */
for (i=0; i < rnumber; i++) {
rnum=rand();
row=rnum%ROWS;
col=(rnum/ROWS)%COLS;
world[row][col]='X'; /* put in a cell */
scr_rowcol(row,col);
if (color_opt) scr_aputs("\2",++color | 0X80);
else scr_co(2);
}
if (rnumber == 0) create(1);
}
screen() { /* update the screen and set world back to x's */
int row,col;
char cell;
population=0;
for (row=0; row < ROWS; row++) {
for (col=0; col < COLS; col++) {
cell=world[row][col];
/* stay alive if 3 neighbors, born if next to 2 or 3 */
if (cell && (cell == 3 || cell == 'X'+2 || cell == 'X'+3)) {
population++;
if (cell < 'X') {
scr_rowcol(row,col);
if (color_opt) scr_aputs("\2",++color | 0X80);
else scr_co(2);
}
cell='X';
}
else {
if (cell >= 'X') {
scr_rowcol(row,col);
scr_co(' ');
}
cell=0;
}
world[row][col]=cell;
}
}
scr_rowcol(ROWS,31);
printf("%4d",generation);
scr_rowcol(ROWS,51);
printf("%4d",population);
}
create(suspend) /* see if need to create or kill cells */
char suspend; {
char ch,wait;
while ((ch=scr_csts()) || suspend) {
switch (ch) {
case up_char: crow=crow ? crow-1: ROWS-1;
break;
case down_char: crow=crow == ROWS-1 ? 0: crow+1;
break;
case left_char: ccol=ccol ? ccol-1: COLS-1;
break;
case right_char:ccol=ccol == COLS-1 ? 0: ccol+1;
break;
case bol_char: ccol=0;
break;
case eol_char: ccol=COLS-1;
break;
case '+': suspend=!suspend;
continue;
case Ins_char: create_mode=1;
continue;
case Del_char: create_mode=0;
continue;
case 0x1b: quit_flag=1; /* flag for stop */
return;
default: continue;
}
world[crow][ccol]= create_mode ? 'X': 0;
scr_rowcol(crow,ccol);
if (create_mode) {
if (color_opt) scr_aputs("\2",++color | 0X80);
else scr_co(2);
population++;
}
else {
wait=30;
while (wait--) {
if (color_opt) scr_aputs("\1",++color | 0X80);
else scr_co(1);
scr_rowcol(crow,ccol);
}
scr_co(' ');
}
}
}
cycle() { /* cycle to the next generation */
int row,col;
create(0);
/* take care of left and right column first */
for (row=0; row < ROWS; row++) {
if (world[row][0] >= 'X') add8(row,0);
if (world[row][COLS-1] >= 'X') add8(row,COLS-1);
}
/* take care of top and bottom line */
for (col=1; col < COLS-1;col++) {
if (world[0][col] >= 'X') add8(0,col);
if (world[ROWS-1][col] >= 'X') add8(ROWS-1,col);
}
/* fill in the box, ignoring border conditions */
for (row=1; row < ROWS-1; row++) {
for (col=1; col < COLS-1; col++) {
if (world[row][col] >= 'X' ) {
world[row-1][col-1]++;
world[row-1][col]++;
world[row-1][col+1]++;
world[row][col-1]++;
world[row][col+1]++;
world[row+1][col-1]++;
world[row+1][col]++;
world[row+1][col+1]++;
}
}
}
}
add8(row,col)
int row,col; {
int rrow,ccol,rr,cc;
for (rr=row-1; rr <= row+1; rr++) {
for (cc=col-1; cc <= col+1; cc++) {
rrow=rr != -1 ? rr : ROWS-1;
ccol=cc != -1 ? cc : COLS-1;
if (rrow >= ROWS) rrow=0;
if (ccol >= COLS) ccol=0;
world[rrow][ccol]++;
}
}
world[row][col]--;
}

BIN
DeSmet C88 v24/LIFE.EXE Normal file

Binary file not shown.

7
DeSmet C88 v24/MATH.H Normal file
View File

@ -0,0 +1,7 @@
extern int errno;
#define EDOM 33
#define ERANGE 34
extern int errno;extern double sqrt(), sin(), cos(), tan(), cot(), asin(), acos(), atan(), atan2();
extern double exp(), exp10(), log(), log10(), pow(), fabs(), frand();
extern double floor(), ceil(), ldexp(), frexp(), modf();

122
DeSmet C88 v24/MM.C Normal file
View File

@ -0,0 +1,122 @@
/* BYTE magazine October 1982. Jerry Pournelle. */
/* ported to C by David Lee */
/* various bugs not found because dimensions are square fixed by David Lee */
/* expected result: 4.65880E+05 */
/* normal version runs in 13 seconds on the original PC and 8.9 seconds with the "f/fast" versions */
#define LINT_ARGS
#include <stdio.h>
#define l 20 /* rows in A and resulting matrix C */
#define m 20 /* columns in A and rows in B (must be identical) */
#define n 20 /* columns in B and resulting matrix C */
#define ftype float
ftype Summ;
ftype A[ l ] [ m ];
ftype B[ m ] [ n ];
ftype C[ l ] [ n ];
void filla()
{
register int i, j;
for ( i = 0; i < l; i++ )
for ( j = 0; j < m; j++ )
A[ i ][ j ] = i + j + 2;
}
void fillb()
{
register int i, j;
for ( i = 0; i < m; i++ )
for ( j = 0; j < n; j++ )
B[ i ][ j ] = (ftype) ( ( i + j + 2 ) / ( j + 1 ) );
}
void fillc()
{
register int i, j;
for ( i = 0; i < l; i++ )
for ( j = 0; j < n; j++ )
C[ i ][ j ] = 0;
}
void ffillc()
{
ftype * p = (ftype *) C;
ftype * pend = ( (ftype *) C ) + ( l * n );
while ( p < pend )
*p++ = 0;
}
void matmult()
{
register int i, j, k;
for ( i = 0; i < l; i++ )
for ( j = 0; j < n; j++ )
for ( k = 0; k < m; k++ )
C[ i ][ j ] += A[ i ][ k ] * B[ k ][ j ];
}
void fmatmult()
{
static int i, j, k;
static ftype * pC, * pA, * pAI, * pBJ, *pCI;
for ( i = 0; i < l; i++ )
{
pAI = (ftype *) & ( A[ i ][ 0 ] );
pCI = (ftype *) & ( C[ i ][ 0 ] );
for ( j = 0; j < n; j++ )
{
pC = (ftype *) & pCI[ j ];
pA = pAI;
pBJ = & ( B[ 0 ][ j ] );
for ( k = 0; k < m; k++ )
{
*pC += pA[ k ] * ( *pBJ );
pBJ += m;
}
}
}
}
void summit()
{
register int i, j;
for ( i = 0; i < l; i++ )
for ( j = 0; j < n; j++ )
Summ += C[ i ][ j ];
}
void fsummit()
{
ftype * p = (ftype *) C;
ftype * pend = ( (ftype *) C ) + ( l * n );
while ( p < pend )
Summ += *p++;
}
int main( argc, argv ) int argc; char * argv[];
{
Summ = 0;
filla();
fillb();
ffillc();
fmatmult();
fsummit();
printf( "summ is : %f\n", Summ );
return 0;
}

3
DeSmet C88 v24/MSDOS.BAT Normal file
View File

@ -0,0 +1,3 @@
c88 config
bind see config
bind d88 d88rest config

575
DeSmet C88 v24/PCIO.A Normal file
View File

@ -0,0 +1,575 @@
; PCIO.A -- Screen and keyboard interface routines for the PC
dseg
; In this implementation, all special and function keys are translated
; to the following values.
;/* control key translations */
up_char equ 30
down_char equ 31
left_char equ 29
right_char equ 28
bol_char equ 200
eol_char equ 201
pageup_char equ 202
pagedown_char equ 203
bof_char equ 204
eof_char equ 205
Ins_char equ 206
Del_char equ 207
NextWord_char equ 208
PrevWord_char equ 209
M1 equ 210
M2 equ 211
M3 equ 212
M4 equ 213
M5 equ 214
M6 equ 215
M7 equ 216
M8 equ 217
M9 equ 218
M10 equ 219
; the table that is used to make the translation
convert:
db 72, up_char
db 80, down_char
db 75, left_char
db 77, right_char
db 71, bol_char
db 79, eol_char
db 73, pageup_char
db 81, pagedown_char
db 77H, bof_char
db 75H, eof_char
db 82, Ins_char
db 83, Del_char
db 115, PrevWord_char
db 116, NextWord_char
db 59, M1
db 60, M2
db 61, M3
db 62, M4
db 63, M5
db 64, M6
db 65, M7
db 66, M8
db 67, M9
db 68, M10
db 0, 255 ; illegal character
; equates for bios interface.
; the interrupt and codes for the screen interface interrupt.
video equ 10h ;interrupt for dealing with screen
mode equ 0 ;code for setting new screen mode
curtype equ 1 ;code for setting new cursor type
setcur equ 2 ;code for addressing cursor
readcur equ 3 ;code for reading cursor location
readlp equ 4 ;code for reading light pen position
setpage equ 5 ;code to select active page
scrollup equ 6 ;code to scroll screen up
scrolldn equ 7 ;code to scroll screen nown
readch equ 8 ;code to read a character from screen
writeach equ 9 ;code to write char and attributes
writech equ 10 ;code to write character only
setpal equ 11 ;code to set new setpal or border
wdot equ 12 ;code to write a dot
rdot equ 13 ;code to read a dot
wtty equ 14 ;code to write as if teletype
state equ 15 ;code to find current screen status
; the interrupt and codes for the keyboard interface.
keyboard equ 16h ;interrupt 16 to deal with keyboard
cicode equ 0 ;code for reading a character
cstscode equ 1 ;code for keyboard status
; caution: must change column number if 40 column mode
crt_cols equ 80
; variables available to a C88 program
public scr_cols_, scr_rows_, scr_scrollup_, scr_scrolldown_
public scr_mode_,scr_page_,scr_attr_,scr_window_top_
scr_cols_: dw crt_cols ;current number of columns
; note- make 25 for ms-dos and 24 for cp/m as cp/m steals the bottom
; line.
scr_rows_: dw 25 ;current number of rows
scr_mode_ db 0 ;current screen mode
scr_page_ db 0 ;current page
scr_attr_ db 7 ;current attributes for screen
;7 is white letters on black
scr_window_top_ db 2 ;first line to scroll
; variables needed by SEE. Not used here.
scr_scrollup_: db 0 ;zero if scrollup leaves top line alone
scr_scrolldown_:db 0 ;zero if scroll down supported
cseg
; SCR_SETUP_ scr_setup must be called before any use of any
; other routine unless the starting mode is 80X25
; character mode (3,4 or 7). Must be called for monocrome
; (mode 7) for scr_curson to set a proper cursor.
; Usage: scr_setup();
public scr_setup_
scr_setup_: push bp
mov ah,state ;get current state
int video
mov scr_mode_,al ;current mode
mov cl,ah ;make cols a word
mov ch,0
mov scr_cols_,cx ;40 or 80 columns
mov scr_page_,bh
mov scr_attr_,7 ;set to white chars on black
cmp al,4 ;see if a character mode
jc got_attr
cmp al,7 ;7 is for graphics mode
jz got_attr
mov scr_attr_,0 ;attribute is zero in graphics
got_attr: mov ah,0 ;return int containing mode
pop bp
ret
; SCR_TERM_ do any required termination.
; Usage: scr_term();
public scr_term_
scr_term_:
ret
; SCR_SETMODE_ set a new screen mode
; Usage: scr_setmode(new mode);
public scr_setmode_
scr_setmode_: push bp
mov bp,sp
mov al,[bp+4] ; new mode value
mov ah,mode
int video ; set new mode
call scr_setup_ ;remember new values
pop bp
ret
; SCR_ROWCOL_ sets cursor at any location.
; Usage: scr_rowcol(new row, new column);
public scr_rowcol_
scr_rowcol_: ; move cursor to x,y
push bp ; save from bios
mov bp,sp
mov dx,[bp+6] ; column
mov ax,[bp+4] ; row
mov dh,al
mov bh,scr_page_ ; force page zero
mov ah,setcur ; set cursor location
int video ; call bios
pop bp
ret
; SCR_CLR_ clear entire screen
; Usage: scr_clr();
public scr_clr_
scr_clr_: ; clear screen
push bp ;save from video call
mov al,0 ;ask for a clear window
xor cx,cx ;start at 0,0
mov dh,byte scr_rows_;last line
dec dh
mov dl,byte scr_cols_ ;clear entire width
dec dl ;last column is width-1
mov bh,scr_attr_ ;attributes for new blanks
mov ah,scrollup ;ask for a scrollup to clear
int video ;do the clear
pop bp
ret
; SCR_CLRL_ clear rest of line.
; Usage: scr_clrl();
public scr_clrl_
scr_clrl_: ; clear rest of line
push bp
mov bh,scr_page_
mov ah,readcur ;see where we are
int video
mov cl,byte scr_cols_ ;calc how many chars left in line
sub cl,dl ;number left
mov ch,0 ;number of blanks needed
mov al,' ' ;write blanks
mov bl,scr_attr_ ;normal attributes
mov bh,scr_page_ ;page number
mov ah,writeach ;write the blanks
int video
pop bp
ret
; SCR_CLS_ clear rest of screen.
; Usage: scr_cls();
public scr_cls_
scr_cls_: ; clear rest of screen
push bp
call scr_clrl_ ;clear rest of line
mov ah,readcur ;see where we are
mov bh,scr_page_
int video
mov al,0 ;ask for a clear window
mov ch,dh ;current row
inc ch ;+1
cmp ch,byte scr_rows_;see if in last line
jz cleared ;all done
mov cl,0 ;first column
mov dh,byte scr_rows_;24 is the last line
dec dh
mov dl,byte scr_cols_ ;clear entire width
dec dl ;last column is width-1
mov bh,scr_attr_ ;attributes for new blanks
mov ah,scrollup ;ask for a scrollup to clear
int video ;do the clear
cleared: pop bp
ret
; SCR_SCUP_ scroll text up leaving top lines alone.
; Usage: scr_scup();
public scr_scup_
scr_scup_: ; scroll last line, screen from line
; scr_windor_top to end
mov ax,scr_cols_ ;need last column of screen
dec ax
push ax
mov ax,scr_rows_ ;scroll through last line
dec ax
push ax
xor ax,ax ;from column 0
push ax
mov al,scr_window_top_;leave top line alone
push ax
mov al,1
push ax ;scroll by 1
call scr_scrup_ ;do the scroll
add sp,10 ;clear arge
ret
; SCR_SCRUP_ Scroll the screen up. The window is scrolled
; up nline lines. A zero nline will clear the
; window. Top left of the screen in 0,0.
; Usage: scr_scrup(nline,fromrow,fromcol,torow,tocol);
public scr_scrup_
scr_scrup_: push bp
mov bp,sp
mov al,[bp+4] ;number of lines
mov ch,[bp+6] ;starting row
mov cl,[bp+8] ;starting column
mov dh,[bp+10] ;ending row
mov dl,[bp+12] ;ending column
mov bh,scr_attr_ ;current attribute
mov ah,scrollup
int video ;do the scroll
pop bp
ret
; SCR_SCDN_ scroll all but the top lines down one.
; Usage: scr_scdn();
public scr_scdn_
scr_scdn_:
mov ax,scr_cols_ ;need last column of screen
dec ax
push ax
mov ax,scr_rows_ ;scroll through last line
dec ax
push ax
xor ax,ax ;from column 0
push ax
mov al,scr_window_top_;leave top lines alone
push ax
mov al,1
push ax ;scroll by 1
call scr_scrdn_ ;do the scroll
add sp,10 ;clear arge
ret
; SCR_SCRDN_ scroll the screen down. the window is scrolled
; down nline lines. A zero nline will clear the
; window. Top left of the screen in 0,0.
; Usage: scr_scrdn(nline,fromrow,fromcol,torow,tocol);
public scr_scrdn_
scr_scrdn_: push bp
mov bp,sp
mov al,[bp+4] ;number of lines
mov ch,[bp+6] ;starting row
mov cl,[bp+8] ;starting column
mov dh,[bp+10] ;ending row
mov dl,[bp+12] ;ending column
mov bh,scr_attr_ ;current attribute
mov ah,scrolldn
int video ;do the scroll
pop bp
ret
; SCR_CO_ write a character to the screen. this
; routine increments the cursor position
; after writing. normal C88 puts and printf
; statements can also be used to write to the
; screen.
; Usage: scr_co_(character);
public scr_co_
scr_co_: ; standard console output
push bp
mov bp,sp
mov al,[bp+4] ;character to write
mov bh,scr_page_
mov ah,wtty ;use tty write routine
int video
pop bp
ret
; SCR_CI_ keyboard input. function and soft keys are
; translated. see equates for values.
; Usage: character = scr_ci();
public scr_ci_
scr_ci_: ;return the next character
; translate if necessary
push bp
mov ah,cicode ;ask for a keyboard character
int keyboard
cmp al,0
jne not_special
mov bx, offset convert ; convert special key
ci_loop:
cmp byte[bx],0
jz got_it
cmp ah, byte[bx]
je got_it
add bx,2
jmp ci_loop
got_it: inc bx
mov al,[bx]
mov ah,0
pop bp
ret
not_special: mov ah,0
pop bp
ret
; SCR_CSTS_ return character if any available. otherwise
; return zero.
; Usage: character = scr_csts();
public scr_csts_
scr_csts_: ;return coded character if any available
push bp
mov ah,cstscode
int keyboard
mov ax,0
jz csts_over
call scr_ci_ ;get the coded character
csts_over: pop bp
ret
; SCR_SET_CURSOR_ does nothing. needed by SEE.
public scr_set_cursor_
scr_set_cursor_: ; set the visible cursor to the
; current position
ret
; SCR_SINP_ screen input (read character from the screen).
; Usage: character = scr_sinp();
public scr_sinp_
scr_sinp_:
push bp ;save the registers
mov bh,scr_page_
mov ah,readch ;code to read a character
int video ;al is letter, ah=attributes
or al,al ;zero returned instead of blank in
;graphics mode
jnz ret_ch
mov al,' '
ret_ch: mov ah,0 ;kill the attributes
pop bp
ret
; SCR_CURSOFF_ turn cursor off.
; Usage: scr_cursoff();
public scr_cursoff_
scr_cursoff_:
push bp ;save registers
cmp scr_mode_,4 ;see if graphics
jc text_coff
cmp scr_mode_,7
jnz no_cur
text_coff:
mov cx,0f00h ;should turn cursor off
new_cur: mov ah,curtype ;set a new cursor type
int video
no_cur: pop bp
ret
; SCR_CURSON_ turn cursor back on.
; Usage: scr_curson();
public scr_curson_
scr_curson_:
push bp
mov cx,0c0dh ;assume monocrome
cmp scr_mode_,7 ;true is mono
jz new_cur ;set it
mov cx,0607h ;assume color card in text mode
cmp scr_mode_,4 ;color text is 0 to 3
jc new_cur
pop bp ;do nothing if in graphics mode
ret
; SCR_MARK -- mark the current character on the screen.
; Used to delimit block areas in SEE. Just write
; an X or something if reverse video is not available.
; Usage: scr_mark(current character);
public scr_mark_
scr_mark_: ; mark the passed char,
; cursor does not advance
push bp
mov al,219 ;just write a block character
mov bl,scr_attr_ ;normal attributes
mov cx,1 ; one character
mov bh,scr_page_ ;page number
mov ah,writeach ;write char and attr
int video ;write character and attributes
pop bp
ret
; the following routine is not used by either SEE or D88.
; SCR_APUTS_ write a string and attributes to the screen.
; the cursor is moved normally
; Usage: acr_aputs("Print This",attribute);
; attribute is BRGBIRGB
; | | | |
; | | | color for letter. 7 is white
; | | intensity for letter
; | color for background. 0 is black
; blinking
public scr_aputs_
scr_aputs_:
push bp
mov bp,sp
mov ah,readcur ;see where we are
int video ;dx is cursor location, bh is page
mov si,[bp+4] ;string pointer
mov cx,1 ;number of characters to write
mov bl,[bp+6] ;attribute
naputs: cld
lodsb ;next character to write
or al,al ;zero at end
jz eaputs
cmp al,10 ;look for LF
jnz normal_ap
ap_scroll: mov bp,sp ;reset pointer to next char
mov [bp+4],si
mov al,13 ;use tty output to scroll screen
mov ah,wtty
int video ;write cr,lf
mov ah,wtty
mov al,10
int video
pop bp
jmp scr_aputs_ ;start over
normal_ap:
mov bh,scr_page_ ;page number
mov ah,writeach ;write char and attr
int video ;write character and attributes
inc dl ;next column
cmp dl,crt_cols ;see if wrapping around
jc set_loc
mov dl,0 ;at start of column
inc dh ;at next row
cmp dh,byte scr_rows_;see if need a scroll
jc set_loc
jmp ap_scroll ;do a scroll up
set_loc: mov ah,setcur ;move the cursor
int video
jmp naputs
eaputs: pop bp
ret

BIN
DeSmet C88 v24/PROFEND.EXE Normal file

Binary file not shown.

BIN
DeSmet C88 v24/PROFILE.EXE Normal file

Binary file not shown.

BIN
DeSmet C88 v24/PROFSTAR.EXE Normal file

Binary file not shown.

BIN
DeSmet C88 v24/RAM.COM Normal file

Binary file not shown.

BIN
DeSmet C88 v24/SEE.EXE Normal file

Binary file not shown.

BIN
DeSmet C88 v24/SEE.O Normal file

Binary file not shown.

35
DeSmet C88 v24/SIEVE.C Normal file
View File

@ -0,0 +1,35 @@
/* sieve.c */
/* Eratosthenes Sieve Prime Number Program in C from Byte Jan 1983
to compare the speed. */
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define SIZE 8190
typedef int bool;
char flags[SIZE+1];
int main()
{
int i,k;
int prime,count,iter;
for (iter = 1; iter <= 10; iter++) { /* do program 10 times */
count = 0; /* initialize prime counter */
for (i = 0; i <= SIZE; i++) /* set all flags TRUE */
flags[i] = TRUE;
for (i = 0; i <= SIZE; i++) {
if (flags[i]) { /* found a prime */
prime = i + i + 3; /* twice index + 3 */
for (k = i + prime; k <= SIZE; k += prime)
flags[k] = FALSE; /* kill all multiples */
count++; /* primes found */
}
}
}
printf("%d primes.\n",count); /*primes found in 10th pass */
return 0;
}

18
DeSmet C88 v24/STDIO.H Normal file
View File

@ -0,0 +1,18 @@
/* STDIO.H Include file for C88 input/output. */
/* a 'FILE' is simply an integer is this implimentation */
typedef int FILE;
/* Standard input, standard output and standard error. */
#define stdin 0
#define stdout 1
#define stderr 2
#define NULL 0
#define TRUE 1
#define FALSE 0
#define EOF (-1)
#define ERR (-1)


169
DeSmet C88 v24/TM.C Normal file
View File

@ -0,0 +1,169 @@
#include <stdio.h>
#ifdef AZTEC86
#include <stdlib.h>
#endif
#ifdef HISOFTC
#include <stdlib.h>
#endif
#ifdef INTELC
#include <stdlib.h>
#endif
#ifdef WATCOM
#include <malloc.h>
#include <process.h>
#endif
#ifdef powerc
#define allocs 50
#else
#ifdef HISOFTC
#define allocs 66 /* not enough RAM with hisoft to go higher */
#else
/* most c runtimes work up to 69, but use 66 to have a consistent benchmark */
#define allocs 66
#endif
#endif
int logging = 1;
char * memset_x( p, v, c ) char * p; int v; int c;
{
unsigned char * pc = (unsigned char *) p;
unsigned char val = (unsigned char) ( v & 0xff );
int i;
if ( 0 == p )
{
printf( "request to memset a null pointer\n" );
exit( 1 );
}
if ( logging )
#ifdef CPMTIME
printf( " memset p %u, v %d, val %x, c %d\n", p, v, val, c );
#else
#ifdef HISOFTC
printf( " memset p %u, v %d, val %x, c %d\n", p, v, val, c );
#else
printf( " memset p %p, v %d, val %x, c %d\n", p, v, val, c );
#endif
#endif
for ( i = 0; i < c; i++ )
*pc++ = val;
return p;
}
void chkmem( p, v, c ) char * p; int v; int c;
{
unsigned char * pc = (unsigned char *) p;
unsigned char val = (unsigned char) ( v & 0xff );
int i;
if ( 0 == p )
{
printf( "request to chkmem a null pointer\n" );
exit( 1 );
}
for ( i = 0; i < c; i++ )
{
if ( *pc != val )
{
#ifdef CPMTIME
printf( "memory isn't as expected! p %u, v %d, c %d, *pc %d\n",p, v, c, *pc );
#else
printf( "memory isn't as expected! p %p, v %d, c %d, *pc %d\n",p, v, c, *pc );
#endif
exit( 1 );
}
pc++;
}
}
int main( argc, argv ) int argc; char * argv[];
{
int i, cb, c_cb, j;
char * pc;
char * ap[ allocs ];
logging = ( argc > 1 );
pc = argv[ 0 ]; /* evade compiler warning */
for ( j = 0; j < 10; j++ )
{
if ( logging )
printf( "in alloc mode\n" );
for ( i = 0; i < allocs; i++ )
{
cb = 8 + ( i * 10 );
c_cb = cb + 5;
if ( logging )
printf( " i, cb: %d %d\n", i, cb );
pc = (char *) calloc( c_cb, 1 );
chkmem( pc, 0, c_cb );
memset_x( pc, 0xcc, c_cb );
ap[ i ] = (char *) malloc( cb );
memset_x( ap[ i ], 0xaa, cb );
chkmem( pc, 0xcc, c_cb );
free( pc );
}
if ( logging )
printf( "in free mode, even first\n" );
for ( i = 0; i < allocs; i += 2 )
{
cb = 8 + ( i * 10 );
c_cb = cb + 3;
if ( logging )
printf( " i, cb: %d %d\n", i, cb );
pc = (char *) calloc( c_cb, 1 );
chkmem( pc, 0, c_cb );
memset_x( pc, 0xcc, c_cb );
chkmem( ap[ i ], 0xaa, cb );
memset_x( ap[ i ], 0xff, cb );
free( ap[ i ] );
chkmem( pc, 0xcc, c_cb );
free( pc );
}
if ( logging )
printf( "in free mode, now odd\n" );
for ( i = 1; i < allocs; i += 2 )
{
cb = 8 + ( i * 10 );
c_cb = cb + 7;
if ( logging )
printf( " i, cb: %d %d\n", i, cb );
pc = (char *) calloc( c_cb, 1 );
chkmem( pc, 0, c_cb );
memset_x( pc, 0xcc, c_cb );
chkmem( ap[ i ], 0xaa, cb );
memset_x( ap[ i ], 0xff, cb );
free( ap[ i ] );
chkmem( pc, 0xcc, c_cb );
free( pc );
}
}
printf( "success\n" );
return 0;
}

527
DeSmet C88 v24/TTT.C Normal file
View File

@ -0,0 +1,527 @@
/*
This version builds with old compilers including:
Aztec C 1.06 for 8080 & Z80 on CP/M.
Microsoft C Compiler V1.04 for 8086 on DOS. (This is Lattice C)
Microsoft C Compiler V2.03 for 8086 on DOS. (Still Lattice C)
Microsoft C Compiler V3.00 for 8086 on DOS.
QuickC 1.0
Turbo C 2.0
The syntax is old and reminds me of 7th grade summer vacation.
Much of this code is awkward to satisfy the lowest common denominator of many compilers.
unsigned long isn't supported in many older compilers, so long is used instead.
Early DOS and CP/M require register variabes to be int, not char or other types.
The perf improvement of using register-int instead of stack-char is worth it.
*/
#define LINT_ARGS
#include <stdio.h>
#ifdef DOSTIME
#include <time.h>
#include <dos.h>
#endif
#define true 1
#define false 0
/* Function Pointers are the fastest implementation for almost every compiler */
#define UseFunPointers 1
#define UseWinner2 2
#define UseLookForWinner 3
#define WinMethod UseFunPointers
#define ABPrune true /* alpha beta pruning */
#define WinLosePrune true /* stop early on win/lose */
#define ScoreWin 6
#define ScoreTie 5
#define ScoreLose 4
#define ScoreMax 9
#define ScoreMin 2
#define DefaultIterations 10
#define PieceX 1
#define PieceO 2
#define PieceBlank 0
typedef char ttype; /* 8-bit and 16-bit cpus do best with char aside from register in locals */
int g_Iterations = DefaultIterations;
ttype g_board[ 9 ];
#if WinMethod == UseFunPointers
ttype pos0func()
{
/* using "register int" instead of "ttype" for x is faster on 8086 and Z80 */
register int x = g_board[0];
if ( ( x == g_board[1] && x == g_board[2] ) ||
( x == g_board[3] && x == g_board[6] ) ||
( x == g_board[4] && x == g_board[8] ) )
return x;
return PieceBlank;
}
ttype pos1func()
{
register int x = g_board[1];
if ( ( x == g_board[0] && x == g_board[2] ) ||
( x == g_board[4] && x == g_board[7] ) )
return x;
return PieceBlank;
}
ttype pos2func()
{
register int x = g_board[2];
if ( ( x == g_board[0] && x == g_board[1] ) ||
( x == g_board[5] && x == g_board[8] ) ||
( x == g_board[4] && x == g_board[6] ) )
return x;
return PieceBlank;
}
ttype pos3func()
{
register int x = g_board[3];
if ( ( x == g_board[4] && x == g_board[5] ) ||
( x == g_board[0] && x == g_board[6] ) )
return x;
return PieceBlank;
}
ttype pos4func()
{
register int x = g_board[4];
if ( ( x == g_board[0] && x == g_board[8] ) ||
( x == g_board[2] && x == g_board[6] ) ||
( x == g_board[1] && x == g_board[7] ) ||
( x == g_board[3] && x == g_board[5] ) )
return x;
return PieceBlank;
}
ttype pos5func()
{
register int x = g_board[5];
if ( ( x == g_board[3] && x == g_board[4] ) ||
( x == g_board[2] && x == g_board[8] ) )
return x;
return PieceBlank;
}
ttype pos6func()
{
register int x = g_board[6];
if ( ( x == g_board[7] && x == g_board[8] ) ||
( x == g_board[0] && x == g_board[3] ) ||
( x == g_board[4] && x == g_board[2] ) )
return x;
return PieceBlank;
}
ttype pos7func()
{
register int x = g_board[7];
if ( ( x == g_board[6] && x == g_board[8] ) ||
( x == g_board[1] && x == g_board[4] ) )
return x;
return PieceBlank;
}
ttype pos8func()
{
register int x = g_board[8];
if ( ( x == g_board[6] && x == g_board[7] ) ||
( x == g_board[2] && x == g_board[5] ) ||
( x == g_board[0] && x == g_board[4] ) )
return x;
return PieceBlank;
}
typedef ttype pfunc_t();
pfunc_t * winner_functions[9] =
{
pos0func,
pos1func,
pos2func,
pos3func,
pos4func,
pos5func,
pos6func,
pos7func,
pos8func
};
#endif
#if WinMethod == UseWinner2
ttype winner2( move ) ttype move;
{
register int x; /* faster than ttype x on the stack */
switch( move ) /* msc v3 from 1985 generates a jump table! */
{
case 0:
{
x = g_board[ 0 ];
if ( ( ( x == g_board[1] ) && ( x == g_board[2] ) ) ||
( ( x == g_board[3] ) && ( x == g_board[6] ) ) ||
( ( x == g_board[4] ) && ( x == g_board[8] ) ) )
return x;
break;
}
case 1:
{
x = g_board[ 1 ];
if ( ( ( x == g_board[0] ) && ( x == g_board[2] ) ) ||
( ( x == g_board[4] ) && ( x == g_board[7] ) ) )
return x;
break;
}
case 2:
{
x = g_board[ 2 ];
if ( ( ( x == g_board[0] ) && ( x == g_board[1] ) ) ||
( ( x == g_board[5] ) && ( x == g_board[8] ) ) ||
( ( x == g_board[4] ) && ( x == g_board[6] ) ) )
return x;
break;
}
case 3:
{
x = g_board[ 3 ];
if ( ( ( x == g_board[4] ) && ( x == g_board[5] ) ) ||
( ( x == g_board[0] ) && ( x == g_board[6] ) ) )
return x;
break;
}
case 4:
{
x = g_board[ 4 ];
if ( ( ( x == g_board[0] ) && ( x == g_board[8] ) ) ||
( ( x == g_board[2] ) && ( x == g_board[6] ) ) ||
( ( x == g_board[1] ) && ( x == g_board[7] ) ) ||
( ( x == g_board[3] ) && ( x == g_board[5] ) ) )
return x;
break;
}
case 5:
{
x = g_board[ 5 ];
if ( ( ( x == g_board[3] ) && ( x == g_board[4] ) ) ||
( ( x == g_board[2] ) && ( x == g_board[8] ) ) )
return x;
break;
}
case 6:
{
x = g_board[ 6 ];
if ( ( ( x == g_board[7] ) && ( x == g_board[8] ) ) ||
( ( x == g_board[0] ) && ( x == g_board[3] ) ) ||
( ( x == g_board[4] ) && ( x == g_board[2] ) ) )
return x;
break;
}
case 7:
{
x = g_board[ 7 ];
if ( ( ( x == g_board[6] ) && ( x == g_board[8] ) ) ||
( ( x == g_board[1] ) && ( x == g_board[4] ) ) )
return x;
break;
}
case 8:
{
x = g_board[ 8 ];
if ( ( ( x == g_board[6] ) && ( x == g_board[7] ) ) ||
( ( x == g_board[2] ) && ( x == g_board[5] ) ) ||
( ( x == g_board[0] ) && ( x == g_board[4] ) ) )
return x;
break;
}
}
return PieceBlank;
} /*winner2*/
#endif
#if WinMethod == UseLookForWinner
ttype LookForWinner()
{
register int p = g_board[0]; /* faster as register int than ttype on 8086 and Z80 */
if ( PieceBlank != p )
{
if ( p == g_board[1] && p == g_board[2] )
return p;
if ( p == g_board[3] && p == g_board[6] )
return p;
}
p = g_board[3];
if ( PieceBlank != p && p == g_board[4] && p == g_board[5] )
return p;
p = g_board[6];
if ( PieceBlank != p && p == g_board[7] && p == g_board[8] )
return p;
p = g_board[1];
if ( PieceBlank != p && p == g_board[4] && p == g_board[7] )
return p;
p = g_board[2];
if ( PieceBlank != p && p == g_board[5] && p == g_board[8] )
return p;
p = g_board[4];
if ( PieceBlank != p )
{
if ( ( p == g_board[0] ) && ( p == g_board[8] ) )
return p;
if ( ( p == g_board[2] ) && ( p == g_board[6] ) )
return p;
}
return PieceBlank;
} /*LookForWinner*/
#endif
int g_IMoves = 0;
ttype MinMax( alpha, beta, depth, move ) ttype alpha; ttype beta; ttype depth; ttype move;
{
ttype pieceMove, score; /* better perf with char than int. out of registers so use stack */
register int p, value; /* better perf with these as an int on Z80, 8080, and 8086 */
g_IMoves++;
if ( depth >= 4 )
{
#if WinMethod == UseFunPointers
p = ( * winner_functions[ move ] )();
#endif
#if WinMethod == UseWinner2
p = winner2( move );
#endif
#if WinMethod == UseLookForWinner
p = LookForWinner();
#endif
if ( PieceBlank != p )
{
if ( PieceX == p )
return ScoreWin;
return ScoreLose;
}
if ( 8 == depth )
return ScoreTie;
}
if ( depth & 1 )
{
value = ScoreMin;
pieceMove = PieceX;
}
else
{
value = ScoreMax;
pieceMove = PieceO;
}
for ( p = 0; p < 9; p++ )
{
if ( PieceBlank == g_board[ p ] )
{
g_board[p] = pieceMove;
score = MinMax( alpha, beta, depth + 1, p );
g_board[p] = PieceBlank;
if ( depth & 1 )
{
#if WinLosePrune /* #if statements must be in first column for MS C 1.0 */
if ( ScoreWin == score )
return ScoreWin;
#endif
if ( score > value )
{
value = score;
#if ABPrune
if ( value >= beta )
return value;
if ( value > alpha )
alpha = value;
#endif
}
}
else
{
#if WinLosePrune
if ( ScoreLose == score )
return ScoreLose;
#endif
if ( score < value )
{
value = score;
#if ABPrune
if ( value <= alpha )
return value;
if ( value < beta )
beta = value;
#endif
}
}
}
}
return value;
} /*MinMax*/
long g_Moves = 0;
int FindSolution( position ) ttype position;
{
register int i;
for ( i = 0; i < 9; i++ )
g_board[ i ] = PieceBlank;
g_board[ position ] = PieceX;
for ( i = 0; i < g_Iterations; i++ )
{
g_IMoves = 0;
MinMax( ScoreMin, ScoreMax, 0, position );
g_Moves += g_IMoves; /* do the 4-byte long addition once per loop to save work */
}
return 0;
} /*FindSolution*/
#ifdef CPMTIME
struct CPMTimeValue
{
int h, m, s, l;
};
void print_time_now()
{
/* This CP/M BDOS call of 105 is only implemented in NTVCM -- it's not a standard CP/M 2.2 call */
struct CPMTimeValue t;
t.h = t.m = t.s = t.l = 0;
bdos( 105, &t );
printf( "current time: %02d:%02d:%02d.%02d\n", t.h, t.m, t.s, t.l );
} /*print_time_now*/
long get_ms()
{
/* This CP/M BDOS call of 105 is only implemented in NTVCM -- it's not a standard CP/M 2.2 call */
long h, m, s, l;
struct CPMTimeValue t;
t.h = t.m = t.s = t.l = 0;
bdos( 105, &t );
h = t.h;
m = t.m;
s = t.s;
l = t.l;
return h * 3600000 + m * 60000 + s * 1000 + l * 10;
} /*get_ms*/
#else /* no elif with old compilers */
#ifdef DOSTIME
void print_time_now()
{
/* Make a DOS interrupt call to get the time */
union REGS wrIn, wrOut;
wrIn.h.ah = 0x2c;
intdos( &wrIn, &wrOut );
printf( "current time: %02d:%02d:%02d.%02d\n", wrOut.h.ch, wrOut.h.cl, wrOut.h.dh, wrOut.h.dl );
fflush( stdout );
} /*print_time_now*/
long get_ms()
{
/* this function takes about 3 milliseconds on the original IBM PC */
long h, m, s, l;
union REGS wrIn, wrOut;
wrIn.h.ah = 0x2c;
intdos( &wrIn, &wrOut );
h = wrOut.h.ch;
m = wrOut.h.cl;
s = wrOut.h.dh;
l = wrOut.h.dl;
return h * 3600000 + m * 60000 + s * 1000 + l * 10;
} /*get_ms*/
#else
/* must do this on actual CP/M machines */
int print_time_now() { return 0; }
long get_ms() { return 0; }
#endif
#endif
int main( argc, argv ) int argc; char * argv[];
{
long start_time, end_time;
if ( 2 == argc )
sscanf( argv[ 1 ], "%d", &g_Iterations ); /* no atoi in MS C 1.0 */
start_time = get_ms();
FindSolution( 0 );
FindSolution( 1 );
FindSolution( 4 );
end_time = get_ms();
printf( "runtime in ms: %ld\n", end_time - start_time );
printf( "move count: %ld\n", g_Moves ); /* 6493 * g_Iterations */
printf( "iteration count: %d\n", g_Iterations );
printf( "method: %s\n",
( WinMethod == UseFunPointers ) ? "function pointers" :
( WinMethod == UseWinner2 ) ? "winner2" :
( WinMethod == UseLookForWinner ) ? "look for winner" :
"invalid method" );
return 0;
} /*main*/

BIN
DeSmet C88 v24/c88_251.pdf Normal file

Binary file not shown.

3
DeSmet C88 v24/errno.h Normal file
View File

@ -0,0 +1,3 @@
/* david lee made this */

3
DeSmet C88 v24/fcntl.h Normal file
View File

@ -0,0 +1,3 @@
/* david lee made this */

3
DeSmet C88 v24/io.h Normal file
View File

@ -0,0 +1,3 @@
/* david lee made this */

3
DeSmet C88 v24/m.bat Normal file
View File

@ -0,0 +1,3 @@
rem -nDESMETC doesn't work in this version of c88
ntvdm c88 %1
ntvdm bind %1 other

3
DeSmet C88 v24/setjmp.h Normal file
View File

@ -0,0 +1,3 @@
/* david lee made this */

3
DeSmet C88 v24/stdarg.h Normal file
View File

@ -0,0 +1,3 @@
/* david lee made this */

3
DeSmet C88 v24/stdlib.h Normal file
View File

@ -0,0 +1,3 @@
/* david lee made this */

3
DeSmet C88 v24/string.h Normal file
View File

@ -0,0 +1,3 @@
/* david lee made this */

3
DeSmet C88 v24/time.h Normal file
View File

@ -0,0 +1,3 @@
/* david lee made this */