home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPMHELP
/
HELPER.LBR
/
HELPER.MZC
/
HELPER.MAC
Wrap
Text File
|
2000-06-30
|
7KB
|
412 lines
;INTERACTIVE TEXT PRESENTER
;JULY 2, 1988
;TO TURN THIS INTO A PROGRAM, TACK TEXT FILE ON TO END OF IT AND
;THEN TACK A ZERO BYTE ON TO END OF TEXT FILE.
;
;E.G. PIP PROG.COM=HELPER.COM,FILE.TXT,0.DAT
;
;WHERE 0.DAT IS A 1-SECTOR FILE CONTAINING A 0 FOLLOWED BY A ^Z
.Z80
ASEG
BDOS EQU 5
;CHARACTER THAT INTRODUCES COMMANDS
;MUST NOT BE USED FOR OTHER PURPOSES IN TEXT FILE.
;CAN BE ANY 7-BIT CHAR OTHER THAN 0 OR ^Z
CMARK EQU '~'
ORG 100H
LD (SPSAVE),SP
LD SP,TSTACK
LD A,23
LD (LINES),A
;CLEAR STACKS AND GO TO TOP OF TEXT
START: LD HL,USTACK
LD (USTAKP),HL
LD HL,LSTACK
LD (LSTAKP),HL
LD DE,TEXT
;OUTPUTTING TEXT. READ NEXT CHAR AND CHECK FOR COMMAND
MAIN: LD A,(DE)
INC DE
OR A
JP Z,EXIT
AND 7FH
CP CMARK
JR Z,DOCMD
CP '^'
JR Z,PUTCTL
MAIN1: CALL PUTCHR
CP 10
JR NZ,MAIN
;AUTO-PAUSE EVERY 23 LINES
LD HL,LINES
DEC (HL)
JR NZ,MAIN
CALL PAUSE
JR MAIN
;CONVERT NEXT CHARACTER TO CONTROL EQUIVALENT
PUTCTL: LD A,(DE)
INC DE
CP '^'
JR Z,MAIN1
AND 31
JR MAIN1
;PROCESS COMMAND
DOCMD: LD A,(DE)
INC DE
CP CMARK
JR Z,MAIN1 ;LITERAL
CALL TOUPPR
;QUIT-LEAVE PROGRAM
CP 'Q'
JP Z,EXIT
;LABEL-IGNORE IT HERE
CP 'L'
JR NZ,DOCM1
CALL SKIPNL
JR MAIN
;SWITCH
DOCM1: CP 'S'
JP Z,DOSWIT
;PAUSE-FORCE PAUSE UNLESS WE JUST FINISHED AN AUTO-PAUSE
CP 'P'
JR NZ,DOCM2
LD A,(LINES)
CP 23
JR Z,DOCM3
CALL PAUSE
DOCM3: JR MAIN
;TOP-RESTART
DOCM2: CP 'T'
JP Z,START
;USE-PICK UP DESTINATION, STACK CURRENT POSITION AND BRANCH
CP 'U'
JR NZ,DOCM4
CALL GETLBL
LD HL,(USTAKP)
LD (HL),E
INC HL
LD (HL),D
INC HL
LD (USTAKP),HL
JR DOCM5
;GOTO-PICK UP LABEL AND BRANCH
DOCM4: CP 'G'
JR NZ,DOCM6
CALL GETLBL
DOCM5: CALL DOGOTO
JR CMDEND
;RETURN-UNSTACK POSITION AND RESUME READING
DOCM6: CP 'R'
JR NZ,DOCM7
LD HL,(USTAKP)
DEC HL
LD D,(HL)
DEC HL
LD E,(HL)
LD (USTAKP),HL
JR CMDEND
;CASE OR DEFAULT-IF WE SEE THEM HERE, WE NEED TO SKIP TILL END OF
;CURRENT SWITCH SECTION
DOCM7: CP 'C'
JP Z,SKSWIT
CP 'D'
JP Z,SKSWIT
;END-RESUME AFTER IT
CP 'E'
JR NZ,DOCM8
CALL SKIPNL
JR CMDEND
;ECHO LAST RESPONSE
DOCM8: CP 'O'
JR NZ,DOCM9
CALL OTRESP
JR CMDEND
;BEGIN LOOP
DOCM9: CP 'B'
JR NZ,DOCM10
DEC DE ;STACK POSITION OF COMMAND
DEC DE
LD HL,(LSTAKP)
LD (HL),E
INC HL
LD (HL),D
INC HL
LD (LSTAKP),HL
INC DE
INC DE
JR CMDEND
;REPEAT LOOP (AGAIN)
DOCM10: CP 'A'
JR NZ,DOCM11
LD HL,(LSTAKP)
DEC HL
LD D,(HL)
DEC HL
LD E,(HL)
LD (LSTAKP),HL
JR CMDEND
;EXIT FROM LOOP
DOCM11: CP 'X'
JR NZ,CMDEND
LD HL,CNEST
LD (HL),1
SKLOOP: CALL SKIPCM
CP 'B'
JR NZ,SKLOP1
INC (HL)
JR SKLOOP
SKLOP1: CP 'A'
JR NZ,SKLOOP
DEC (HL)
JR NZ,SKLOP1
CMDEND: JP MAIN
;PROCESS SWITCH COMMAND. FIRST GET RESPONSE
DOSWIT: CALL GPRMPT
LD HL,CNEST
LD (HL),1
;SKIP OVER TEXT UNTIL WE SEE A CASE COMMAND THAT MATCHES RESPONSE
;OR A DEFAULT COMMAND. SKIP OVER NESTED SWITCH SECTIONS
DOSW1: CALL SKIPCM
CP 'S'
JR NZ,DOSW3
INC (HL)
JR DOSW1
DOSW3: CP 'E'
JR NZ,DOSW4
DEC (HL)
JR NZ,DOSW1
;IF WE SEE END COMMAND WITHOUT MATCHING ANYTHING, RESUME DISPLAY
DOSW6: CALL SKIPNL
JP MAIN
DOSW4: CP 'D'
JR NZ,DOSW5
LD A,(HL)
CP 1
JR NZ,DOSW1
JR DOSW6
DOSW5: CP 'C'
JR NZ,DOSW1
LD A,(HL)
CP 1
JR NZ,DOSW1
;SEE IF RESPONSE MATCHES THIS CASE
PUSH HL
LD HL,RESPNS
CALL MATSTR
POP HL
JR NZ,DOSW1
JP MAIN
;SKIP TO END OF CURRENT SWITCH SECTION, DEALING WITH NESTED
;SWITCH SECTIONS
SKSWIT: LD HL,CNEST
LD (HL),1
SKSW1: CALL SKIPCM
CP 'S'
JR NZ,SKSW2
INC (HL)
JR SKSW1
SKSW2: CP 'E'
JR NZ,SKSW1
DEC (HL)
JR NZ,SKSW1
CALL SKIPNL
JP MAIN
;LEAVE PROGRAM
EXIT: LD SP,(SPSAVE)
RET
;SKIP PAST END OF CURRENT LINE
SKIPNL: LD A,(DE)
INC DE
;CHECK FOR RUNNING OFF THE END
OR A
JP Z,EXIT
CP 10
JR NZ,SKIPNL
RET
;OUTPUT A CHARACTER
PUTCHR: PUSH AF
PUSH DE
LD E,A
LD C,2
CALL BDOS
POP DE
POP AF
RET
;SKIP TEXT UNTIL A COMMAND SEEN. RETURN COMMAND LETTER
SKIPCM: LD A,(DE)
INC DE
OR A
JP Z,EXIT
CP CMARK
JR NZ,SKIPCM
LD A,(DE)
INC DE
TOUPPR: CP 'a'
JR C,TOUPP1
CP '{'
JR NC,TOUPP1
AND 5FH
TOUPP1: RET
;SEARCH FOR A LABEL IN TEXT, STARTING AT TOP
DOGOTO: LD DE,TEXT
DOGO1: CALL SKIPCM
CP 'L'
JR NZ,DOGO1
LD HL,GOLAB
CALL MATSTR
JR NZ,DOGO1
RET
;EXTRACT TARGET LABEL FROM TEXT
GETLBL: LD HL,GOLAB
GETLB1: LD A,(DE)
LD (HL),A
INC DE
INC HL
CP 13
JR NZ,GETLB1
INC DE
RET
;COMPARE TEXT WITH STRING POINTED TO BY HL. RETURN Z IF MATCH,
;NZ IF NO MATCH. IN EITHER CASE, POINT TO START OF LINE AFTER
;MATCHING TEXT
MATSTR: LD A,(DE)
CALL TOUPPR
LD B,A
LD A,(HL)
CALL TOUPPR
CP B
JR NZ,MATST1
INC HL
INC DE
CP 13
JR NZ,MATSTR
INC DE
XOR A
RET
MATST1: CALL SKIPNL
LD A,1
OR A
RET
;SHOW "MORE" MESSAGE, WAIT FOR ANY KEY.
;USES BACKSPACES INSTEAD OF RETURNS TO AVOID MESSING UP
;TABBED TEXT. RESETS LINE COUNT WHEN DONE.
PAUSE: PUSH DE
LD DE,P1STR
LD C,9
CALL BDOS
PAUS1: LD C,6
LD E,255
CALL BDOS
OR A
JR Z,PAUS1
PUSH AF
LD DE,P2STR
LD C,9
CALL BDOS
POP AF
POP DE
CP 3
JP Z,EXIT
LD A,23
LD (LINES),A
RET
P1STR: DB '[any key]',8,8,8,8,8,8,8,8,8,'$'
P2STR: DB ' ',8,8,8,8,8,8,8,8,8,'$'
;GET RESPONSE TO PROMPT
GPRMPT: PUSH DE
LD DE,RESBUF
LD C,10
CALL BDOS
LD A,(RESCNT)
LD E,A
LD D,0
LD HL,RESPNS
ADD HL,DE
LD (HL),13
LD A,10
CALL PUTCHR
LD A,23 ;RESET LINE COUNT
LD (LINES),A
POP DE
RET
;ECHO MOST RECENT RESPONSE
OTRESP: LD HL,RESPNS
OTRES1: LD A,(HL)
CP 13
RET Z
PUSH HL
CALL PUTCHR
POP HL
INC HL
JR OTRES1
;VARIABLES
;RESPONSE BUFFER (SET UP FOR BDOS READ BUFFER FUNCTION)
RESBUF: DB 16
RESCNT: DS 1
RESPNS: DS 16
;STACK FOR "USE" COMMAND NESTING
USTAKP: DS 2
USTACK: DS 16
;STACK FOR LOOP NESTING
LSTAKP: DS 2
LSTACK: DS 16
;SCREEN LINE COUNTER
LINES: DS 1
;NESTING LEVEL FOR CASE SKIPPING
CNEST: DS 1
;TARGET LABEL FOR GOTO AND USE COMMANDS
GOLAB: DS 16
;PLACE TO KEEP CCP STACK
SPSAVE: DS 2
;LOCAL STACK
DS 32
TSTACK:
;ACTUAL TEXT GETS TAGGED ON HERE. FORCE IT TO BEGIN AT NEAREST
;RECORD BOUNDARY SO PIP DOESN'T LEAVE JUNK IN BETWEEN
IFE $ MOD 128
TEXT EQU $
ELSE
TEXT EQU ($+128) AND NOT 127
ENDIF
END