; -------------------------------------------------------------- ; HJELP.ASM is a derivative of HELP8080.ASM (SIG/M 122.03), ; which was gotten by disassembling HELP8080.COM (SIG/M 122.04), ; inserting UNSQ.LIB (this disk), and making all the adjustments ; required to ensure the compatibility of the two. The objective ; of this procedure was to obtain a version of HELP which would ; work with squeezed HELP files, and to correct minor errors in ; the original program. ; ; HELP8080.ASM in turn has a history, of having been derived from ; a Z80 version which forms part of Richard Conn's ZCPR2 package ; (SIG/M 98-107 and others). In the documentation for these ; programs he makes the requirement that their contents not be ; propagated for commercial purposes without his express written ; consent, but permitting their non-commercial usage or their ; incorporation as a necessary part of a new program. HJELP.ASM ; contains about 50% new or revised code, and in time may evolve ; into still less dependence. In the meantime we feel that it ; should continue to carry the requirements of the original author. ; ; Besides incorporating a pipeline through which the Huffman code ; of a squeezed file can be decoded, the principal changes made ; to HELP8080 consist in establishing a directory and pushdown ; list to locate the beginnings of information sections and of ; individual panels. Besides speeding up the program, they are ; required by the Huffman code because the sign bit can no longer ; be used to flag these locations. ; ; Minor errors in HELP8080 which were corrected include: 1) The ; option "L" did not always back up to panel 1 properly. 2) The ; option to list a single panel on the printer did not always ; work if the panels were not separated by form feeds. ; ; For consistency with its acceptance of squeezed HELP files, ; HJELP will search for HQP as well as HLP files when summoned ; with a null command line. ; ; [Harold V. McIntosh, July 20, 1984] ; -------------------------------------------------------------- CR equ 0DH VT equ 0CH LF equ 0AH HT equ 09H X0004 equ 0004H ;CP/M Disk Byte X0005 equ 0005H ;call point to BDOS NH equ 6 ;number of HELP file names to print per line ND equ 10 ;maximum node depth NS equ 9 ;bytes to save for panel markers csiz equ 256 psiz equ 50*NS ;textpointer pushdown size ; ------------- org 0100H ; ------------- X0100: jmp X017B ; A data area which is specific to ZCPR2 and which ; defines the parameters needed for HELP.COM to ; interact with ZCPR2. X0103: db 000H ;00/FF = no/external path available X0104: dw 0040H ;address of external path if used X0106: db 00,00 ;disk, user for first path db 00,00 ;second path db 00,00 db 00,00 db 00,00 db 00,00 db 00,00 db 00,00 ;eighth path db 00 ;end of path db 0FFH ;00/FF = multiple command line buffer dw 0FF00H ;its address if present db 04 ;max number of disks db 31 ;max user number db 0FFH ;00/FF = can/'t change disk db 0FFH ;00/FF = can/'t change user db 10 ;begnning of privleged user area db 'chdir' ;password for privleged area ds 36 ;remainder of 41 char buffer X0148: db '$' ;usual value for path expressions dw 0080H ;DMA for disk = tbuf dw 0000 ;address of named directory db 64 ;maximum number of directory names db 'NAMES DIR' ;name.ext of disk name file db 0FFH ;00/FF = y/n external path db 00 ;multiple command line db 00 ;max user/disk db 00 ;user/disk change db 00 ;privileged user db 00 ;current indic and dma db 00 ;named directories db 05 ;class 5 db 'ZCPR2' ds 10 ;reserved spaces ; Default file name. X0170: db 'HELP ' X0178: db 'HLP' ;default ext X0179: db 'HQP' ;default squeezed file ; Program begins here. X017B: lxi h,0000 dad sp shld X0D31 ;save stack lxi sp,X0D31 ;stack mvi e,0FFH mvi c,32 ;(20) Set/Get User Code call X0005 ; B D O S sta X0C62 ;user code lda X0005+2 sui 0AH sta X0C63 ;memory pages xra a sta X0C6D ;nz/z = y/n default file sta X0C71 ;level # lxi d,X08BE ;'signon' call mssg ;message to console lxi h,005CH+1 ;TFCB+1 mov a,m cpi ' ' jnz X01BB ;loop lxi d,X0170 ;'HELP HLP' mvi b,11 ;bytes in disk name call miuc mvi a,001H sta X0C6D ;nz/z = y/n default file ; Loop. X01BB: lxi sp,X0D31 ;stack lxi h,005CH ;TFCB mvi m,000H lxi d,000CH dad d mvi b,018H ;24 X01C9: mvi m,000H inx h dcr b jnz X01C9 lxi h,005CH+1 ;TFCB+1 mvi b,11 ;bytes in disk name X01D5: mov a,m ani 07FH cpi '?' jz X0227 inx h dcr b jnz X01D5 lxi h,005CH+9 mov a,m cpi ' ' jnz X01EE lxi d,X0178 ;default ext mvi b,003H call miuc X01EE: lda X0C6D ;nz/z = y/n default file ora a jnz X0230 lxi h,X0106 lda X0103 ora a jz X0202 lhld X0104 X0202: lxi d,005CH ;TFCB call X0408 ;search through users/disks jnz X0323 ;load file lda X0103 ora a jz X021E lxi h,X0106 lxi d,005CH ;TFCB call X0408 ;search through users/disks jnz X0323 ;load file X021E: lxi h,005CH+10 mvi a,'Q' cmp m jz X021F mov m,a jmp X01EE X021F: lxi d,X0AA1 ;'File Not Found' call mssg ;message to console jmp X0362 ;return to CP/M X0227: lxi d,X0A6E ;'File Name w/Wildcard' call mssg ;message to console jmp X0362 ;return to CP/M X0230: lxi d,X08DC ;'Default HELP' call mssg ;message to console call X02A9 ;reset HELP file names/line call X03F3 ;restore user/disk call X02AF ;locate available HLP files lda X0103 lhld X0104 ora a cnz X0275 call X03F3 ;restore user/disk lxi h,X0106 call X0275 call X03F3 ;restore user/disk lxi d,X091C ;'Type Any Char for Default Info' call mssg ;message to console call X046B ;read char from console cpi 003H ;^Z jz X0362 ;return to CP/M xra a sta X0C6D ;nz/z = y/n default file lxi d,X0170 ;'HELP HLP' lxi h,005CH+1 ;TFCB+1 mvi b,11 ;bytes in disk name call miuc jmp X01EE X0275: lda X0148 mov b,a mov a,m ani 07FH ora a rz cmp b jnz X0288 lda X0004 ;Disk Byte ani 00FH inr a X0288: dcr a mov e,a mvi c,14 ;(0E) select disk call X045D ;generic BDOS call inx h mov a,m inx h ani 07FH cmp b jnz X029B lda X0C62 ;user code X029B: mov e,a mvi c,32 ;(20) Get/Set User Code call X045D ;generic BDOS call push h call X02AF ;locate available HLP files pop h jmp X0275 ; Set number of HELP file names to be typed per line. X02A9: mvi a,NH sta X0C6C ;HELP file names/line ret ; Search out the available HLP files X02AF: lxi h,005CH ;TFCB mvi m,000H mvi b,008H inx h X02B7: mvi m,'?' inx h dcr b jnz X02B7 push h lxi d,X0178 ;default ext mvi b,003H call miuc call X02C0 lxi d,shlp ;'squeezed HELP files' call mssg pop h lxi d,X0179 ;default squeezed extension mvi b,003H call miuc X02C0: mvi b,018H X02CA: mvi m,000H inx h dcr b jnz X02CA lxi d,005CH ;TFCB mvi c,17 ;(11) search for first call X0005 ; B D O S cpi 0FFH rz X02DC: call X02ED ;pick up file name, type it lxi d,005CH ;TFCB mvi c,18 ;(12) search for next call X0005 ; B D O S cpi 0FFH jnz X02DC ret ; Pick file name out of directory, type it. X02ED: rrc rrc rrc ani 060H lxi h,0080H add l mov l,a mov a,h aci 000H mov h,a inx h mvi b,008H X02FE: mov a,m ani 07FH inx h call cona ;char to console dcr b jnz X02FE mvi a,' ' call cona ;char to console call cona ;char to console call cona ;char to console lda X0C6C ;HELP file names/line dcr a sta X0C6C ;HELP file names/line rnz call X02A9 ;reset HELP file names/line call X04F4 ;type options at bottom of panel ret ; Open file, load it, close it. X0323: lxi d,005CH ;TFCB mvi c,15 ;(0F) open file call X0005 ; B D O S lxi h,X0D33 ;free memory shld X0C6E ;ptr end of text X0331: call X04AC ;read record from disk jz X0331 lxi d,005CH ;TFCB X033A: mvi c,16 ;(10) close file call X0005 ; B D O S call X03F3 ;restore user/disk ; Decide whether it is a squeezed file. lxi h,X0D33 shld tptr ;text pointer shld xptr ;ptr to bgn of HELP file lxi h,dens ;z/nz = normal/squeezed file mvi m,0 lxi h,wflg ;z/nz = no/byte left waiting by abyt mvi m,0 call gbyt ;one byte, direct or through onsq cpi 076H jnz unjj call gbyt ;one byte, direct or through onsq cpi 0FFH jz unii unjj: lxi h,X0D33 shld tptr ;text pointer jmp gogo ; Squeezed, so go through initialization unii: lxi h,rcnt ;repetition count mvi m,0 lxi h,roco ;bit rotation counter mvi m,1 ; The "squeezed" marker is followed by a two-byte checksum, ; which is the simple sum of all the one-byte characters in ; the source file, carried as a two byte sum modulo 2**16. rchk: call iwor ;fetch two bytes from input stream shld cksm ;checksum ; Unsqueezed file name. It is an ASCII sequence, may be lower ; case if SQ.COM received it in response to a prompt, ending ; with a zero byte. luup: call gbyt ;fetch one byte from input stream ora a jnz luup ; Load code dictionary. It is preceded by its two-byte length, ; and consists of a series of pairs of two-byte addresses. For ; each bit in the code, select the first element (0) or the ; second (1) element of the pair. If the pair is positive, it ; is the table entry (code + 4*index) at which to continue with ; the next bit. If the pair is negative, it is the complement ; of the coded ASCII character (low order byte except for [end]). ldic: call iwor ;fetch two bytes from input stream dad h dad h xchg lhld tptr ;text pointer shld cptr ;Huffman code table dad d shld tptr ;text pointer shld xptr ;ptr to bgn of HELP file lxi h,dens mvi m,0FFH ; Scan the HELP text to find and record the section headings. gogo: lxi h,pudl shld pptr ;pushdown pointer lxi h,mopt mvi m,'A' ;A, not @, to make work call abyt ;lookahead one byte cpi ':' jz gogu gugu: call rbyt ;fetch one byte cpi LF jnz gigi call rbyt ;fetch one byte cpi ':' jz gege gigi: cpi 1AH jz gogu jmp gugu gege: call pupu lxi h,mopt ;maximum option inr m jmp gugu gogu: lhld pptr ;pushdown pointer shld zptr ;ptr to bgn of info sect lhld xptr ;ptr to bgn of HELP file shld tptr ;text pointer lxi h,roco ;bit rotation counter mvi m,1 lxi h,wflg ;z/nz = no/byte left waiting by abyt mvi m,0 ; Display menu. Here we distinguish between a simple HELP ; file which begins with a colon and has only one section, ; and an indexed HELP file, which starts out with a list of ; section descriptors. X0342: lxi sp,X0D31 ;stack mvi a,000H sta X0C72 ;panel # call abyt ;lookahead one byte cpi ':' jnz X036A ;show menu, request option call rbyt ;fetch one byte call X05E5 ;initialize new section lda X0C71 ;level # ora a jz X0362 ;return to CP/M jmp X07ED ;go up one level ; Return to CP/M X0362: call X03F3 ;restore user/disk lhld X0D31 ;save stack sphl ret ; Show menu, request option. X036A: call X058D ;run through the menu push b call crlf ;CR,LF call X0859 ;type level I.D. lxi d,X0C19 ;'Type [^C]' call mssg ;message to console lxi d,X0C27 ;'Type [level or root]' lda X0C71 ;level # ora a jz X0387 call mssg ;message to console X0387: lxi d,X0C37 ;'Enter Selection' call mssg ;message to console pop b call X046B ;read char from console cpi 003H ;^C jz X0362 ;return to CP/M cpi '.' jz X07E1 ;back to root cpi '^' jz X07ED ;go up one level push psw call crlf ;CR,LF pop psw lxi h,mopt ;maximum option cmp m jnc X03AE sui '@' jc X03AE jz X03AE call anth ;access nth option call X05E5 ;initialize new section jmp X036A ;show menu, request option X03AE: lxi d,X0AC6 ;'Invalid Response' call mssg ;message to console jmp X036A ;show menu, request option ; Restore user/disk. X03F3: lda X0004 ;Disk Byte ani 00FH mov e,a mvi c,14 ;(0E) select disk call X0005 ; B D O S lda X0C62 ;user code mov e,a mvi c,32 ;(20) Get/Set User Code call X0005 ; B D O S ret ; Search through users/disks. X0408: shld X0469 ;save FCB addr mvi c,17 ;(11) search for first call X045D ;generic BDOS call inr a jnz X0459 xchg shld X0467 ;save DE after 'search first' lhld X0469 ;save FCB addr X041B: lda X0148 mov b,a mov a,m ani 07FH ora a jnz X0428 xra a ret X0428: cmp b jnz X0432 lda X0004 ;Disk Byte ani 00FH inr a X0432: dcr a mov e,a mvi c,14 ;(0E) select disk call X045D ;generic BDOS call inx h mov a,m ani 07FH inx h cmp b jnz X0445 lda X0C62 ;user code X0445: mov e,a mvi c,32 ;(20) Get/Set User Code call X045D ;generic BDOS call xchg lhld X0467 ;save DE after 'search first' xchg mvi c,17 ;(11) search for first call X045D ;generic BDOS call inr a jz X041B X0459: mvi a,0FFH ora a ret ; Generic BDOS call. X045D: push h push d push b call X0005 ; B D O S pop b pop d pop h ret X0467: ds 2 ;save DE after 'search first' X0469: ds 2 ;save FCB addr ; Read a character from the console. X046B: push b push d push h mvi c,1 ;(01) console input call X0005 ; B D O S pop h pop d pop b push psw call crlf ;CR,LF pop psw X047B: ani 07FH ;upper case fold cpi 'a' rc cpi '{' rnc ani 05FH ret ; Character to console. cona: push psw push b push d push h mvi c,2 ;(02) console output mov e,a call X0005 ; B D O S pop h pop d pop b pop psw ret ; Message to Console. mssg: push b push d push h mvi c,9 ;(09) print string to $ call X0005 ; B D O S pop h pop d pop b ret ; Move B bytes from (DE) to (HL). miuc: ldax d mov m,a inx d inx h dcr b jnz miuc ret ; Move B bytes from (HL) to (DE) mduc: dcx h dcx d mov a,m stax d dcr b jnz mduc ret ; Initialize pudl. izpu: mvi b,NS lxi d,lach lhld zptr ;ptr to bgn of info sect call miuc shld yptr ;zptr+NS shld pptr ;pushdown pointer lxi h,X0C72 ;panel # mvi m,1 ret ; Restore to the head of pudl. rspu: mvi b,NS lhld yptr ;zptr+NS shld pptr ;pushdown pointer lxi d,lach+NS call mduc lxi h,X0C72 ;panel # mvi m,0 ret ; Access nth option. anth: mov e,a mvi d,0 mov l,e mov h,d dad h dad h dad h dad d lxi d,pudl dad d lxi d,lach+NS mvi b,NS call mduc lhld zptr ;ptr to bgn of info sect shld pptr ;pushdown pointer lxi h,X0C72 mvi m,1 ret ; Push state onto pudl. pupu: lhld pptr ;pushdown pointer lxi d,pudl+psiz mov a,l sub e mov a,h sbb d rnc mvi b,NS lxi d,lach call miuc shld pptr ;pushdown pointer lxi h,X0C72 ;panel # inr m ret ; Pop state from pudl. popu: lhld zptr xchg lhld pptr ;pushdown pointer mov a,e sub l mov a,d sbb h rnc mvi b,NS lxi d,lach+NS call mduc shld pptr ;pushdown pointer lxi h,X0C72 ;panel # mov a,m ora a rz dcr m ret ; Read one record from the disk. X04AC: mvi c,20 ;(14) read one record lxi d,005CH ;TFCB call X0005 ; B D O S push psw lhld X0C6E ;ptr end of text lda X0C63 ;memory pages cmp h jz X04D1 lxi d,0080H mvi b,080H call miuc mvi m,01AH ;^Z pop psw ora a shld X0C6E ;ptr end of text ret X04D1: lxi d,X0BDC ;'Not Enough Room' ferm: call mssg ;message to console jmp X0362 ;return to CP/M onsq: lda rcnt ;repetition count ora a jnz onsr call dnch ;decode next character jc vchk ;verify the checksum cpi 090H ;repeat last character jnz onsu ;normal character call dnch ;decode next character ora a jz onss dcr a onsr: dcr a sta rcnt ;repetition count lda lach jmp achk onss: mvi a,090H jmp achk onsu: sta lach ;last character typed jmp achk ; Decode next character. dnch: lhld cptr ;Huffman code table dncr: call ibit ;read next bit jnc dncs ;skip for 1, stay for 0 inx h inx h dncs: mov e,m ;get next offset inx h mov d,m mov a,d cpi 0FEH ;FEFF means [end] jz dnct ora a jp dncu ;p means new offset mov a,e ;m means complemented char cma stc cmc ret dnct: stc ;flag [end] with carry bit ret ; Calculate +4*. dncu: lhld cptr ;Huffman code table dad d dad d dad d dad d jmp dncr ; Read one bit at a time. ibit: push h lxi h,roco ;bit rotation counter dcr m jnz ibiu mvi m,8 call ibyt ;fetch one byte from input stream sta roby ;rotating byte ibiu: lda roby ;rotating byte rar sta roby ;rotating byte pop h ret ; Read one word. iwor: call ibyt ;fetch one byte from input stream mov l,a push h call ibyt ;fetch one byte from input stream pop h mov h,a ret ; Accumulate checksum. achk: stc cmc ret ; Verify the checksum. vchk: lhld cksm ;checksum mov a,l ora h stc rz ;return to CP/M lxi d,chno ;'Checksum failure.' jmp ferm ;fatal error message abyt: push h lxi h,wflg ;z/nz = no/byte left waiting by abyt mov a,m ora a jz abyy lda wbyt ;byte left waiting by abyt jmp abyr abyy: dcr m call gbyt ;one byte, direct or through onsq sta wbyt ;byte left waiting by abyt abyr: pop h ret rbyt: lda wflg ;z/nz = no/byte left waiting by abyt ora a jz gbyt ;one byte, direct or through onsq mvi a,0 sta wflg ;z/nz = no/byte left waiting by abyt lda wbyt ;byte left waiting by abyt ret gbyt: lda dens ;one byte, direct or through onsq ora a jnz onsq ;one byte from squeezed file ibyt: push h ;fetch byte from the input stream lhld tptr ;text pointer mov a,m inx h shld tptr ;text pointer pop h ret ; Type line, solicit option. X04DA: call rbyt ;fetch one byte cpi CR jz X04F4 ;type options at bottom of panel cpi LF jz X04F5 ;type options at bottom of panel cpi 01AH ;^Z jz X04F5 ;type options at bottom of panel call cona ;char to console jmp X04DA ;type line, solicit option ; Type the options at bottom of panel. ; Entry point according to how line ended. X04F4: call rbyt ;decomission following LF X04F5: call crlf ;CR,LF lxi h,X0C6B ;console remaining lines dcr m rnz ; Solicit options (without marking or incrementing line). X0504: call X0859 ;type level I.D. lxi d,X097A ;'^C = Exit' call mssg ;message to console X050D: lxi d,X0983 ;'[level, root]' lda X0C71 ;level # ora a jz X0521 call mssg ;message to console X0521: lxi d,X0993 ;'[option list]' call mssg ;message to console call X046B ;read char from console sta char ;char read from console cpi 'M' jnz pnla jmp X0342 ;display menu pnla: cpi 003H ;^C jnz pnlb jmp X0362 ;return to CP/M pnlb: cpi 'P' jnz pnlc jmp X06FE ;fulfil PRINT request pnlc: cpi '.' jnz pnld jmp X07E1 ;back to root pnld: cpi '^' jnz pnle jmp X07ED ;go up one level pnle: cpi 'L' jnz pnlf call popu call popu jmp pnlg pnlf: cpi 'S' jnz pnlg call rspu ;restore start of info section pnlg: call pupu ;save reference to section head call X0587 ;reset line count jmp crlf ;CR,LF ; CR, LF. crlf: mvi a,CR call cona ;char to console mvi a,LF jmp cona ;char to console ; Reset line count. X0587: mvi a,23 ;lines per screen panel sta X0C6B ;console remaining lines ret ; Run through the menu. X058D: mvi a,000H sta X0C72 ;panel # lhld xptr ;ptr to bgn of HELP file shld tptr ;text pointer lxi h,roco ;bit rotation counter mvi m,1 lxi h,wflg ;z/nz = no/byte left waiting by abyt mvi m,0 call X0587 ;reset line count lxi h,X0C6B ;console remaining lines dcr m mvi a,'A' sta X0C68 ;option letter lxi d,X0954 ;'Selections are ...' call mssg ;message to console mvi c,000H X05AC: call abyt ;lookahead one byte cpi ':' jz X05D4 ;finish panel w/CR,LF's cpi 01AH ;^Z jz X0362 ;return to CP/M inr c lda X0C68 ;option letter call cona ;char to console inr a sta X0C68 ;option letter mvi a,'.' call cona ;char to console mvi a,' ' call cona ;char to console call X04DA ;type line, solicit option jmp X05AC ; Finish out panel with CR, LF's. X05D4: lda X0C6B ;console remaining lines mov b,a ora a rz X05DD: call crlf ;CR,LF dcr b jnz X05DD ret ; A loop which will print out an information section. It calls ; X04DA, which will count out lines as it types them. If the ; line it has just typed is the last one of the panel, it ; will pause for the panel to be read, having solicited some ; indication of whether it should procede, repeat the last panel, ; go back to the beginning, or go back to the menu. X05E5: call X075D ;is section disk file? call izpu call X0587 ;reset line count X05FA: call abyt ;lookahead one byte cpi 01AH ;^Z jz X0624 ;mark panel, type legend, read option cpi ':' jz X0624 ;mark panel, type legend, read option cpi VT ;form feed jz X05FB call X04DA jmp X05FA X05FB: call rbyt ;fetch one byte lda X0C6B ;console remaining lines X061A: push psw call X04F5 ;type options at bottom of panel pop psw dcr a jnz X061A jmp X05FA ; Mark panel, type legend, select option. X0624: call rbyt ;fetch one byte X0628: call crlf ;CR,LF lxi h,X0C6B ;console remaining lines dcr m jnz X0628 X0635: call X0859 ;type level I.D. lxi d,X0976 ;'EOI & ^C' call mssg ;message to console call X050D lda char ;char read from console cpi 'L' jz X05FA cpi 'S' jz X05FA cpi 'P' jz X05FA ret ; Send line to LST:, check for interrupt request. X06B3: call rbyt ;fetch one byte cpi CR jz X06CE ;list CR, LF's at end of line cpi LF jz X06CF ;list CR, LF's at end of line cpi 01AH ;^Z jz X06CF ;list CR, LF's at end of line call X06E4 ;list output, read status jnz X06B3 ;line to LST: ret ; Type CR, LF at end of line. Entry point according ; to whether CR, LF, or ^Z was encountered. X06CE: call rbyt ;decomission following LF X06CF: mvi a,CR call X06E4 ;list output, read status rz ;to catch a ^C between CR, LF mvi a,LF X06E4: push h push d push b mov e,a mvi c,5 ;(05) list output call X0005 ; B D O S mvi e,0FFH mvi c,6 ;(06) direct console I/O call X0005 ; B D O S pop b pop d pop h cpi 003H ret ; Respond to PRINT request. X06FE: lxi d,X09DE ;'Set Top-of-Form' call mssg ;message to console xra a sta X0C61 ;z/nz = panel/section (P) call popu call pupu call X046B ;read char from console cpi 003H ;^Z jz X071B cpi 'S' jz X0718 call rspu call pupu mvi a,0FFH sta X0C61 ;z/nz = panel/section (P) X0718: call X0730 X071B: call popu jmp pnlg X0730: lxi d,X09B2 ;'Printing in Progress ...' call mssg ;message to console call X0587 ;reset line count X0739: call X06B3 ;line to LST: cpi 003H ;^C rz call abyt ;lookahead one byte cpi 01AH ;^Z rz cpi ':' rz cpi VT ;Form Feed cz X06CF ;list CR, LF's at end of line lda X0C61 ;z/nz = panel/section (P) ora a jnz X0739 lxi h,X0C6B ;console remaining lines dcr m jnz X0739 ret ; Check whether section is a disk file. X075D: call abyt ;lookahead one byte cpi ':' rnz lda X0C71 ;level # cpi ND ;maximum node depth jnz X0776 ;read file, type name lxi d,X0B4A ;'Node Limit' call mssg ;message to console jmp X0362 ;return to CP/M ; Read file, type name. X0776: call X0845 ;locate file name on stack lxi d,005CH+1 ;TFCB+1 mvi b,11 ;bytes in file name call miuc lxi h,X0C71 ;level # inr m lxi d,X0C4C ;'Loading HELP File' call mssg ;message to console call rbyt ;fetch one byte lxi h,005CH+1 ;TFCB+1 mvi b,008H call X07AB ;parse field mvi a,'.' call cona ;char to console mvi b,003H call X07AB ;parse field call crlf ;CR,LF jmp X01BB ;loop ; Read and parse field in file name. ; B is field length, HL beginning of field. X07AB: push h push b call rbyt ;fetch one byte pop b pop h cpi '.' jz X07D6 ;end field w/blanks cpi '!' jc X07D6 ;end field w/blanks call X047B ;upper case fold call cona ;char to console mov m,a inx h dcr b jnz X07AB ;parse field call rbyt ;fetch one byte cpi '.' rz cpi '!' rc lxi d,X0B81 ;'Invalid File Name' call mssg ;message to console jmp X0362 ;return to CP/M ; Fill out field with blanks X07D6: mov c,a X07D7: mvi m,' ' inx h dcr b jnz X07D7 ;loop mov a,c ret ; Go back to root. X07E1: lda X0C71 ;level # ora a jz X0342 ;display menu mvi a,000H jmp X07FE ; Go up one level. X07ED: lda X0C71 ;level # ora a jnz X07FD ;revert to last level lxi d,X0BAD ;'No Higher Level' call mssg ;message to console jmp X0342 ;display menu ; Revert to upper level, type name. X07FD: dcr a X07FE: sta X0C71 ;level # call X0845 ;locate file name on stack push h lxi d,X0C4C ;'Loading HELP File' call mssg ;message to console mvi b,008H X080D: mov a,m cpi ' ' inx h jz X081E call cona ;char to console dcr b jnz X080D jmp X0826 ;type extension X081E: dcr b jz X0826 ;type extension inx h jmp X081E ; Type extension. X0826: mvi a,'.' call cona ;char to console mvi b,003H X082D: mov a,m inx h call cona ;char to console dcr b jnz X082D call crlf ;CR,LF pop d lxi h,005CH+1 ;TFCB+1 mvi b,11 ;bytes in file name call miuc jmp X01BB ;loop ; Locate file name on stack. X0845: call X084D ;HL=A*11 lxi d,X0C73 ;PDL for HELP file names dad d ret ; HL = A*11 X084D: mov l,a mvi h,000H mov e,l mov d,h dad h dad h dad h dad d dad d dad d ret ; Type level identification. X0859: lda X0C71 ;level # ora a jz X0872 lxi d,X0C0C ;'Level 1' call mssg ;message to console lda X0C71 ;level # call X0881 ;translate level # to ASCII lxi d,X0C13 ;'/ ' call mssg ;message to console X0872: lda X0C72 ;panel # ora a rz call X0881 ;translate level # to ASCII lxi d,X0C16 ;': ' call mssg ;message to console ret ; Translate level number to ASCII string. X0881: push psw xra a sta X0C70 ;z/nz = 1/2 digit number pop psw mvi b,100 ;one hundred call X0896 ;type A as decimal number mvi b,10 ;ten call X0896 ;type A as decimal number adi '0' jmp cona ;char to console ; Type A as decimal number. X0896: mvi c,000H X0898: sub b jc X08A0 inr c jmp X0898 X08A0: add b mov b,a lda X0C70 ;z/nz = 1/2 digit number ora a jnz X08B6 mov a,c sta X0C70 ;z/nz = 1/2 digit number ora a jnz X08B6 mvi a,' ' jmp X08B9 X08B6: mov a,c adi '0' X08B9: call cona ;char to console mov a,b ret X08BE: db 'HELP (from ZCPR) Modified for squeezed HELP files.',CR,LF,'$' X08DC: db CR,LF,'Default HELP Facility Invoked',CR,LF db ' - Available HELP Files are -',CR,LF,CR,LF,'$' shlp: db CR,LF,CR,LF,' - Squeezed HELP Files -',CR,LF,CR,LF,'$' X091C: db CR,LF,CR,LF,' Type Any Character for Default Info' db ' (^C to Quit) - $' X0954: db CR,LF,' HELP File Selections are --',CR,LF,'$' X0976: db 'EOI ' X097A: db '^C=Exit $' X0983: db '^=Level .=Root $' X0993: db 'M=Menu S=Start L=Last P=Print $' X09B2: db 'Printing in Progress -- Strike ^C to Quit $' X09DE: db 'Please Set Top-of-Form on Printer',CR,LF db ' Strike S to Print this Screen Only,' db ' ^C to Quit, or',CR,LF db ' Any Other Char to Print Entire Information Section - $' X0A6E: db CR,LF,'HELP FATAL ERROR -- File Name Contains Wild Card$' X0AA1: db CR,LF,'HELP FATAL ERROR -- File not Found$' X0AC6: db CR,LF,'HELP ERROR -- Invalid Response',CR,LF,'$' X0AE9: db CR,LF,'HELP ERROR -- EOF on HELP File',CR,LF,'$' X0B4A: db CR,LF,'HELP ERROR -- Node Level Limit Reached' db ' -- Returning to CP/M',CR,LF,'$' X0B81: db CR,LF,'HELP ERROR -- Invalid File Name in Load',CR,LF,'$' X0BAD: db CR,LF,'HELP ERROR -- No Higher Level to Return to',CR,LF,'$' X0BDC: db CR,LF,'HELP ERROR -- Not Enough Room for HELP File',CR,LF,'$' X0C0C: db 'Level $' X0C13: db '/ $' X0C16: db ': $' X0C19: db 'Type ^C=Exit$' X0C27: db ' ^=Level .=Root$' X0C37: db ' or Enter Selection $' X0C4C: db CR,LF,'Loading HELP File $' chno: db CR,LF,'Checksum failure.$' X0C61: ds 1 ;z/nz = panel/section (P) X0C62: ds 1 ;user code X0C63: ds 1 ;memory pages X0C68: ds 1 ;option letter X0C6B: ds 1 ;console remaining lines X0C6C: ds 1 ;HELP file names/line X0C6D: ds 1 ;nz/z = y/n default file X0C6E: ds 2 ;ptr end of text X0C70: ds 1 ;z/nz = 1/2 digit number X0C71: ds 1 ;level # X0C72: ds 1 ;panel # X0C73: ds 190 ;PDL for HELP file names/stack X0D31: ds 2 ;save stack pointer cksm: ds 2 ;checksum lach: ds 1 ;%; last character typed S rcnt: ds 1 ;%; repetition count E roco: ds 1 ;%; rotating bit counter Q roby: ds 1 ;%; rotating byte U dens: ds 1 ;%; z/nz=normal/squeezed file E wflg: ds 1 ;%; z/nz=no/byte awaiting abyt N wbyt: ds 1 ;%; byte left waiting by abyt C tptr: ds 2 ;%; text pointer E xptr: ds 2 ;ptr to bgn of HELP file yptr: ds 2 ;zptr+NS zptr: ds 2 ;ptr to bgn of info sect cptr: ds 2 ;Huffman code table pptr: ds 2 ;pushdown pointer mopt: ds 1 ;maximum option char: ds 1 ;char read from console pudl: ds NS*50 ;pushdown for section heads X0D33: ds 0 ;free memory ; Layout of pudl and pointers: ; ; pudl: menu ; ... ; menu ; zptr-> panel 1 ; yptr-> panel 2 ; ... ; pptr-> panel n ; x ; x ; x ; X0D33: x ; x ; cptr-> Huffman code ; x ; x ; xptr-> HELPfile text ; x ; x ; tptr-> x ; x ; x end