home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol145 / bishow-2.asm < prev    next >
Encoding:
Assembly Source File  |  1984-04-29  |  9.4 KB  |  320 lines

  1. title    'BISHOW.ASM'
  2. ;A buffered, bidirectional version of SHOW.ASM.
  3. ;Ver 1.0, 23 Aug 82
  4. ;Phil Cary, 748 Kenilworth Parkway, Baton Rouge, LA  70808
  5. ;Ver 1.1, 30 Mar 83 added BDOS function 6 W.F.McGee
  6. ;Ver 1.2, 22 May 83 added hi-bit mask for WordStar files
  7. ;         and Wyse-100/200 SCRL keys-changed messages
  8. ;         also made CP/M-86 ver using XLT86 see A86 file
  9. ;      H.M. Van Tassell
  10. ;BISHOW is a buffered, bidirectional version of SHOW.ASM which first
  11. ;appeared in Interface Age, November, 1981.  That program could
  12. ;only scroll forward in a file, and read sectors from disk one at a
  13. ;time as they were sent to the console.  I used SHOW frequently to take
  14. ;a quick look at a file without loading a big text editor, and to examine
  15. ;another file with the RUN command while in Wordstar.  TYPE does not work
  16. ;since it is not a file that Wordstar can load and run.
  17. ;
  18. ;It was annoying when I went past the point I was looking for in a file 
  19. ;with SHOW, and could not go backwards.  Thus, this bidirectional version 
  20. ;which uses random access reads. In addition, buffering was added so that
  21. ;the number of disk reads would be reduced, and moving back and forth
  22. ;in a moderate sized file would be speeded up.  There is a trade off
  23. ;between the size of the buffer and the length of time it takes to refill
  24. ;the buffer which should be set to the user's preference.
  25. ;
  26. ;There are three customizing items in this program.  One is the equate
  27. ;"maxsec" which sets the buffer size.  The other is the string in the
  28. ;subroutine "clrscr" just after the org statement.  This should be changed 
  29. ;to the erase screen and home cursor sequence for the user's terminal. The 
  30. ;program is presently set up for a H/Z-19.  The program, as written, does
  31. ;require a 24 X 80 screen with an erase screen and home cursor function.
  32. ;Finally, direct I/O to the console is used to avoid echoing the commands
  33. ;to the console as the CP/M write console function does.  Three equates
  34. ;under "Console equates" must be changed to match the user's system.
  35. ;
  36. ;Just a small contribution to the public domain software as partial
  37. ;payment for the many fine and educational programs the system has
  38. ;given me.  Phil Cary.
  39.  
  40. ; Begin code
  41.  
  42. false    equ    0
  43. true    equ    not false
  44. APPLE    EQU    false
  45.  
  46. ; BDOS equates
  47.  
  48. boot    equ    0    ;warm boot
  49. wrcon    equ    2    ;console write
  50. bdos    equ    5    ;bdos entry
  51. open    equ    15    ;open file
  52. readr    equ    33    ;read file random access
  53. stdma    equ    26    ;set dma address
  54.  
  55. ; FCB equates
  56.  
  57. fcb    equ    05ch    ;default fcb drive number
  58. fcbfn    equ    fcb+1    ;start of filename
  59. fcbft    equ    fcb+9    ;start of filetype
  60. fcbex    equ    fcb+12    ;current extent number
  61. fcbcrr    equ    fcb+33    ;current record number, random access
  62.  
  63. ; ASCII equates
  64.  
  65. cr    equ    0dh    ;carriage return
  66. lf    equ    0ah    ;line feed
  67. eof    equ    01ah    ;end of file
  68. esc    equ    01bh    ;escape
  69. bell    equ    07h    ;bell
  70.  
  71.  
  72. ; Operational equates
  73.  
  74. maxsec    equ    64    ;number of sectors in buffer
  75.  
  76.     org    100h
  77.  
  78. fulbuf:    set    dskbuf+(maxsec*128)    ;need to know end of buffer
  79.     jmp    start            ;skip over next subroutine
  80.  
  81. clrscr:    call    ilprt        ;code to erase screen and home cursor
  82.  
  83.     IF NOT APPLE
  84.     db    esc,'*',0    ;..Wyse-100/200 terminal. change as required
  85.     ENDIF
  86.     IF APPLE
  87.     db    esc,'*',0    ;..for terminal screen function table
  88.     ENDIF
  89.     ret
  90.  
  91. start:    lxi    sp,stack    ;set up local stack
  92.     call    clrscr        ;clear the screen
  93.     call    opnfil        ;open file in default fcb
  94.     xra    a        ;get a 0
  95.     sta    lincnt        ;store in line count
  96.     sta    fcbex        ;zero current extent
  97.     sta    fcbcrr        ;zero current record
  98.     sta    fcbcrr+1    ;..both bytes
  99.     sta    fcbcrr+2    ;..and the overflow
  100.     call    filbuf        ;fill the disk buffer
  101.  
  102. wrtfwd:    lxi    h,dskbuf    ;point to beginning of buffer
  103. wrtfwd1    mov    a,m        ;get a character
  104.     cpi    eof        ;if it is EOF
  105.     jz    getcmd        ;..loop for another command
  106.     push    psw        ;save character from BDOS clobber
  107.     call    ctype        ;put it on console
  108.     pop    psw        ;get character
  109.     ani    7fh        ;strip hi bit
  110.     cpi    cr        ;see if end of line
  111.     jz    fwdcnt        ;yes, count line
  112. wrtfwd2    inx    h        ;no, bump buffer
  113.     lxi    d,fulbuf    ;get end of buffer address
  114.     mov    a,d        ;compare high
  115.     cmp    h        ;..order bytes
  116.     jnz    wrtfwd1        ;if not equal, continue
  117.     mov    a,e        ;else compare low
  118.     cmp    l        ;..order bytes
  119.     cz    filbuf        ;if end of buffer, go refill
  120.     jz    wrtfwd        ;..and start at beginning of buffer
  121.     jmp    wrtfwd1        ;else, continue with next character
  122.  
  123. fwdcnt:    lda    lincnt        ;get number of lines displayed
  124.     inr    a        ;bump it
  125.     sta    lincnt        ;..and store it
  126.     xchg            ;save the buffer pointer
  127.     lxi    h,linmax    ;point to max number of line for this pass
  128.     cmp    m        ;compare with line count
  129.     xchg            ;restore pointer
  130.     jnz    wrtfwd2        ;if not there, continue, else get command
  131.     xra    a        ;zero the
  132.     sta    lincnt        ;..line count
  133.  
  134. getcmd:
  135.     push    h
  136.     push    d
  137.     push    b
  138. getcmd1:
  139.     mvi     c,06
  140.     mvi    e,0FFH
  141.     call    bdos
  142.     cmp    00h
  143.     jz    getcmd1
  144.     cpi    esc        ;skip if esc
  145.     jz    getcmd1
  146.     ani    5fH        ;make it upper case
  147.     push    psw        ;save chars
  148.     mvi    a,22        ;set up for only 22 lines on forward
  149.     sta    linmax        ;..scrolls
  150.     pop    psw        ;get flags
  151.     pop    b
  152.     pop    d
  153.     pop    h
  154.     cpi    'W'        ;scroll forward?-WYSE-100 SCRL DOWN
  155.     jz    wrtfwd1        ;scroll forward
  156.     cpi    'C'-40h        ;CTRL C
  157.     jz    wrtfwd1
  158.     cpi    'Z'-40h        ;CTRL Z
  159.     jz    wrtfwd1
  160.     push    psw        ;else save character and flags again
  161.     mvi    a,24        ;set up for full screen on scroll
  162.     sta    linmax        ;..backward
  163.     pop    psw        ;get character
  164.     cpi    'V'        ;scroll backward?-WYSE-100 SCRL UP
  165.     jz    wrtbak        ;yes
  166.     cpi    'R'-40h        ;CTRL R?
  167.     jz    wrtbak        ;yes
  168.     cpi    'W'-40h        ;CTRL W?
  169.     jz    wrtbak        ;yes
  170.     cpi    'X'        ;must be exit
  171.     jz    exit        ;yes, or
  172.     call    ilprt        ;..a wrong choice so give message
  173.     db    cr,lf,lf,'Use the SCRL keys (or ^C,^R) to go forward and backward, '
  174.     db    'or X to exit.',cr,bell,0
  175.     jmp    getcmd        ;try again for command
  176.  
  177. wrtbak    mvi    a,44
  178.     sta    lincnt
  179.     call    clrscr        ;clear the screen
  180. wrtbak1    lxi    d,dskbuf    ;get address of buffer start
  181.     mov    a,d        ;compare high
  182.     cmp    h        ;..order bytes
  183.     jnz    wrtbak2        ;continue if not equal
  184.     mov    a,e        ;else, compare low
  185.     cmp    l        ;..order bytes
  186.     jnz    wrtbak2        ;continue if not equal
  187.     jmp    filbak        ;..and go write it
  188. wrtbak2    mov    a,m        ;get a character
  189.     ani    7fh        ;strip hi bit
  190.     cpi    cr        ;see if end of line
  191.     dcx    h        ;decrement buffer
  192.     jnz    wrtbak1        ;..and loop if not
  193.  
  194. bakcnt:    lda    lincnt        ;else, get number of lines to move back
  195.     dcr    a        ;..and decrement it
  196.     sta    lincnt        ;..store it
  197.     jnz    wrtbak1        ;..and loop if not there
  198.     inx    h        ;else bump pointer to account for lf with cr
  199.     jmp    wrtfwd1        ;..and go write a screen
  200.  
  201. filbak:    lxi    d,maxsec    ;get the buffer size
  202.     lhld    seccnt        ;..and number of sectors last read
  203.     dad    d        ;add them
  204.     xchg            ;..and put them in DE
  205.     lda    fcbcrr        ;subtract low order byte 
  206.     sub    e        ;..from current record count
  207.     sta    fcbcrr        ;..and store in current record count
  208.     lda    fcbcrr+1    ;same with high order byte
  209.     sbb    d        ;..but with borrow
  210.     jm    filbeg        ;if beyond beginning of file, go zero count
  211.     sta    fcbcrr+1    ;else, store high order byte
  212.     call    filbuf        ;fill the buffer
  213.     lxi    h,fulbuf    ;..and point to end of buffer
  214.     call    clrscr        ;clear the screen
  215.     jmp    wrtbak2        ;continue moving back in file
  216.                     
  217. filbeg:    xra    a        ;if beyond beginning of file
  218.     sta    fcbcrr        ;..zero the current record field
  219.     sta    fcbcrr+1
  220.     sta    lincnt        ;..and the line count
  221.     call     filbuf        ;fill the buffer again
  222.     jmp    wrtfwd        ;..and go write it
  223.  
  224. filbuf:    lxi    d,dskbuf    ;load start of disk buffer
  225.     mvi    b,maxsec    ;number of sectors to resd
  226.     lxi    h,0        ;zero out the
  227.     shld    seccnt        ;..number of sectors in buffer
  228. filbuf1    push    h        ;save all
  229.     push    d        ;..registers from
  230.     push    b        ;..BDOS clobber
  231.     mvi     c,stdma        ;set dma to
  232.     call    bdos        ;..disk buffer
  233.     lxi    d,fcb        ;set up to read
  234.     mvi    c,readr        ;..a record
  235.     call    bdos        ;do it
  236.     cpi    0        ;read OK?
  237.     lhld    fcbcrr        ;get current record number
  238.     inx    h        ;..bump it
  239.     shld    fcbcrr        ;..and save it
  240.     lhld    seccnt        ;get sectors in buffer
  241.     inx    h        ;bump it
  242.     shld    seccnt        ;store it
  243.     jnz    rderr        ;no, last sector read
  244.     pop    b        ;yes, get sector count
  245.     dcr    b        ;decrement it
  246.     pop    d        ;get de off stack to expose return address
  247.     pop    h        ;
  248.     rz            ;if done return
  249.     lxi    h,128        ;else, add 128 to
  250.     dad    d        ;..dma address
  251.     xchg            ;put it in de
  252.     jmp    filbuf1        ;read another sector
  253.  
  254. rderr:    pop    b        ;restore
  255.     pop    d        ;..registers
  256.     pop    h        ;..and
  257.     xra    a        ;..get a zero to direct to start of buffer
  258.     ret            ;..on ret
  259.  
  260. opnfil:    lda    fcbfn        ;point to first letter of filename
  261.     cpi    ' '        ;anything there?
  262.     jz    help        ;no, give help message
  263.     lxi    d,fcb        ;file name in default fcb
  264.     mvi    c,open        ;set up to open
  265.     call    bdos        ;do it
  266.     cpi    0ffh        ;open OK?
  267.     rnz            ;yes
  268.     call    ilprt        ;else, give error msg and quit
  269.     db    cr,lf,lf,'Requested file is not on this disk.',cr,lf,bell
  270.     db    'Please check your spelling or use DIR.',cr,lf,lf,bell,0
  271.     jmp    exit1        ;leave msg on screen on exit
  272.  
  273. help:    call    ilprt
  274.     db    'Correct usage of SHOW is --',cr,lf,lf
  275.     db    '    A>SHOW filename  ',cr,lf,lf
  276.     db    'After first page is displayed, '
  277.     db    'press SCRL down (^C) for forward,'
  278.     db     cr,lf
  279.     db    'and SCRL up (^R) for backward, or X to exit.',bell,cr,lf,lf,0       
  280.     jmp    exit1
  281.  
  282. ilprt:    xthl            ;exchange top of stack and HL
  283. ilprt1    mov    a,m        ;HL now pointing to db message
  284.     ora    a        ;see if 0 at end of message
  285.     jz    ilprt2        ;yes, restore stack and return
  286.     call    ctype        ;no, print the character
  287.     inx    h        ;bump the pointer
  288.     jmp    ilprt1        ;..and loop
  289. ilprt2    xthl            ;get return address on top of stack
  290.     ret            ;..and return
  291.  
  292. ctype:    push    b        ;Save the registers
  293.     push    d        ;..from bdos
  294.     push    h        ;..clobber
  295.     cpi    'O'-40h        ;wordstar uses ^O for
  296.     jnz    notco        ;non-break space
  297.     mvi    a,' '        ;so substitute a space
  298. notco:    ani    7fh        ;strip hi bit
  299.     mov    e,a        ;set up character
  300.     mvi    c,wrcon        ;..to send to console
  301.     call    bdos        ;do it
  302.     pop    h        ;restore
  303.     pop    d        ;..the registers
  304.     pop    b
  305.     ret
  306.  
  307. exit:    call     clrscr        ;clear the screen
  308. exit1    jmp    0        ;warm boot
  309.  
  310. ; Memory allocation
  311.  
  312. seccnt:    dw    0    ;number of sectors read into buffer
  313. linmax:    db    24    ;number of to write lines on console
  314. lincnt:    db    0    ;line number on write or move back in buffer
  315.     ds    60    ;stack area
  316. stack:    ds    2
  317. dskbuf:    equ    $    ;disk buffer area above the program
  318.  
  319.     end    100h
  320.