home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / tp_fast / version4 / tpfscrn.asm < prev    next >
Assembly Source File  |  1991-11-14  |  75KB  |  1,221 lines

  1. ;   _______________________________________________________________
  2. ;  |                                                               |
  3. ;  |            CopyRight (c) 1990,1991  Steven Lutrov             |
  4. ;  |_______________________________________________________________|____
  5. ;  |                                                               |    |
  6. ;  |  program title : fastgrp.asm                                  |    | ___
  7. ;  |  author        : Steven Lutrov                                |    |    |
  8. ;  |  revision      : 4.00                                         |    |    |
  9. ;  |  date          : 1990-11-11                                   |    |    |
  10. ;  |  language      : turbo assembler                              |    |    |
  11. ;  |                                                               |    |    |
  12. ;  |  description   : assembly functions for graphics screen       |    |    |
  13. ;  |                : movement and primitive screen management.    |    |    |
  14. ;  |                : tested on turbo pascal 6.0                   |    |    |
  15. ;  |                                                               |    |    |
  16. ;  |_______________________________________________________________|    |    |
  17. ;      |                                                                |    |
  18. ;      |________________________________________________________________|    |
  19. ;          |                                                                 |
  20. ;          |_________________________________________________________________|
  21. ;
  22.  
  23.  
  24. code segment word public
  25.  
  26. assume cs:code,ds:data
  27.  
  28.  
  29. public screendown,screenleft,screenright,screenup,fillscreen
  30. public drawbox,copyclear,restorescreen,savescreen,scrollx,scrolly
  31.  
  32. data    segment
  33.         extrn  video_buff : word
  34.         extrn  snow_check  :byte;
  35.         extrn  TPFError   :byte;
  36. data    ends
  37.  
  38.  
  39. ;-------------------------------------------------------------------------------
  40. ;procedure screendown(box :pointer; var x,y :byte;; xx,y :byte;);
  41. ;-------------------------------------------------------------------------------
  42. ;
  43. screendown proc far
  44.                 push bp                         ;preserve register bp
  45.                 mov  bp,sp                      ;set stack frame
  46.                 push ds                         ;save turbo's ds
  47.                 mov  dx,video_buff              ;grab video_buff
  48.                 push dx                         ;save it
  49.                 les  di,dword ptr[bp+14]        ;es:di pts to x
  50.                 mov  al,snow_check              ;grab snow_check
  51.                 mov  [bp+16],al                 ;save on stack
  52.                 sub  cx,cx                      ;
  53.                 mov  cl,es:[di]                 ;get column position
  54.                 jcxz screendf1                  ;quit if column is zero
  55.                 dec  cx                         ;count from zero
  56.                 cmp  cx,79                      ;in range?
  57.                 jna  screendg1                  ;jump ahead if so
  58. screendf1:      jmp  screendm1                  ;else quit
  59. screendg1:      mov  ax,[bp+20]                 ;segment of box
  60.                 mov  es,ax                      ;load in es
  61.                 mov  di,[bp+18]                 ;offset of box
  62.                 mov  byte ptr[bp+7],0           ;zero out high byte
  63.                 mov  ax,[bp+6]                  ;y to ax
  64.                 dec  ax                         ;dec for test
  65.                 cmp  ax,24                      ;in range?
  66.                 jna  screendh1                  ;jump ahead if so
  67.                 jmp  screendm1                  ;else quit routine
  68. screendh1:      inc  ax                         ;readjust
  69.                 mov  byte ptr[bp+9],0           ;zero out high byte
  70.                 mov  bx,[bp+8]                  ;xx to bx
  71.                 dec  bx                         ;dec for test
  72.                 cmp  bx,79                      ;in range?
  73.                 jna  screendi1                  ;jump ahead if so
  74.                 jmp  screendm1                  ;else quit
  75. screendi1:      inc  bx                         ;readjust
  76.                 mul  bl                         ;xx times y
  77.                 shl  ax,1                       ;double for attributes
  78.                 add  ax,di                      ;offset to end of box
  79.                 mov  [bp+14],ax                 ;end of box ptr to stack
  80.                 mov  di,ax                      ;pt es:di to end of box
  81.                 lds  si,dword ptr[bp+10]        ;point ds:si to y
  82.                 sub  ax,ax                      ;
  83.                 mov  al,[si]                    ;get y value
  84.                 dec  ax                         ;count from zero
  85.                 cmp  ax,24                      ;in range?
  86.                 jna  screendk1                  ;jump ahead if so
  87. screendj1:      jmp  screendm1                  ;else quit
  88. screendk1:      mov  bx,ax                      ;copy in bx
  89.                 add  bx,[bp+6]                  ;add y
  90.                 cmp  bx,24                      ;edge of screen?
  91.                 ja   screendj1                  ;quit if so
  92.                 add  ax,2                       ;inc old y value
  93.                 mov  [si],al                    ;reset y variable
  94.                 sub  ax,2                       ;back to old value
  95.                 mov  bl,160                     ;bytes per y
  96.                 mul  bl                         ;calculate y offset
  97.                 shl  cx,1                       ;x offset
  98.                 add  ax,cx                      ;add to y offset
  99.                 mov  si,ax                      ;si pts to topleft corner
  100.                 mov  [bp+12],si                 ;save on stack
  101.                 mov  ax,dx                      ;video_buff
  102.                 mov  ds,ax                      ;move to ds
  103.                 mov  ax,[bp+6]                  ;y
  104.                 mov  cl,160                     ;bytes per y
  105.                 mul  cl                         ;times y
  106.                 add  si,ax                      ;ds:si pts to topright
  107.                 mov  [bp+10],si                 ;copy position on stack
  108.                 pop  bx                         ;video_buff
  109.                 cld                             ;set direction
  110.                 mov  cx,[bp+8]                  ;xx
  111.                 shl  cx,1                       ;double for attributes
  112.                 call boxd_screen                ;write a char
  113.                 mov  ax,ds                      ;ds to ax
  114.                 mov  es,ax                      ;now es pts to screen too
  115.                 mov  di,[bp+10]                 ;new bottom right pos
  116.                 mov  si,di                      ;copy to si
  117.                 sub  si,160                     ;si one y higher
  118.                 mov  ax,[bp+6]                  ;y to ax
  119. screendl1:      mov  cx,[bp+8]                  ;xx to cx
  120.                 push di                         ;save target ptr
  121.                 push si                         ;save source ptr
  122.                 shl  cx,1                       ;dbl xx for attributes
  123.                 call boxd_screen                ;write a char
  124.                 pop  si                         ;restore ptr
  125.                 pop  di                         ;restore ptr
  126.                 sub  di,160                     ;ptr up one y
  127.                 sub  si,160                     ;ditto
  128.                 dec  ax                         ;dec y counter
  129.                 jnz  screendl1                  ;loop till finished
  130.                 mov  ax,[bp+20]                 ;segment of box
  131.                 mov  ds,ax                      ;move to ds
  132.                 mov  si,[bp+18]                 ;offset of box
  133.                 mov  di,[bp+12]                 ;es:di pts to topleft
  134.                 mov  dx,[bp+8]                  ;xx
  135.                 shl  dx,1                       ;double for attributes
  136.                 mov  cx,dx                      ;use as counter
  137.                 call boxd_screen                ;write a char
  138.                 mov  ax,ds                      ;ds pts to box
  139.                 mov  es,ax                      ;now es does too
  140.                 mov  di,[bp+18]                 ;offset to start of box
  141.                 mov  si,di                      ;copy to si
  142.                 add  si,dx                      ;offset to second y
  143.                 mov  ax,[bp+6]                  ;y
  144.                 mov  cx,[bp+8]                  ;xx
  145.                 mul  cl                         ;size of box
  146.                 mov  cx,ax                      ;move to cx as counter
  147.                 rep  movsw                      ;shift all upwards
  148.                 jmp  short screendn1            ;jump to end
  149. screendm1:      pop  bx                         ;balance stack if error
  150. screendn1:      sti                             ;reenable interrupts
  151.                 pop  ds                         ;restore ds and quit
  152.                 pop  bp                         ;restore bp
  153.                 ret  16
  154. screendown endp
  155.  
  156.  
  157.  
  158. ;-------------------------------------------------------------------------------
  159. ;procedure screenleft(box:pointer; var x,y :byte;; xx,y :byte;);
  160. ;-------------------------------------------------------------------------------
  161. ;
  162. screenleft proc far
  163.                 push bp                         ;preserve register bp
  164.                 mov  bp,sp                      ;set stack frame
  165.                 push ds                         ;save turbo's ds
  166.                 mov  dx,video_buff              ;grab video_buff
  167.                 push dx                         ;save it
  168.                 les  di,dword ptr[bp+14]        ;es:di pts to x
  169.                 mov  al,snow_check              ;grab snow_check
  170.                 mov  [bp+16],al                 ;save on stack
  171.                 sub  cx,cx                      ;
  172.                 mov  cl,es:[di]                 ;get column position
  173.                 jcxz screenlj1                  ;quit if column is zero
  174.                 dec  cx                         ;count from zero
  175.                 cmp  cx,79                      ;in range?
  176.                 jna  screenli1                  ;jump ahead if so
  177.                 jmp  screenlt1                  ;else quit
  178. screenli1:      cmp  cx,2                       ;not on left edge?
  179.                 jnb  screenlk1                  ;jump ahead if not
  180. screenlj1:      jmp  screenlt1                  ;else quit routine
  181. screenlk1:      dec  cx                         ;old x minus 2
  182.                 mov  es:[di],cl                 ;change the setting
  183.                 inc  cx                         ;restore old x pos
  184.                 mov  ax,[bp+20]                 ;segment of box
  185.                 mov  es,ax                      ;load in es
  186.                 mov  di,[bp+18]                 ;offset of box
  187.                 mov  byte ptr[bp+7],0           ;zero out high byte
  188.                 mov  ax,[bp+6]                  ;y to ax
  189.                 dec  ax                         ;dec for test
  190.                 cmp  ax,24                      ;in range?
  191.                 jna  screenll1                  ;jump ahead if so
  192.                 jmp  screenlt1                  ;else quit routine
  193. screenll1:      inc  ax                         ;readjust
  194.                 mov  byte ptr[bp+9],0           ;zero out high byte
  195.                 mov  bx,[bp+8]                  ;xx to bx
  196.                 dec  bx                         ;dec for test
  197.                 cmp  bx,79                      ;in range?
  198.                 jna  screenlm1                  ;jump ahead if so
  199.                 jmp  screenlt1                  ;else quit
  200. screenlm1:      inc  bx                         ;readjust
  201.                 mul  bl                         ;xx times y
  202.                 shl  ax,1                       ;double for attributes
  203.                 add  ax,di                      ;offset to end of box
  204.                 mov  [bp+14],ax                 ;end of box ptr to stack
  205.                 mov  di,ax                      ;pt es:di to end of box
  206.                 lds  si,dword ptr[bp+10]        ;ds:si pts to y
  207.                 sub  ax,ax                      ;
  208.                 mov  al,[si]                    ;get y value
  209.                 dec  ax                         ;count from zero
  210.                 cmp  ax,24                      ;in range?
  211.                 jna  screenln1                  ;jump ahead if so
  212.                 jmp  screenlt1                  ;else quit
  213. screenln1:      mov  bl,160                     ;bytes per y
  214.                 mul  bl                         ;calculate y offset
  215.                 shl  cx,1                       ;x offset
  216.                 add  ax,cx                      ;add to y offset
  217.                 mov  si,ax                      ;si pts to topleft corner
  218.                 mov  [bp+12],si                 ;save on stack
  219.                 mov  ax,dx                      ;video_buff
  220.                 mov  ds,ax                      ;move to ds
  221.                 mov  ax,[bp+8]                  ;xx
  222.                 shl  ax,1                       ;double for attributes
  223.                 add  si,ax                      ;ds:si pts to topright
  224.                 mov  [bp+10],si                 ;copy position on stack
  225.                 pop  bx                         ;video_buff
  226.                 cld                             ;set direction
  227.                 mov  si,[bp+12]                 ;point to topleft corner
  228.                 sub  si,4                       ;minus two columns
  229.                 mov  cx,[bp+6]                  ;y
  230.                 mov  dx,si                      ;dx holds start x
  231. screenlo1:      mov  si,dx                      ;set start x
  232.                 call boxl_screen                ;write a char
  233.                 call boxl_screen                ;write another
  234.                 add  dx,160                     ;forward one y
  235.                 loop screenlo1                  ;do next y
  236.                 mov  ax,ds                      ;ds to ax
  237.                 mov  es,ax                      ;now es pts to screen too
  238.                 mov  si,[bp+12]                 ;top left position
  239.                 mov  di,si                      ;copy to di
  240.                 sub  di,4                       ;will shift right by 2
  241.                 mov  dx,[bp+6]                  ;y
  242.                 mov  ax,[bp+8]                  ;xx
  243. screenlp1:      mov  cx,ax                      ;xx to cx
  244.                 push di                         ;save target start
  245.                 push si                         ;save source start
  246. screenlq1:      call boxl_screen                ;write a char
  247.                 loop screenlq1                  ;go do next
  248.                 pop  si                         ;restore source start
  249.                 pop  di                         ;restore target start
  250.                 add  di,160                     ;forward dest ptr
  251.                 add  si,160                     ;forward source ptr
  252.                 dec  dx                         ;dec y counter
  253.                 jnz  screenlp1                  ;loop till image shifted
  254.                 mov  ax,[bp+20]                 ;segment of box
  255.                 mov  ds,ax                      ;move to ds
  256.                 mov  si,[bp+18]                 ;offset of box
  257.                 mov  di,[bp+10]                 ;es:di pts to old topleft
  258.                 sub  di,4                       ;leftwards by 2 cols
  259.                 mov  cx,[bp+6]                  ;y
  260.                 mov  dx,[bp+8]                  ;xx
  261.                 sub  dx,2                       ;minus 2 for 2 columns
  262.                 shl  dx,1                       ;double for attributes
  263. screenlr1:      add  si,dx                      ;forward box ptr
  264.                 call boxl_screen                ;write a char
  265.                 call boxl_screen                ;write another
  266.                 add  di,156                     ;forward target ptr
  267.                 loop screenlr1                  ;do next y
  268.                 std                             ;reverse direction flag
  269.                 mov  ax,ds                      ;ds pts to box
  270.                 mov  es,ax                      ;now es does too
  271.                 mov  di,[bp+14]                 ;offset to end of box
  272.                 dec  di                         ;dec screen ptr
  273.                 dec  di                         ;again
  274.                 mov  si,di                      ;copy to si
  275.                 sub  si,4                       ;source pos 2 chars left
  276.                 mov  ax,[bp+6]                  ;y
  277.                 mov  cx,[bp+8]                  ;xx
  278.                 mul  cl                         ;size of box
  279.                 mov  cx,ax                      ;move to cx as counter
  280.                 rep  movsw                      ;shift all downwards
  281.                 mov  di,[bp+18]                 ;offset of box
  282.                 mov  si,[bp+14]                 ;offset of x
  283.                 mov  cx,[bp+6]                  ;y
  284.                 cld                             ;direction flag forward
  285. screenls1:      movsw                           ;move first word of two
  286.                 movsw                           ;move the next
  287.                 add  di,dx                      ;forward target ptr
  288.                 loop screenls1                  ;go move 2 more chars
  289.                 jmp  short screenlu1            ;jump to end
  290. screenlt1:      pop  bx                         ;balance stack if error
  291. screenlu1:      sti                             ;reenable interrupts
  292.                 pop  ds                         ;restore ds and quit
  293.                 pop  bp                         ;restore bp
  294.                 ret  16
  295. screenleft endp
  296.  
  297.  
  298. ;-------------------------------------------------------------------------------
  299. ;procedure screenright(box:pointer; var x,y :byte;; xx,y :byte;);
  300. ;-------------------------------------------------------------------------------
  301. ;
  302. screenright proc far
  303.                 push bp                         ;save bp
  304.                 mov  bp,sp                      ;set stack frame
  305.                 push ds                         ;save turbo's ds
  306.                 mov  dx,video_buff              ;grab video_buff
  307.                 mov  bl,snow_check              ;grab snow_check
  308.                 push bx                         ;save it
  309.                 les  di,dword ptr[bp+14]        ;es:di pts to x
  310.                 sub  cx,cx                      ;
  311.                 mov  cl,es:[di]                 ;get column position
  312.                 jcxz screenrti1                 ;quit if column is zero
  313.                 dec  cx                         ;count from zero
  314.                 mov  ax,cx                      ;copy to ax
  315.                 mov  byte ptr[bp+9],0           ;zero out high byte
  316.                 add  ax,[bp+8]                  ;add xx
  317.                 cmp  ax,78                      ;in range?
  318.                 jna  screenrtj1                 ;jump ahead if so
  319. screenrti1:     jmp  screenrtt1                 ;else quit routine
  320. screenrtj1:     add  cx,3                       ;add 2 (+ inc) to x pos
  321.                 mov  es:[di],cl                 ;change the setting
  322.                 sub  cx,3                       ;back to old x position
  323.                 mov  ax,[bp+20]                 ;segment of box
  324.                 mov  es,ax                      ;load in es
  325.                 mov  di,[bp+18]                 ;offset of box
  326.                 mov  byte ptr[bp+7],0           ;zero out high byte
  327.                 mov  ax,[bp+6]                  ;y to ax
  328.                 dec  ax                         ;dec for test
  329.                 cmp  ax,24                      ;in range?
  330.                 jna  screenrtk1                 ;jump ahead if so
  331.                 jmp  screenrtt1                 ;else quit routine
  332. screenrtk1:     inc  ax                         ;readjust
  333.                 mov  bx,[bp+8]                  ;xx to bx
  334.                 dec  bx                         ;dec for test
  335.                 cmp  bx,79                      ;in range?
  336.                 jna  screenrtl1                 ;jump ahead if so
  337.                 jmp  screenrtt1                 ;else quit
  338. screenrtl1:     inc  bx                         ;readjust
  339.                 mul  bl                         ;xx times y
  340.                 shl  ax,1                       ;double for attributes
  341.                 add  ax,di                      ;offset to end of box
  342.                 mov  [bp+14],ax                 ;end of box ptr to stack
  343.                 mov  di,ax                      ;pt es:di to end of box
  344.                 lds  si,dword ptr[bp+10]        ;ds:si pts to y
  345.                 sub  ax,ax                      ;
  346.                 mov  al,[si]                    ;get y value
  347.                 dec  ax                         ;count from zero
  348.                 cmp  ax,24                      ;in range?
  349.                 jna  screenrtm1                 ;jump ahead if so
  350.                 jmp  screenrtt1                 ;else quit
  351. screenrtm1:     mov  bl,160                     ;bytes per y
  352.                 mul  bl                         ;calculate y offset
  353.                 shl  cx,1                       ;x offset
  354.                 add  ax,cx                      ;add to y offset
  355.                 mov  si,ax                      ;si pts to topleft corner
  356.                 mov  [bp+12],si                 ;save on stack
  357.                 mov  ax,dx                      ;video_buff
  358.                 mov  ds,ax                      ;move to ds
  359.                 mov  ax,[bp+8]                  ;xx
  360.                 shl  ax,1                       ;double for attributes
  361.                 add  si,ax                      ;ds:si pts to topright
  362.                 mov  [bp+10],si                 ;copy position on stack
  363.                 pop  bx                         ;restore procedure ptr
  364.                 cld                             ;set direction
  365.                 mov  cx,[bp+6]                  ;y
  366.                 mov  dx,si                      ;dx holds start x
  367. screenrtn1:     mov  si,dx                      ;set start x
  368.                 call boxr_screen                ;write a char
  369.                 call boxr_screen                ;write another
  370.                 add  dx,160                     ;forward one y
  371.                 loop screenrtn1                 ;do next y
  372.                 mov  ax,ds                      ;ds to ax
  373.                 mov  es,ax                      ;now es pts to screen too
  374.                 mov  si,[bp+10]                 ;top right position + 2
  375.                 sub  si,2                       ;minus 2
  376.                 mov  di,si                      ;copy to di
  377.                 add  di,4                       ;will shift right by 2
  378.                 std                             ;reverse direction flag
  379.                 cmp  ax,0b800h                  ;graphics card?
  380.                 jb   screenrto1                 ;jump if monochrome
  381.                 inc  di                         ;forward ptr to start
  382.                 inc  si                         ;other ptr
  383. screenrto1:     mov  dx,[bp+6]                  ;y
  384.                 mov  ax,[bp+8]                  ;xx
  385. screenrtp1:     mov  cx,ax                      ;xx to cx
  386.                 push di                         ;save target start
  387.                 push si                         ;save source start
  388. screenrtq1:     call boxr_screen                ;write a char
  389.                 loop screenrtq1                 ;go do next
  390.                 pop  si                         ;restore source start
  391.                 pop  di                         ;restore target start
  392.                 add  di,160                     ;forward dest ptr
  393.                 add  si,160                     ;forward source ptr
  394.                 dec  dx                         ;dec y counter
  395.                 jnz  screenrtp1                 ;loop till image shifted
  396.                 cld                             ;reset direction flag
  397.                 mov  ax,[bp+20]                 ;segment of box
  398.                 mov  ds,ax                      ;move to ds
  399.                 mov  si,[bp+18]                 ;offset of box
  400.                 mov  di,[bp+12]                 ;es:di pts to old topleft
  401.                 mov  cx,[bp+6]                  ;y
  402.                 mov  dx,[bp+8]                  ;xx
  403.                 sub  dx,2                       ;minus 2 for 2 columns
  404.                 shl  dx,1                       ;double for attributes
  405. screenrtr1:     call boxr_screen                ;write a char
  406.                 call boxr_screen                ;write another
  407.                 add  di,156                     ;forward target ptr
  408.                 add  si,dx                      ;forward source ptr
  409.                 loop screenrtr1                 ;do next y
  410.                 mov  ax,[bp+20]                 ;segment of box
  411.                 mov  es,ax                      ;move to es
  412.                 mov  di,[bp+18]                 ;offset of box
  413.                 mov  ax,[bp+16]                 ;segment of x
  414.                 mov  ds,ax                      ;move to ds
  415.                 mov  si,[bp+14]                 ;offset of x
  416.                 add  di,4                       ;di to new start of box
  417.                 mov  cx,[bp+6]                  ;y
  418. screenrts1:     add  di,dx                      ;forward target ptr
  419.                 movsw                           ;move one char of two
  420.                 movsw                           ;move the next
  421.                 loop screenrts1                 ;go move 2 more chars
  422.                 mov  di,[bp+18]                 ;offset to start of box
  423.                 mov  si,di                      ;copy to si
  424.                 add  si,4                       ;si 2 chars to the right
  425.                 mov  ax,[bp+6]                  ;y
  426.                 mov  cx,[bp+8]                  ;xx
  427.                 mul  cl                         ;size of box
  428.                 mov  cx,ax                      ;move to cx as counter
  429.                 rep  movsw                      ;shift all downwards
  430.                 jmp  short screenrtu1           ;jump to end
  431. screenrtt1:     pop  bx                         ;balance stack if error
  432. screenrtu1:     sti                             ;reenable interrupts
  433.                 pop  ds                         ;restore ds and quit
  434.                 pop  bp                         ;restore bp
  435.                 ret  16
  436. screenright endp
  437.  
  438.  
  439. ;-------------------------------------------------------------------------------
  440. ;procedure screenup(box :pointer; var x,y :byte;; xx,y :byte;);
  441. ;-------------------------------------------------------------------------------
  442. ;
  443. screenup proc far
  444.                 push bp                         ;save bp
  445.                 mov  bp,sp                      ;set stack frame
  446.                 push ds                         ;save turbo's ds
  447.                 mov  dx,video_buff              ;grab video_buff
  448.                 push dx                         ;save it
  449.                 les  di,dword ptr[bp+14]        ;point es:di to x
  450.                 mov  al,snow_check              ;grab snow_check
  451.                 mov  [bp+16],al                 ;save on stack
  452.                 sub  cx,cx                      ;
  453.                 mov  cl,es:[di]                 ;get column position
  454.                 jcxz scrupf1                    ;quit if column is zero
  455.                 dec  cx                         ;count from zero
  456.                 cmp  cx,79                      ;in range?
  457.                 jna  scrupg1                    ;jump ahead if so
  458. scrupf1:        jmp  scrupm1                    ;else quit
  459. scrupg1:        les  di,dword ptr[bp+18]        ;point es:di to byte array
  460.                 mov  byte ptr[bp+7],0           ;zero out high byte
  461.                 mov  ax,[bp+6]                  ;y to ax
  462.                 dec  ax                         ;dec for test
  463.                 cmp  ax,24                      ;in range?
  464.                 jna  scruph1                    ;jump ahead if so
  465.                 jmp  scrupm1                    ;else quit routine
  466. scruph1:        inc  ax                         ;readjust
  467.                 mov  byte ptr[bp+9],0           ;zero out high byte
  468.                 mov  bx,[bp+8]                  ;xx to bx
  469.                 dec  bx                         ;dec for test
  470.                 cmp  bx,79                      ;in range?
  471.                 jna  scrupi1                    ;jump ahead if so
  472.                 jmp  scrupm1                    ;else quit
  473. scrupi1:        inc  bx                         ;readjust
  474.                 mul  bl                         ;xx times y
  475.                 shl  ax,1                       ;double for attributes
  476.                 add  ax,di                      ;offset to end of box
  477.                 mov  [bp+14],ax                 ;end of box ptr to stack
  478.                 mov  di,ax                      ;pt es:di to end of box
  479.                 lds  si,dword ptr[bp+10]        ;point ds:si to y
  480.                 sub  ax,ax                      ;
  481.                 mov  al,[si]                    ;get y value
  482.                 cmp  ax,1                       ;top y already?
  483.                 je   scrupj1                    ;quit if so
  484.                 dec  ax                         ;count from zero
  485.                 cmp  ax,24                      ;in range?
  486.                 jna  scrupk1                    ;jump ahead if so
  487. scrupj1:        jmp  scrupm1                    ;else quit
  488. scrupk1:        mov  bx,ax                      ;copy in bx
  489.                 add  bx,[bp+6]                  ;add y
  490.                 cmp  bx,25                      ;in range?
  491.                 ja   scrupj1                    ;quit if so
  492.                 mov  [si],al                    ;reset y variable
  493.                 mov  bl,160                     ;bytes per y
  494.                 mul  bl                         ;calculate y offset
  495.                 shl  cx,1                       ;x offset
  496.                 add  ax,cx                      ;add to y offset
  497.                 mov  si,ax                      ;si pts to topleft corner
  498.                 mov  [bp+12],si                 ;save on stack
  499.                 mov  ax,dx                      ;video_buff
  500.                 mov  ds,ax                      ;move to ds
  501.                 mov  ax,[bp+6]                  ;y
  502.                 mov  cl,160                     ;bytes per y
  503.                 mul  cl                         ;times y
  504.                 add  si,ax                      ;ds:si pts to topright
  505.                 mov  [bp+10],si                 ;copy position on stack
  506.                 pop  bx                         ;video_buff
  507.                 cld                             ;set direction
  508.                 mov  si,[bp+12]                 ;topright position
  509.                 sub  si,160                     ;y higher
  510.                 mov  cx,[bp+8]                  ;xx
  511.                 shl  cx,1                       ;double for movsb
  512.                 call boxu_screen                ;write a char
  513.                 mov  ax,ds                      ;ds to ax
  514.                 mov  es,ax                      ;now es pts to screen too
  515.                 mov  di,[bp+12]                 ;top left position
  516.                 mov  si,di                      ;copy to si
  517.                 sub  di,160                     ;di one y higher
  518.                 mov  ax,[bp+6]                  ;y to ax
  519. scrupl1:        mov  cx,[bp+8]                  ;xx to cx
  520.                 push di                         ;save target ptr
  521.                 push si                         ;save source ptr
  522.                 shl  cx,1                       ;double xx for movsb
  523.                 call boxu_screen                ;write a char
  524.                 pop  si                         ;restore ptr
  525.                 pop  di                         ;restore ptr
  526.                 add  di,160                     ;ptr down one y
  527.                 add  si,160                     ;ditto
  528.                 dec  ax                         ;dec y counter
  529.                 jnz  scrupl1                    ;loop till finished
  530.                 mov  ax,[bp+20]                 ;segment of box
  531.                 mov  ds,ax                      ;move to ds
  532.                 mov  si,[bp+14]                 ;offset of end of box
  533.                 mov  di,[bp+10]                 ;es:di pts to bottomleft
  534.                 sub  di,160                     ;one y higher
  535.                 mov  dx,[bp+8]                  ;xx
  536.                 shl  dx,1                       ;double for attributes
  537.                 sub  si,dx                      ;ds:si pts to last y
  538.                 mov  cx,dx                      ;use as counter
  539.                 call boxu_screen                ;write a char
  540.                 std                             ;reverse direction flag
  541.                 mov  ax,ds                      ;ds pts to box
  542.                 mov  es,ax                      ;now es does too
  543.                 mov  di,[bp+14]                 ;offset to end of box
  544.                 sub  di,2                       ;last char of box
  545.                 mov  si,di                      ;copy to si
  546.                 sub  si,dx                      ;offset to second y
  547.                 mov  ax,[bp+6]                  ;y
  548.                 dec  ax                         ;minus one y
  549.                 mov  cx,[bp+8]                  ;xx
  550.                 mul  cl                         ;size of box minus 1 y
  551.                 mov  cx,ax                      ;move to cx as counter
  552.                 rep  movsw                      ;shift all upwards
  553.                 mov  di,[bp+18]                 ;offset of box
  554.                 mov  si,[bp+14]                 ;end of box
  555.                 mov  cx,[bp+8]                  ;xx
  556.                 cld                             ;direction flag forward
  557.                 rep  movsw                      ;move new data
  558.                 jmp  short scrupn1              ;jump to end
  559. scrupm1:        pop  bx                         ;balance stack if error
  560. scrupn1:        sti                             ;reenable interrupts
  561.                 pop  ds                         ;restore ds
  562.                 pop  bp                         ;restore bp
  563.                 ret
  564. screenup endp
  565.  
  566.  
  567. ;-------------------------------------------------------------------------------
  568. ;procedure fillscreen(ch :char; x,y,xx,y,colour :byte;);
  569. ;-------------------------------------------------------------------------------
  570. ;
  571. fillscreen proc far
  572.                 push bp                         ;save bp
  573.                 mov  bp,sp                      ;set stack frame
  574.                 cld                             ;set direction flag
  575.                 mov  ax,video_buff              ;fetch video_buff
  576.                 mov  es,ax                      ;es pts to screen
  577.                 mov  si,bx                      ;procedure addr to si
  578.                 sub  ax,ax                      ;
  579.                 mov  al,[bp+12]                 ;get y
  580.                 dec  ax                         ;count from 0
  581.                 mov  dl,160                     ;bytes in a y
  582.                 mul  dl                         ;times y
  583.                 sub  dx,dx                      ;
  584.                 mov  dl,[bp+14]                 ;get column
  585.                 dec  dx                         ;count from 0
  586.                 shl  dx,1                       ;double for attributes
  587.                 add  ax,dx                      ;add to y offset
  588.                 mov  di,ax                      ;es:di pts to first char
  589.                 sub  bx,bx                      ;
  590.                 mov  bl,[bp+10]                 ;xx in bx
  591.                 or   bx,bx                      ;test for zero
  592.                 jz   fillscrl6                  ;quit if zero
  593.                 sub  dx,dx                      ;
  594.                 mov  dl,[bp+8]                  ;y in dx
  595.                 or   dx,dx                      ;test for zero
  596.                 jz   fillscrl6                  ;quit if zero
  597.                 mov  al,[bp+16]                 ;char in al
  598.                 mov  ah,[bp+6]                  ;attribute in ah
  599. fillscrl1:      mov  cx,bx                      ;xx to cx as counter
  600.                 push di                         ;save starting point
  601.                 push dx                         ;save y counter
  602. fillscrl2:      cmp  snow_check,0               ;protect against snow?
  603.                 je   fillscrl5                  ;jump ahead if not
  604.                 mov  dx,3dah                    ;status byte address
  605.                 mov  si,ax                      ;save ax contents
  606. fillscrl3:      in   al,dx                      ;get status byte
  607.                 test al,1                       ;test bit
  608.                 jnz  fillscrl3                  ;loop till 0
  609.                 cli                             ;disable interrupts
  610. fillscrl4:      in   al,dx                      ;get status byte
  611.                 test al,1                       ;test bit
  612.                 jz   fillscrl4                  ;loop till 1
  613.                 mov  ax,si                      ;restore ax contents
  614. fillscrl5:      stosw                           ;write char and attribute
  615.                 loop fillscrl2                  ;go do next
  616.                 pop  dx                         ;restore y counter
  617.                 pop  di                         ;restore starting point
  618.                 add  di,160                     ;forward ptr one y
  619.                 dec  dx                         ;dec y counter
  620.                 jnz  fillscrl1                  ;go do next y
  621. fillscrl6:      sti                             ;reenable interrupts
  622.                 pop  bp                         ;restore bp
  623.                 ret  12
  624. fillscreen endp
  625.  
  626.  
  627. ;-------------------------------------------------------------------------------
  628. ;procedure drawbox(char_x ,char_y  :char ; x,y,xx,y,colour :byte);
  629. ;-------------------------------------------------------------------------------
  630. ;
  631. drawbox proc  far
  632.                 push bp                         ;save bp
  633.                 mov  TPFError,1                ;1 = y out of range
  634.                 mov  bp,sp                      ;set up stack frame
  635.                 mov  al,[bp+18]                 ;horz double or single?
  636.                 mov  dh,205                     ;assume double
  637.                 cmp  al,68                      ;is it a double line ?
  638.                 je   drawboxe1                  ;jump ahead if so
  639.                 cmp  al,100                     ;is it a double line?
  640.                 je   drawboxe1                  ;jump ahead if so
  641.                 mov  dh,196                     ;else single line
  642. drawboxe1:      mov  al,[bp+16]                 ;vert double or single?
  643.                 mov  dl,186                     ;assume double line
  644.                 cmp  al,68                      ;double line?
  645.                 je   drawboxg1                  ;jump ahead if so
  646.                 cmp  al,100                     ;double line?
  647.                 je   drawboxg1                  ;jump ahead if so
  648.                 mov  dl,179                     ;else single line
  649.                 cmp  dh,196                     ;horizontal single?
  650.                 jne  drawboxf1                  ;jump ahead if not
  651.                 mov  ax,0dabfh                  ;top sngl vert, sngl horz
  652.                 mov  bx,0c0d9h                  ;bot sngl vert, sngl horz
  653.                 jmp  short drawboxi1            ;registers set
  654. drawboxf1:      mov  ax,0d5b8h                  ;top sngl vert, dbl horz
  655.                 mov  bx,0d4beh                  ;bot sngl vert, dbl horz
  656.                 jmp  short drawboxi1            ;registers set
  657. drawboxg1:      cmp  dh,196                     ;horizontal single?
  658.                 jne  drawboxh1                  ;jump ahead if not
  659.                 mov  ax,0d6b7h                  ;top dbl vert, sngl horz
  660.                 mov  bx,0d3bdh                  ;bot dbl vert, sngl horz
  661.                 jmp  short drawboxi1            ;registers set
  662. drawboxh1:      mov  ax,0c9bbh                  ;top dbl vert, dbl horz
  663.                 mov  bx,0c8bch                  ;bot dbl vert, dbl horz
  664. drawboxi1:      mov  [bp+18],ax                 ;save top corners
  665.                 mov  [bp+16],bx                 ;save bottom corners
  666.                 mov  ax,video_buff              ;get ptr to video_buff
  667.                 mov  es,ax                      ;move to es
  668.                 sub  ax,ax                      ;
  669.                 mov  al,[bp+12]                 ;y to ax
  670.                 dec  ax                         ;count from 0
  671.                 cmp  ax,24                      ;in range?
  672.                 jbe  drawboxj1                  ;jump ahead if so
  673.                 jmp  drawboxo1                  ;else quit routine
  674. drawboxj1:      inc  TPFError                  ;2 = column out of range
  675.                 mov  cl,160                     ;bytes in a y
  676.                 mul  cl                         ;times y
  677.                 sub  cx,cx                      ;
  678.                 mov  cl,[bp+14]                 ;column to cx
  679.                 dec  cx                         ;count from 0
  680.                 cmp  cx,79                      ;in range?
  681.                 jna  drawboxk1                  ;jump ahead if ok
  682.                 jmp  drawboxo1                  ;else quit
  683. drawboxk1:      inc  TPFError                  ;3 = xx out of range
  684.                 shl  cx,1                       ;double for attributes
  685.                 add  ax,cx                      ;buffer offset
  686.                 mov  di,ax                      ;es:di pts to offset
  687.                 sub  bx,bx                      ;
  688.                 mov  bl,[bp+10]                 ;xx to bx
  689.                 dec  bx                         ;count from 0
  690.                 dec  bx                         ;ready for test
  691.                 cmp  bx,78                      ;out of range?
  692.                 ja   drawboxo1                  ;quit if so
  693.                 inc  TPFError                  ;4 = y out of range
  694.                 inc  bx                         ;readjust after test
  695.                 shl  bx,1                       ;double for attributes
  696.                 mov  ah,[bp+6]                  ;attribute to ah
  697.                 mov  al,[bp+19]                 ;topleft corner to al
  698.                 call drawb_screen               ;write the character
  699.                 add  di,bx                      ;add offset to scrn ptr
  700.                 mov  al,[bp+18]                 ;topright corner to al
  701.                 call drawb_screen               ;write the character
  702.                 sub  di,bx                      ;sub offset from scrn ptr
  703.                 sub  cx,cx                      ;
  704.                 mov  cl,[bp+8]                  ;get box y
  705.                 dec  cx                         ;minus 2
  706.                 dec  cx                         ;  for corners
  707.                 cmp  cx,23                      ;test length
  708.                 ja   drawboxo1                  ;quit if out of range
  709.                 mov  TPFError,0                ;else no error
  710.                 push di                         ;save initial position
  711.                 add  di,160                     ;forward screen ptr
  712.                 jcxz drawboxm1                  ;jump if no chr to write
  713.                 mov  al,dl                      ;vertical char to al
  714. drawboxl1:      call drawb_screen               ;write the character
  715.                 add  di,bx                      ;add offset to scrn ptr
  716.                 call drawb_screen               ;write the character
  717.                 sub  di,bx                      ;sub offset from scrn ptr
  718.                 add  di,160                     ;forward screen ptr
  719.                 loop drawboxl1                  ;on to next vert chars
  720. drawboxm1:      mov  al,[bp+17]                 ;bottomleft corner to al
  721.                 call drawb_screen               ;write the character
  722.                 mov  al,[bp+16]                 ;bottomright corner to al
  723.                 add  di,bx                      ;add offset to scrn ptr
  724.                 call drawb_screen               ;write the character
  725.                 sub  di,bx                      ;sub offset from scrn ptr
  726.                 mov  bx,di                      ;save bottom left pos
  727.                 pop  di                         ;restore top left pos
  728.                 mov  al,dh                      ;horizontal char to al
  729.                 sub  cx,cx                      ;
  730.                 mov  cl,[bp+10]                 ;get xx
  731.                 dec  cx                         ;minus 2
  732.                 dec  cx                         ;  for corners
  733.                 jcxz drawboxo1                  ;quit if no chrs to print
  734.                 inc  di                         ;forward scrn ptr
  735.                 inc  di                         ;  to 1st position on top
  736. drawboxn1:      call drawb_screen               ;write the character
  737.                 inc  di                         ;forward base ptr
  738.                 inc  di                         ;...again
  739.                 inc  bx                         ;forward scrn ptr
  740.                 inc  bx                         ;  for bottom line
  741.                 xchg di,bx                      ;get ready to write
  742.                 call drawb_screen               ;write the character
  743.                 xchg di,bx                      ;restore scrn ptr
  744.                 loop drawboxn1                  ;go do next char
  745. drawboxo1:      sti                             ;reenable interrupts
  746.                 pop  bp                         ;restore bp and quit
  747.                 ret  14
  748. drawbox endp
  749.  
  750.  
  751. ;-------------------------------------------------------------------------------
  752. ;procedure copyclear(box :pointer; x,y,xx,y,colour :byte;);
  753. ;-------------------------------------------------------------------------------
  754. ;
  755. copyclear proc far
  756.                 push bp                         ;save bp
  757.                 mov  bp,sp                      ;set stack frame
  758.                 push ds                         ;save ds
  759.                 mov  bl,snow_check              ;grab snow_check
  760.                 mov  ax,video_buff              ;fetch video address
  761.                 mov  ds,ax                      ;ds points to buffer
  762.                 les  di,dword ptr[bp+16]        ;es:di pts to byte array
  763.                 sub  ax,ax                      ;
  764.                 mov  al,[bp+12]                 ;y in ax
  765.                 dec  ax                         ;count y from 0
  766.                 mov  dl,160                     ;160 bytes per y
  767.                 mul  dl                         ;ax times 160
  768.                 sub  dx,dx                      ;
  769.                 mov  dl,[bp+14]                 ;x in dx
  770.                 dec  dx                         ;count cols from 0
  771.                 shl  dx,1                       ;double for attributes
  772.                 add  ax,dx                      ;offset of topleft corner
  773.                 mov  dh,[bp+10]                 ;xx in dh
  774.                 mov  dl,[bp+8]                  ;y in dl
  775.                 mov  ch,[bp+6]                  ;fill attribute
  776.                 mov  cl,32                      ;space char for fill
  777.                 mov  bp,ax                      ;scrn ptr copy in bp
  778.                 mov  ah,bl                      ;move snow_check
  779.                 mov  bx,cx                      ;copy in bx
  780.                 sub  cx,cx                      ;clear loop counter
  781.                 cld                             ;set direction flag
  782. copyclear1:     mov  si,bp                      ;set ds:si scrn ptr
  783.                 mov  cl,dh                      ;count box xx
  784.                 push dx                         ;save xx,y ctr
  785. copyclear2:     cmp  ah,0                       ;protect against snow?
  786.                 je   copyclear7                 ;jump ahead if not
  787.                 mov  dx,3dah                    ;status byte port addr
  788. copyclear3:     in   al,dx                      ;get status byte
  789.                 test al,1                       ;test bit
  790.                 jnz  copyclear3                 ;loop till 0
  791.                 cli                             ;disable interrupts
  792. copyclear4:     in   al,dx                      ;get status byte
  793.                 test al,1                       ;test bit
  794.                 jz   copyclear4                 ;loop till 1
  795.                 movsw                           ;transfer word to buffer
  796.                 sub  si,2                       ;pull back screen ptr
  797. copyclear5:     in   al,dx                      ;get status byte
  798.                 test al,1                       ;test bit
  799.                 jnz  copyclear5                 ;loop till 0
  800. copyclear6:     in   al,dx                      ;get status byte
  801.                 test al,1                       ;test bit
  802.                 jz   copyclear6                 ;loop till 1
  803.                 mov  [si],bx                    ;clear cell on screen
  804.                 add  si,2                       ;move scrn ptr back
  805.                 jmp  short copyclear8           ;jump ahead
  806. copyclear7:     movsw                           ;monochrome: transf char
  807.                 mov  [si-2],bx                  ;clear screen cell
  808. copyclear8:     loop copyclear2                 ;go do next
  809.                 pop  dx                         ;restore xx,y ctrs
  810.                 add  bp,160                     ;forward ptr to next y
  811.                 dec  dl                         ;dec y counter
  812.                 jnz  copyclear1                 ;loop if another line
  813. copyclear9:     sti                             ;reenable interrupts
  814.                 pop  ds                         ;restore ds
  815.                 pop  bp                         ;restore bp
  816.                 ret  14
  817. copyclear endp
  818.  
  819.  
  820. ;-------------------------------------------------------------------------------
  821. ;procedure restorescreen(box :pointer; x,y,xx,y :byte;);
  822. ;-------------------------------------------------------------------------------
  823. ;
  824. restorescreen proc far
  825.                 push bp                         ;save bp
  826.                 mov  bp,sp                      ;set stack frame
  827.                 mov  bl,snow_check              ;grab snow_check
  828.                 push ds                         ;save ds
  829.                 cld                             ;set direction flag
  830.                 mov  ax,video_buff              ;fetch video address
  831.                 mov  es,ax                      ;es points to screen
  832.                 lds  si,dword ptr[bp+14]        ;ds:si pts to byte array
  833.                 mov  [bp+14],bl                 ;save snow_check on stack
  834.                 sub  ax,ax                      ;
  835.                 mov  al,[bp+10]                 ;y in ax
  836.                 dec  ax                         ;count y from 0
  837.                 mov  dl,160                     ;160 bytes per y
  838.                 mul  dl                         ;ax times 160
  839.                 sub  dx,dx                      ;
  840.                 mov  dl,[bp+12]                 ;x in dx
  841.                 dec  dx                         ;count cols from 0
  842.                 shl  dx,1                       ;double for attributes
  843.                 add  ax,dx                      ;offset of topleft corner
  844.                 mov  bx,ax                      ;move scrn ptr to bx
  845.                 mov  dh,[bp+8]                  ;xx in bx
  846.                 mov  dl,[bp+6]                  ;y in dx
  847.                 sub  cx,cx                      ;clear cx
  848. restorescrl1:   mov  di,bx                      ;set es:di scrn ptr
  849.                 mov  cl,dh                      ;xx counter
  850.                 push dx                         ;save xx,y ctrs
  851. restorescrl2:   cmp  byte ptr[bp+14],0          ;protect against snow?
  852.                 je   restorescrl5               ;jump ahead if not
  853.                 mov  dx,3dah                    ;status byte address
  854. restorescrl3:   in   al,dx                      ;get status byte
  855.                 test al,1                       ;test bit
  856.                 jnz  restorescrl3               ;loop till 0
  857.                 cli                             ;disable interrupts
  858. restorescrl4:   in   al,dx                      ;get status byte
  859.                 test al,1                       ;test bit
  860.                 jz   restorescrl4               ;loop till 1
  861. restorescrl5:   movsw                           ;transfer char to scrn
  862.                 loop restorescrl2               ;go do next in y
  863.                 pop  dx                         ;restore xx,y ctrs
  864.                 add  bx,160                     ;forward ptr to next y
  865.                 dec  dl                         ;dec y counter
  866.                 jnz  restorescrl1               ;loop if another line
  867. restorescrl6:   sti                             ;reenable interrupts
  868.                 pop  ds                         ;restore ds
  869.                 pop  bp                         ;restore bp
  870.                 ret  12
  871. restorescreen endp
  872.  
  873.  
  874. ;-------------------------------------------------------------------------------
  875. ;procedure savescreen(box :pointer; x,y,xx,y :byte;);
  876. ;-------------------------------------------------------------------------------
  877. ;
  878. savescreen proc far
  879.                 push bp                         ;save bp
  880.                 mov  bp,sp                      ;set stack frame
  881.                 push ds                         ;ds changed
  882.                 mov  bl,snow_check              ;getch snow_check
  883.                 mov  ax,video_buff              ;fetch video address
  884.                 mov  ds,ax                      ;ds points to buffer
  885.                 les  di,dword ptr[bp+14]        ;es:di pts to box
  886.                 sub  ax,ax                      ;
  887.                 mov  al,[bp+10]                 ;y in ax
  888.                 dec  ax                         ;count y from 0
  889.                 mov  dl,160                     ;160 bytes per y
  890.                 mul  dl                         ;ax times 160
  891.                 sub  dx,dx                      ;
  892.                 mov  dl,[bp+12]                 ;x in dx
  893.                 dec  dx                         ;count cols from 0
  894.                 shl  dx,1                       ;double for attributes
  895.                 add  ax,dx                      ;offset of topleft corner
  896.                 mov  dh,[bp+8]                  ;xx to dh
  897.                 mov  dl,[bp+6]                  ;y to dl
  898.                 sub  cx,cx                      ;clear cx
  899.                 cld                             ;set direction flag
  900. savescrl1:      mov  si,ax                      ;set ds:si scrn ptr
  901.                 mov  cl,dh                      ;xx counter
  902.                 push dx                         ;save xx, y ctrs
  903.                 push ax                         ;save line start ptr
  904. savescrl2:      or   bl,bl                      ;protect against snow?
  905.                 je   savescrl5                  ;jump ahead if not
  906.                 mov  dx,3dah                    ;status byte address
  907. savescrl3:      in   al,dx                      ;get status byte
  908.                 test al,1                       ;test bit
  909.                 jnz  savescrl3                  ;loop till 0
  910.                 cli                             ;disable interrupts
  911. savescrl4:      in   al,dx                      ;get status byte
  912.                 test al,1                       ;test bit
  913.                 jz   savescrl4                  ;loop till 1
  914. savescrl5:      movsw                           ;move word to buffer
  915.                 loop savescrl2                  ;go do next in y
  916.                 pop  ax                         ;restore line start ptr
  917.                 pop  dx                         ;restore xx,y ctrs
  918.                 add  ax,160                     ;forward ptr to next y
  919.                 dec  dl                         ;dec y counter
  920.                 jnz  savescrl1                  ;loop if another line
  921. savescrl6:      sti                             ;reenable interrupts
  922.                 pop  ds                         ;restore ds
  923.                 pop  bp                         ;restore bp
  924.                 ret  12
  925. savescreen endp
  926.  
  927.  
  928. ;-------------------------------------------------------------------------------
  929. ;procedure scrollx(where :char; x,y,xx,y,cols,colour :byte;);
  930. ;-------------------------------------------------------------------------------
  931. ;
  932. scrollx proc far
  933.                 push bp                         ;save bp
  934.                 mov  bp,sp                      ;set stack frame
  935.                 push ds                         ;save turbo's ds
  936.                 mov  ax,video_buff              ;fetch video_buff
  937.                 mov  bl,snow_check              ;get snow_check before change ds
  938.                 mov  es,ax                      ;move to es
  939.                 mov  ds,ax                      ;copy in ds
  940.                 sub  ax,ax                      ;
  941.                 mov  al,[bp+14]                 ;top left y to ax
  942.                 mov  [bp+14],bl                 ;save snow_check
  943.                 dec  ax                         ;count from 0
  944.                 cmp  ax,24                      ;in range?
  945.                 jna  scrollxl2                  ;jump ahead if so
  946. scrollxl1:      jmp  scrollxl8                  ;else quit routine
  947. scrollxl2:      mov  cl,160                     ;bytes per y
  948.                 mul  cl                         ;times y count
  949.                 sub  cx,cx                      ;
  950.                 mov  cl,[bp+16]                 ;top left x to cx
  951.                 dec  cx                         ;count from 0
  952.                 cmp  cx,79                      ;in range?
  953.                 ja   scrollxl1                  ;quit if not
  954.                 shl  cx,1                       ;double for attributes
  955.                 add  ax,cx                      ;add to y offset
  956.                 sub  dx,dx                      ;
  957.                 mov  dl,[bp+10]                 ;y to dx
  958.                 or   dx,dx                      ;test for zero length
  959.                 jz   scrollxl1                  ;quit if zero
  960.                 mov  cl,[bp+18]                 ;get direction flag
  961.                 cmp  cl,'l'                     ;test for 'l'
  962.                 je   scrollxl3                  ;jump ahead if 'l'
  963.                 cmp  cl,'l'                     ;test for 'l'
  964.                 je   scrollxl3                  ;jump ahead if 'l'
  965.                 sub  cx,cx                      ;
  966.                 mov  cl,[bp+12]                 ;xx to cx
  967.                 dec  cx                         ;adjust
  968.                 shl  cx,1                       ;double for attributes
  969.                 add  ax,cx                      ;add to x,y position
  970.                 mov  di,ax                      ;es:di pts to top right
  971.                 sub  cx,cx                      ;
  972.                 mov  cl,[bp+8]                  ;get cols to scroll
  973.                 shl  cx,1                       ;double for attributes
  974.                 sub  ax,cx                      ;sub from top right pos
  975.                 mov  si,ax                      ;ds:si pts to source
  976.                 std                             ;set direction for 'r'
  977.                 jmp  short scrollxl4            ;jump ahead
  978. scrollxl3:      sub  cx,cx                      ;
  979.                 mov  cl,[bp+8]                  ;cols to cx
  980.                 shl  cx,1                       ;double for attributes
  981.                 mov  di,ax                      ;es:di pts leftmost char
  982.                 add  ax,cx                      ;offset to lst scrl char
  983.                 mov  si,ax                      ;ds:si pts scrl char
  984.                 cld                             ;set direction for 'l'
  985. scrollxl4:      sub  cx,cx                      ;
  986.                 mov  cl,[bp+12]                 ;box xx to dx
  987.                 or   cx,cx                      ;test for zero xx
  988.                 jz   scrollxl8                  ;quit routine if zero
  989.                 sub  ax,ax                      ;
  990.                 mov  al,[bp+8]                  ;number cols to scroll
  991.                 or   ax,ax                      ;test for zero cols
  992.                 jnz  scrollxl5                  ;jump ahead if not zero
  993.                 xchg ax,cx                      ;else cols = xx
  994.                 jmp  short scrollxl6            ;jump ahead
  995. scrollxl5:      sub  cx,ax                      ;xx minus cols
  996.                 cmp  cx,0                       ;more cols than xx?
  997.                 jge  scrollxl6                  ;jump ahead if not
  998.                 sub  ax,ax                      ;
  999.                 mov  al,[bp+12]                 ;else cols = xx
  1000.                 mov  cx,0                       ;scroll = 0
  1001. scrollxl6:      push ax                         ;save number cols
  1002.                 push cx                         ;save xx counter
  1003.                 push si                         ;save source ptr
  1004.                 push di                         ;save destination ptr
  1005.                 push dx                         ;save y counter
  1006.                 push ax                         ;save number cols
  1007.                 cmp  byte ptr[bp+14],0          ;protect against snow?
  1008.                 je   scrollxl7                  ;jump ahead if not
  1009.                 mov  dx,3d8h                    ;cga mode select register
  1010.                 mov  al,25h                     ;shut off screen
  1011.                 out  dx,al                      ;do it
  1012. scrollxl7:      pop  ax                         ;restore number cols
  1013.                 pop  dx                         ;restore y counter
  1014.                 rep  movsw                      ;move a y
  1015.                 mov  cx,ax                      ;number cols scrolled
  1016.                 mov  al,32                      ;clear with spc char
  1017.                 mov  ah,[bp+6]                  ;attribute for clear
  1018.                 rep  stosw                      ;clear opened area
  1019.                 pop  di                         ;restore destination ptr
  1020.                 add  di,160                     ;forward to next line
  1021.                 pop  si                         ;restore source ptr
  1022.                 add  si,160                     ;forward to next line
  1023.                 pop  cx                         ;restore xx counter
  1024.                 pop  ax                         ;restore num cols
  1025.                 dec  dx                         ;dec the y counter
  1026.                 jnz  scrollxl6                  ;loop until finished
  1027.                 cmp  byte ptr[bp+14],0          ;protected against snow?
  1028.                 je   scrollxl8                  ;jump if not
  1029.                 mov  dx,3d8h                    ;cga mode select register
  1030.                 mov  al,41                      ;80x25, blink enabled
  1031.                 out  dx,al                      ;reenable video
  1032. scrollxl8:      pop  ds                         ;restore ds
  1033.                 pop  bp                         ;restore bp
  1034.                 ret  14
  1035. scrollx endp
  1036.  
  1037. ;-------------------------------------------------------------------------------
  1038. ;procedure scrolly(where :char; x,y,xx,yy,lines,colour :byte;);
  1039. ;-------------------------------------------------------------------------------
  1040. ;
  1041. scrolly proc far
  1042.                 push bp                         ;save bp
  1043.                 mov  bp,sp                      ;set stack frame
  1044.                 mov  ah,7                       ;assume downward scroll
  1045.                 mov  al,[bp+18]                 ;get direction code
  1046.                 cmp  al,'d'                     ;downward scroll?
  1047.                 je   scrollyl1                  ;jump ahead if so
  1048.                 cmp  al,'d'                     ;downward scroll?
  1049.                 je   scrollyl1                  ;jump ahead if so
  1050.                 mov  ah,6                       ;else code to scroll up
  1051. scrollyl1:      mov  cl,[bp+16]                 ;top left x in cl
  1052.                 dec  cl                         ;count from 0
  1053.                 mov  ch,[bp+14]                 ;top left y in ch
  1054.                 dec  ch                         ;count from 0
  1055.                 mov  dl,[bp+12]                 ;xx in dl
  1056.                 dec  dl                         ;adjust
  1057.                 add  dl,cl                      ;bottom right x in dl
  1058.                 mov  dh,[bp+10]                 ;y in dh
  1059.                 dec  dh                         ;adjust
  1060.                 add  dh,ch                      ;bottom right y in dh
  1061.                 mov  al,[bp+8]                  ;number lines in al
  1062.                 mov  bh,[bp+6]                  ;fill attribute
  1063.                 int  10h                        ;make the scroll
  1064.                 pop  bp                         ;restore bp and quit
  1065.                 ret  14
  1066. scrolly endp
  1067.  
  1068.  
  1069. ;-------------------------------------------------------------------------------
  1070. ;                 local procedures used by other procedures
  1071. ;-------------------------------------------------------------------------------
  1072.  
  1073. boxd_screen proc
  1074.                 push dx                         ;save dx
  1075.                 push ax                         ;save ax
  1076.                 mov  dx,3dah                    ;status byte address
  1077.                 mov  bx,es                      ;get target segment
  1078.                 mov  ax,ds                      ;get source segment
  1079.                 cmp  ax,bx                      ;is source larger?
  1080.                 jna  boxdscra1                  ;jump if not
  1081.                 mov  bx,ax                      ;else use source
  1082. boxdscra1:      cmp  byte ptr[bp+16],0          ;protect against snow?
  1083.                 je   boxdscrd1                  ;jump ahead if not
  1084. boxdscrb1:      in   al,dx                      ;get status byte
  1085.                 test al,1                       ;test bit
  1086.                 jnz  boxdscrb1                  ;loop till 0
  1087.                 cli                             ;disable interrupts
  1088. boxdscrc1:      in   al,dx                      ;get status byte
  1089.                 test al,1                       ;test bit
  1090.                 jz   boxdscrc1                  ;loop till 1
  1091. boxdscrd1:      movsb                           ;move a character
  1092.                 loop boxdscra1                  ;go do next
  1093.                 pop  ax                         ;restore ax
  1094.                 pop  dx                         ;restore dx
  1095.                 ret                             ;
  1096. boxd_screen endp
  1097.  
  1098. ;-------------------------------------------------------------------------------
  1099. boxl_screen proc
  1100.                 push dx                         ;save dx
  1101.                 push ax                         ;save ax too
  1102.                 mov  dx,es                      ;get target segment
  1103.                 mov  ax,ds                      ;get source segment
  1104.                 cmp  ax,dx                      ;is source larger?
  1105.                 jna  boxlscra1                  ;jump if not
  1106.                 mov  dx,ax                      ;else use source
  1107. boxlscra1:      cmp  byte ptr[bp+16],0          ;protect against snow?
  1108.                 je   boxlscrf1                  ;jump ahead if not
  1109.                 mov  dx,3dah                    ;status byte address
  1110. boxlscrb1:      in   al,dx                      ;get status byte
  1111.                 test al,1                       ;test bit
  1112.                 jnz  boxlscrb1                  ;loop till 0
  1113.                 cli                             ;disable interrupts
  1114. boxlscrc1:      in   al,dx                      ;get status byte
  1115.                 test al,1                       ;test bit
  1116.                 jz   boxlscrc1                  ;loop till 1
  1117.                 movsb                           ;write a char
  1118. boxlscrd1:      in   al,dx                      ;get status byte
  1119.                 test al,1                       ;test bit
  1120.                 jnz  boxlscrd1                  ;loop till 0
  1121. boxlscre1:      in   al,dx                      ;get status byte
  1122.                 test al,1                       ;test bit
  1123.                 jz   boxlscre1                  ;loop till 1
  1124.                 movsb                           ;write a char
  1125.                 jmp  short boxlscrg1            ;jump ahead and quit
  1126. boxlscrf1:      movsw                           ;move the character
  1127. boxlscrg1:      pop  ax                         ;restore ax
  1128.                 pop  dx                         ;restore dx
  1129.                 ret                             ;
  1130. boxl_screen endp
  1131.  
  1132. ;-------------------------------------------------------------------------------
  1133. boxr_screen proc
  1134.                 push dx                         ;save dx
  1135.                 push bx                         ;save bx
  1136.                 push ax                         ;save ax
  1137.                 mov  dx,es                      ;get target segment
  1138.                 mov  ax,ds                      ;get source segment
  1139.                 cmp  ax,dx                      ;is source larger?
  1140.                 jna  boxriscra1                 ;jump if not
  1141.                 mov  dx,ax                      ;else use source
  1142. boxriscra1:     cmp  bl,0                       ;protect against snow?
  1143.                 je   boxriscrf1                 ;jump ahead if not
  1144.                 mov  dx,3dah                    ;status byte address
  1145. boxriscrb1:     in   al,dx                      ;get status byte
  1146.                 test al,1                       ;test bit
  1147.                 jnz  boxriscrb1                 ;loop till 0
  1148. boxriscrc1:     in   al,dx                      ;get status byte
  1149.                 test al,1                       ;test bit
  1150.                 jz   boxriscrc1                 ;loop till 1
  1151.                 movsb                           ;move a character
  1152. boxriscrd1:     in   al,dx                      ;get status byte
  1153.                 test al,1                       ;test bit
  1154.                 jnz  boxriscrd1                 ;loop till 0
  1155. boxriscre1:     in   al,dx                      ;get status byte
  1156.                 test al,1                       ;test bit
  1157.                 jz   boxriscre1                 ;loop till 1
  1158.                 movsb                           ;move a character
  1159.                 jmp  short boxriscrg1           ;jump ahead and quit
  1160. boxriscrf1:     movsw                           ;move the character
  1161. boxriscrg1:     pop  ax                         ;restore ax
  1162.                 pop  bx                         ;restore bx
  1163.                 pop  dx                         ;restore dx
  1164.                 ret                             ;
  1165. boxr_screen endp
  1166.  
  1167. ;-------------------------------------------------------------------------------
  1168. boxu_screen  proc
  1169.                 push dx                         ;save dx
  1170.                 push ax                         ;save ax
  1171.                 mov  dx,3dah                    ;status byte address
  1172.                 mov  bx,es                      ;get target segment
  1173.                 mov  ax,ds                      ;get source segment
  1174.                 cmp  ax,bx                      ;is source larger?
  1175.                 jna  boxuscra1                  ;jump if not
  1176.                 mov  bx,ax                      ;else use source
  1177. boxuscra1:      cmp  byte ptr[bp+16],0          ;protect against snow?
  1178.                 je   boxuscrd1                  ;jump ahead if not
  1179. boxuscrb1:      in   al,dx                      ;get status byte
  1180.                 test al,1                       ;test bit
  1181.                 jnz  boxuscrb1                  ;loop till 0
  1182.                 cli                             ;disable interrupts
  1183. boxuscrc1:      in   al,dx                      ;get status byte
  1184.                 test al,1                       ;test bit
  1185.                 jz   boxuscrc1                  ;loop till 1
  1186. boxuscrd1:      movsb                           ;move a character
  1187.                 loop boxuscra1                  ;go do next
  1188.                 pop  ax                         ;restore ax
  1189.                 pop  dx                         ;restore dx
  1190.                 ret                             ;
  1191. boxu_screen  endp
  1192.  
  1193. ;-------------------------------------------------------------------------------
  1194. drawb_screen proc                               ;procedures writes char,
  1195.                 push dx                         ;fix snow
  1196.                 push bx                         ;save dx and bx
  1197.                 cld                             ;set direction flag
  1198.                 cmp  snow_check,0               ;protect against snow?
  1199.                 je   dboxscrc1                  ;jump ahead if not
  1200.                 mov  dx,3dah                    ;status byte address
  1201.                 mov  bx,ax                      ;store ax contents
  1202. dboxscra1:      in   al,dx                      ;get status byte
  1203.                 test al,1                       ;test bit
  1204.                 jnz  dboxscra1                  ;loop till 0
  1205.                 cli                             ;disable interrupts
  1206. dboxscrb1:      in   al,dx                      ;get status byte
  1207.                 test al,1                       ;test bit
  1208.                 jz   dboxscrb1                  ;loop till 1
  1209.                 mov  ax,bx                      ;restore ax contents
  1210. dboxscrc1:      stosw                           ;write the character
  1211.                 dec  di                         ;pull ptr back
  1212.                 dec  di                         ;again
  1213.                 pop  bx                         ;restore bx
  1214.                 pop  dx                         ;restore dx and return
  1215.                 ret
  1216. drawb_screen    endp
  1217.  
  1218.  
  1219. code ends
  1220. end
  1221.