data           segment     public
               org     0f6h
fhandle        dw      ?
ndx            dw      ?
pg             dw      ?
ddh            dw      ?
ddl            dw      ?
data           ends
main           proc    near
               call    curpos          ;clear screen
               call    init            ;check dos, print title
               call    rdfn            ;read file name
               call    openit          ;open file
               call    ptbuf           ;get chapter index
               call    curpos          ;set cursor position
               call    menu            ;index options
               endp
rdfn           proc    near            ;read file name
               cld                     ;positive increment
               mov     si, 081h        ;initial offset F.N.
rdl1:          lodsb                   ;get character
               cmp     al, 0dh         ;is it CR ?
               je      rdlo            ;if yes print msg.
               mov     di, 0162h
               mov     cx, 05h
               repne   scasb
               cmp     al, 020h        ;count blank spaces
               je      rdl1
               mov     dx,si           ;true offset F.N.
               dec     dx
rdl2:          lodsb                   ;get character
               cmp     al, 0dh         ;is it CR ?
               je      rdl3            ;done if yes
               jne     rdl2            ;get another if no
rdl3:          mov     b[si-1], 00h
               jmp     rdl4
rdlo:          mov     ah, 09h         ;print msg
               mov     dx, offset rdlmsg
               int     21h
               int     20h
rdl4:          ret
               endp
rdlmsg:        db      'Syntax:    BOOK [file_path]FILE_NAME ',0dh,0ah,'$'
curpos         proc    near
               push    dx              ;
               mov     ax, 0200h       ;position cursor
               mov     bx, 0000h       ;
               mov     dx, 0000h       ;
               int     10h             ;
               mov     cx,0000h        ;blank screen
               mov     dx, 184fh       ;
               mov     bh, 07h         ;
               mov     ax, 0600h       ;
               int     10h             ;
               pop     dx              ;
               ret
               endp
init           proc    near            ;initialization routine
               mov     ah, 30h         ;what dos are we under?
               int     21H
               cmp     al,2            ;dos 2.0 or over?
               jae     a1              ;yes, skip
               mov     ah, 09h         ;no, bitch
               mov     dx, offset baddos
               int     21H
               int     20h             ;and exit
a1:            call    curpos          ;blank and position
               mov     ah, 09h         ;send title message
               mov     dx, offset title_msg1
               int     21H
               call    tdelay          ;time delay
               ret
baddos:        db      0dh,0ah,'This program requires DOS 2.0!',0dh,0ah,0dh,0ah,'$'
title_msg1:    db      0dh,0ah,'Book    version 2.0  Copyright (c) 1992 ',0dh,0ah,
               db      0dh,0ah,'If you find this program useful or interesting, please  '
               db      0dh,0ah,'send a minimum contribution of Fifteen Dollars to: ',0dh,0ah,
               db      0dh,0ah,'Robert Wallingford, 2338 N. McVicker Ave., Chicago, IL 60639',0dh,0ah,
               db      0dh,0ah,'For more information, exit and type BOOK HOW2DOIT.FIL <ENTER>',0dh,0ah,0dh,0ah,'$'
               endp
tdelay         proc    near            ;time delay
               mov     cx, 0a0h        ;time delay
td1:           push    cx
               mov     ah, 0h
               int     1ah
td2:           push    dx
               mov     ah, 0h
               int     1ah
               pop     bx
               cmp     bx, dx
               je      td2
               pop     cx
               loop    td1
               ret
               endp
openit         proc    near            ;Open file
               mov     ax, 3d00h
               int     21h
               jc      fail_end
               mov     fhandle, ax     ;save fhandle
               jmp     open_end
fail_end:      mov     ah, 09h         ;fail exit
               mov     dx, offset fnfmsg
               int     21h
               int     20h
open_end:      ret
fnfmsg:        db      'File not found   $'
               endp
closeit        proc    near            ;close file
               mov     ax, 3e00h
               mov     bx, fhandle
               int     21h
               jc      ffail_end
               jmp     close_end
ffail_end:     int     20h             ;fail exit
close_end:     ret
               endp
fpoint         proc    near            ;set file pointer
               mov     ax, 4200h       ;using data from
               mov     bx, fhandle     ;first part of file
               mov     cx, ddh
               mov     dx, ddl
               int     21h
               jc      err
               ret
err:           int     20h             ;fail exit
               endp
ptbuf          proc    near            ;move file pointer
               mov     ddh, 0000h      ;information from
               mov     ddl, 0000h      ;file to buffer
               call    fpoint
               mov     ah, 3fh
               mov     cx, 0006h
               mov     dx, offset(1ef0h)
               int     21h             ;get index length
               mov     bp, 1ef0h
               mov     bx, [bp]
               mov     ndx, bx         ;store index length
               mov     dx, [bp+2]
               mov     cx, [bp+4]
               cmp     dl, 'B'
               jne     stop            ;is this file
               cmp     dh, 'O'         ;a 'BOOK' file?
               jne     stop            ;if not, exit
               cmp     cl, 'O'
               jne     stop
               cmp     ch, 'K'
               je      ok
stop:          mov     ah, 09h         ;print password msg
               mov     dx, offset pswd
               int     21h
               int     20h             ;and exit
ok:            mov     ddl, 0000h
               mov     ddh, 0000h
               call    fpoint          ;zero pointer again
               mov     ah, 3fh
               mov     cx, ndx         ;pointer buffer length
               mov     dx, offset(1ef0h) ;and location
               int     21h             ;fill index buffer
               ret
