home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / edit / point20 / support.asm < prev    next >
Encoding:
Assembly Source File  |  1991-02-04  |  16.6 KB  |  692 lines

  1. DGROUP    GROUP    CONST,    _BSS,    _DATA
  2.     ASSUME  DS: DGROUP, SS: DGROUP, ES: DGROUP
  3. ;
  4. SUPPORT_TEXT    SEGMENT  WORD PUBLIC 'CODE'
  5. SUPPORT_TEXT    ENDS
  6. ;
  7. CONST    SEGMENT  WORD PUBLIC 'CONST'
  8. CONST    ENDS
  9. ;
  10. _BSS    SEGMENT  WORD PUBLIC 'BSS'
  11.     assume    ds:dgroup
  12.     extrn    _evtail:word
  13.     extrn    _evaddr:word
  14. _BSS    ENDS
  15. ;
  16. _DATA    SEGMENT  WORD PUBLIC 'DATA'
  17.     assume    ds:dgroup
  18. minus1    dw    -1
  19. minus2    dw    -2
  20. _DATA    ENDS
  21. ;
  22. SUPPORT_TEXT    SEGMENT  WORD PUBLIC 'CODE'
  23.     assume    cs:SUPPORT_TEXT
  24.     assume    ds:dgroup
  25.     public    _evinit, _mbintr
  26. ;
  27. ;
  28. ;************************ _repword *************************
  29. ; XTAG:repword
  30.         public    _repword
  31. ;
  32. ; repword(wordToReplicate, startAddress, numberOfReplications);
  33. ; char *startAddress;
  34. ; int wordToReplicate, numberOfReplications;
  35. ;
  36. _repword    proc    far
  37.         push    bp        ; save bp
  38.         mov    bp,sp        ; set up bp to access the arguments
  39.         push    di        ; save di
  40.         cld    ; set search direction to forwards
  41.         mov    ax,[bp+6]    ; ax = word to replicate
  42.         mov    di,[bp+8]    ; di = address to start reps
  43.         mov    cx,[bp+10]    ; cx = number of replications
  44.     rep    stosw            ; search for a newline
  45.         pop    di        ; restore di
  46.         pop    bp        ; restore bp
  47.         ret
  48. _repword    endp
  49. ;
  50. ;
  51. ; mouse event (software) interrupt handler
  52. ;
  53. pgmds    dw    ?
  54. ;
  55. ;
  56. ;************************ _movwords *************************
  57. ;
  58.         public    _movwords
  59. ;
  60. ; movwords(wordToReplicate, startAddress, numberOfReplications);
  61. ; char *startAddress;
  62. ; int wordToReplicate, numberOfReplications;
  63. ;
  64. _movwords    proc    far
  65.         push    bp        ; save bp
  66.         mov    bp,sp        ; set up bp to access the arguments
  67.         push    ds        ; save ds
  68.         push    es        ; save es
  69.         push    si        ; save si
  70.         push    di        ; save di
  71.         cld            ; set move direction to forwards
  72. ;
  73.         mov    ax,[bp+6]
  74.         mov    ds,ax
  75.         mov    si,[bp+8]    ; si = address of source data
  76.         mov    ax,[bp+10]    ; ax = word to replicate
  77.         mov    es,ax
  78.         mov    di,[bp+12]    ; di = address of destination data
  79. ;
  80.         mov    cx,[bp+14]    ; cx = number of replications
  81.         sar    cx,1        ; convert to a word count
  82.     rep    movsw            ; move the word
  83. ;
  84.         pop    di        ; restore di
  85.         pop    si        ; restore si
  86.         pop    es        ; restore es
  87.         pop    ds        ; restore ds
  88.         pop    bp        ; restore bp
  89.         ret
  90. _movwords    endp
  91. ;
  92. ;
  93. ;************************ _mbintr *************************
  94. ;
  95. _mbintr    proc    far
  96.     cli    ; disable hardware interrupts
  97. ;
  98. ; first save all the registers on entry
  99. ;
  100.     push    ds    ; save ds
  101.     push    si    ; save si
  102.     push    cx    ; save cx
  103.     push    bx    ; save bx
  104.     push    ax    ; save ax
  105. ;
  106.     push    dx    ; save dx
  107.     push    cx    ; save cx
  108.     push    bx    ; save bx
  109.     push    ax    ; save ax
  110. ;
  111. ; set us DS to Point's DS since the interrupt mechanism does not
  112. ; set it (how could it?)
  113. ;
  114.     mov    ds,pgmds
  115. ;
  116. ; now compute the address of the event slot to put this in
  117. ; and store the next value (no interrupts so not need to wait on the store)
  118. ;
  119.     mov    bx,_evaddr    ; address of the event array
  120.     mov    ax,_evtail    ; where the last event was put
  121.     inc    ax        ; move to the next event
  122.     cmp    ax,30        ; do modulo adjustment?
  123.     jl    l1
  124.     sub    ax,ax
  125. l1:
  126.     mov    _evtail,ax    ; record the increment so C can see it
  127.     mov    cl,3        ; 4 words/event x 2 bytes/word
  128.     shl    ax,cl        ; get an offset in 8 byte chunks
  129.     add    bx,ax        ; address of the next event
  130. ;
  131. ; store the four event words in the event slot
  132. ;
  133.     pop    [bx+0]    ; ax on entry moved to event slot
  134.     pop    [bx+2]    ; bx on entry moved to event slot
  135.     pop    [bx+4]    ; cx on entry moved to event slot
  136.     pop    [bx+6]    ; dx on entry moved to event slot
  137. ;
  138. ; restore registers
  139. ;
  140.     pop    ax
  141.     pop    bx
  142.     pop    cx
  143.     pop    si
  144.     pop    ds
  145. ;
  146. ; done
  147. ;
  148.     sti    ; re-enable interrupts
  149.     ret
  150. _mbintr    endp
  151. ;
  152. ;************************ _evinit *************************
  153. ;
  154. ; set up mbintr as the mouse software interrupt handler
  155. ;
  156. _evinit    proc    far
  157.     push    bp        ; save bp
  158.     mov    bp,sp
  159.     push    es        ; save es
  160.     mov    pgmds,ds    ; save ds for later
  161. ;
  162.     mov    ax,12        ; set subroutine mask
  163.     mov    cx,7FH        ; interrupt on mouse buttons
  164.     mov    dx,offset _mbintr; address of interrupt handler
  165.     push    cs        ; move cs to es
  166.     pop    es
  167.     int    51        ; mouse function call
  168. ;
  169.     pop    es
  170.     pop    bp
  171.     ret
  172. _evinit    endp
  173. ;
  174. ;************************ _getvect *************************
  175. ;
  176. ;
  177.         public    _getvect
  178. _getvect    PROC        far
  179.         push        bp            ; save bp
  180.         mov        bp,sp
  181.         push        es            ; save es
  182.         mov        al,[bp+6]        ; first arg is vector num
  183.         mov        ah,35H
  184.         int        21H            ; dos function call
  185.         mov        dx,es
  186.         mov        ax,bx
  187.         pop        es
  188.         pop        bp
  189.         ret
  190. _getvect    endp
  191. ;
  192.         public    _matchdn
  193. ;
  194. ; match = matchdn(text, textLength, pat, patlength);
  195. ; char *text, *pat, *match;
  196. ; int textLength, patLength;
  197. ;
  198. _matchdn    proc    far
  199.         push    bp
  200.         mov    bp,sp
  201.         push    si        ; save si
  202.         push    di        ; save di
  203.         push    es        ; save es
  204.         push    ds    ; move ds to es since di used a ds base
  205.         pop    es    ; in medium model not always(es==ds)
  206.         cld        ; set search direction to forward
  207.         mov    cx,[bp+8]    ; cx = length(text)
  208.         sub    cx,[bp+12]    ; cx = length(text)-length(pat)
  209.         jl    notFound    ; text shorter than pat
  210.         inc    cx        ;    + 1
  211.         mov    di,[bp+6]    ; di --> text
  212. loop1:
  213.         mov    si,[bp+10]    ; si --> pat
  214.         mov    al,[si]        ; al = first char in pat
  215.     repne    scasb            ; search for first char in pat
  216.         jne    notFound    ; last comparison was not equal
  217.                     ; so cx got to zero w/o finding char
  218.         mov    dx,cx        ; save text's cx
  219.         mov    bx,di        ; save text's di
  220.         mov    cx,[bp+12]    ; match for length of pat
  221.         dec    cx        ; we already matched the first char
  222.         jz    foundIt        ; pat is only one character long
  223.         mov    si,[bp+10]    ; the cmpsb uses this
  224.         inc    si        ; first char already was matched
  225.                     ; di is already set up
  226.     repe    cmpsb            ; compare the strings
  227.         je    foundIt        ; last compare was equal so we matched
  228.         mov    cx,dx        ; restore cx
  229.         mov    di,bx        ; the repe cmpsb changed di
  230.         jmp    loop1
  231. ;
  232. notFound:
  233.         xor    ax,ax        ; return 0 == NULL
  234.         jmp    retlab
  235. foundIt:
  236.         mov    ax,bx        ; bx = saved di (beginning of match)
  237.         dec    ax        ; di was one past the start of
  238.                     ; the match
  239. retlab:
  240.         pop    es
  241.         pop    di
  242.         pop    si
  243.         pop    bp
  244.         ret
  245. _matchdn    endp
  246. ;
  247. ;************************ _matchup *************************
  248. ;
  249. ;
  250.         public    _matchup
  251. ;
  252. ; match = matchup(text, textLength, pat, patlength);
  253. ; char *text, *pat, *match;
  254. ; int textLength, patLength;
  255. ;
  256. _matchup    proc    far
  257.         push    bp
  258.         mov    bp,sp
  259.         push    si        ; save si
  260.         push    di        ; save di
  261.         push    es        ; save es
  262.         push    ds    ; move ds to es since di used a ds base
  263.         pop    es    ; in medium model not always(es==ds)
  264.         mov    cx,[bp+8]    ; cx = length(text)
  265.         sub    cx,[bp+12]    ; cx = length(text)-length(pat)
  266.         jl    notupFound    ; text shorter than pat
  267.         inc    cx        ;    + 1
  268.         mov    di,[bp+6]    ; di --> text
  269.         add    di,cx        ; start cx bytes up since we are
  270.                     ; searching backwards (std)
  271. loopup:
  272.         mov    si,[bp+10]    ; si --> pat
  273.         mov    al,[si]        ; al = first char in pat
  274.         std            ; set search direction to backward
  275.     repne    scasb            ; search for first char in pat
  276.         jne    notupFound    ; last comparison was not equal
  277.                     ; so cx got to zero w/o finding char
  278.         mov    dx,cx        ; save text's cx
  279.         mov    bx,di        ; save text's di
  280.         mov    cx,[bp+12]    ; match for length of pat
  281.         dec    cx        ; we already matched the first char
  282.         jz    foundupIt    ; pat is only one character long
  283.         mov    si,[bp+10]    ; the cmpsb uses this
  284.         inc    si        ; first char already was matched
  285.                     ; di is already set up
  286.         cld            ; set search direction to forward
  287.     repe    cmpsb            ; compare the strings
  288.         je    foundupIt        ; last compare was equal so we matched
  289.         mov    cx,dx        ; restore cx
  290.         mov    di,bx        ; the repe cmpsb changed di
  291.         jmp    loopup
  292. ;
  293. notupFound:
  294.         xor    ax,ax        ; return 0 == NULL
  295.         jmp    retup
  296. foundupIt:
  297.         mov    ax,bx        ; bx = saved di (beginning of match)
  298.         dec    ax        ; di was one past the start of
  299.                     ; the match
  300. retup:
  301.         cld            ; set search direction to forward
  302.         pop    es
  303.         pop    di
  304.         pop    si
  305.         pop    bp
  306.         ret
  307. _matchup    endp
  308. ;
  309. ;************************ _match2dn *************************
  310. ;
  311.         public    _match2dn
  312. ;
  313. ; match = match2dn(text, textLength, ch1);
  314. ; char far *text;
  315. ; char *match, ch1;
  316. ; int textLength;
  317. ;
  318. _match2dn    proc    far
  319.         push    bp
  320.         mov    bp,sp
  321.         push    di        ; save di
  322.         push    es        ; save es
  323.         cld        ; set search direction to forward
  324. ;
  325. ; look for the first character
  326. ;
  327.         mov    di,[bp+6]    ; di --> text
  328.         mov    es,[bp+8]    ; es = segment of text
  329.         mov    cx,[bp+10]    ; cx = length(text)
  330.         mov    al,[bp+12]    ; al = first char in pat
  331.     repne    scasb            ; search for first char
  332.         je    found2It    ; last comparison was equal
  333.         mov    ax,minus2    ; -2 for not found
  334.         jmp    comm2It
  335. found2It:
  336.         mov    ax,di        ; save the result
  337. comm2It:
  338.         pop    es
  339.         pop    di
  340.         pop    bp
  341.         ret
  342. _match2dn    endp
  343. ;
  344. ;************************ _match1dn *************************
  345. ;
  346.         public    _match1dn
  347. ;
  348. ; match = match1dn(text, textLength, ch1, ch2);
  349. ; char far *text;
  350. ; char *match, ch1, ch2;
  351. ; int textLength;
  352. ;
  353. _match1dn    proc    far
  354.         push    bp
  355.         mov    bp,sp
  356.         push    di        ; save di
  357.         push    es        ; save es
  358.         cld        ; set search direction to forward
  359. ;
  360. ; look for the first character
  361. ;
  362.         mov    di,[bp+6]    ; di --> text
  363.         mov    es,[bp+8]    ; es = segment of text
  364.         mov    cx,[bp+10]    ; cx = length(text)
  365.         mov    al,[bp+12]    ; al = first char in pat
  366.     repne    scasb            ; search for first char
  367.         je    found1It    ; last comparison was equal
  368.         mov    bx,minus2    ; -2 for not found
  369.         jmp    comm1It
  370. found1It:
  371.         mov    bx,di        ; save the result
  372. comm1It:
  373. ;
  374. ; look for the second character
  375. ;
  376.         mov    di,[bp+6]    ; di --> text
  377.         mov    cx,[bp+10]    ; cx = length(text)
  378.         mov    al,[bp+14]    ; al = second char in pat
  379.     repne    scasb            ; search for first char
  380.         jne    ret1        ; not found, so use 1st result
  381.         cmp    bx,minus2    ; found before also?
  382.         jne    ret2        ; yes, so compare the two
  383.         mov    bx,di        ; no, so use this one
  384.         jmp    ret1
  385. ret2:
  386.         cmp    bx,di        ; was first result smaller?
  387.         jle    ret1
  388.         mov    bx,di
  389. ret1:
  390.         mov    ax,bx
  391.         pop    es
  392.         pop    di
  393.         pop    bp
  394.         ret
  395. _match1dn    endp
  396. ;
  397. ;************************ _match1up *************************
  398. ;
  399. ;
  400.         public    _match1up
  401. ;
  402. ; match = match1up(text, textLength, ch1, ch2);
  403. ; char far *text;
  404. ; char *match, ch1, ch2;
  405. ; int textLength;
  406. ;
  407. _match1up    proc    far
  408.         push    bp
  409.         mov    bp,sp
  410.         push    di        ; save di
  411.         push    es        ; save es
  412.         std        ; set search direction to backward
  413. ;
  414. ; look for the first character
  415. ;
  416.         mov    di,[bp+6]    ; di --> LAST byte of the text
  417.         mov    es,[bp+8]    ; es = segment of text
  418.         mov    cx,[bp+10]    ; cx = length(text)
  419.         mov    al,[bp+12]    ; al = first char in pat
  420.     repne    scasb            ; search for first char
  421.         je    found1upIt    ; last comparison was equal
  422.         mov    bx,minus2    ; -2 for not found
  423.         jmp    comm1upIt
  424. found1upIt:
  425.         mov    bx,di        ; save the result
  426. comm1upIt:
  427. ;
  428. ; look for the second character
  429. ;
  430.         mov    di,[bp+6]    ; di --> text
  431.         mov    cx,[bp+10]    ; cx = length(text)
  432.         mov    al,[bp+14]    ; al = second char in pat
  433.     repne    scasb            ; search for first char
  434.         jne    ret1up        ; not found, so use 1st result
  435.         cmp    bx,minus2    ; found before?
  436.         jne    ret2up        ; yes, compare the two answers
  437.         mov    bx,di        ; no, so use this result
  438.         jmp    ret1up
  439. ret2up:
  440.         cmp    bx,minus1    ; This is a special case.  bx=-1
  441.                     ; when the match was at the 0th
  442.                     ; character.  We need to count this
  443.                     ; as low.  If bx=-1 and both are
  444.                     ; valid use the other one.
  445.         je    useSecond
  446.         cmp    bx,di        ; was first result larger?
  447.         jae    ret1up
  448. useSecond:
  449.         mov    bx,di
  450. ret1up:
  451.         mov    ax,bx
  452.         cld        ; set search direction to forward
  453.         pop    es
  454.         pop    di
  455.         pop    bp
  456.         ret
  457. _match1up    endp
  458. ;
  459. ;************************ _countnl *************************
  460. ;
  461. ;
  462.         public    _countnl
  463. ;
  464. ; find = countnl(addr, len);
  465. ; char far *addr;
  466. ; int len;
  467. ;
  468. _countnl    proc    far
  469.         push    bp
  470.         mov    bp,sp
  471.         push    di
  472.         push    es        ; save es
  473. ;;;;        push    ds        ; move ds to es (via the stack)
  474. ;;;;        pop    es        ; complete move ds to es
  475.         cld            ; set search direction to forward
  476.         xor    bx,bx        ; bx counts newlines (start at 0)
  477.         mov    cx,[bp+10]    ; cx = length(text)
  478.         mov    di,[bp+6]    ; di --> text to find nl in
  479.         mov    es,[bp+8]    ; es --> segment of text
  480.         mov    al,10        ; al = newline (line feed) ASCII 10
  481. loopCnl:
  482.     repne    scasb            ; search for a newline
  483.         jne    doneCnl        ; last comparison was not equal
  484.                     ; so cx got to zero w/o finding nl
  485.                     ; so we are done
  486.         inc    bx        ; count up the newlines
  487.         jmp    loopCnl
  488. doneCnl:
  489.         mov    ax,bx        ; bx = newline count
  490.         pop    es
  491.         pop    di
  492.         pop    bp
  493.         ret
  494. _countnl    endp
  495. ;
  496. ;************************ _nextnl *************************
  497. ;
  498. ;
  499.         public    _nextnl
  500. ;
  501. ; find = nextnl(addr, len);
  502. ; char *addr;
  503. ; int len;
  504. ;
  505. _nextnl        proc    far
  506.         push    bp
  507.         mov    bp,sp
  508.         push    di
  509.         push    es        ; save es
  510.         push    ds        ; move ds to es (via the stack)
  511.         pop    es        ; complete move ds to es
  512.         cld    ; set search direction to forward
  513.         mov    cx,[bp+8]    ; cx = length(text)
  514.         mov    di,[bp+6]    ; di --> text to find nl in
  515.         mov    al,10        ; al = newline (line feed)
  516.     repne    scasb            ; search for a newline
  517.         je    foundIt2    ; last comparison was not equal
  518.                     ; so cx got to zero w/o finding nl
  519.         dec    cx        ; return -1
  520. foundIt2:
  521.         mov    ax,cx        ; cx = chars left unscanned
  522.         pop    es
  523.         pop    di
  524.         pop    bp
  525.         ret
  526. _nextnl        endp
  527. ;
  528. ;************************ _prevnl *************************
  529. ;
  530.         public    _prevnl
  531. ;
  532. ; find = prevnl(addr, len);
  533. ; char *addr;
  534. ; int len;
  535. ;
  536. _prevnl        proc    far
  537.         push    bp
  538.         mov    bp,sp
  539.         push    di
  540.         push    es        ; save es
  541.         push    ds        ; move ds to es (via the stack)
  542.         pop    es        ; complete move ds to es
  543.         std    ; set search direction to backwards
  544.         mov    cx,[bp+8]    ; cx = length(text)
  545.         mov    di,[bp+6]    ; di --> text to find nl in
  546.         mov    al,10        ; al = newline (line feed)
  547.     repne    scasb            ; search for a newline
  548.         je    foundIt3    ; last comparison was not equal
  549.                     ; so cx got to zero w/o finding nl
  550.         dec    cx        ; return -1
  551. foundIt3:
  552.         mov    ax,cx        ; cx = chars left unscanned
  553.         pop    es
  554.         pop    di
  555.         pop    bp
  556.         cld        ; set search direction to forward
  557.         ret
  558. _prevnl        endp
  559. ;
  560. ;************************ _horvid *************************
  561. ;
  562. ;
  563.         public    _horvid,_hor1vid
  564. ;
  565. ; this version writes the regen buffer during the horizontal refresh
  566. ; two characters per horizontal refresh
  567. ;
  568. _horvid    proc        far
  569. ; save registers
  570.         push        bp
  571.         mov        bp,sp
  572.         push        ax
  573.         push        bx
  574.         push        cx
  575.         push        dx
  576.         push        si
  577.         push        di
  578.         push        es
  579. ; set up video regen buffer
  580.         mov        ax,0B800H ; color/graphics regen buffer
  581.         mov        es,ax    ; video regen memory in es
  582.         mov        di,[bp+6] ; offset into video regen buffer
  583. ; get other parameters
  584.         mov        si,[bp+8] ; offset of screen buffer from ds
  585.         mov        cx,[bp+10] ; number of words to move
  586.         cld                ; clear the direction flag
  587. ; wait for the vertical retrace
  588. ; we want the beginning of it, so wait until it is not
  589. ; on a retrace, then wait for the beginning of the next one
  590. l2:
  591.         mov        dx,3DAH    ; I/O address of video port
  592. l3:
  593.         in        al,dx    ; get video status
  594.         test        al,1        ; wait untile we are NOT
  595.         jnz        l3        ; on a horizontal retrace
  596.         lodsw    ; get the next word
  597.         mov        bx,ax    ; save it in bx (need ax for 'in')
  598. ;
  599. ; disable interrupts, since the timing is critical here
  600. ; once we find the retrace, we have to write all the words
  601. ; without getting interrupted.  An interrupt will throw us
  602. ; off and cause snow on the screen
  603. ;
  604.         cli        ; diable interrupts while writing
  605. l4:
  606.         in        al,dx    ; get video status
  607.         test        al,1        ; wait for horizontal retrace
  608.         jz        l4
  609. ; move a word into the video buffer
  610.         mov        ax,bx    ; recover from bx
  611.         stosw            ; store one word
  612.         sti        ; re-enable interrupts
  613.         loop        l2  ; loop while cx > 0 (more words to move)
  614. ; restore the registers and return
  615.         pop        es
  616.         pop        di
  617.         pop        si
  618.         pop        dx
  619.         pop        cx
  620.         pop        bx
  621.         pop        ax
  622.         pop        bp
  623.         ret
  624. ;
  625. _horvid    endp
  626. ;
  627. ;************************ _hor1vid *************************
  628. ;
  629. ; this version writes the regen buffer during the horizontal refresh
  630. ; one character per horizontal refresh
  631. ;
  632. _hor1vid    proc        far
  633. ; save registers
  634.         push        bp
  635.         mov        bp,sp
  636.         push        ax
  637.         push        bx
  638.         push        cx
  639.         push        dx
  640.         push        si
  641.         push        di
  642.         push        es
  643. ; set up video regen buffer
  644.         mov        ax,0B800H ; color/graphics regen buffer
  645.         mov        es,ax    ; video regen memory in es
  646.         mov        di,[bp+6] ; offset into video regen buffer
  647. ; get other parameters
  648.         mov        si,[bp+8] ; offset of screen buffer from ds
  649.         mov        cx,[bp+10] ; number of words to move
  650.         cld                ; clear the direction flag
  651. ; wait for the vertical retrace
  652. ; we want the beginning of it, so wait until it is not
  653. ; on a retrace, then wait for the beginning of the next one
  654. m2:
  655.         mov        dx,3DAH    ; I/O address of video port
  656. m3:
  657.         in        al,dx    ; get video status
  658.         test        al,1        ; wait untile we are NOT
  659.         jnz        m3        ; on a horizontal retrace
  660.         lodsb    ; get the next byte
  661.         mov        bl,al    ; save it in bl (need al for 'in')
  662. ;
  663. ; disable interrupts, since the timing is critical here
  664. ; once we find the retrace, we have to write all the words
  665. ; without getting interrupted.  An interrupt will throw us
  666. ; off and cause snow on the screen
  667. ;
  668.         cli        ; diable interrupts while writing
  669. m4:
  670.         in        al,dx    ; get video status
  671.         test        al,1        ; wait for horizontal retrace
  672.         jz        m4
  673. ; move a word into the video buffer
  674.         mov        al,bl     ; recover from bx
  675.         stosb            ; store one byte
  676.         sti        ; re-enable interrupts
  677.         loop        m2  ; loop while cx > 0 (more bytes to move)
  678. ; restore the registers and return
  679.         pop        es
  680.         pop        di
  681.         pop        si
  682.         pop        dx
  683.         pop        cx
  684.         pop        bx
  685.         pop        ax
  686.         pop        bp
  687.         ret
  688. ;
  689. _hor1vid    endp
  690. SUPPORT_TEXT    ENDS
  691.         end
  692.