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

  1. ;* SHOWP.ASM - Text file displayer for OS/2 (protect mode).
  2.  
  3.         TITLE   Show
  4.         .MODEL  small, pascal, os_os2
  5.         .DOSSEG
  6.         .286
  7.  
  8. INCL_NOCOMMON   EQU 1         ; Enable call groups
  9. INCL_DOSFILEMGR EQU 1
  10. INCL_DOSMEMMGR  EQU 1
  11. INCL_KBD        EQU 1
  12. INCL_VIO        EQU 1
  13.  
  14.         INCLUDE os2.inc
  15.         INCLUDE show.inc
  16.         INCLUDELIB os2.lib
  17.  
  18.         .STACK
  19.  
  20.         .DATA
  21.  
  22. ; Status line
  23.  
  24. stLine  BYTE    "Line: 12345 "
  25. stFile  BYTE    "File: 12345678.123  "
  26.         BYTE    "Quit: Q  Next: ESC  Move:   PGUP PGDN HOME END"
  27.  
  28. ; Variables for screen and cursor handling
  29.  
  30. yCur    WORD    1               ; Current line number
  31. yMax    WORD    ?               ; Lines per screen
  32. vmiMode VIOMODEINFO < SIZE VIOMODEINFO > ; Structure for video data
  33.                                 ; First field initialized to size
  34. vciCsr  VIOCURSORINFO <>        ; Structure for cursor data
  35. atCsr   WORD    -1              ; Cursor attribute (initized to hidden)
  36. bCsrSta BYTE    0               ; 0 = cursor visible, position unchanged
  37.                                 ; 1 = cursor invisible, position unchanged
  38.                                 ; 2 = cursor invisible, position changed
  39.  
  40. atSta   BYTE    STAT_CLR        ; Status line color
  41. celScr  LABEL   WORD            ; Cell (character and attribute)
  42. chScr   BYTE    " "             ; Initialize to space
  43. atScr   BYTE    SCRN_CLR        ; Screen color
  44. chInit  BYTE    0               ; Cell to restore when finished
  45. atInit  BYTE    0
  46.  
  47. ; Buffer variables
  48.  
  49. fpBuf   LABEL   PBYTE
  50. offBuf  WORD    0               ; Position in buffer (offset)
  51. segBuf  SEL     ?               ; Base of buffer (segment selector)
  52. cbBuf   WORD    ?               ; Count in bytes of buffer
  53.  
  54. ; File information
  55.  
  56. hFileIn HFILE   ?               ; Holds file handle on open
  57. usAct   WORD    ?               ; Result of open
  58. usMode  WORD    OPEN_ACCESS_READONLY OR OPEN_SHARE_DENYNONE
  59. cbRead  WORD    ?               ; Bytes read from file
  60.  
  61. ; Directory information for file name search
  62.  
  63. stFiles BYTE    NAME_MAX DUP ("w")
  64. hFiles  WORD    HDIR_CREATE     ; Directory handle
  65. fiFiles FILEFINDBUF <>          ; Structure for results
  66. usCount WORD    1               ; Find one file at a time
  67.  
  68. ; Buffer for file name
  69.  
  70. kkiChar KBDKEYINFO <>           ; Structure for character input
  71. sibStr  STRINGINBUF < NAME_MAX >; Structure for string input
  72.  
  73. ; Messages
  74.  
  75. stMsg1  BYTE    13, 10, "Enter filename: "
  76. stMsg2  BYTE    13, 10, "File problem. Try again? "
  77. stMsg3  BYTE    13, 10, "File too large: "
  78. stMsg4  BYTE    13, 10, "Memory problem.",13,10
  79.  
  80. ; Call table
  81.  
  82. achKeys BYTE    71, 72, 73, 79, 80, 81, 'q', 'Q'; Key table
  83. afnKeys WORD    HomeKey                         ; Corresponding procedures
  84.         WORD    UpKey
  85.         WORD    PgUpKey
  86.         WORD    EndKey
  87.         WORD    DownKey
  88.         WORD    PgDnKey
  89.         WORD    Quit
  90.         WORD    Quit
  91.         WORD    UnknownKey
  92.  
  93.         .CODE
  94.         .STARTUP
  95.  
  96. ; Load environment segment
  97.  
  98.         mov     es, ax                  ; AX points to environment segment
  99.         mov     di, bx                  ; BX points to command line offset
  100.  
  101. ; Throw away .EXE name
  102.  
  103.         sub     ax, ax                  ; Find null at end of program name
  104.         repne   scasb
  105.         cmp     BYTE PTR es:[di], 0     ; If double zero, there's no name
  106.         je      Prompter                ;   so get from prompt
  107.  
  108.         .IF     BYTE PTR es:[di] == ' '
  109.         inc     di                      ; Skip leading space
  110.         .ENDIF
  111.  
  112. ; Copy command line to file name buffer
  113.  
  114.         mov     si, di                  ; Filename source
  115.         mov     di, OFFSET stFiles      ; Name buffer destination
  116.         mov     bx, ds                  ; Save segment registers
  117.         mov     dx, es
  118.         mov     ds, dx                  ; DS = ES
  119.         mov     es, bx                  ; ES = DS
  120.         mov     cx, NAME_MAX            ; Count = max file name allowed
  121.  
  122.         .REPEAT
  123.         lodsb                           ; Copy characters
  124.         .BREAK .IF (al == ' ') || (al == 0) ; Stop at space or null
  125.         stosb
  126.         .UNTILCXZ                       ; Until name exceeds max
  127.  
  128.         mov     ds, bx                  ; Restore DS
  129.         mov     BYTE PTR [di], 0
  130.         jmp     FindFile
  131.  
  132. ; Prompt for file
  133.  
  134. NoFile:
  135.         INVOKE  VioWrtTTy,              ; Write message
  136.                 ADDR stMsg2,
  137.                 LENGTHOF stMsg2,
  138.                 0
  139.  
  140.         INVOKE  KbdCharIn,
  141.                 ADDR kkiChar,
  142.                 IO_WAIT,
  143.                 0
  144.  
  145.         and     kkiChar.chChar_, 11011111y ; Convert to uppercase
  146.         cmp     kkiChar.chChar_, "Y"
  147.  
  148.         mov     hFiles, -1
  149.         mov     usCount, 1
  150.         .IF     !zero?
  151.         jmp     Quit                    ; Quit if not yes
  152.         .ENDIF
  153. Prompter:
  154.         INVOKE  VioWrtTTy,              ; Else prompt for file name
  155.                 ADDR stMsg1,
  156.                 LENGTHOF stMsg1,
  157.                 0
  158.  
  159.         INVOKE  KbdStringIn,
  160.                 ADDR stFiles,
  161.                 ADDR sibStr,
  162.                 IO_WAIT,
  163.                 0
  164.  
  165.         mov     di, sibStr.cchIn_       ; Null terminate
  166.         mov     stFiles[di], 0
  167.  
  168. ; Find first (or only) file in filespec
  169.  
  170. FindFile:
  171.         INVOKE  DosFindFirst,
  172.                 ADDR stFiles,
  173.                 ADDR hFiles,
  174.                 0,
  175.                 ADDR fiFiles,
  176.                 SIZE fiFiles,
  177.                 ADDR usCount,
  178.                 0
  179.  
  180.         or      ax, ax
  181.         jnz     NoFile
  182.  
  183.         INVOKE  GetVid                  ; Adjust for current mode and
  184.                                         ;  video adapter and hide cursor
  185.  
  186. ; Main program loop to process files
  187.  
  188.         .REPEAT
  189.  
  190. ; Copy file name to file spec
  191.  
  192.         mov     bCsrSta, 2              ; Cursor hidden, position unchanged
  193.         INVOKE  GetNamePos,             ; Get file name position in file spec
  194.                 ADDR stFiles
  195.  
  196.         mov     si, OFFSET fiFiles.achName_; Load source name
  197.         mov     di, ax                  ; Load adjusted destination address
  198.                                         ;   from return value
  199.         sub     cx, cx                  ; Load file name length
  200.         mov     cl, fiFiles.cchName_
  201.         rep     movsb                   ; Copy to spec
  202.         mov     BYTE PTR es:[di], 0     ; Null terminate
  203.  
  204. ; Copy file name to status line
  205.  
  206.         sub     cx, cx                  ; Load file length
  207.         mov     cl, fiFiles.cchName_
  208.         mov     bx, 12                  ; Calculate blank spaces to fill
  209.         sub     bx, cx
  210.         push    ds                      ; ES=DS
  211.         pop     es
  212.         mov     si, OFFSET fiFiles.achName_; File name as source
  213.         mov     di, OFFSET stFile[FILE_POS]; Status line as destination
  214.         rep     movsb
  215.         mov     al, " "                 ; Fill rest of name space with blanks
  216.         mov     cx, bx
  217.         rep     stosb
  218.  
  219. ; Skip any file that is larger than 64K
  220.  
  221.         .IF     WORD PTR fiFiles.cbFile_[2] != 0
  222.  
  223.         INVOKE  VioWrtTTy,
  224.                 ADDR stMsg3,
  225.                 LENGTHOF stMsg3,
  226.                 0
  227.  
  228.         INVOKE  VioWrtTTy,
  229.                 ADDR fiFiles.achName_,
  230.                 fiFiles.cchName_,
  231.                 0
  232.  
  233.         .IF     usCount <= 0            ; Get key if there's another file
  234.         INVOKE  KbdCharIn,
  235.                 ADDR kkiChar,
  236.                 IO_WAIT,
  237.                 0
  238.         .ENDIF
  239.         .ENDIF
  240.  
  241. ; Allocate file Buffer
  242.  
  243.         mov     ax, WORD PTR fiFiles.cbFile_[0] ; Save size
  244.         mov     cbBuf, ax
  245.         mov     offBuf, 0
  246.         INVOKE  DosAllocSeg,
  247.                 ax,
  248.                 ADDR segBuf,
  249.                 0
  250.  
  251.         .IF     ax != 0
  252.         mov     bCsrSta, 1              ; Cursor hidden, position unchanged
  253.         INVOKE  VioWrtTTy,
  254.                 ADDR stMsg4,
  255.                 LENGTHOF stMsg4,
  256.                 0
  257.  
  258.         jmp     Quit
  259.         .ENDIF
  260.  
  261. ; Open file and read contents into buffer
  262.  
  263.         INVOKE  DosOpen,
  264.                 ADDR stFiles,
  265.                 ADDR hFileIn,
  266.                 ADDR usAct,
  267.                 0,
  268.                 FILE_NORMAL,
  269.                 FILE_OPEN,
  270.                 usMode,
  271.                 0
  272.  
  273.         .IF     ax != 0
  274.         jmp     NoFile
  275.         .ENDIF
  276.  
  277.         INVOKE  DosRead,
  278.                 hFileIn,
  279.                 fpBuf,
  280.                 cbBuf,
  281.                 ADDR cbRead
  282.  
  283.         .IF     ax != 0
  284.         jmp     NoFile
  285.         .ENDIF
  286.  
  287. ; Search back for EOF marker and adjust if necessary
  288.  
  289.         mov     di, cbRead              ; Load file length
  290.         dec     di                      ;   and adjust
  291.         mov     es, segBuf              ; Save ES and load buffer segment
  292.         std                             ; Look backward for 255 characters
  293.         mov     cx, 0FFh
  294.         .IF     cx >= di
  295.         mov     cx, di
  296.         .ENDIF
  297.  
  298.         mov     al, 1Ah                 ; Search for EOF marker
  299.         repne   scasb
  300.         cld
  301.         .IF     cx != 0                 ; If found:
  302.         inc     di                      ; Adjust and save file size
  303.         mov     cbBuf, di
  304.         .ENDIF
  305.  
  306. ; Show a screen of text and allow commands
  307.  
  308.         INVOKE  Show
  309.  
  310.         INVOKE  DosClose,               ; Close file
  311.                 hFileIn
  312.  
  313.         INVOKE  DosFreeSeg,             ; Free memofy
  314.                 segBuf
  315.  
  316.         INVOKE  DosFindNext,            ; Get next file
  317.                 hFiles,
  318.                 ADDR fiFiles,
  319.                 SIZE fiFiles,
  320.                 ADDR usCount
  321.  
  322.         .UNTIL  ax != 0                 ; Fall through to Quit if
  323.                                         ;  this is the last file
  324. Quit    PROC
  325.  
  326.         cmp     bCsrSta, 1              ; Check cursor status
  327.         jg      csrvislast              ; 2 - Make cursor visible on last line
  328.         je      csrvis                  ; 1 - Make cursor visible
  329.         jmp     csrasis                 ; 0 - Leave cursor as is
  330.  
  331. csrvislast:
  332.         INVOKE  VioSetCurPos,           ; Restore cursor on last line
  333.                 yMax,
  334.                 0,
  335.                 0
  336.         INVOKE  VioScrollDn,
  337.                 yMax,
  338.                 0,
  339.                 yMax,
  340.                 79,
  341.                 1,
  342.                 ADDR chInit,
  343.                 0
  344. csrvis:                                 ; Fall through
  345.         mov     ax, atCsr               ; Restore cursor attribute
  346.         mov     vciCsr.attr_, ax
  347.         INVOKE  VioSetCurType,
  348.                 ADDR vciCsr,
  349.                 0
  350. csrasis:                                ; Fall through
  351.         .EXIT   0
  352.  
  353. Quit    ENDP
  354.  
  355.  
  356. Show    PROC
  357.  
  358. ; Display first page
  359.  
  360.         mov     yCur, 1
  361.         INVOKE  Pager,                  ; Start at 0
  362.                 0
  363.  
  364. ; Handle keys
  365.  
  366.         .REPEAT
  367.         INVOKE  KbdCharIn,              ; Get a key and load to register
  368.                 ADDR kkiChar,
  369.                 IO_WAIT,
  370.                 0
  371.  
  372.         mov     al, kkiChar.chChar_
  373.  
  374.         .BREAK .IF al == 27             ; If ESCAPE get out for next file
  375.  
  376.         ; If null or E0 (for extended keyboard), it's an extended key
  377.         .IF     (al == 0) || (al == 0E0h)
  378.         mov     al, kkiChar.chScan_      ; Load scan code
  379.         .ENDIF
  380.  
  381.         push    ds                      ; ES = DS
  382.         pop     es
  383.         mov     di, OFFSET achKeys      ; Load address and length of key list
  384.         mov     cx, LENGTHOF achKeys + 1
  385.         repne   scasb                   ; Find position and point to key
  386.         sub     di, OFFSET achKeys + 1
  387.         shl     di, 1                   ; Adjust pointer for word addresses
  388.         call    afnKeys[di]             ; Call procedure
  389.         .UNTIL  0
  390.  
  391.         ret
  392. Show    ENDP
  393.  
  394. HomeKey:
  395.         mov     offBuf, 0               ; HOME - set position to 0
  396.         mov     yCur, 1
  397.         INVOKE  Pager, offBuf
  398.         retn
  399.  
  400. UpKey:
  401.         INVOKE  Pager, -1               ; UP - scroll back 1 line
  402.         retn
  403.  
  404. PgUpKey:
  405.         mov     ax, yMax                ; PGUP - Page back
  406.         neg     ax
  407.         INVOKE  Pager, ax
  408.         retn
  409.  
  410. EndKey:
  411.         mov     ax, cbBuf               ; END - Get last byte of file
  412.         dec     ax                      ; Zero adjust
  413.         mov     offBuf, ax              ; Make it the file position
  414.         mov     yCur, -1                ; Set illegal line number as flag
  415.         mov     ax, yMax                ; Page back
  416.         neg     ax
  417.         INVOKE  Pager, ax
  418.         retn
  419.  
  420. DownKey:
  421.         INVOKE  Pager, 1                ; DOWN - scroll forward 1 line
  422.         retn
  423.  
  424. PgDnKey:
  425.         INVOKE  Pager, yMax             ; PGDN - page forward
  426.         retn
  427.  
  428. UnknownKey:
  429.         retn                            ; Ignore unknown key
  430.  
  431.  
  432. ;* GetVid - Gets the video mode and sets related global variables.
  433. ;*
  434. ;* Params: None
  435. ;*
  436. ;* Return: Number of lines in current mode (25, 43, or 50)
  437.  
  438. GetVid  PROC
  439.  
  440.         LOCAL   x:USHORT, y:USHORT, cb:USHORT
  441.  
  442.  
  443.         INVOKE  VioGetMode,             ; Get video mode
  444.                 ADDR vmiMode,
  445.                 0
  446.  
  447.         sub     ax, ax                  ; Clear AH
  448.         mov     al, vmiMode.fbType_     ; Put type in register
  449.  
  450.         ; If monochrome or color burst off:
  451.         .IF     (al & VGMT_GRAPHICS) || (al & VGMT_DISABLEBURST)
  452.         mov     atSta, STAT_BW          ; Set B&W defaults for status line
  453.         mov     atScr, SCRN_BW          ;   and screen background
  454.         .ENDIF
  455.  
  456.         INVOKE  VioGetCurPos,           ; Get cursor position (for cell read)
  457.                 ADDR y,                 ; Row
  458.                 ADDR x,                 ; Column
  459.                 0                       ; Console handle
  460.  
  461.         mov     cb, 1                   ; One cell
  462.         INVOKE  VioReadCellStr,         ; Read cell to get current attribute
  463.                 ADDR chInit,            ; Address to receive cell
  464.                 ADDR cb,                ; Address of length
  465.                 y,                      ; Row
  466.                 x,                      ; Column
  467.                 0                       ; Console handle
  468.         mov     chInit, ' '             ; Make sure character is space
  469.  
  470.         INVOKE  VioGetCurType,          ; Get cursor mode
  471.                 ADDR vciCsr,
  472.                 0
  473.         mov     ax, vciCsr.attr_        ; Save cursor attribute
  474.         xchg    atCsr, ax
  475.         mov     vciCsr.attr_, ax        ; Set hidden cursor attribute
  476.         mov     ax, vmiMode.row_        ; Get number of rows and adjust
  477.         dec     ax
  478.         mov     yMax, ax
  479.  
  480.         INVOKE  VioSetCurType,          ; Hide cursor
  481.                 ADDR vciCsr,
  482.                 0
  483.  
  484.         ret
  485.  
  486. GetVid  ENDP
  487.  
  488.  
  489.         END
  490.