home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / asmutil / usoftpd.zip / PAGER.ASM < prev    next >
Assembly Source File  |  1987-07-31  |  11KB  |  434 lines

  1.       PAGE      60,132
  2.       .MODEL  small
  3.       .DATA
  4.       EXTRN      statatr:BYTE,scrnatr:BYTE,sbuffer:WORD,pbuffer:WORD
  5.       EXTRN      fsize:WORD,cell:WORD,statline:BYTE,linenum:WORD
  6.       EXTRN      rows:WORD,vidadr:WORD,cga:BYTE
  7.  
  8.       .CODE
  9.       PUBLIC  Pager,isEGA
  10.  
  11. ; Procedure Pager
  12. ; Purpose   Displays status and    text lines
  13. ; Input        Stack variable: lines to scroll (negative up, positive down)
  14. ;        Global variables: "sbuffer", "pbuffer", "linenum"
  15. ; Output    To screen
  16.  
  17. Pager      PROC
  18.       push      bp
  19.       mov      bp,sp
  20.  
  21.       mov      es,sbuffer        ; Initialize buffer position
  22.       mov      di,pbuffer
  23.  
  24.       mov      cx,[bp+4]        ; Get count argument
  25.       mov      ax,10            ; Search for linefeed
  26.  
  27.       or      cx,cx            ; Argument 0?
  28.       jg      forward        ; If above, forward
  29.       jl      backward        ; If below, backward
  30.       jmp      SHORT    show        ; If equal, done
  31.  
  32. backward: call      GoBack        ; Adjust backward
  33.       jmp      SHORT    show        ; Show screen
  34. forward:  call      GoForwd        ; Adjust forward
  35.  
  36. ; Write    line number to status line
  37.  
  38. show:      cld                ; Go forward
  39.       push      di
  40.       push      es
  41.       push      ds            ; Load DS to ES
  42.       pop      es
  43.  
  44. ; BinToStr (linenum,OFFSET statline[7])
  45.  
  46.       push      linenum        ; Arg 1
  47.       mov      ax,OFFSET statline[7]
  48.       push      ax            ; Arg 2
  49.       call      BinToStr        ; Convert to string
  50.  
  51. ; Fill in status line
  52.  
  53.       mov      cx,7            ; Seven    spaces to fill
  54.       sub      cx,ax            ; Subtract those already done
  55.       mov      al," "        ; Fill with space
  56.       rep      stosb
  57.       pop      es
  58.  
  59.       mov      bl,statatr        ; Load status attribute
  60.       mov      BYTE PTR cell[1],bl
  61.  
  62. ; CellWrt (DS,OFFSET statline,0,cell)
  63.  
  64.       push      ds            ; Arg 1
  65.       mov      ax,OFFSET statline    ; Arg 2
  66.       push      ax
  67.       sub      ax,ax            ; Arg 3
  68.       push      ax
  69.       push      cell            ; Arg 4
  70.       call      CellWrt        ; Write    status line
  71.  
  72.       pop      di
  73.       mov      bl,scrnatr        ; Load screen attribute
  74.       mov      BYTE PTR cell[1],bl
  75.       mov      si,di            ; Update position
  76.       mov      cx,rows        ; Lines    per screen
  77.  
  78. show1:      mov      bx,rows        ; Lines    of text
  79.       inc      bx            ; Adjust for 0
  80.       sub      bx,cx            ; Calculate current row
  81.       push      cx            ; Save line number
  82.  
  83. ; CellWrt (sbuffer,position,line,cell)
  84.  
  85.       push      sbuffer        ; Arg 1
  86.       push      si            ; Arg 2
  87.       push      bx            ; Arg 3
  88.       push      cell            ; Arg 4
  89.       call      cellwrt        ; Write    line
  90.  
  91.       push      ss            ; Restore DS from SS
  92.       pop      ds
  93.  
  94.       pop      cx            ; Restore line number
  95.       mov      si,ax            ; Get returned position
  96.  
  97.       cmp      ax,fsize        ; Beyond end of    file?
  98.       jae      fillout        ; Yes? Fill screen with    spaces
  99.       loop      show1            ;    else next line
  100.       jmp      SHORT    pagedone    ; Get out if done
  101.  
  102. ; Fill the rest    with spaces
  103.  
  104. fillout:  dec      cx            ; Adjust
  105.       jcxz      pagedone
  106.       mov      al,80            ; Columns times    remaining lines
  107.       mul      cl
  108.  
  109. ; CellFil (sbuffer,count,cell)
  110.  
  111.       push      sbuffer        ; Arg 1
  112.       push      ax            ; Arg 2
  113.       push      cell            ; Arg 3
  114.       call      CellFil        ; Fill screen with spaces
  115.  
  116.       push      ss            ; Restore DS from SS
  117.       pop      ds
  118.  
  119. pagedone: pop      bp
  120.       ret      2
  121. Pager      ENDP
  122.  
  123. ; Procedure CellWrt (segment,offset,line,cell)
  124. ; Purpose   Writes a line to screen buffer
  125. ; Input        Stack variables: 1 - segment of line
  126. ;                 2 - offset
  127. ;                 3 - line number
  128. ;                 4 - attribute
  129. ; Output    Line to screen buffer
  130.  
  131. CellWrt      PROC
  132.       push      bp
  133.       mov      bp,sp
  134.       sub      dx,dx            ; Clear    as flag    for scan
  135.       cmp      cga,1            ; CGA?
  136.       jne      noscan
  137.       mov      dx,03DAh        ; Load port #
  138.  
  139. noscan:      mov      es,vidadr        ; Load screen buffer segment
  140.       mov      ds,[bp+10]        ; Buffer segment
  141.       mov      si,[bp+8]        ; Buffer position
  142.       mov      cx,80            ; Cells    per row
  143.       mov      ax,[bp+6]        ; Starting row
  144.       mov      bx,80*2        ; Bytes    per row
  145.       mul      bl            ; Figure columns per row
  146.       mov      di,ax            ; Load as destination
  147.       mov      bx,di            ; Save start for tab calculation
  148.       mov      ax,[bp+4]        ; Attribute
  149. movechar: lodsb                ; Get character
  150.       cmp      al,13            ; CR?
  151.       je      fillspc
  152.       cmp      al,9            ; Tab?
  153.       jne      notab
  154.       call      filltab        ; Yes? fill with spaces
  155.       jcxz      nextline        ; If beyond limit done
  156.       jmp      SHORT    movechar
  157.  
  158. notab:      or      dx,dx            ; CGA?
  159.       je      notab2
  160.       call      Retrace        ; Yes? Write during retrace
  161.       loop      movechar
  162.       jmp      SHORT    nextline
  163.  
  164. notab2:      stosw                ; Write
  165.       loop      movechar
  166.       jmp      SHORT    nextline    ; Done
  167.  
  168. fillspc:  mov      al," "        ; Fill with space
  169.  
  170.       or      dx,dx            ; CGA?
  171.       je      space2
  172. space1:      call      Retrace        ; Yes? Write during retrace
  173.       loop      space1
  174.       inc      si            ; Adjust
  175.       jmp      SHORT    exit        ; Done
  176.  
  177. space2:      rep      stosw            ; Write
  178.       inc      si            ; Adjust for LF
  179.       jmp      SHORT    exit        ; Done
  180.  
  181. nextline: mov      ah,10            ; Search for next line feed
  182. chklf:      lodsb                ; Load and compare
  183.       cmp      al,ah
  184.       loopne  chklf
  185.  
  186. exit:      mov      ax,si            ; Return position
  187.       pop      bp
  188.       ret      8
  189. CellWrt      ENDP
  190.  
  191. ; Procedure CellFil (segment,count,cell)
  192. ; Purpose   Fills screen with character
  193. ; Input        Stack variables: 1 - segment of text (offset 0)
  194. ;                 2 - number    of characters
  195. ;                 3 - attribute and character
  196. ; Output    Characters to screen buffer
  197.  
  198. CellFil      PROC
  199.       push      bp
  200.       mov      bp,sp
  201.       sub      dx,dx            ; Clear    as flag    for scan
  202.       cmp      cga,1            ; CGA?
  203.       jne      noscan2
  204.       mov      dx,03DAh        ; Load port #
  205.  
  206. noscan2:  mov      es,vidadr        ; Load screen buffer segment
  207.       mov      ds,[bp+8]        ; Buffer segment (position 0)
  208.       mov      cx,[bp+6]        ; Characters to    fill
  209.       mov      ax,[bp+4]        ; Attribute
  210.       or      dx,dx            ; CGA?
  211.       je      fillem2
  212. fillem1:  call      Retrace        ; Yes? Write during retrace
  213.       loop      fillem1
  214.       jmp      SHORT    filled        ; Done
  215. fillem2:  rep      stosw            ; Write
  216.  
  217. filled:      pop      bp
  218.       ret      6
  219. CellFil      ENDP
  220.  
  221. ; Procedure FillTab
  222. ; Purpose   Writes spaces for tab to screen
  223. ; Input        BX points to start of line,    DI points to current position
  224. ; Output    Spaces to screen buffer
  225.  
  226. FillTab      PROC
  227.       push      bx
  228.       push      cx
  229.  
  230.       sub      bx,di            ; Get current position in line
  231.       neg      bx
  232.       shr      bx,1            ; Divide by 2 bytes per    character
  233.  
  234.       mov      cx,8            ; Default count    8
  235.       and      bx,7            ; Get modulus
  236.       sub      cx,bx            ; Subtract
  237.       mov      bx,cx            ; Save modulus
  238.  
  239.       mov      al," "        ; Spaces
  240.       or      dx,dx            ; CGA?
  241.       je      tabem2
  242.  
  243. tabem1:      call      Retrace        ; Yes? Write during retrace
  244.       loop      tabem1
  245.       jmp      SHORT    tabbed
  246. tabem2:      rep      stosw            ; Write
  247.  
  248. tabbed:      pop      cx
  249.       sub      cx,bx            ; Adjust count
  250.       jns      nomore        ; Make negative    count 0
  251.       sub      cx,cx
  252. nomore:      pop      bx
  253.       ret
  254. FillTab      ENDP
  255.  
  256. ; Procedure GoBack
  257. ; Purpose   Searches backward through buffer
  258. ; Input        CX has number of lines; ES:DI has buffer position
  259. ; Output    Updates "linenum" and "pbuffer"
  260.  
  261. GoBack      PROC
  262.       std                ; Go backward
  263.       neg      cx            ; Make count positive
  264.       mov      dx,cx            ; Save a copy
  265.       inc      cx            ; One extra to go up one
  266.       or      di,di            ; Start    of file?
  267.       je      exback        ; If so, ignore
  268. findb:      push      cx            ;   else save count
  269.       mov      cx,0FFh        ; Load maximum character count
  270.       cmp      cx,di            ; Near start of    buffer?
  271.       jl      notnear        ; No? Continue
  272.       mov      cx,di            ;   else search    only to    start
  273. notnear:  repne      scasb            ; Find last previous LF
  274.       jcxz      atstart        ; If not found,    must be    at start
  275.       pop      cx
  276.       loop      findb
  277.       cmp      linenum,0FFFFh    ; End of file flag?
  278.       jne      notend        ; No? Continue
  279.       add      di,2            ; Adjust for cr/lf
  280.       mov      pbuffer,di        ; Save position
  281.       call      EndCount        ; Count    back to    get line number
  282.       ret
  283.  
  284. notend:      sub      linenum,dx        ; Calculate line number
  285.       jg      positive
  286.       mov      linenum,1        ; Set to 1 if negative
  287. positive: add      di,2            ; Adjust for cr/lf
  288.       mov      pbuffer,di        ; Save position
  289.       ret
  290.  
  291. atstart:  pop      cx
  292.       sub      di,di            ; Load start of    file
  293.       mov      linenum,1        ; Line 1
  294.       mov      pbuffer,di        ; Save position
  295. exback:      ret
  296. GoBack      ENDP
  297.  
  298. ; Procedure GoForwd
  299. ; Purpose   Searches forward through a buffer
  300. ; Input        CX has number of lines; ES:DI has buffer position
  301. ; Output    Updates "linenum" and "pbuffer"
  302.  
  303. GoForwd      PROC
  304.       cld                ; Go forward
  305.       mov      dx,cx            ; Copy count
  306. findf:      push      cx            ; Save count
  307.       mov      cx,0FFh        ; Load maximum character count
  308.       repne      scasb            ; Find next LF
  309.       jcxz      atend            ; If not found,    must be    at end
  310.       cmp      di,fsize        ; Beyond end?
  311.       jae      atend
  312.       pop      cx
  313.       loop      findf
  314.       add      linenum,dx        ; Calulate line    number
  315.       mov      pbuffer,di        ; Save position
  316.       ret
  317.  
  318. atend:      pop      cx
  319.       mov      di,pbuffer        ; Restore position
  320.       ret
  321. GoForwd      ENDP
  322.  
  323. ; Procedure EndCount
  324. ; Purpose   Counts backward to count lines in file
  325. ; Input        ES:DI has buffer position
  326. ; Output    Modifies "linenum"
  327.  
  328. EndCount  PROC
  329.       push      di
  330.  
  331.       mov      al,13            ; Search for CR
  332.       mov      linenum,0        ; Initialize
  333.  
  334. findstrt: inc      linenum        ; Adjust count
  335.       mov      cx,0FFh        ; Load maximum character count
  336.       cmp      cx,di            ; Near start of    buffer?
  337.       jl      notnear2        ; No? Continue
  338.       mov      cx,di            ;   else search    only to    start
  339. notnear2: repne      scasb            ; Find last previous cr
  340.       jcxz      found            ; If not found,    must be    at start
  341.       jmp      SHORT    findstrt
  342.  
  343. found:      pop      di
  344.       ret
  345. EndCount  ENDP
  346.  
  347. ; Procedure isEGA
  348. ; Purpose   Determines if an EGA is active
  349. ; Input        None
  350. ; Output    0 if no; lines per screen if yes
  351.  
  352. isEGA      PROC
  353.       push      bp
  354.       push      es
  355.       mov      ah,12h        ; Call EGA status function
  356.       mov      bl,10h
  357.       sub      cx,cx            ; Clear    status bits
  358.       int      10h
  359.       sub      ax,ax            ; Segment 0 and    assume no EGA
  360.       jcxz      noega            ; If status still clear, no EGA
  361.  
  362.       mov      es,ax            ; ES=0
  363.       test      BYTE PTR es:[487h],1000b ; Test active bit
  364.       jnz      noega            ; If set, not active
  365.       mov      ax,1130h        ; Get EGA information
  366.       int      10h
  367.       mov      al,dl            ; Return lines per screen
  368.       cbw
  369.  
  370. noega:      pop      es
  371.       pop      bp
  372.       ret
  373. isEGA      ENDP
  374.  
  375. ; Procedure BinToStr (number,address)
  376. ; Purpose   Converts integer to    string
  377. ; Input        Stack arguments: 1 - Number    to convert; 2 -    Near address for write
  378. ; Output    AX has characters written
  379.  
  380. BinToStr  PROC
  381.       push      bp
  382.       mov      bp,sp
  383.       mov      ax,[bp+6]        ; Arg 1
  384.       mov      di,[bp+4]        ; Arg 2
  385.  
  386.       sub      cx,cx            ; Clear    counter
  387.       mov      bx,10            ; Divide by 10
  388.  
  389. ; Convert and save on stack backwards
  390.  
  391. getdigit: sub      dx,dx            ; Clear    top
  392.       div      bx            ; Divide to get    last digit as remainder
  393.       add      dl,"0"        ; Convert to ASCII
  394.       push      dx            ; Save on stack
  395.       or      ax,ax            ; Quotient 0?
  396.       loopnz  getdigit        ; No? Get another
  397.  
  398. ; Take off the stack and store forward
  399.  
  400.       neg      cx            ; Negate and save count
  401.       mov      dx,cx
  402. putdigit: pop      ax            ; Get character
  403.       stosb                ; Store    it
  404.       loop      putdigit
  405.       mov      ax,dx            ; Return digit count
  406.  
  407.       pop      bp
  408.       ret      4
  409. BinToStr  ENDP
  410.  
  411. ; Procedure Retrace
  412. ; Purpose   Writes cell    during horizontal retrace (CGA)
  413. ; Input        ES:DI has screen buffer position, AX has cell
  414. ; Output    Character to screen    buffer
  415.  
  416. Retrace      PROC
  417.       push      bx
  418.       mov      bx,ax            ; Save character
  419. lscan2:      in      al,dx            ; Look in the port
  420.       shr      al,1            ;   until it goes low
  421.       jc      lscan2
  422.       cli
  423. hscan2:      in      al,dx            ; Look in the port
  424.       shr      al,1            ;   until it goes high
  425.       jnc      hscan2
  426.       mov      ax,bx            ; Restore and write it
  427.       stosw
  428.       sti
  429.       pop      bx
  430.       ret
  431. Retrace      ENDP
  432.  
  433.       END
  434.