|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 16000 (0x3e80) Types: TextFile Names: »PACMAN.PAS«
└─⟦9f1fc2afd⟧ Bits:30005939 Spil: Pacman, Invaders, Kong til RC700 └─ ⟦this⟧ »PACMAN.PAS«
(*$A+ NO PROCEDURE-RECURSIVITY *) PROGRAM PACMAN; (* MADE BY Keld K. Jensen 17/2-83 *) (* AND REVIDED BY Torben Simonsen 8/3-83 *) LABEL EXIT; CONST MACHINE='RC702'; BELL=7; (* THE ASCII CODE FOR A BEEP *) LF=10; (* THE ASCII CODE FOR LINE FEED *) FF=12; (* THE ASCII CODE FOR FORM FEED (CLEAR SCREEN) *) CR=13; (* THE ASCII CODE FOR CARRIAGE RETURN *) SUB=26; (* THE ASCII CODE FOR CURSOR UP *) ESC=27; (* THE <ESC> OR ^Æ KEY *) GS=29; (* THE ASCII CODE FOR CURSOR-HOME *) CLREOLN=30; (* THE ASCII CODE FOR CLEAR-TO-END-OF-LINE *) CLREOS=31; (* THE ASCII CODE FOR CLEAR-TO-END-OF-SCREEN *) NORM=128; (* NORMAL DISPLAY CODE *) FLASH=130; (* FLASHING DISPLAY CODE *) UP=26; (* THE ARROW-UP KEY *) DOWN=10; (* THE ARROW-DOWN KEY *) LEFT=8; (* THE ARROW-LEFT KEY *) RIGHT=24;(* THE ARROW-RIGHT KEY *) SCREENPLACE=$F800; (* THE POSITION OF THE SCREEN MEMORY-MAP *) PACNO=3; (* THE NUMBER OF TIMES THE PACMAN CAN BE EATEN *) TYPE BYTE=0..255; SCREENTYPE=ARRAY(.1..25,1..80.) OF BYTE; SCORETYPE=ARRAY(.1..10.) OF RECORD NAME:STRING(.20.); SCORE:INTEGER END; (* RECORD *) HTYPE=(LOWER,HIGHER); VAR X,Y, (* THE POSITION OF THE PACMAN *) A,B,C, (* ALL-PURPOSE VARIABLES *) HORI,VERTI,HORIX,VERTIX, (* DIRECTION OF THE PACMAN *) DEADTIMES, (* THE NUMBER OF TIMES THE PACMAN HAS BEEN EATEN *) PILLS, (* THE NUMBER OF PILLS YOU HAVE EATEN *) POWER, (* THE TIME COUNT FROM AN EATEN POWER-PILL *) IDELAY,DELAY, (* DELAY TIME *) DUMMY, (* DUMMY VARIABLE *) POINT: (* THE POINT COUNT *) INTEGER; FV: FILE OF SCREENTYPE; (* THE FILES CONTAINING THE SCREEN IMAGES *) F:FILE OF SCORETYPE; (* THE FILE CONTAINING THE HIGH-SCORE *) HISCORE:SCORETYPE; (* HIGH-SCORE NAME AND VALUE *) SCREEN:SCREENTYPE AT SCREENPLACE; (* THE MEMORY-MAP OF THE SCREEN *) EDISP:SCREENTYPE; (* THE ENDING DISPLAY *) DISPS, (* THE BOARD TO DISPLAY *) CONTS, (* THE BOARD TO CONTROL THE MONSTERS *) IDISP: (* THE STARTING DISPLAY *) ARRAY(.HTYPE.) OF SCREENTYPE; KEY:STRING(.1.); (* INPUT KEY VARIABLE *) LT,VT, (* THE MONSTER POSITIONS *) PX,PY, (* THE MONSTER DIRECTIONS *) LEG: (* THE LEG-TYPE OF THE MONSTERS *) ARRAY(.1..3.) OF INTEGER; DEAD:BOOLEAN; (* BECOMES TRUE WHEN THE PACMAN IS EATEN *) BX, (* ALL-PURPOSE VARIABLE *) BOARD: (* THE NUMBER OF THE BOARD ON WHICH THE PACMAN IS *) HTYPE; ALIVE,TURNMONST:ARRAY(.1..3.) OF BOOLEAN; MBOARD:ARRAY(.1..3.) OF HTYPE; PROCEDURE PACMAN; VAR A:INTEGER; BEGIN A:=ADDR(SCREEN(.Y+2*VERTI,X+3*HORI.)); CODE $F5,$C5,$D5,$E5,$3E,$20,$2A,A,$01,$50,$00,$77,$23,$77,$23,$77,$09, $77,$2B,$77,$2B,$77,$E1,$D1,$C1,$F1; A:=ADDR(SCREEN(.Y,X.)); CODE $F5,$C5,$D5,$E5,$2A,A,$01,$50,$00,$36,126,$23,$36,127,$23,$36,125, $09,$36,63,$2B,$36,127,$2B,$36,111,$E1,$D1,$C1,$F1; END; PROCEDURE MOUTH; BEGIN CASE ORD(KEY) OF 8: BEGIN SCREEN(.Y,X.):=43; SCREEN(.Y+1,X.):=120 END; 24: BEGIN SCREEN(.Y,X+2.):=39; SCREEN(.Y+1,X+2.):=116 END; 10: BEGIN SCREEN(.Y+1,X.):=63; SCREEN(.Y+1,X+1.):=35; SCREEN(.Y+1,X+2.):=111 END; 26: BEGIN SCREEN(.Y,X.):=125; SCREEN(.Y,X+1.):=112; SCREEN(.Y,X+2.):=126 END END (* CASE *) END; PROCEDURE MONSTERS; VAR B,C:INTEGER; BEGIN IF BOARD=MBOARD(.A.) THEN BEGIN B:=ADDR(SCREEN(.LT(.A.)-2*PY(.A.),VT(.A.)-3*PX(.A.).)); C:=ADDR(DISPS(.BOARD,LT(.A.)-2*PY(.A.),VT(.A.)-3*PX(.A.).)); CODE $F5,$C5,$D5,$E5,$2A,B,$ED,$5B,C,$01,$50,$00,$1A,$77,$23,$13, $1A,$77,$23,$13,$1A,$77,$09,$EB,$09,$EB,$1A,$77,$2B,$1B,$1A,$77,$2B, $1B,$1A,$77,$E1,$D1,$C1,$F1; B:=ADDR(SCREEN(.LT(.A.),VT(.A.).)); LEG(.A.):=(LEG(.A.) MOD 3)+1; CASE A OF 1: CODE $E5,$2A,B,$36,118,$23,$36,127,$23,$36,121,$E1; 2: CODE $E5,$2A,B,$36,102,$23,$36,127,$23,$36,57,$E1; 3: CODE $E5,$2A,B,$36,119,$23,$36,127,$23,$36,123,$E1; END (* CASE *); B:=ADDR(SCREEN(.LT(.A.)+1,VT(.A.).)); CASE LEG(.A.) OF 1: CODE $E5,$2A,B,$36,9,$23,$36,17,$23,$36,9,$E1; 2: CODE $E5,$2A,B,$36,24,$23,$36,17,$23,$36,25,$E1; 3: CODE $E5,$2A,B,$36,25,$23,$36,17,$23,$36,24,$E1; END (* CASE *) END ELSE IF ALIVE(.A.) THEN BEGIN SCREEN(.LT(.A.)-2*PY(.A.),VT(.A.)-3*PX(.A.)+1.):= DISPS(.BOARD,LT(.A.)-2*PY(.A.),VT(.A.)-3*PX(.A.)+1.); SCREEN(.LT(.A.),VT(.A.)+1.):=28;(* DIAMOND *) END END; PROCEDURE TURN(RT:INTEGER); VAR B,C,D,E,F:INTEGER; MULIGY,MULIGX:ARRAY(.1..3.) OF BOOLEAN; BEGIN CASE RT OF 28,31: BEGIN B:=PY(.A.); PY(.A.):=0-PX(.A.); PX(.A.):=0-B; END; 29,30: BEGIN B:=PY(.A.); PY(.A.):=PX(.A.); PX(.A.):=B; END; 18,19: BEGIN IF (PY(.A.)=0) AND (MBOARD(.A.)<>BOARD) THEN BEGIN PY(.A.):=-1; PX(.A.):=0; END; IF PY(.A.)=1 THEN BEGIN PY(.A.):=0; PX(.A.):=(X>VT(.A.))-(X<=VT(.A.)); END END; 20,21,22,23: BEGIN IF MBOARD(.A.)<>BOARD THEN BEGIN D:=40; C:=3; END ELSE BEGIN C:=Y; D:=X; IF POWER>0 THEN BEGIN C:=24-C; D:=79-D; END END; FOR B:=1 TO 3 DO MULIGY(.B.):=TRUE; FOR B:=1 TO 3 DO MULIGX(.B.):=TRUE; FOR B:=1 TO 3 DO BEGIN IF A<>B THEN BEGIN IF (ABS(LT(.A.)-LT(.B.))*3+ABS(VT(.A.)-VT(.B.))*2)<25 THEN BEGIN IF PY(.A.)<>0 THEN MULIGY(.2-PY(.A.).):=FALSE; IF PX(.A.)<>0 THEN MULIGX(.2-PX(.A.).):=FALSE END END END; IF PY(.A.)<>0 THEN MULIGY(.2-PY(.A.).):=FALSE; IF PX(.A.)<>0 THEN MULIGX(.2-PX(.A.).):=FALSE; CASE RT OF 20: MULIGY(.1.):=FALSE; 21: MULIGX(.1.):=FALSE; 22: MULIGX(.3.):=FALSE; 23: MULIGY(.3.):=FALSE END; E:=(C>LT(.A.))-(C<=LT(.A.)); F:=(D>VT(.A.))-(D<=VT(.A.)); IF NOT MULIGY(.E+2.) AND NOT MULIGX(.F+2.) THEN BEGIN E:=0-E; F:=0-F END; PY(.A.):=0; PX(.A.):=0; IF MULIGY(.E+2.) AND MULIGX(.F+2.) THEN BEGIN IF ABS(LT(.A.)-C)*3+ABS(VT(.A.)-D)*2<31 THEN BEGIN IF ABS(LT(.A.)-C)*3>ABS(VT(.A.)-D)*2 THEN PY(.A.):=E ELSE PX(.A.):=F; END ELSE BEGIN IF TURNMONST(.A.) THEN PY(.A.):=E ELSE PX(.A.):=F; IF TURNMONST(.A.) THEN TURNMONST(.A.):=0 ELSE TURNMONST(.A.):=1 END END; IF MULIGY(.E+2.) AND NOT MULIGX(.F+2.) THEN PY(.A.):=E; IF NOT MULIGY(.E+2.) AND MULIGX(.F+2.) THEN PX(.A.):=F; IF (LT(.A.)=15) AND (VT(.A.)=40) AND (MBOARD(.A.)=LOWER) AND (BOARD=HIGHER) THEN BEGIN PX(.A.):=0;PY(.A.):=-1 END END END (* CASE *) END; PROCEDURE START; VAR C,B:BYTE; BEGIN IF NOT ALIVE(.A.) THEN BEGIN VT(.A.):=34; LT(.A.):=7; IF BOARD=LOWER THEN FOR C:=0 TO 2 DO FOR B:=0 TO 1 DO SCREEN(.11+B,25+3*A+C.):=32; PY(.A.):=1; PX(.A.):=0; ALIVE(.A.):=TRUE; END ELSE BEGIN ALIVE(.A.):=FALSE; PY(.A.):=0; PX(.A.):=0; LT(.A.):=11; VT(.A.):=25+3*A END END; PROCEDURE CHEET; VAR B:BYTE; BEGIN FOR B:=1 TO 3 DO BEGIN IF (LT(.A.)=LT(.B.)) AND (VT(.A.)=VT(.B.)) AND (A<>B) AND (MBOARD(.A.)=MBOARD(.B.)) AND (LT(.A.)<>3) AND (VT(.A.)<>40) THEN IF (PY(.B.)=PY(.A.)) AND (PX(.B.)=PX(.A.)) THEN BEGIN PY(.A.):=0-PY(.A.); PX(.A.):=0-PX(.A.) END END END; PROCEDURE CLEARKEY; BEGIN IF KEYPRESS THEN GET(KEY); KEY:=CHR(0) END; BEGIN WRITELN(CHR(FF)); WRITELN('PACMAN GAME VERS. 2.1 FOR ',MACHINE,' CP/M VERS. 2.2'); WRITELN; (*$I- NO IOCHECK *) WRITELN('RESETTING CP/M DISK SYSTEM'); RESET; FOR BX:=LOWER TO HIGHER DO BEGIN WRITELN('OPENING OVERLAY FILE : ''PACMAN.00',CHR(BX+49),''''); RESET(FV,'PACMAN.00'+CHR(BX+49)); IF IORES<>0 THEN BEGIN WRITELN('''PACMAN.00',CHR(BX+49),''' NOT PRESENT AT CURRENT DISK'); GOTO EXIT END; WRITELN('GETTING CONTROL SCREEN NUMBER ',CHR(BX+49)); GET(FV,CONTS(.BX.)); WRITELN('GETTING DISPLAY SCREEN NUMBER ',CHR(BX+49)); GET(FV,IDISP(.BX.)); WRITELN('CLOSING FILE : ''PACMAN.00',CHR(BX+49),''''); CLOSE(FV) END; WRITELN('OPENING OVERLAY FILE : ''PACMAN.003'''); RESET(F,'PACMAN.003'); IF IORES<>0 THEN BEGIN WRITELN('''PACMAN.003'' NOT PRESENT AT CURRENT DISK'); WRITELN('CREATING NEW FILE : ''PACMAN.003'''); REWRITE(F,'PACMAN.003'); FOR A:=1 TO 10 DO BEGIN HISCORE(.A.).NAME:=EMPTY; HISCORE(.A.).SCORE:=0 END; WRITELN('CLEARING HIGH-SCORE NAME AND VALUE'); PUT(F,HISCORE); SEEK(F,0); WRITELN('NEW ''PACMAN.003'' IS NOW CREATED AND CLEARED'); WRITELN('CLOSING FILE : ''PACMAN.003'''); CLOSE(F,LOCK) END ELSE BEGIN WRITELN('GETTING HIGH-SCORE NAME AND VALUE'); GET(F,HISCORE); WRITELN('CLOSING FILE : ''PACMAN.003'''); CLOSE(F) END; (*$I+ IOCHECK *) IDELAY:=1000; REPEAT WRITE('PRESS <RETURN>'); GET(KEY); WRITELN; IF (KEY='D') OR (KEY='d') THEN BEGIN WRITE('ENTER DELAY : '); (*$I- NO IOCHECK *) READLN(IDELAY); WHILE IORES<>0 DO BEGIN WRITELN('*** INTEGER EXPECTED'); WRITE('ENTER DELAY : '); READLN(IDELAY) END (*$I+ IOCHECK *) END; IF KEY=CHR(3) THEN GOTO EXIT UNTIL KEY=CHR(CR); WRITE(CHR(GS)); REPEAT POINT:=0; DEADTIMES:=0; PILLS:=0; DELAY:=IDELAY; REPEAT IF PILLS=0 THEN BEGIN DISPS(.LOWER.):=IDISP(.LOWER.); DISPS(.HIGHER.):=IDISP(.HIGHER.) END; SCREEN:=DISPS(.LOWER.); X:=40; Y:=21; DEAD:=FALSE; VERTI:=0; HORI:=0; BOARD:=LOWER; POWER:=0; FOR A:=1 TO 3 DO BEGIN LT(.A.):=11; VT(.A.):=25+(3*A); PY(.A.):=0; PX(.A.):=0; ALIVE(.A.):=FALSE; MBOARD(.A.):=LOWER; LEG(.A.):=A; MONSTERS END; PACMAN; WRITELN(CHR(GS),'POINT : ',POINT:6,'YOU HAVE ':46,PACNO-DEADTIMES-1, ' PACM',CHR((PACNO-DEADTIMES-1<>1)*4+65),'N LEFT'); CLEARKEY; GET(KEY); REPEAT IF KEYPRESS THEN GET(KEY); IF KEY=CHR(3) THEN (* IF CTRL/C IS TYPED THEN BREAK *) BEGIN WRITELN(CHR(FF),'PACMAN BREAKED BY USER'); GOTO EXIT END; IF KEY=CHR(6) THEN (* IF CTRL/F IS TYPED THEN FREEZE *) BEGIN CLEARKEY; REPEAT UNTIL KEYPRESS END; IF KEYPRESS THEN GET(KEY); HORIX:=(KEY=CHR(LEFT))-(KEY=CHR(RIGHT)); VERTIX:=(KEY=CHR(UP))-(KEY=CHR(DOWN)); IF (DISPS(.BOARD,Y-2*VERTIX,X-3*HORIX.)=134) OR (DISPS(.BOARD,Y-2*VERTIX,X-3*HORIX.)=32) THEN BEGIN HORI:=HORIX; VERTI:=VERTIX END; IF DISPS(.BOARD,Y-2*VERTI,X-3*HORI.)=134 THEN BEGIN POWER:=75; DISPS(.BOARD,Y-2*VERTI,X-3*HORI.):=32; FOR A:=1 TO 75 DO SCREEN(.24,3+A.):=124 END; IF DISPS(.BOARD,Y-2*VERTI,X-3*HORI.)=32 THEN BEGIN X:=X-3*HORI; Y:=Y-2*VERTI; IF (X=40) AND (Y=3) AND (KEY=CHR(UP)) THEN BEGIN IF BOARD=LOWER THEN BOARD:=HIGHER ELSE BOARD:=LOWER; KEY:=CHR(DOWN); VERTI:=1;HORI:=0; SCREEN:=DISPS(.BOARD.); WRITELN(CHR(GS),'POINT : ',POINT:6,'YOU HAVE ':46, PACNO-DEADTIMES-1,' PACM',CHR((PACNO-DEADTIMES-1<>1)*4+65), 'N LEFT'); FOR A:=1 TO POWER DO SCREEN(.24,3+A.):=124 END; IF KEYPRESS THEN GET(KEY); PACMAN; FOR A:=1 TO DELAY DO (* NOTHING *); MOUTH; FOR A:=1 TO DELAY DO (* NOTHING *); IF (Y=21) AND (X=40) AND (KEY=CHR(DOWN)) THEN BEGIN Y:=3; FOR A:=1 TO 3 DO FOR B:=1 TO 2 DO SCREEN(.20+B,39+A.):=32; END; IF DISPS(.BOARD,Y,X+1.)=112 THEN BEGIN DISPS(.BOARD,Y,X+1.):=32; DISPS(.BOARD,Y+1,X+1.):=32; PILLS:=SUCC(PILLS); POINT:=POINT+5; C:=POINT; FOR B:=14 DOWNTO 10 DO BEGIN SCREEN(.1,B.):=C MOD 10+48; C:=C DIV 10 END END END ELSE FOR A:=1 TO DELAY*2 DO (* NOTHING *); IF KEYPRESS THEN GET(KEY); FOR A:=1 TO 3 DO BEGIN IF (X=VT(.A.)) AND (Y=LT(.A.)) AND (MBOARD(.A.)=BOARD) THEN BEGIN IF POWER=0 THEN DEAD:=TRUE ELSE BEGIN START; MBOARD(.A.):=LOWER; POINT:=POINT+ABS(80-POWER)*3 END END; IF (POWER=0) AND NOT ALIVE(.A.) THEN START; IF (CONTS(.MBOARD(.A.),LT(.A.),VT(.A.).)>18) AND (CONTS(.MBOARD(.A.),LT(.A.),VT(.A.).)<32) THEN TURN(CONTS(.MBOARD(.A.),LT(.A.),VT(.A.).)) ELSE CHEET; LT(.A.):=LT(.A.)+2*PY(.A.); VT(.A.):=VT(.A.)+3*PX(.A.); IF KEYPRESS THEN GET(KEY); MONSTERS; IF (LT(.A.)=3) AND (VT(.A.)=40) THEN BEGIN PY(.A.):=1; MBOARD(.A.):=BOARD END; IF (X=VT(.A.)) AND (Y=LT(.A.)) AND (MBOARD(.A.)=BOARD) THEN BEGIN IF POWER=0 THEN DEAD:=TRUE ELSE BEGIN START; MBOARD(.A.):=LOWER; POINT:=POINT+ABS(80-POWER)*3 END END; IF POWER>0 THEN BEGIN POWER:=PRED(POWER); SCREEN(.24,POWER+4.):=32; IF POWER=5 THEN WRITE(CHR(BELL)) END END UNTIL ((PILLS MOD 291=0) AND (PILLS<>0)) OR DEAD; IF DEAD THEN BEGIN DEADTIMES:=SUCC(DEADTIMES); EDISP:=SCREEN; FOR DUMMY:=1 TO 50 DO IF (DUMMY DIV 10) MOD 2=0 THEN SCREEN:=IDISP(.BOARD.) ELSE SCREEN:=EDISP END ELSE BEGIN DELAY:=DELAY-200*(DELAY>0); PILLS:=0 END UNTIL DEADTIMES=PACNO; FOR DUMMY:=1 TO 400 DO (* IMPLEMENTATION DEPENDENT !!! ( ON RC702 THE CRTC IS CONTROLLED BY THE CPU'S PORT 1. THE CRTC ( INTEL I8275 ) HAS GOT THE COMMANDS : 35 : DISPLAY START, 64 : DISPLAY STOP. ) *) PORT(.1.):=((DUMMY DIV 100) MOD 2)*29+35; (* FLASH *) FOR DUMMY:=1 TO 16000 DO; CLEARKEY; WRITELN(CHR(FF)); WRITELN('................................HIGH-SCORE LIST.................', '.............'); WRITELN; FOR A:=1 TO 10 DO WRITELN(A:10,'.',HISCORE(.A.).NAME:20,' ----->> ', HISCORE(.A.).SCORE:10,' POINTS...'); WRITELN; WRITELN(' YOUR SCORE WAS ',POINT,' POINTS...'); FOR A:=1 TO 10 DO IF POINT>HISCORE(.A.).SCORE THEN BEGIN FOR B:=10 DOWNTO A+1 DO BEGIN HISCORE(.B.).NAME:=HISCORE(.B-1.).NAME; HISCORE(.B.).SCORE:=HISCORE(.B-1.).SCORE END; IF A<>1 THEN BEGIN WRITE(' THAT''S THE ',A); CASE A OF 2: WRITE('ND'); 3: WRITE('RD'); OTHERS: WRITE('TH') END; (* CASE *) WRITELN(' BEST SCORE YET...') END ELSE WRITELN(' THAT''S A NEW HIGH-SCORE ! ! ! '); WRITELN; WRITE(' ENTER YOUR NAME : '); BUFLEN:=20;READLN(HISCORE(.A.).NAME); HISCORE(.A.).SCORE:=POINT; WRITELN; WRITE(CHR(FLASH), ' INSERT DISK AND PRESS <RETURN>',CHR(NORM)); CLEARKEY; REPEAT GET(KEY) UNTIL KEY=CHR(CR); WRITE(CHR(CR),' WRITING HIGH-SCORE ONTO DISK', CHR(CLREOLN)); REWRITE(F,'PACMAN.003'); PUT(F,HISCORE); CLOSE(F,LOCK); WRITE(CHR(CR),CHR(CLREOLN)); A:=11; WRITELN(CHR(GS),CHR(LF),CHR(LF)); FOR A:=1 TO 10 DO WRITELN(A:10,'.',HISCORE(.A.).NAME:20,' ----->> ', HISCORE(.A.).SCORE:10,' POINTS...'); WRITELN(CHR(LF),CHR(LF),CHR(LF),CHR(LF),CHR(LF)); END; WRITELN; REPEAT WRITE(CHR(CR),CHR(CLREOS),CHR(FLASH), ' PRESS <ESC> FOR STOP OR <SPACE> FOR NEW GAME.',CHR(NORM)); GET(KEY); IF (KEY='D') OR (KEY='d') THEN BEGIN WRITELN(CHR(LF)); WRITE('ENTER DELAY : '); (*$I- NO IOCHECK *) READ(IDELAY); WHILE IORES<>0 DO BEGIN WRITELN; WRITE('*** INTEGER EXPECTED',CHR(SUB),CHR(CR),'ENTER DELAY : ', CHR(CLREOLN)); READ(IDELAY) END; (*$I+ IOCHECK *) WRITE(CHR(SUB),CHR(SUB)) END UNTIL (KEY=' ') OR (KEY=CHR(ESC)); UNTIL (KEY=CHR(ESC)); WRITE(CHR(FF)); EXIT: WRITELN('END OF PACMAN...'); WRITE('INSERT CP/M SYSTEM DISK AND PRESS <RETURN>'); CLEARKEY; REPEAT GET(KEY) UNTIL KEY=CHR(CR) END.«eof»