pswd:          db      'This is not a BOOK file.  ',0dh,0ah,'$'
               endp
cbu            proc    near            ;count display and
               mov     bx, 1fffh       ;back up pointer
cbu1:          add     bx, 0001h
               mov     al, [bx]
               cmp     bx, 27cfh
               jz      cbu3
               cmp     al, '$'
               jz      cbu2            ;out loop if '$'
               jmp     cbu1            ;loop back
cbu2:          mov     ax, bx
               add     ax, 0003h       ;for $ CR LF combination
               mov     bx, 2800h
               add     bx, pg
               add     bx, pg          ;address page size
               sub     ax, 2000h
               mov     [bx], ax        ;store page size
               sub     ax, [27ddh]
               mov     dx, ax          ;desired displacement
               mov     cx, 0ffffh
               mov     bx, fhandle
               mov     ax, 4201h
               int     21h
               ret
cbu3:          mov     bx, 2800h
               add     bx, pg
               add     bx, pg
               mov     ax, 07d2h       ;store page size
               mov     [bx], ax
               ret
               endp
menu           proc    near            ;get menu
mu0:           mov     bp, 1ef6h       ;menu address
               push    bx
               mov     bx, [bp]
               mov     pg, bx
               mov     bx, [bp+2]
               mov     ddh, bx
               mov     bx, [bp+4]
               mov     ddl, bx
               pop     bx
               call    fpoint          ;from pointers
               mov     ah, 3fh         ;read menu
               mov     bx, fhandle
               mov     cx, 07d2h       ;menu length
               mov     dx, offset(2000h) ;to buffer
               int     21h
               or      ax, ax          ;stop if empty
               jz      stp
               jc      stp
               jmp     goo
stp:           ret                     ;empty exit
goo:           call    curpos          ;cls & set cursor
               mov     ah, 09h         ;display
               int     21h
               mov     pg, 0000h
               call    cbu
mu1:           mov     ax, 0000h       ;wait for character
               int     16h
               or      al, al
               jz      mu1             ;extended code?
               cmp     al, 'e'         ;exit on e
               jz      donemp
               cmp     al, 'E'         ;exit on E
               jz      donemp
               cmp     al, '0'
               jb      mu1             ;return if <'0'
               cmp     al, '9'
               jbe     muu             ;go if digit
               cmp     al, 'A'
               jb      mu1             ;return if <'A'
               sub     al, 07h
               cmp     al, 'S'
               jbe     muu             ;go if capital letter
               add     al, 07h
               cmp     al, 'a'
               jb      mu1             ;return if <'a'
               sub     al, 27h
               cmp     al, 'S'
               ja      mu1             ;return if >'z'
muu:           sub     al, '0'         ;use key to set pointer
               push    ax
               push    bx
               add     al, 02h
               mov     bl, al          ;copy index to bl
               mov     ah, 00h
               mov     bh, 00h
               add     ax, bx
               add     ax, bx
               add     ax, ax          ;6 * index
               add     ax, 1ef0h       ;1ef0h + 6 * index
               mov     bp, ax
               mov     bx, [bp]
               mov     pg, bx          ;number of pages this ch.
               mov     bx, [bp+2]
               mov     ddh, bx         ;high pointer index this ch.
               mov     bx, [bp+4]
               mov     ddl, bx         ;low pointer index this ch.
               pop     bx
               pop     ax
               call    fpoint          ;set pointers for chapter
               call    curpos          ;cls & set cursor
               call    doit            ;display chapter
               jmp     mu0
donemp:        call    closeit         ;ready for good exit
               int     20h             ;exit
               ret
               endp
doit           proc    near            ;display chapter
               mov     bx, 27dah
               mov     cx, pg
               mov     [bx], cx
do1:           cmp     pg, 0000h       ;more pages in chapter?
               jz      out1
               mov     ah, 3fh         ;read next page
               mov     bx, fhandle
               mov     cx, 07d2h       ;set buffer's size
               mov     dx, offset(2000h) ;buffer location
               int     21H
               or      ax, ax          ;set ZF to 1 if ax=0
               jz      out1            ;quit if page is empty
               jc      out1
               mov     [27ddh], ax     ;bytes read
               jmp     out2
do11:          jmp     do1
out1:          ret
out2:          call    curpos          ;cls & set cursor
               mov     ah, 09h         ;display page
               int     21h
               call    cbu
               sub     pg, 0001h
do2:           mov     ax, 0000h
               int     16h             ;wait
               cmp     al, 00h
               jnz     nxc             ;extended code
               cmp     ah, 51h         ;PgDn
               jz      do1
               cmp     ah, 49h         ;PgUp
               jz      pgup
               jmp     do2
pgup:          mov     ax, pg
               add     ax, 0002h
               mov     bx, 27dah
               cmp     [bx], ax        ;don't go back before
               jl      do2             ;beginning of chapter
               add     pg, 0002h
               mov     ax, 4201h       ;set file pointer
               mov     bx, fhandle     ;back two pages
               mov     bp, 2800h
               add     bp, pg
               add     bp, pg
               mov     cx, [bp]
               sub     bp, 0002h
               add     cx, [bp]
               mov     dx, 0000h
               sub     dx, cx
               mov     cx, 0ffffh
               int     21h
               jmp     do1
nxc:           sub     al, 20h         ;for space bar
               jz      do11
               sub     al, 25h         ;or for E
               jz      done
               sub     al, 20h         ;or for e
               jz      done
               jmp     do2
done:          ret
               endp
               end
