; -------------------------------------------------------------- ; HJELP.ASM Copyright (C) 1984 ; Universidad Autonoma de Puebla ; ; [HELP.xxx (SIG/M xxx.xx) Richard Conn] ; [HELP8080.ASM (SIG/M 122.03) = original model] ; [squeezed HELP files - Harold V. McIntosh, July 20, 1984] ; ["L" backs up to panel 1 - 20 Jul 84 - HVM] ; [Library files - 5 October 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 tfcb equ 005CH ;CP/M's file control block tbuf equ 0080H ;CP/M's I-O buffer bred equ 4000H ;red screen area bgrn equ 6000H ;green screen area bblu equ 8000H ;blue screen area 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 257 psiz equ 50*NS ;textpointer pushdown size ; ------------- org 0100H ; ------------- begn: lxi h,0000 dad sp shld X0D31 ;save stack lxi sp,X0D31 ;stack lda tfcb+1 ;TFCB+1 cpi ' ' jnz nnul lxi d,tuto ;'tutorial' ferm: call mssg gbye: lhld X0D31 ;save stack sphl ret nnul: lda X0005+2 sui 0AH sta X0C63 ;memory pages lxi h,nbuf+1 mvi m,' ' xra a sta X0C71 ;level # lxi d,X08BE ;'signon' call mssg ;message to console lda tfcb+1 cpi '(' jnz loop lxi h,tbuf mov b,m inx h xchg lxi h,obuf shld optr call miuc mvi m,00 lxi d,lohf ;'loading HELP file' call mssg call pafr lxi h,nbuf+1 mov a,m cpi ' ' jnz ymbr lxi d,tfcb+1 mvi b,8 call miuc call phlp jmp loop ymbr: lxi h,nbuf+9 mov a,m cpi ' ' cz phlp ; Loop. loop: lxi sp,X0D31 ;stack lxi h,tfcb+9 mov a,m cpi ' ' cz phlp lxi h,tfcb ;TFCB mvi m,000H lxi d,000CH dad d ; Zero out tail of FCB. mvi b,018H ;24 X01C9: mvi m,000H inx h dcr b jnz X01C9 lxi h,0FFFFH shld mlen ldfi: call opef call sefl mvi m,1AH ;^Z call desq jmp gogo sefl: lxi h,X0D33 ;beginning of free memory sefm: lda X0C63 cmp h jz X04D1 ;'not enough room' call rerb jc sefn mov m,a inx h jmp sefm sefn: shld X0C6E ;ptr end of text ret ; ------------------------------------ ; opef will open file even within .LBR ; ofil will open a normal file ; Test for .LBR file. opef: lda nbuf+1 cpi ' ' jz ofil ; ----------------------------------------- ; Open a .LBR file to the member specified ; at nbuf+1 of the .LBR file referenced by ; tfcb. Termination results if either item ; cannot be found, otherwise the next read ; will pick up the desired member. ; ---------------------------------------- ; Open .LBR file, read first record. olbr: mvi c,15 ;(0F) open file lxi d,tfcb call X0005 inr a jnz fopn lxi d,nlib ;'requested library not found' jmp ferm ;send message to console fopn: lxi h,tfcb+32 mvi m,00 lxi h,0000 shld mctr ;counter for tbuf dcx h shld mlen ;length (records) of member call afil ;fill "A" buffer lhld abuf+14 ;length of LBR dir shld mlen ;length (records) of member dad h dad h shld rlen ;length (32-byte lines) of directory ; Library member was requested, so look it up in directory. tmem: lhld rlen ;length (32-byte lines) of directory dcx h shld rlen ;length (32-byte lines) of directory mov a,h ora l jnz tmen lxi d,nfil ;'requested file not present' call ferm ;message to console tmen: call afil ;read a directory line mvi b,11 lxi d,abuf+1 lxi h,nbuf+1 ;member name buffer call ciuc ;block compare jnz tmem ; Record length and whether 'Q' in extension. lhld abuf+14 shld mlen ;length (records) of member lxi h,dens ;z/nz=un/squeezed mvi m,0 lda abuf+10 cpi 'Q' jnz sefi dcr m ; Advance to the proper section of the library. ; This is not an elegant way to do it, but it avoids ; computing with CP/M extents and record sizes. sefi: mvi c,15 ;(0F) open file lxi d,tfcb call X0005 xra a sta tfcb+32 ; Skip up to (but don't read) beginning of member. sefj: lhld abuf+12 mov a,h ora l jz sefk dcx h shld abuf+12 mvi c,20 ;(14) read one record lxi d,tfcb call X0005 jmp sefj sefk: lxi h,0000 shld mctr ret ; Fill the "A" buffer, which holds .LBR directory lines. afil: mvi c,20H lxi h,abuf ;"A" buffer = line of LBR dir afim: call rerb mov m,a inx h dcr c jnz afim ret ; Read a byte from tbuf, replenishing as necessary. ; Carry signifies End of File. rerb: push h lhld mctr ;counter for tbuf mov a,h ora l stc cz rerx ;read one record cmc dcx h shld mctr ;counter for tbuf lhld mptr ;pointer for tbuf mov a,m inx h shld mptr ;pointer for tbuf pop h ret ; Read another record, but don't read past the number ; allocated to the member. Likewise, we have to be careful ; about an ASCII file which ends exactly on a record boundary. rerx: lhld mlen ;length (records) of member mov a,h ora l jz rery dcx h shld mlen ;length (records) of member push b push d mvi c,20 ;(14) read one record lxi d,tfcb call X0005 pop d pop b ora a jnz rery lxi h,tbuf shld mptr ;pointer for tbuf lxi h,0080H stc ret ; Squeezed files should end with a special end ; of file marker (non-1-byte 100H), which has to be seen ; to terminate the file. ASCII files normally terminate with ; a ^Z, but this may be implicit if the file exactly fills a ; record. rery: lxi h,tbuf shld mptr mvi m,1AH ;^Z lxi h,0001H stc cmc ret ; Open an ordinary file. If not found, try for a squeezed ; version instead. ofil: lxi h,0000 shld mctr dcx h shld mlen xra a sta tfcb+32 sta dens ofim: lxi d,tfcb ;TFCB mvi c,15 ;(0F) open file call X0005 ; B D O S inr a rnz lxi h,tfcb+10 mov a,m mvi m,'Q' cmp m jnz ofim lxi d,nfil ;'no file' jmp ferm ; ------------------------ ; Decide whether it is a squeezed file. desq: 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 ret ; 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 ret ; 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 '!' jc xxxx cpi ':' jnz X036A ;show menu, request option call rbyt ;fetch one byte xxxx: call X05E5 ;initialize new section lda X0C71 ;level # ora a jz gbye ;return to CP/M jmp X07ED ;go up one level ; Return to CP/M ; 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 gbye ;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 ; Insert extension .HLP phlp: mvi m,'H' inx h mvi m,'L' inx h mvi m,'P' ret ; 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 ; CR, LF. crlf: mvi a,CR call cona ;char to console mvi a,LF jmp cona ;char to console ; 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 ; Type file name. tyfn: mov a,m cpi ' ' rz mvi b,8 call tyfo mov a,m cpi ' ' rz mvi a,'.' call cona mvi b,3 tyfo: mov a,m inx h cpi ' ' cnz cona dcr b jnz tyfo ret ; Compare B bytes between (HL) and (DE) ciuc: ldax d cmp m rnz inx d inx h dcr b jnz ciuc 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 X04D1: lxi d,X0BDC ;'Not Enough Room' jmp ferm 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: lxi h,cksm mov b,a mov a,m sub b mov m,a inx h mov a,m sbi 0 mov m,a mov a,b 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 jz ibyt push h call onsq ;one byte from squeezed file pop h ret ibyt: push h ;fetch byte from the input stream push d lhld X0C6E ;ptr end of text xchg lhld tptr ;text pointer mov a,l sub e mov a,h sbb d mov a,m inx h shld tptr ;text pointer cmc pop d 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 gbye ;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 ; 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 gbye ;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 call rbyt 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 gbye ;return to CP/M ; Type name, read file. X0776: call X0845 ;locate file name on stack lxi d,tfcb+1 ;TFCB+1 mvi b,11 ;bytes in file name call miuc mvi b,11 lxi d,nbuf+1 call miuc lxi h,X0C71 ;level # inr m ; If there can be several color overlays and the like, ; we have to set aside the panel defining them so that ; the space it occupies can be used for loading. mvi b,0 lxi d,0000 lxi h,obuf shld optr olay: call rbyt jc loaz cpi 1AH ;^Z jz loaz cpi ':' jnz olax mvi a,LF cmp b jz loaz mvi a,':' olax: mov m,a mov b,a inx d inx h cpi ':' jnz olay call rbyt cpi ':' jnz loaz jmp olay loaz: xchg shld octr jmp colo ; Subroutine which will read out the bytes saved from ; the instruction panel when overlays are to be used. obyt: push h ; lhld octr ; mov a,h ; ora l ; jz obyz ; dcx h ; shld octr lhld optr mov a,m inx h shld optr obyz: pop h ret ; Load any requested overlays. colo: lxi d,lohf ;'Loading HELP File' call mssg ;message to console lxi h,dest mvi m,' ' call pafr ;parse file reference. jmp coov ;execute it ; Parse a file reference, and type it. pafr: mvi a,' ' sta nbuf+1 paff: call obyt cpi ' ' jz paff cpi '(' jz ylbr lxi h,tfcb call pars cpi ')' jz wlbr lxi h,tfcb+1 jmp tyfn ylbr: lxi h,tfcb call part wlbr: lxi h,nbuf call part ; Insert extension .LBR if none was given. lxi h,tfcb+9 mov a,m cpi ' ' jnz ylbs mvi m,'L' inx h mvi m,'B' inx h mvi m,'R' ylbs: mvi a,'(' call cona lxi h,tfcb+1 call tyfn mvi a,')' call cona mvi a,' ' call cona lxi h,nbuf+1 jmp tyfn ; Check for color overlay. coov: lxi h,dest mov a,m mvi m,' ' cmp m jnz coow call crlf jmp loop ;loop coow: cpi 'R' jnz gree call opef call sefl call desq lxi h,bred ;red screen area call lcbf jmp colo gree: cpi 'G' jnz blue call opef call sefl call desq lxi h,bgrn ;green screen area call lcbf jmp colo blue: cpi 'B' jnz colo call opef call sefl call desq lxi h,bblu ;blue screen area call lcbf jmp colo ; Load color buffer. HL designates the buffer. lcbf: lda oper cpi '=' jnz ocbf ldbf: call rbyt jc colo mov m,a inx h jmp ldbf ocbf: cpi '+' jnz xcbf odbf: call rbyt jc colo ora m mov m,a inx h jmp odbf xcbf: cpi '-' jnz colo xdbf: call rbyt jc colo xra m mov m,a inx h jmp xdbf ; --------------------------------------------- ; Parse disk, filename, extension. HL points to ; FCB, new characters arrive via . ; --------------------------------------------- ; Pass over leading blanks. ; to ignore A ; to test A first part: call obyt pars: cpi ' ' jz part call term rz ;null buffer ; Insert filename field. If a disk unit is specified, ; record it in the first byte of the FCB, then try again ; for the filename. Likewise, if a destination is given, ; note it. mvi m,0 infn: inx h infi: push h mvi b,8 call stof call oprn jnz dsku sta oper pop h mov a,m sta dest call obyt cpi '(' jnz infi call obyt jmp infi dsku: cpi ':' jnz inxt pop h mov a,m sui '@' mov m,a dcx h call obyt jmp infn ; Insert extension field. inxt: inx sp inx sp mvi b,3 cpi '.' jnz shof call obyt ; Store field. stof: mov m,a inx h dcr b jz lonf call obyt call term ;z=terminator jnz stof ; Complete short field with blanks. shof: mvi m,' ' inx h dcr b jnz shof ret ; Ignore remainder of long field. lonf: call obyt call term ;z=terminator jnz lonf ret ; Check for a field terminator (z). ; Check for an operation (z). term: cpi '.' rz cpi ' ' rz cpi ':' rz cpi ')' rz cpi CR rz ora a rz oprn: cpi '=' rz cpi '+' rz cpi '-' 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,lohf ;'Loading HELP File' call mssg ;message to console call tyfn ;type filename call crlf pop d lxi h,tfcb+1 ;TFCB+1 mvi b,11 ;bytes in file name call miuc mvi b,11 lxi h,nbuf+1 call miuc jmp loop ;loop ; Locate file name on stack. X0845: call X084D ;HL=A*22 lxi d,X0C73 ;PDL for HELP file names dad d ret ; HL = A*22 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 dad h 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 'HJELP/ICUAP/05-OCT-84',CR,LF,'$' tuto: db 'Many systems feature HELP files containing information',CR,LF db 'about the usage or characteristics of the system itself',CR,LF db 'or the programs which it contains. HELP files are often',CR,LF db 'structured, and require an auxiliary program which will',CR,LF db 'facilitate their consultation. HJELP.COM satisfies this',CR,LF db 'requirement, even if the HELP files have been squeezed',CR,LF db 'or have been placed in a library.',CR,LF db ' HJELP FILE',CR,LF db 'will display either FILE.HLP or FILE.HQP, using a menu',CR,LF db 'of information sections and a series of prompts which',CR,LF db 'are largely self-explanatory.',CR,LF db ' HJELP (LIBR) FILE',CR,LF db 'will display FILE.HLP, taken from the library LIBR.LBR.',CR,LF db 'Finally,',CR,LF db ' HJELP (FILE)',CR,LF db 'will assume that FILE.HLP is a member of FILE.LBR. Such',CR,LF db 'a construction presupposes that FILE.LBR contains many',CR,LF db 'additional files which are referenced through FILE.HLP.',CR,LF db 'In all cases, an explicitly given extension will be',CR,LF db 'respected, even when it is different from the default.',CR,LF db '$' 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 - $' X0AC6: db CR,LF,'% -- Invalid Response',CR,LF,'$' X0AE9: db CR,LF,'% -- EOF on HELP File',CR,LF,'$' X0B4A: db CR,LF,'% -- Node Level Limit Reached' db ' -- Returning to CP/M',CR,LF,'$' X0B81: db CR,LF,'% -- Invalid File Name in Load',CR,LF,'$' X0BAD: db CR,LF,'% -- No Higher Level to Return to',CR,LF,'$' X0BDC: db CR,LF,'% -- 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 $' lohf: db CR,LF,'Loading HELP File $' chno: db CR,LF,'Checksum failure.$' nlib: db CR,LF,'Requested library not present.$' rerr: db CR,LF,'Read error.$' nfil: db CR,LF,'Requested file not present.$' mlen: ds 2 ;length (records) of member rlen: ds 2 ;length (32-byte lines) of directory actr: ds 2 aptr: ds 2 abuf: ds 32 nbuf: ds 12 mctr: ds 2 mptr: ds 2 oper: ds 1 ;color operation dest: ds 1 ;color area octr: ds 2 optr: ds 2 obuf: ds 80H 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 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 ND*22+100 ;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