home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / masm / masm5 / showp.asm < prev    next >
Encoding:
Assembly Source File  |  1988-08-11  |  14.7 KB  |  431 lines

  1.           TITLE   Show
  2.  
  3. ; Program SHOW.ASM
  4. ; Purpose Text file displayer
  5. ; Input   File name from command line or prompt
  6. ; Output  Display file to screen
  7.  
  8.           DOSSEG
  9.           .MODEL  small, pascal
  10.  
  11. INCL_DOSFILEMGR   EQU 1         ; Enable call groups
  12. INCL_DOSMEMMGR    EQU 1
  13. INCL_KBD          EQU 1
  14. INCL_VIO          EQU 1
  15.  
  16.           INCLUDE os2.inc
  17.           INCLUDELIB doscalls.lib
  18.  
  19.           .STACK  800h
  20.  
  21.           .DATA
  22.  
  23. ; Status line
  24.  
  25.           PUBLIC  stLine, nLines, curLine
  26. curLine   DW      1             ; Current line number
  27. nLines    DW      ?             ; Lines per screen
  28. stLine    DB      "Line: 12345 "
  29. stFile    DB      "File: 12345678.123  "
  30.           DB      "Quit: Q  Next: ESC  Move:   PGUP PGDN HOME END"
  31.  
  32. ; Variables for screen and cursor handling
  33.  
  34.           PUBLIC  vMode, Cell, stAtrib, scAtrib
  35. vMode     VIOMODEINFO <>        ; Structures for video and cursor data
  36. lvMode    EQU     $ - vMode     ; Length of structure
  37. vType     DW      0             ; Video type - 0 flag for no change
  38.  
  39. cMode     VIOCURSORINFO <>
  40. cAtrib    DW      -1            ; Cursor attribute (initized to hidden)
  41. cStatus   DB      0             ; 0 = cursor visible, position unchanged
  42.                                 ; 1 = cursor invisible, position unchanged
  43.                                 ; 2 = cursor invisible, position changed
  44.  
  45. stAtrib   DB      030h          ; Status line color default - black on cyan
  46. stBW      EQU     070h          ; B&W default - black on white
  47. Cell      LABEL   WORD          ; Cell (character and attribute)
  48. scChar    DB      " "           ; Initialize to space
  49. scAtrib   DB      017h          ; Screen color default - white on blue
  50. scBW      EQU     007h          ; B&W default - white on black
  51.  
  52. ; Variables for buffer and file handling
  53.  
  54.           PUBLIC  Buffer, oBuffer, sBuffer, lBuffer
  55. Buffer    LABEL   DWORD
  56. oBuffer   DW      0             ; Position in buffer (offset)
  57. sBuffer   DW      ?             ; Base of buffer (segment)
  58. lBuffer   DW      ?             ; Length of buffer
  59.  
  60. ; File information
  61.  
  62. lfName    EQU     66
  63. fName     DB      lfName DUP (" ")
  64. fHandle   DW      ?             ; Holds file handle on open
  65. fAction   DW      ?             ; Result of open
  66. fAtrib    EQU     0             ; Normal file
  67. fFlag     EQU     1             ; Open file if exist, fail if not exist
  68. ; Read only, deny none, private, error codes, use cache, normal file
  69. fModeRec  RECORD  DA:1=0,WT:1=0,FE:1=0,R1:5=0,INF:1=1,SM:3=2,R2:1=0,AM:3=0
  70. fMode     fModeRec <>
  71. fRead     DW      ?             ; Bytes read from file
  72.  
  73. ; Directory information for file name search
  74.  
  75. dHandle   DW      -1            ; Directory handle
  76. dResult   FILEFINDBUF <>        ; Structure for results
  77. dlResult  EQU     $ - dResult   ;   length of result
  78. dCount    DW      1             ; Find one file at a time
  79.  
  80. Prompt    DB      13,10,"Enter filename: "
  81. lPrompt   EQU     $ - Prompt
  82. Prompt2   DB      13,10,"No such file. Try again? "
  83. lPrompt2  EQU     $ - Prompt2
  84. Prompt3   DB      13,10,"File too large: "
  85. lPrompt3  EQU     $ - Prompt3
  86. Prompt4   DB      13,10,"Memory problem.",13,10
  87. lPrompt4  EQU     $ - Prompt4
  88.  
  89. ; Keyboard data
  90.  
  91. kChar     KBDKEYINFO <>         ; Structures for character and string input
  92. kStr      STRINGINBUF <>
  93. kWait     EQU     0             ; Wait flag
  94.  
  95. ; Call table
  96.  
  97. kTable    DB      71,72,73,79,80,81,'q','Q'; Key codes
  98. lkTable   EQU     $-kTable
  99. procTable DW      homek                    ; Table of keys and procedures
  100.           DW      upk
  101.           DW      pgupk
  102.           DW      endk
  103.           DW      downk
  104.           DW      pgdnk
  105.           DW      Quit
  106.           DW      Quit
  107.           DW      nonek
  108.  
  109.           .CODE
  110.           EXTRN   Pager:PROC         ; Routine in other module
  111.  
  112. start     PROC
  113.           mov     es, ax             ; Load environment segment
  114.           mov     di, bx
  115.  
  116. ; Throw away .EXE name
  117.  
  118.           sub     ax, ax             ; Find null at end of program name
  119.           repne   scasb
  120.           cmp     BYTE PTR es:[di], 0; If double zero, there's no name
  121.           je      Prompter           ;   so get from prompt
  122.  
  123.       cmp      BYTE PTR es:[di], ' '
  124.           jne     skip1
  125.           inc     di                 ; Skip leading space
  126. skip1:
  127. ; Copy command line to file name buffer
  128.  
  129.           mov     si, di             ; Filename source
  130.           mov     di, OFFSET fName   ; Name buffer destination
  131.           mov     bx, ds             ; Save segment registers
  132.           mov     dx, es
  133.           mov     ds, dx             ; DS = ES
  134.           mov     es, bx             ; ES = DS
  135.       mov      cx, lfName         ; Count = max file name allowed
  136. loop1:      lodsb              ; Copy first character
  137.       stosb
  138.           cmp     al,' '             ; Terminate on space too
  139.           je      skip2
  140.       or      al,al
  141.       loopnz  loop1          ; If not null, copy another
  142. skip2:
  143.           mov     ds, bx             ; Restore DS
  144.       mov      BYTE PTR [di-1], 0
  145.           jmp     FindFile
  146.  
  147. NoFile:   @VioWrtTTy Prompt2, lPrompt2, 0
  148.           @KbdCharIn kChar, kWait, 0
  149.           and     kChar.kbci_chChar, 11011111b ; Convert to uppercase
  150.           cmp     kChar.kbci_chChar, "Y"
  151.           mov     dHandle, -1
  152.           mov     dCount, 1
  153.           je      Prompter           ; If yes, try again
  154.           jmp     Quit               ;   else quit
  155.  
  156. Prompter: @VioWrtTTy Prompt, lPrompt, 0 ; Else prompt for file name
  157.  
  158.           mov     kStr.kbsi_cb, lfName
  159.  
  160.           @KbdStringIn fName, kStr, kWait, 0
  161.           mov     di, kStr.kbsi_cchIn ; Null terminate
  162.           mov     fName[di], 0
  163.  
  164. ; Find first (or only) file in filespec
  165.  
  166. FindFile: @DosFindFirst fName, dHandle, 0, dResult, dlResult, dCount, 0
  167.           or      ax, ax
  168.           jz      skip3
  169.           jmp     NoFile
  170.  
  171. ; Adjust for current mode and video adapter and hide cursor
  172. skip3:    call    GetVid
  173.  
  174. FileLoop:
  175.           mov     cStatus, 2         ; Cursor invisible, position unchanged
  176.  
  177. ; Copy file name to file spec
  178.  
  179.           push    ds                 ; Get file name position in file spec
  180.           @Pushc  <OFFSET fName>
  181.           call    GetNamPos
  182.           mov     si, OFFSET dResult.findbuf_achName ; Load source name
  183.           mov     es, dx             ; Load adjusted destination address
  184.           mov     di, ax             ;   from return value
  185.           sub     cx, cx             ; Load file length
  186.           mov     cl, dResult.findbuf_cchName
  187.           rep     movsb              ; Copy to spec
  188.           mov     BYTE PTR es:[di], 0; Null terminate
  189.  
  190. ; Copy file name to status line
  191.  
  192.           sub     cx, cx             ; Load file length
  193.           mov     cl, dResult.findbuf_cchName
  194.           mov     bx, 12             ; Calculate blank spaces to fill
  195.           sub     bx, cx
  196.           push    ds                 ; ES=DS
  197.           pop     es
  198.           mov     si, OFFSET dResult.findbuf_achName ; File name as source
  199.           mov     di, OFFSET stFile[6] ; Status line as destination
  200.           rep     movsb
  201.           mov     al, " "            ; Fill rest of name space with blanks
  202.           mov     cx, bx
  203.           rep     stosb
  204.  
  205. ; Open file
  206.  
  207.           @DosOpen fName, fHandle, fAction, 0, fAtrib, fFlag, [fMode], 0
  208.           or      ax, ax
  209.           jz      skip4
  210.           jmp     NoFile
  211.  
  212. skip4:    cmp     WORD PTR dResult.findbuf_cbFile[2], 0
  213.           jz      skip6              ; Make sure file is less than a segment
  214.           mov     cStatus, 1         ; Cursor invisible, position unchanged
  215.           @VioWrtTTy Prompt3, lPrompt3, 0
  216.           @VioWrtTTy <stFile + 6>, 12, 0
  217.           cmp     [dCount], 0        ; Get key if there's another file
  218.           je      skip5
  219.           @KbdCharIn kChar, kWait, 0
  220. skip5:    jmp     skip11
  221.  
  222. ; Allocate file buffer
  223.  
  224. skip6:    mov     ax, WORD PTR dResult.findbuf_cbFile[0] ; Save size
  225.           mov     lBuffer, ax
  226.           mov     oBuffer, 0
  227.           @DosAllocSeg ax, sBuffer, 0
  228.           or      ax, ax
  229.           jz      skip7
  230.           mov     cStatus, 1         ; Cursor invisible, position unchanged
  231.           @VioWrtTTy Prompt4, lPrompt4, 0
  232.           jmp     Quit
  233.  
  234. ; Read the file into the buffer
  235.  
  236. skip7:    @DosRead [fHandle], [Buffer], [lBuffer], fRead
  237.           or      ax, ax
  238.           jz      skip8
  239.           jmp     NoFile
  240.  
  241. ; Search back for EOF marker and adjust if necessary
  242.  
  243. skip8:    mov     di, [fRead]        ; Load file length
  244.           dec     di                 ;   and adjust
  245.           mov     es, [sBuffer]      ; Save ES and load buffer segment
  246.           std                        ; Look backward for 255 characters
  247.           mov     cx, 0FFh
  248.           cmp     cx, di
  249.           jb      skip9
  250.           mov     cx, di
  251. skip9:    mov     al, 1Ah            ; Search for EOF marker
  252.           repe    scasb
  253.           cld
  254.           jcxz    skip10             ; If none, we're OK
  255.           inc     di                 ;   else adjust and save file size
  256.           mov     [lBuffer], di
  257.  
  258. ; Show a screen of text and allow commands
  259.  
  260. skip10:   call    Show
  261.  
  262.  
  263. skip11:   @DosClose [fHandle]        ; Close file
  264.  
  265.           @DosFreeSeg [sBuffer]      ; Free memofy
  266.  
  267.           @DosFindNext [dHandle], dResult, dlResult, dCount ; Get next file
  268.           
  269.           cmp     [dCount], 0        ; Quit if no next file
  270.           jz      exit
  271.           jmp     FileLoop
  272.  
  273. exit:     jmp     Quit
  274. start     ENDP
  275.           
  276. Show      PROC
  277.  
  278. ; Display first page
  279.  
  280.           @Pushc  0                  ; Start at 0
  281.           call    Pager
  282.  
  283. ; Handle keys
  284.  
  285. nextkey:  @KbdCharIn kChar, kWait, 0 ; Get a key and load to register
  286.           mov     al, kChar.kbci_chChar
  287.           or      al, al             ; Is ascii code null?
  288.           jz      skip1              ; Yes? Load scan
  289.           cmp     al, 0E0h           ; Extended key on extended keyboard?
  290.           jne     skip2              ; No? Got code
  291. skip1:    mov     al, kChar.kbci_chScan
  292. skip2:
  293.           cmp     al, 27             ; Is it ESCAPE?
  294.           je      Exit               ; Yes? Get out for next file
  295.  
  296.           push    ds                 ; ES = DS
  297.           pop     es
  298.           mov     di, OFFSET kTable  ; Load address and length of key list
  299.           mov     cx, lkTable + 1
  300.           repne   scasb              ; Find position and point to key
  301.           sub     di, (OFFSET kTable) + 1
  302.           shl     di, 1              ; Adjust pointer for word addresses
  303.           call    procTable[di]      ; Call procedure
  304.           jmp     nextkey
  305.  
  306. exit:     ret
  307. Show      ENDP
  308.  
  309. homek:    mov     oBuffer, 0         ; HOME - set position to 0
  310.           push    oBuffer
  311.           mov     curLine, 1
  312.           call    Pager
  313.           retn
  314.  
  315. upk:      @Pushc  -1                 ; UP - scroll back 1 line
  316.           call    Pager
  317.           retn
  318.  
  319. pgupk:    mov     ax, nLines         ; PGUP - Page back
  320.           neg     ax
  321.           push    ax
  322.           call    Pager
  323.           retn
  324.  
  325. endk:     mov     ax, lBuffer        ; END - Get last byte of file
  326.           mov     oBuffer, ax        ; Make it the file position
  327.           mov     curLine, -1        ; Set illegal line number as flag
  328.           mov     ax, nLines         ; Page back
  329.           neg     ax
  330.           push    ax
  331.           call    Pager
  332.           retn
  333.  
  334. downk:    @Pushc  1                  ; DOWN - scroll forward 1 line
  335.           call    Pager
  336.           retn
  337.  
  338. pgdnk:    push    nLines             ; PGDN - page forward
  339.           call    Pager
  340.           retn
  341.  
  342. nonek:    retn                       ; Ignore unknown key
  343.  
  344. GetVid    PROC
  345.  
  346.           mov     vMode.viomi_cb, lvMode
  347.           @VioGetMode vMode, 0       ; Get video mode
  348.  
  349.           sub     ax, ax             ; Clear AH
  350.           mov     al, vMode.viomi_fbType ; Put type in register
  351.           mov     vType, ax          ;   and save
  352.           test    al, 1              ; Test for color
  353.           jz      skip1              ; No? Mono
  354.           test    al, 100b           ; Test for color burst on
  355.           jz      skip2              ; Yes? Color
  356. skip1:    mov     stAtrib, stBW      ; Set B&W defaults for status line
  357.           mov     scAtrib, scBW      ;   and screen background
  358.  
  359. skip2:    @VioGetCurType cMode, 0    ; Get cursor mode
  360.           mov     ax, cMode.vioci_attr ; Save attribute
  361.           xchg    cAtrib, ax
  362.           mov     cMode.vioci_attr, ax ; Set hidden cursor attribute
  363.           mov     ax, vMode.viomi_row; Get number of rows and adjust
  364.           dec     ax
  365.           mov     nLines, ax
  366.  
  367.           @VioSetCurType cMode, 0    ; Hide cursor
  368.  
  369.           ret
  370. GetVid    ENDP
  371.  
  372. GetNamPos PROC    USES di si, argline:FAR PTR BYTE
  373.  
  374.           les     di, argline        ; Load address of file name
  375.           mov     si, di             ; Save copy
  376.  
  377.           sub     cx, cx             ; Ignore count
  378.           sub     dx, dx             ; Use DX as found flag
  379.           dec     di                 ; Adjust
  380.           mov     ax, "\"            ; Search for backslash
  381. loop1:    scasb                      ; Get next character
  382.           jz      skip1              ; If backslash, set flag and save
  383.           cmp     BYTE PTR es:[di], 0; If end of name, done
  384.           je      skip2
  385.           loop    loop1              ; If neither, continue
  386. skip1:    mov     si, di             ; Save position
  387.           inc     dx                 ; Set flag to true
  388.           loop    loop1
  389.  
  390. skip2:    or      dx, dx             ; Found backslash?
  391.           je      skip3              ; If none, search for colon
  392.           mov     ax, si             ;   else return position in DX:AX
  393.           jmp     SHORT exit
  394.  
  395. skip3:    neg     cx                 ; Adjust count
  396.           mov     di, si             ; Restore start of name
  397.           mov     ax, ":"            ; Search for colon
  398.           repne   scasb
  399.           jnz     skip4              ; If no colon, restore original
  400.           mov     ax, di             ;   else return position in DX:AX
  401.           jmp     SHORT exit
  402.  
  403. skip4:    mov     ax, si             ; Return original address
  404.  
  405. exit:     mov     dx, es
  406.           ret
  407. GetNamPos ENDP
  408.  
  409. Quit      PROC
  410.  
  411.           mov     scAtrib, 7         ; Restore cell attribute for clear screen
  412.  
  413.           cmp     cStatus, 1         ; Check cursor status
  414.           jg      skip1              ; 2 - Make cursor visible on last line
  415.           je      skip1              ; 1 - Make cursor visible
  416.           jmp     SHORT skip3        ; 0 - Leave cursor as is
  417.  
  418. skip1:    @VioSetCurPos [nLines], 0, 0 ; Restore cursor on last line
  419.           @VioScrollDn [nLines], 0, [nLines], 79, 1, Cell, 0
  420.  
  421.  
  422. skip2:    mov     ax, cAtrib         ; Restore cursor attribute
  423.           mov     cMode.vioci_attr, ax
  424.           @VioSetCurType cMode, 0
  425.  
  426. skip3:    @DosExit 1, 0              ; Quit
  427.  
  428. Quit      ENDP
  429.  
  430.           END    start
  431.