Skip to content

Instantly share code, notes, and snippets.

@svofski
Last active February 15, 2023 14:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save svofski/c2aae20e1180aec73e0201ffa347e3cf to your computer and use it in GitHub Desktop.
Save svofski/c2aae20e1180aec73e0201ffa347e3cf to your computer and use it in GitHub Desktop.
stalk1.sav MT-Pascal refactoring
(*
Это восстановленный из исполнимого файла код на языке Паскаль для игры,
которая называлась 'Зона' или 'Сталкер', файл игры назывался
STALK.SAV, PIKNIK.SAV или ZONA.SAV и предназначался для советских PDP11-
совместимых машин - таких как ДВК и УКНЦ.
Это игра в жанре рогалик (Rogue-like), бродилка по подземельям, по мотивам
повести Стругацких "Пикник на обочине".
Игра, по-видимому, создана в конце 1980-х, автор игры - неизвестный
программист из Ульяновска - первоначально программа писала копирайт:
*** (С)УЛЬЯНОВСК УЛПИ "ГОЛОГРАФИЯ"***
Данный исходник предназначается для Паскаля ДВК или OMSI PASCAL-1
и компилируется в исполнимый файл под системой RT-11 командами:
PASCAL STALK1,STALK1=STALK1.PAS
LINK/STACK:1000 STALK1,FRANDU,PASCAL
*)
{$S-} { no recursion, all static }
{$R-} { run-time range checking off }
{$L+} { generate listing }
{$P-} { no form feed between pages }
PROGRAM STALK;
const
{ IND indices }
{ 1 - Рейтинг, 2 - Энергия, 3 - Оружие, 4 - Защита, 5 - В банке денег }
IRating = 1;
IEnergy = 2;
IWeapon = 3;
IArmor = 4;
IGold = 5;
{ quaff & 6
0 = sense objects
2 = refresh fatigue
4 = show map
6 = alcohol
whistle & 6
4 = whistle
2 = dig -2..+2 around self
0 = teleport
6 = destroy all monsters?
zap wand & 3
3 = fake
2 = show map (single use)
1 = golden orb owner teleports 3 levels up
otherwise, 3 levels down (single use)
0 = turn chasing beast into random junk
read & 6
0 = remove curse
2 = funny joke
4 = find staircase
6 = find golden orb location at level 8
}
SEEN = $40;
NOTSEEN = $bf;
CURSED = $20;
CURSEDNOT = $df;
SACKLO = 1;
SACKHI = 6;
type
TFlags = byte;
TState = (SCont, SRestart, SQuit);
TTile = record
CH: char;
FLAGS: TFlags;
end;
PTile = ^TTile;
TLoc = record
Y, X: integer;
end;
TMonster = record
TILE: TTile;
Y, X: integer;
end;
var
DUNGEON:integer; { Номер подземелья }
STEPCTR: integer;
FLOOR: integer; { Номер этажа }
TGT: TLoc;
PLR: TLoc;
LOOK: TLoc;
PREV: TLoc;
TIRED: integer; { Усталость }
HARM: integer; { Вредность }
BCHARGE:integer; { Заряд батарей фонаря }
DRUNK: integer;
SEED: integer; { Число для генератора случайных чисел }
TMPCHAR: char;
{ 1 - Рейтинг, 2 - Энергия, 3 - Оружие, 4 - Защита, 5 - В банке денег }
IND: array[IRating..IGold] of integer; { Индикаторы справа: }
PREVIND:array[IRating..IGold] of integer;
MAP: array[0..8,1..16,1..32] of TTile;
MPTR: PTile;
TGTPTR: PTile;
SACK: array [SACKLO..SACKHI] of TTile;
MONSTERS: array [1..4] of TMonster;
GAMEFLAGS: set of (DRAWSACK, FIGHTING, RING, LAMPON, HAVEORB);
EXTERNAL FUNCTION @BDOS(FUNC:INTEGER; PARM:WORD):INTEGER;
function RANDOM(A,B:integer):integer; {L01046}
var
ans: integer;
begin
SEED := (20077 * seed + 12345);
ans := SEED & $7fff;
if not ((A = 0) and (B = 32767)) then
ans := A + ans mod (B - A + 1);
RANDOM := ans;
end;
function READKEY: char;
begin
READKEY := CHR(@BDOS(6,WRD($FD)));
end;
procedure READCHAR(var CH:char; toupper: boolean);
begin
{ MicroDOS 5: up, 24: down, 8: left, 4: right }
CH := READKEY;
case ORD(CH) of
5: CH := '8';{ стрелка вверх }
24: CH := '2';{ стрелка вниз }
8: CH := '4';{ стрелка влево }
4: CH := '6';{ стрелка вправо }
end;
if (toupper) then { преобразуем в заглавные буквы }
if (ORD(CH) >= ORD('a')) and (ORD(CH) <= ORD('z')) then
CH := CHR(ORD(CH) + ORD('A') - ORD('a'));
end;
{ Поставить курсор на позицию (X*2,Y) }
procedure CURSORTO(Y, X:integer); {L01216}
begin
WRITE(CHR(27), 'Y', CHR(32 + y), CHR(32 + x + x));
end;
procedure CLRSCR;
begin
WRITE(CHR(27),'H',CHR(27),'J');
end;
procedure CLREOL;
begin
WRITE(CHR(27),'K');
end;
procedure TERMCR;
var
CH: char;
begin
CH := CHR(@BDOS(2, WRD(13)));
end;
procedure WRITEAT(y, x: integer; c: char);
begin
CURSORTO(y, x);
WRITE(c);
end;
{ Очистка блока сообщений внизу экрана }
procedure CLEARMSG; {L01320}
var
i: integer;
dummy: integer;
begin
CURSORTO(16,0);
for i := 1 to 7 do begin
dummy := @BDOS(2, WRD(10));
CLREOL;
end;
CURSORTO(17,0);
end;
{ true if LOOK = (0,0) }
function LOOKATPLAYER: boolean;
begin
LOOKATPLAYER := (LOOK.X = 0) and (LOOK.Y = 0);
end;
function INFIELD(Y, X: integer): boolean;
begin
INFIELD := (Y in [2..15]) and (X in [2..31]);
end;
function WALL(c: char): boolean;
begin
WALL := c in ['!', '-'];
end;
procedure USEITEM(item: PTile);
begin
item^.CH := '.';
GAMEFLAGS := GAMEFLAGS + [DRAWSACK];
end;
function NOTCURSED(var T: TTile): boolean;
begin
NOTCURSED := (T.FLAGS & CURSED) = 0;
end;
{ показать один тайл и пометить его как увиденный }
procedure MAKESEEN(T: PTile);
begin
T^.FLAGS := T^.FLAGS | SEEN;
end;
procedure REVEAL(y, x: integer);
var
T: PTile;
begin
T := ADDR(MAP[FLOOR, y, x]);
WRITEAT(y, x, T^.CH);
MAKESEEN(T);
end;
{ печатаем область вокруг игрока и самого игрока }
procedure DRWAROUND;
var
i, j, y, x: integer;
range: integer;
p: PTile;
c: char;
begin
if LAMPON in GAMEFLAGS then
range := 1
else
range := 0;
for j := -range to range do begin
for i := -range to range do begin
y := PLR.Y + j;
x := PLR.X + i;
p := ADDR(MAP[FLOOR, y, x]);
MAKESEEN(p);
if (i | j) = 0 then
c := '@'
else if (p^.CH = '^') and ((p^.FLAGS & 6) <> 4) then
{ тайный студень }
c := '.'
else
c := p^.CH;
WRITEAT(y, x, c);
end;
end;
end;
{ Поиск предметов в рюкзаке }
function INVGET(A, B: char; var ITEM: PTile): boolean;
var
i: integer;
begin
ITEM := nil;
INVGET := FALSE;
for i := SACKLO to SACKHI do with SACK[i] do
if (CH = A) or (CH = B) then begin
ITEM := ADDR(SACK[i]);
INVGET := TRUE;
EXIT;
end;
end;
procedure SACKRESET(randomize: boolean);
var
i: integer;
begin
for i := SACKLO to SACKHI do begin
SACK[i].CH := '.';
if randomize then
SACK[i].FLAGS := RANDOM(0,8191) & CURSEDNOT;
end;
end;
{ выводим содержимое рюкзака }
procedure DRWRUKSAK;
var
i: integer;
begin
if DRAWSACK in GAMEFLAGS then begin
CURSORTO(10,33);
for i := SACKLO to SACKHI do
WRITE(SACK[i].CH:2);
GAMEFLAGS := GAMEFLAGS - [DRAWSACK];
end;
end;
procedure LIFTCURSE;
var
i: integer;
begin
for i := SACKLO to SACKHI do
SACK[i].FLAGS := SACK[i].FLAGS & CURSEDNOT;
WRITELN('"APCHXYZZYURR!!!"... Заклятие снято');
end;
{ переложить вещи в рюкзаке }
procedure CMDPACK;
var
i: integer;
tmp: TTile;
begin
tmp := SACK[SACKHI];
for i := SACKLO to SACKHI do
SACK[SACKHI + 1 - i] := SACK[SACKHI - i];
SACK[1] := tmp;
GAMEFLAGS := GAMEFLAGS + [DRAWSACK];
WRITELN('Перестройка в рюкзаке');
end;
procedure NELZYA;
begin
WRITELN(' Н е л ь з я ! ! !');
end;
{ wake up a monster, sometimes }
{ the original used to overwrite shared globals used in the outside loop }
procedure WAKEUPMONSTER(LY, LX:integer);
var
p: PTile;
i: integer;
found: integer;
begin
p := ADDR(MAP[FLOOR,LY,LX]);
WRITELN('З в е р ь !');
{ monster in REM sleep? }
if (p^.FLAGS & 4) <> 0 then begin
found := 0;
for i := 1 to 3 do
with MONSTERS[i] do begin
if TILE.CH = p^.CH then
EXIT; { такой уже есть, ничего не делаем }
if (TILE.CH = ' ') and (found = 0) then
found := i; { запомнили первый свободный слот }
end;
{ так в оригинале. новый монстр заменяет третьего }
if found = 0 then found := 3;
with MONSTERS[found] do begin
TILE := p^;
Y := LY;
X := LX;
end;
end;
end;
procedure ZAKLYATIE;
begin
WRITELN('На этой штуке заклятие');
end;
{ выводим значения индикаторов }
procedure DRWINDVAL;
var
i: integer;
val: integer;
begin
for i:=IRating to IGold do begin
val := IND[i];
if val <> PREVIND[i] then begin
PREVIND[i] := val;
CURSORTO(i,37);
WRITE(val:3, ' ');
end;
end;
CURSORTO(7,37);
WRITE(HARM:3); { Вредность }
end;
{ update pointers to player location }
procedure MOVEPLAYER(y, x: integer);
begin
PLR.Y := y;
PLR.X := x;
MPTR := ADDR(MAP[FLOOR, PLR.Y, PLR.X]);
end;
{ update pointers to target location }
procedure UPDTGTPTR;
begin
TGTPTR := ADDR(MAP[FLOOR,TGT.Y,TGT.X]);
end;
{ возвращает TRUE если надо перерисовать уровень }
function CLIMB(A: char): boolean;
var
i: integer;
begin
CLIMB := FALSE;
if MPTR^.CH = '%' then begin { Мы стоим на лестнице? }
WIPEMONSTERS;
if (A = '.') and (FLOOR <> 0) then begin
FLOOR := FLOOR - 1; { Этаж вверх }
IND[IEnergy] := IND[IEnergy] - 2; { Энергия минус 2 }
IND[IRating] := IND[IRating] + 1;
CLIMB := TRUE;
end else if FLOOR <> 8 then begin
FLOOR := FLOOR + 1;
IND[IRating] := IND[IRating] + 3;
CLIMB := TRUE;
end;
MOVEPLAYER(PLR.Y,PLR.X); { no change in X,Y but update pointer }
UPDTGTPTR;
end else begin { не на лестнице }
WRITELN(' Без лестницы?'); {L04140}
end;
end;
{ Параметр: 'J' - обновить экран; '.' - вверх; '5' - вниз }
procedure REFRESH(A:char);
var
q, p: integer;
pm: PTile;
begin
{ пометить все как грязное }
GAMEFLAGS := GAMEFLAGS + [DRAWSACK];
for q := IRating to IGold do
PREVIND[q] := -1;
if (A <> 'J') and not CLIMB(A) then EXIT;
CLRSCR;
WRITE(' Подземелье ');
WRITE(DUNGEON); { Номер подземелья }
CURSORTO(1,33); WRITE('Рейтинг');
CURSORTO(2,33); WRITE('Энергия');
CURSORTO(3,33); WRITE('Оружие');
CURSORTO(4,33); WRITE('Защита');
CURSORTO(5,33); WRITE('В банке');
CURSORTO(7, 32);WRITE(' Вредность');
CURSORTO(9, 33);WRITE('Рюкзак:');
DRWINDVAL;
DRWRUKSAK;
for q:=1 to 16 do begin { выводим текущее поле }
for p:=1 to 32 do begin
pm := ADDR(MAP[FLOOR,q,p]);
if (pm^.FLAGS & SEEN) <> 0 then
WRITEAT(q, p, pm^.CH);
end;
end;
CLEARMSG;
end;
procedure WALK(DY,DX:integer);
begin
{ Если не стенка }
if not WALL(MAP[FLOOR, PLR.Y + DY,PLR.X + DX].CH) then
MOVEPLAYER(PLR.Y + DY, PLR.X + DX)
else
NELZYA;
end;
{ place an item A at random position }
procedure RANDPLACE(A:char);
begin
with MAP[FLOOR, RANDOM(2,15), RANDOM(2,31)] do begin
CH := A;
FLAGS := RANDOM(0,32767) & NOTSEEN;
end;
end;
procedure FILLTILE(X: PTile; N: integer; c: char; flg: byte);
var
i: integer;
begin
for i := 1 to N do with X^ do begin
CH := c;
FLAGS := flg;
X := X + SIZEOF(PTile);
end;
end;
{ Начало игры, или рестарт на следующем подземелье }
{ create level outlines, fill floor with flags except cursed }
procedure RSTRT_A;
var
x, y, z: integer;
lflags: integer;
begin
CLRSCR;
CURSORTO(10,1);
{ NB: the original does not initialize border flags }
for z := 0 to 8 do begin
lflags := RANDOM(0,88) & CURSEDNOT;
FILLTILE(ADDR(MAP[z,1,1]), 32, '-', lflags);
FILLTILE(ADDR(MAP[z,16,1]), 32, '-', lflags);
for y:=2 to 15 do begin
FILLTILE(ADDR(MAP[z,y,1]), 32, '.', lflags);
MAP[z,y,1].CH := '!'; { стенка слева }
MAP[z,y,32].CH := '!'; { стенка справа }
end;
end;
end;
{ create horizontal walls on maze levels }
procedure RSTRT_B;
var
x, y, z: integer;
left, right: integer;
begin
for z:=1 to 8 do begin { цикл по этажам }
y:=RANDOM(2,7);
while y < 16 do begin
left:=2;
right:=RANDOM(1,7);
while right < 32 do begin
for x:=left to right do begin
MAP[z,y,x].CH := '-';
end;
left:=RANDOM(1,5)+right;
right:=RANDOM(3,10)+right;
end;
y:=RANDOM(0,7)+y;
end;
end;
end;
{ create vertical walls on maze levels }
procedure RSTRT_C;
var
x, y, z: integer;
top, bottom: integer;
begin
for z := 1 to 8 do begin { цикл по этажам }
x:=RANDOM(2,7);
while x < 32 do begin
top := 2;
bottom := RANDOM(1,7);
while bottom < 16 do begin
for y:=top to bottom do
with MAP[z,y,x] do if CH = '.' then
CH := '!'
else
CH := '#';
top := RANDOM(1,5)+bottom;
bottom := RANDOM(2,7)+bottom;
end;
x := RANDOM(2,5)+x;
end;
end;
end;
{ place random items }
procedure RSTRT_D;
var
i, j: integer;
begin
for i:=1 to DUNGEON do begin
for j:=32 to 127 do begin
FLOOR:=RANDOM(0,8);
RANDPLACE(CHR(j));
end;
end;
end;
procedure RSTRT_E;
var
z: integer;
begin
{ place mandatory items }
for z:=0 to 8 do begin
FLOOR := z;
RANDPLACE('^'); { witches jelly }
RANDPLACE('*'); { gold }
RANDPLACE('%'); { staircase }
end;
FLOOR:=8;
RANDPLACE('%'); { staircase }
RANDPLACE(','); { golden orb }
if DUNGEON = 1 then begin
SACKRESET(true);
SACK[1].CH := ']';
SACK[2].CH := '(';
SACK[3].CH := '<';
for z := IRating to IGold do
begin
PREVIND[z] := -1;
IND[z] := 0; { Очищаем индикаторы }
end;
{ Инициализация переменных }
IND[IEnergy]:=25; { Энергия }
DRUNK:=0;
BCHARGE:=400; { Заряд батарей }
TIRED:=0; { Усталость = 0 }
GAMEFLAGS := GAMEFLAGS + [DRAWSACK] - [LAMPON,RING,FIGHTING];
end;
GAMEFLAGS := GAMEFLAGS - [HAVEORB];
WIPEMONSTERS;
end;
procedure RESTART;
begin
RSTRT_A;
WRITELN(' Для подсказки нажимайте "H" ');
RSTRT_B;
TERMCR;
WRITE(' Темный коридор ... ');
RSTRT_C;
TERMCR;
WRITE(' С к е л е т ы . . . ');
RSTRT_D;
TERMCR;
WRITE(' a-a-a-a-a-a-a-a-a-a-a-a-a . . . . . . .');
RSTRT_E;
FLOOR := 0; { Этаж = 0 }
REFRESH('J');
CLEARMSG;
WRITE('Прогнивший пол провалился...');
STEPCTR := 0;
PREV.Y := 1; { Позиция Y игрока }
PREV.X := 1; { Позиция X игрока }
MOVEPLAYER(2, 2);
HARM := 1;
end;
{ step on, or pass by a monster
passing by may wake it up
stepping on it is a combat situation.
LOOK.Y, LOOK.X -- cell relative to player position (-1..1)
TGT.Y,TGT.X, TGTPTR -- absolute lookat position
LOOK.Y,LOOK.X = (0,0) means TGT points to player position (see LOOKAROUND)
}
procedure DOMONSTER;
var
i: integer;
my, mx: integer;
begin
if LOOKATPLAYER then begin
{ MPTR == TGTPTR here }
if (MPTR^.FLAGS & 6) = 0 then begin
{ enable wakeup flag on a prodded monster }
MPTR^.FLAGS := MPTR^.FLAGS | 6;
WRITELN('Ну, сейчас он вам покажет...')
end else if (MPTR^.FLAGS & 6) = 2 then begin
{ убегающий зверь }
my := RANDOM(-1,1) + PLR.Y;
mx := RANDOM(-1,1) + PLR.X;
if not WALL(MAP[FLOOR, my, mx].CH) then begin
MAP[FLOOR, my, mx] := MPTR^;
MPTR^.CH := '.';
end;
end else if not (RING in GAMEFLAGS) then begin {L15100}
if not (FIGHTING in GAMEFLAGS) then begin {L15120}
if IND[IArmor] > 1 then {L15140}
IND[IArmor] := IND[IArmor] - RANDOM(2, 15)
else
IND[IEnergy] := IND[IEnergy] - RANDOM(2, 15); { Энергия уменьшается }
WRITELN(CHR(7), 'Защищайтесь же!!!');
end else begin
IND[IWeapon] := IND[IWeapon] - RANDOM(2, 11);
IND[IArmor] := IND[IArmor] - 2;
GAMEFLAGS := GAMEFLAGS - [FIGHTING];
WRITELN(CHR(7), 'Готов!');
IND[IRating] := IND[IRating] + 10;
if IND[IArmor] < 0 then begin
IND[IEnergy] := IND[IEnergy] + IND[IArmor];
IND[IArmor] := 0;
end;
if IND[IWeapon] < 0 then begin
IND[IRating] := IND[IRating] + IND[IWeapon];
IND[IWeapon] := 0;
end;
i := 1;
while (MONSTERS[i].TILE.CH <> MPTR^.CH) and (i < 4) do
i := i + 1;
MONSTERS[i].TILE.CH := ' ';
MPTR^.CH := 'm'; { Дохлая крыса }
end;
end;
end
else
WAKEUPMONSTER(TGT.Y, TGT.X);
end;
procedure BLKHOLE;
begin
WRITELN('Черная дыра');
if LOOKATPLAYER then begin
if HAVEORB in GAMEFLAGS then begin
if FLOOR > 0 then
FLOOR:=FLOOR-1; { Этаж вниз }
end else begin
if FLOOR < 8 then
FLOOR:=FLOOR+1; { Этаж вверх }
end;
IND[IEnergy]:=IND[IEnergy]-3; { Энергия минус 3 }
HARM:=HARM + 7; { Вредность увеличиваем на 7 }
REFRESH('J');
WRITELN('Ой, как больно!...');
end;
end;
procedure JELLY;
begin
if LOOKATPLAYER then begin
{ 0,0 = player location, TGTPTR == MPTR }
WRITELN('Ведьмин студень!');
IND[IEnergy]:=IND[IEnergy]-RANDOM(3,15);
HARM:=HARM + RANDOM(0,5);
TGTPTR^.FLAGS := 4;
end;
end;
procedure MANGE;
begin
WRITELN('Комариная плешь');
MOVEPLAYER(TGT.Y, TGT.X);
if HAVEORB in GAMEFLAGS then
MPTR^.CH := '.';
end;
procedure FOOD;
var
taste: integer;
begin
if LOOKATPLAYER then begin
taste:=RANDOM(-7,7);
IND[IEnergy]:=IND[IEnergy]+taste;
if taste > 0 then begin
WRITELN('Недурственно!');
MPTR^.CH := 'z'; { Следы пикника. }
end else begin
WRITELN('Тьфу...');
MPTR^.CH := 'y'; { Что-то очень мерзкое }
end;
end else begin
WRITELN('Свертoк. съедим?');
end;
end;
procedure GHOST;
var
item: PTile;
begin
WRITE('Призрак.');
if INVGET('.', '.', item) then begin
HARM := HARM + 1;
item^.CH := '@';
end;
end;
procedure DESCRIBE;
begin
case TGTPTR^.CH of
'%': WRITE('Лестница.');
'*': WRITE('Золото.');
',': begin
if FLOOR = 8 then begin
WRITE('Золотой шар!!!');
GAMEFLAGS := GAMEFLAGS + [HAVEORB];
end else
WRITE('Волшебная кирка.');
end;
'$','+': WRITELN('Бутылка с надписью "Drink me!"');
' ': BLKHOLE;
'=': WRITE('Кольцо.');
'^': JELLY;
'#': if LOOKATPLAYER then begin
if RANDOM(1,2) = 1 then
MPTR^.CH := '!'
else
MPTR^.CH := '-';
end;
'(',')': WRITE('Доспехи.');
'[',']': WRITE('Оружие.');
'?': WRITE('Свисток.');
':',';': WRITE('Еда!!!');
'\','/': WRITE('"ВП".');
'<','>': WRITE('Батареи.');
'"','''': MANGE;
'&': WRITE('Папирус.');
'C','H','J','T':
begin
WRITE(CHR(7)); { bell }
WRITELN('Холодная, скользкая рука схватила вас за ногу ...');
IND[IEnergy]:=IND[IEnergy]-RANDOM(2,8); { Энергия уменьшается }
TGTPTR^.CH := '.';
end;
'D','E','F','G','I','K','L','M','N','O','P','Q','R','S','U','V','W','X','Y','Z':
DOMONSTER;
'0','2','3','4','5','6','7','8','9','{','}':
FOOD;
'!','-','.':; { Стенки и пустая клетка } {L16046}
'b': WRITELN('Надпись "Здесь был Вася"(здесь Вася и остался)'); {L16046}
'c': WRITE('Груда камней.');
'd': WRITELN('Метла бабы яги (сломана)');
'e': WRITE('Череп.');
'f': WRITELN('Полуистлевший скелет');
'g': WRITELN('Сгоревшая плата процессора М2');
'h': WRITELN('Кусочек Ноева ковчега');
'i': WRITELN('Записка:" Авторы желают вам вернуться живым..."');
'j': WRITE('Черный ящик.');
'k': WRITELN('Лужа машинного масла');
'l': WRITELN('Дистрибут ОС "Holographyx V07" для ЭВМ PDP-12');
'm': WRITE('Дохлая крыса.');
'n': WRITE('Зуда.');
'o': WRITE('Пустышка.');
'p': WRITE('Куча сепулек.');
'r': WRITELN('Надпись "Здесь вы и останетесь!"');
's': WRITELN('Указатель: "Как, вы еще живы? ==> 158 М."');
't': WRITELN('Зачитанный журнал "Илектроникс энд уайрлесс уорлд(Радио)"');
'u': WRITELN('Журнал "Juzhnye Dewochky" за 21 апреля 1999 года');
'v': WRITE('Артефакт.');
'w': WRITELN('Надпись "Здесь-то мы его и съели"');
'x': WRITELN('Надпись "Привет Сивому"');
'y': WRITELN('Что-то очень мерзкое');
'z': WRITE('Следы пикника.');
'q': WRITELN('Останки предыдущего путешест...');
'~': WRITE('Черт-те что.');
'1','A','B': WRITELN('Бродячий торговый автомат');
'|': WRITELN('Пережаренный зелюк.'); { Осциллограф "ИО-4Б" }
'`': WRITELN('Мышелот (в собственном соку)');
'@': GHOST;
else begin {L17302}
if LOOKATPLAYER then with MPTR^ do begin
CH := CHR(RANDOM(32,126));
FLAGS := RANDOM(1,8191);
end else
WRITELN('Мешок с надписью "Take me!"');
end
end; { case of }
end;
{ показать и обработать события в окрестности игрока }
procedure LOOKAROUND;
var
y, x: integer;
begin
for y := -1 to 1 do begin
for x := -1 to 1 do begin
LOOK.Y:=y;
LOOK.X:=x;
TGT.Y := PLR.Y + y; { новый Y }
TGT.X := PLR.X + x; { новый X }
UPDTGTPTR; { update TGTPTR }
DESCRIBE;
end;
end;
end;
{ хелп } {L34046}
procedure CMDHALP;
begin
CLRSCR;
WRITELN('Ладно, я кое-что подскажу. Итак: здесь творится черт знает что,');
WRITELN('но на восьмом уровне лежит золотой шар. Только достав его, Вы');
WRITELN('сможете выйти из подземелья, придя на то же место, откуда вы вышли');
WRITELN('вначале. Своим глазам не всегда стоит доверять!');
WRITELN(' Вы можете использовать команды:');
WRITELN('A - Купить (на золото)');
WRITELN('B - Заменить батареи');
WRITELN('D - Выбросить предмет');
WRITELN('E - Поесть');
WRITELN('F - Приготовиться к сражению');
WRITELN('H - HELP (этот текст)');
WRITELN('I - Надеть кольцо');
WRITELN('J - Обновить экран');
WRITELN('K - Сломать стенку (киркой)');
WRITELN('L - Включить фонарь');
WRITELN('M - Приготовить оружие');
WRITELN('N - Клавиша "Идет начальник" (отбой тревоги - "P")');
WRITELN('O - Выключить фонарь');
WRITELN('P - Надеть доспехи');
WRITELN('Q - Пить');
WRITELN('R - Читать папирус');
WRITELN('S - Свистнуть');
WRITELN('T - Взять предмет, на котором стоишь');
WRITE('U - Вызвать джинна (только в безнадежном случае!)... Дальше? ');
READCHAR(TMPCHAR, FALSE);
if TMPCHAR = CHR(13) then begin
READCHAR(TMPCHAR, FALSE);
end;
WRITELN('');
WRITELN('V - Снять кольцо');
WRITELN('W - Взмахнуть волшебной палочкой');
WRITELN('X - Закончить');
WRITELN('Y - Зажарить убегающего зверя');
WRITELN('Z - Перевести деньги в банк на счет пещеры.');
WRITELN('/ - Переложить вещи в рюкзаке');
WRITELN(' П Е Р Е Д В И Ж Е Н И Е:');
WRITELN('');
WRITELN(' 7 8 9');
WRITELN(' 4 6 - Движение по уровню');
WRITELN(' 1 2 3');
WRITELN('5 - Вниз по лестнице');
WRITELN('. - Вверх по лестнице');
WRITELN('0 - Отдыхать.');
WRITELN('');
WRITELN('Использовать можно лишь вещи, лежащие в рюкзаке.');
WRITELN('Примечание:');
WRITELN(' Волшебная кирка вынесет вас из "комариной плеши" при ударе ей вниз.');
WRITELN('');
WRITE('Ну, что, пойдем дальше? ');
READCHAR(TMPCHAR, TRUE);
if TMPCHAR = CHR(13) then begin
READCHAR(TMPCHAR, TRUE);
end;
REFRESH('J'); { Обновить экран }
IND[IRating]:=IND[IRating] - 2; { Рейтинг }
end;
{ показать объекты на карте, но не весь пол }
procedure SHOWOBJS;
var
x, y: integer;
begin
for y:=2 to 15 do begin {L21734}
for x:=2 to 31 do begin
if MAP[FLOOR,y,x].CH <> '.' then
REVEAL(y,x);
end;
end;
end;
procedure FUNNYMAP;
var
x, y: integer;
tmp: char;
begin
{ print funny map }
for y:=2 to 15 do begin
for x:=2 to 31 do begin
tmp := MAP[FLOOR, y, x].CH;
if tmp <> '.' then begin
if not (tmp in ['!','#','-']) then
tmp := CHR(RANDOM(ORD('!'),ORD('~')));
WRITEAT(y, x, tmp);
end;
end;
end;
end;
{ заглотить зелье }
procedure CMDQUAFF;
var
y: integer;
item: PTile;
begin { пить }
if INVGET('$', '+', item) then begin
USEITEM(item);
HARM:=HARM - 1;
case item^.FLAGS & 6 of
0: begin
FUNNYMAP;
CLEARMSG;
end;
2: begin
IND[IEnergy]:=IND[IEnergy]+20; { выпил }
TIRED:=0;
WRITELN('Чувствуете прилив сил?'); {L21654}
end;
4: begin
SHOWOBJS;
CLEARMSG;
end;
6: begin
DRUNK:=20; {L22404}
WRITELN('Напился - сдай стеклотару!!!!');
end;
end;
end else
WRITELN('Пить нечего');
end;
procedure WIPEMONSTERS;
var
i: integer;
begin
for i := 1 to 4 do
MONSTERS[i].TILE.CH := ' ';
end;
{ свистнуть }
procedure CMDSIFFLER;
var
y, x: integer;
item: PTile;
pc: ^char;
begin
{ Ищем в рюкзаке свисток }
if INVGET('?', '?', item) then begin
case item^.FLAGS & 6 of
4: WRITE(CHR(7)); { bell }
2: begin
for y := -2 to 2 do begin
for x := -2 to 2 do begin
if INFIELD(PLR.Y + y, PLR.X + x) then
MAP[FLOOR,PLR.Y + y,PLR.X + x].CH := ' ';
end;
end;
USEITEM(item);
end;
0: begin
WRITELN('Б А М - М - М ! ! !');
MOVEPLAYER(RANDOM(2,15), RANDOM(2,31));
end;
6: begin
WRITELN('Уничтожение зверя');
WIPEMONSTERS;
for y := -1 to 1 do
for x := -1 to 1 do begin
pc := ADDR(MAP[FLOOR, PLR.Y + y, PLR.X + x].CH);
if pc^ in ['A'..'Z'] then pc^ := '*';
end;
end;
end;
end else
WRITELN('Однако, свисток нужен');
end;
{ выбросить предмет }
procedure CMDDROP;
var
item: PTile;
begin
WRITE('Что выбросить? ');
READCHAR(TMPCHAR, FALSE);
CLEARMSG;
if (TMPCHAR <> '.') and INVGET(TMPCHAR, TMPCHAR, item) then begin
if NOTCURSED(item^) then begin
{ из плеши нельзя выбраться выбросив в нее барахло }
if not (MPTR^.CH in ['"','''']) then
MPTR^ := item^;
HARM := HARM - 1;
USEITEM(item);
end else
ZAKLYATIE;
end else
WRITELN('Нету');
end;
{ поесть }
procedure CMDEAT;
var
item: PTile;
begin
if INVGET(':', ';', item) then begin
IND[IEnergy] := IND[IEnergy] + 18; { Энергия }
USEITEM(item);
HARM := HARM - 1;
WRITELN('Спасибо!');
end else
WRITELN('Еды нет');
end;
{ взять предмет, на котором стоишь }
procedure CMDTAKE;
var
item: PTile;
begin
{ Ищем место в рюкзаке }
if INVGET('.', '.', item) then begin
if MPTR^.CH in ['"',''''] then
NELZYA { Комариную плешь брать нельзя }
else begin
WRITELN('Берем');
HARM := HARM + 1;
item^ := MPTR^;
MPTR^.CH := '.';
GAMEFLAGS := GAMEFLAGS + [DRAWSACK];
end;
end else
WRITELN('Рюкзак полон');
end;
{ перевести деньги в банк на счёт пещеры } {L23010}
procedure CMDWIRE;
var
item: PTile;
begin
if INVGET('*', '*', item) then begin
IND[IRating] := IND[IRating] + 1;
HARM := HARM - 1;
USEITEM(item);
IND[IGold] := IND[IGold] + RANDOM(10, 70);
WRITELN('Там!');
end else
WRITELN('Где золото-тo?');
end;
{ надеть доспехи }
procedure CMDWEAR;
var
item: PTile;
begin
if INVGET(')', '(', item) then begin
if NOTCURSED(item^) then begin
USEITEM(item);
IND[IArmor] := IND[IArmor] + 11;
WRITELN('Доспехи надеты');
end else
ZAKLYATIE;
end else
WRITELN('Нету');
end;
procedure SHOWMAP;
var
x, y: integer;
begin
for x := 2 to 31 do
for y := 2 to 15 do
REVEAL(y, x);
end;
{ взмахнуть волшебной палочкой }
procedure CMDZAP;
var
item: PTile;
i: integer;
begin
if INVGET('/', '\', item) then begin
case item^.FLAGS & 3 of
3: WRITELN('Выпустили до госприемки...');
2: begin
SHOWMAP;
USEITEM(item);
CLEARMSG;
WRITELN('"Да будет свет..."');
end;
1: begin
if HAVEORB in GAMEFLAGS then begin
FLOOR := FLOOR - 3;
if FLOOR < 0 then FLOOR := 0;
end else begin
FLOOR := FLOOR+3;
if FLOOR > 8 then FLOOR := 8;
end;
USEITEM(item);
REFRESH('J');
WRITELN('Пока Вы летели сквозь этажи, "ВП" потерялась');
HARM := HARM - 1;
end;
0: begin
WRITELN('Превращение догоняющего зверя');
for i := 1 to 3 do with MONSTERS[i] do
if TILE.CH <> ' ' then begin
TILE.CH := ' ';
MAP[FLOOR,Y,X].CH := CHR(RANDOM(ord('$'),ord('?')));
end;
end;
end;
end else
WRITELN('Махать-то нечем !');
end;
{ включить фонарь }
procedure CMDLANTERN(on: boolean);
begin
if on then begin
if BCHARGE > 0 then begin
GAMEFLAGS := GAMEFLAGS + [LAMPON];
WRITELN('Фонарь включен');
end else
WRITELN('Батареи сели.Надо было экономить ... ');
end
else begin { выключить фонарь }
GAMEFLAGS := GAMEFLAGS - [LAMPON];
WRITELN('Фонарь выключен');
end;
end;
procedure LOCATE(L: integer; WHAT: char; var Y, X: integer);
var
mx, my: integer;
begin
Y := -1;
X := -1;
for my := 2 to 15 do
for mx := 2 to 31 do
if MAP[L, my, mx].CH = WHAT then
begin
Y := my;
X := mx;
EXIT;
end;
end;
procedure LOCATESTAIRS;
var
mx, my: integer;
begin
LOCATE(FLOOR, '%', my, mx);
WRITELN('Лестница -', my:4, mx:4);
end;
procedure LOCATEORB;
var
mx, my: integer;
begin
LOCATE(8, ',', my, mx);
if my = -1 then
WRITELN('Золотой шар украден!')
else
WRITELN('Золотой шар - 8', my:4, mx:4);
end;
{ читать папирус }
procedure CMDREAD;
var
item: PTile;
begin
if INVGET('&', '&', item) then
case item^.FLAGS & 6 of
0: LIFTCURSE;
2: WRITELN('Надпись гласит: "Сам дурак"');
4: LOCATESTAIRS;
6: LOCATEORB;
end
else
WRITELN('А читать-то и нечего');
end;
{ сломать стенку киркой }
procedure CMDDIG;
var
mx, my: integer;
item: PTile;
begin
if INVGET(',', ',', item) then begin
WRITE('Направление? ');
READCHAR(TMPCHAR, FALSE);
CLEARMSG;
my := PLR.Y;
mx := PLR.X;
case TMPCHAR of
'1': begin my := PLR.Y + 1; mx := PLR.X - 1; end;
'2': my := PLR.Y + 1;
'3': begin my := PLR.Y + 1; mx := PLR.X + 1; end;
'4': mx := PLR.X - 1;
'5': MPTR^.CH := ' ';
'6': mx := PLR.X + 1;
'7': begin my := PLR.Y - 1; mx := PLR.X - 1; end;
'8': my := PLR.Y - 1;
'9': begin my := PLR.Y - 1; mx := PLR.X + 1; end;
'.': if FLOOR > 0 then begin
MAP[FLOOR-1,PLR.Y,PLR.X].CH := ' ';
WRITELN('Кусок свода обрушился и раскололся о вашу глупую голову');
end;
else
NELZYA
end;
if INFIELD(my, mx) and WALL(MAP[FLOOR,my,mx].CH) then begin
MAP[FLOOR,my,mx].CH := 'c';
IND[IEnergy] := IND[IEnergy] - 1;
end else
WRITELN('Ну, чего размахался?');
end
else
WRITELN('А стенку вы будете лбом прошибать?..');
end;
{ вызвать джинна }
procedure CMDGENIE;
var
i: integer;
z: integer;
begin
if not (HAVEORB in GAMEFLAGS) then begin
WRITELN('Что, влип? ладно, попробую тебя перенести');
WRITELN('отсюда. только дороговато это встанет...');
WRITE('Ты готов? ');
READCHAR(TMPCHAR, TRUE);
if TMPCHAR <> 'N' then begin
for i := IRating to IGold do
IND[i] := IND[i] - RANDOM(0,15);
SACKRESET(false); { clear sack, do not change item flags }
z := RANDOM(0, 8);
if z > FLOOR then
z := FLOOR;
FLOOR := z;
MOVEPLAYER(RANDOM(2,15), RANDOM(2,31));
REFRESH('J'); { Обновить экран }
end;
end else
WRITELN('Джинн в отгуле');
end;
{ купить (на золото) }
procedure CMDBUY;
var
item: PTile;
begin
if MPTR^.CH in ['1','A','B'] then begin
if IND[IGold] > 0 then begin { В банке есть деньги? }
WRITE('Чего изволите?');
READCHAR(TMPCHAR, FALSE);
if INVGET('.', '.', item) then begin
item^.CH := TMPCHAR;
item^.FLAGS := RANDOM(1, 8191) & CURSEDNOT;
IND[IGold] := IND[IGold] - RANDOM(10, 250);
TERMCR;
WRITELN('П о л у ч и т е !');
MPTR^.CH := 'k';
end;
end else
WRITELN('Подаю только по пятницам!');
end else
WRITELN('Подойди ближе к автомату!');
end;
{ заменить батареи }
procedure CMDBATT;
var
item: PTile;
begin
if INVGET('<', '>', item) then begin
if NOTCURSED(item^) then begin
USEITEM(item);
HARM := HARM - 1;
BCHARGE := 400;
WRITELN('Батареи заменены');
end else
ZAKLYATIE;
end else
WRITELN('Батарей нет');
end;
procedure CMDRING(on: boolean);
var
item: PTile;
begin
if on then begin { надеть кольцо }
if INVGET('=', '=', item) then begin
if NOTCURSED(item^) then begin
USEITEM(item);
WRITELN('Силовое поле включено!');
GAMEFLAGS := GAMEFLAGS + [RING];
end else
ZAKLYATIE;
end else
WRITELN('Нету');
end
else begin { снять кольцо }
if RING in GAMEFLAGS then begin
if INVGET('.', '.', item) then begin
item^.CH := '=';
item^.FLAGS := CURSED;
GAMEFLAGS := GAMEFLAGS - [RING] + [DRAWSACK];
end else
WRITELN('Рюкзак полон');
end else
WRITELN('Кольца нет');
end;
end;
{ приготовить оружие }
procedure CMDWIELD;
var
item: PTile;
begin
if INVGET('[', ']', item) then begin
if NOTCURSED(item^) then begin
USEITEM(item);
IND[IWeapon] := IND[IWeapon] + 15;
WRITELN('Оружие приготовлено');
end else
ZAKLYATIE;
end else
WRITELN('Нету!');
end;
{ зажарить убегающего зверя }
{ NB: бродячие торговые автоматы A и B, если их флаги соответствуют,
тоже можно зажарить }
procedure CMDCOOK;
begin
if ((MPTR^.FLAGS & 6) = 2) and (MPTR^.CH in ['A'..'Z']) then
MPTR^.CH := ':' { Зверь становится едой }
else
NELZYA;
end;
{ преследование игрока монстрами }
procedure MONSTCHASE;
var
i: integer;
newx, newy: integer;
begin
for i := 1 to 4 do with MONSTERS[i] do begin
if (TILE.CH <> ' ') and ((Y <> PLR.Y) or (X <> PLR.X)) then begin
newy := Y;
newx := X;
if PLR.Y > Y then
newy := Y + 1
else if PLR.Y < Y then
newy := Y - 1;
if PLR.X > X then
newx := X + 1
else if PLR.X < X then
newx := X - 1;
{ зверь расшибается об стенку }
if WALL(MAP[FLOOR,newy,newx].CH) and ((TILE.FLAGS & 6) = 4) then
TILE.CH := ' '
else begin
{ зверь все сносит на своем пути }
MAP[FLOOR, Y, X].CH := '.';
WRITEAT(Y, X, '.');
WRITEAT(newy, newx, TILE.CH);
MAP[FLOOR, newy, newx] := TILE;
Y := newy;
X := newx;
CURSORTO(18, 0);
CLREOL;
end;
end;
end;
end;
function CHKENERGY: boolean;
begin
CHKENERGY := TRUE;
if IND[IEnergy] < 0 then begin { Умер от недостатка Энергии }
WRITE(' Вот Вы и стали', RANDOM(10,1000):4, '-ой жертвой этого подземелья.');
CHKENERGY := FALSE; { ded x_X }
end;
end;
function CHKEXIT: integer;
begin
CHKEXIT := 0;
if (FLOOR = 0) and (HAVEORB in GAMEFLAGS) and
(PLR.Y = 2) and (PLR.X = 2) then begin
if IND[IGold] >= 0 then begin { В банке есть деньги? }
WRITELN('Как, Вы вернулись?! Ну и ну !!!');
WRITE('А дальше пойдете? ');
READCHAR(TMPCHAR, TRUE);
if TMPCHAR = 'Y' then begin
DUNGEON := DUNGEON + 1; { следующее подземелье }
IND[IRating] := IND[IRating] + 50; { Рейтинг }
CHKEXIT := 1; { Рестарт игры }
end
else
CHKEXIT := 2; { Выходим из игрового цикла }
end else
WRITELN('А расплачиваться кто будет?');
end;
end;
{ Расчёт счёта игрока }
procedure ENDSCORE;
var
score: integer;
begin
score := IND[IRating] + ((IND[IEnergy] + IND[IWeapon] + IND[IArmor] +
IND[IGold] div 5) div 3);
WRITELN('Ваш счет -', score:5);
end;
procedure DRUNKWALK;
var
y, x: integer;
begin
if DRUNK > 0 then begin
y := PLR.Y + RANDOM(-1, 1);
x := PLR.X + RANDOM(-1, 1);
if INFIELD(y, x) then begin
MOVEPLAYER(y, x);
DRUNK := DRUNK - 1;
end;
end;
end;
procedure HANDLECMD(var STATE: TState);
begin
case TMPCHAR of
'1': WALK(1,-1); { влево-вниз }
'2': WALK(1,0); { вниз }
'3': WALK(1,1); { вправо-вниз }
'4': WALK(0,-1); { влево }
'5': REFRESH('5'); { вниз по лестнице }
'6': WALK(0,1); { вправо }
'7': WALK(-1,-1); { влево-вверх }
'8': WALK(-1,0); { вверх }
'9': WALK(-1,1); { вправо-вверх }
'0': TIRED := 0; { отдохнуть }
'.': REFRESH('.'); { вверх по лестнице }
'Q': CMDQUAFF;
'D': CMDDROP;
'Z': CMDWIRE;
'S': CMDSIFFLER;
'E': CMDEAT;
'T': CMDTAKE;
'P': CMDWEAR;
'L': CMDLANTERN(true);
'O': CMDLANTERN(false);
'W': CMDZAP;
'/','?': CMDPACK;
'F':begin { приготовиться к сражению }
GAMEFLAGS := GAMEFLAGS + [FIGHTING];
WRITELN('У-р-р-р-а-a ! ! !');
end;
'N':begin { идёт начальник }
{ игнорируем }
end;
'X':begin { закончить }
WRITE('Закончить изволите? ');
READCHAR(TMPCHAR, TRUE);
if TMPCHAR in ['D','Y'] then begin
WRITELN('А ведь предупреждали...');
STATE := SQuit;
end;
end;
'M': CMDWIELD;
'B': CMDBATT;
'J': REFRESH('J'); { обновить экран }
'R': CMDREAD;
'I': CMDRING(true);
'V': CMDRING(false);
'A': CMDBUY;
'K': CMDDIG;
'Y': CMDCOOK;
'H': CMDHALP;
'U': CMDGENIE;
else
WRITELN('Что-что?')
end;
end;
procedure GAMELOOP;
var
state: TState;
begin
WRITELN(' ^_^_^_^ __ С Т А Л К Е Р __ ');
WRITE('загадайте число. может быть, оно вам пригодится... там... ');
READLN(SEED);{ Ввод числа, которое "может быть пригодится там" }
DUNGEON := 1; { Подземелье = 1 }
repeat
state := SCont;
RESTART;
(* MAP[0,5,4].FLAGS := 2; 42: жарить торговый автомат *)
{ Начало игрового цикла }
while state = SCont do begin
{ обработать все, что под игроком и вокруг:
LOOKAROUND -> DESCRIBE -> (BLKHOLE,JELLY,MANGE,DOMONSTER,FOOD,*)
}
LOOKAROUND;
{ нарисовать окрестность игрока и самого игрока }
DRWAROUND;
{ восстановить предыдущую позицию }
if (PREV.Y <> PLR.Y) or (PREV.X <> PLR.X) then
WRITEAT(PREV.Y, PREV.X, MAP[FLOOR, PREV.Y, PREV.X].CH);
PREV := PLR;
CURSORTO(1,0);
WRITE(FLOOR:3);
{ изобразить индикаторы }
DRWINDVAL;
{ изобразить рюкзак }
DRWRUKSAK;
{ Ввод символа - команда игрока }
CURSORTO(0,0);
READCHAR(TMPCHAR, TRUE);
CLEARMSG;
HANDLECMD(state);
if state = SQuit then
EXIT;
DRUNKWALK;
STEPCTR := STEPCTR + ((IND[IWeapon] + IND[IArmor]) div 10);
if STEPCTR > 200 then begin
STEPCTR := 0;
IND[IRating] := IND[IRating] + 1;
IND[IEnergy] := IND[IEnergy] - 1;
end;
if IND[IEnergy] < 5 then
WRITELN('Силы на исходе');
if IND[IEnergy] > 50 then IND[IEnergy]:=50;
if LAMPON in GAMEFLAGS then begin
BCHARGE := BCHARGE - 1; { Уменьшаем заряд батарей }
if (BCHARGE > 1) and (BCHARGE < 10) then
WRITELN('Фонарь гаснет');
if BCHARGE = 1 then begin
IND[IRating] := IND[IRating] - 1;
GAMEFLAGS := GAMEFLAGS - [LAMPON]; { Фонарь не горит }
BCHARGE:=0; { Заряд батарей }
end;
end;
TIRED := TIRED + HARM;
if TIRED > 200 then
WRITELN('Отдохнуть-бы');
if TIRED > 215 then begin { Слишком устал }
IND[IEnergy] := IND[IEnergy] - 3;
TIRED:=50;
end;
MONSTCHASE;
if not CHKENERGY then
state := SQuit
else
case CHKEXIT of
1: state := SRestart;
2: state := SQuit;
end;
end;
until state = SQuit;
end;
(*
procedure TETS;
var
x, y: integer;
begin
RSTRT_A;
WRITELN;
for y := 1 to 16 do begin
for x := 1 to 32 do begin
WRITE(MAP[0,y,x].CH:2);
end;
WRITELN;
end;
INLINE($76);
end;
procedure TEST;
var i: integer;
begin
for i := 0 to 20 do WRITELN(RANDOM(-1,1));
end;
*)
BEGIN
GAMELOOP;
ENDSCORE;
END.
@svofski
Copy link
Author

svofski commented Jun 2, 2021

To build

set -e

if [ "$1" == "prn" ] ; then
    opt='$PA X'
fi

rm -f stalk1.com stalk1.erl stalk1.prn stalk1.dis

../../cpm/cpm mtplus stalk1.pas "$opt"
../../cpm/cpm linkmt stalk1,paslib/s/d:8000/m
ls -l stalk1.com
mkdir -p fdd

if [ "$1" == "prn" ] ; then
  ../../cpm/cpm dis8080 stalk1 >stalk1.dis
fi

cp stalk1.* fdd/

# listing + disasm
#../../cpm/cpm mtplus stalk1.pas '$PA X'
#../../cpm/cpm dis8080 stalk1 >stalk1.dis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment