home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / msdos / viewers / pcshow / no9.asm < prev    next >
Assembly Source File  |  1991-07-01  |  13KB  |  496 lines

  1. ;
  2. ;   Number Nine Revolution 512x8 
  3. ;   support routines for raster oriented graphics
  4. ;
  5. ;   Tim Krauskopf      July 1986
  6. ;
  7. ;   National Center for Supercomputing Applications, University of Illinois
  8. ;   153 Water Resources Building
  9. ;   605 E. Springfield Ave.
  10. ;   Champaign, IL  61820
  11. ;   (217)244-0072
  12. ;
  13. ;
  14.     TITLE      NUMBER 9 GRAPHICS SUPPORT
  15.     INCLUDE DOS.MAC
  16.     SETX
  17.     PSEG
  18.     PUBLIC    PUTMAP9,NO9LINE,SHOWPAL9,NOPAL9,OUTLINE9,MAKECUR9;,NO9PT
  19. ;
  20. SETBANK    MACRO
  21.     LOCAL    NO706
  22.     LOCAL    NO705    
  23.     LOCAL    OKBANK        ; A MACRO TO SET THE BANK FOR THE LINE OF THE NO9 MONITOR
  24.                         ; BX MUST CONTAIN THE Y POSITION
  25.     MOV    AX,BX        ; y location on screen
  26.     MOV    CL,7        ; divide by 128
  27.     SHR    AX,CL
  28.     MOV    CL,AL        ; make a copy
  29.     CMP    AL,CS:BANK    ; is it the same bank?
  30.     JZ    OKBANK
  31.  
  32.     MOV    CS:BANK,AL    ; bank will be this one
  33.     MOV    DH,00H        ; default, might be changed
  34.     AND    AL,02H        ; is high bit on?
  35.     JZ    NO706
  36.  
  37.     MOV    DH,0FFH        ;  setting for new bank
  38. NO706:
  39.     MOV    DL,00H        ; default setting for 705
  40.     MOV    AL,CL        ; get back copy
  41.     AND    AL,01H        ; is low bit on?
  42.     JZ    NO705
  43.  
  44.     MOV    DL,0FFH        ; other portion of new bank
  45. NO705:
  46.     MOV    DI,0705H    ; where bank reg is
  47.     MOV    AX,DX
  48.     STOSW            ; sets both bytes, lo then hi
  49. ;
  50. ;   READY TO PUT THE LINE
  51. ;
  52. OKBANK:
  53.     ENDM            ; END OF THE COMPUTE BANK MACRO
  54. ;
  55. ;  take three arrays of color table entries and transfer them to the
  56. ;  board's registers
  57. ;
  58. ;  usage:  putmap9(rmap,gmap,bmap);
  59. ;
  60. PUTMAP9    PROC    FAR
  61.     PUSH    BP
  62.     MOV    BP,SP
  63.     PUSH    DS
  64.     PUSH    ES
  65.     MOV    AX,[BP+X+2]
  66.     MOV    DS,AX            ; where to get maps (seg)
  67.     MOV    SI,[BP+X]        ; where to get red
  68.     MOV    AX,0C000H        ; control seg for #9
  69.     MOV    ES,AX
  70.     MOV    DI,0100H        ; red map
  71.     MOV    CX,256            ; length of map
  72.     REP    MOVSB            ; mov red
  73. ;
  74.     MOV    SI,[BP+X+4]
  75.     MOV    DI,0200H        ; green map
  76.     MOV    CX,256
  77.     REP    MOVSB
  78. ;
  79.     MOV    SI,[BP+X+8]        ; blue map
  80.     MOV    DI,0300H    
  81.     MOV    CX,256
  82.     REP    MOVSB
  83. ;
  84.     POP    ES
  85.     POP    DS
  86.     POP    BP
  87.     RET
  88.  
  89. PUTMAP9    ENDP
  90. ;
  91. ;  Transfer line to #9 screen, one byte per pixel
  92. ;
  93. ;   usage : no9line(x,y,buf,xoff,nbytes)
  94. ;
  95. NO9LINE    PROC    FAR
  96.     PUSH    BP
  97.     MOV    BP,SP
  98.     PUSH    DS
  99.     PUSH    ES
  100.     MOV    AX,0C000H    ; control regs
  101.     MOV    ES,AX
  102.  
  103.     MOV    AX,[BP+X+6]    ; ds of buffer
  104.     MOV    DS,AX
  105.     MOV    BX,[BP+X+2]    ; y location on screen
  106.     SETBANK            ; CALL MACRO TO SET THE CORRECT MEMORY BANK FOR THE Y POSITION
  107.     MOV    AX,0A000H    ; data buffer
  108.     MOV    ES,AX
  109.     MOV    SI,[BP+X+4]    ; where data will come from
  110.     MOV    AX,[BP+X+8]    ; GET THE X OFFSET INTO THE ARRAY
  111.     CMP    AX,0        ; CHECK FOR NEGATIVE OFFSET
  112.     JGE    OKSIGN        ; JUMP AROUND FIXING THE WINDOW
  113.     NEG    AX            ; TAKE THE OPPOSITE VALUE
  114.     ADD AX,[BP+X]    ; AND ADD IT TO THE POSITION ON THE SCREEN
  115.     MOV    [BP+X],AX    ; AND RE-STORE THE POSITION
  116.     MOV    AX,[BP+X+8]    ; GET THE NEGATIVE OFFSET AGAIN
  117.     ADD    AX,[BP+X+10]    ; REDUCE THE NUMBER OF BYTES TO COPY TO THE SCREEN
  118.     MOV    [BP+X+10],AX    ; AND STORE THE NUMBER OF BYTES AGAIN
  119. OKSIGN:
  120.     ADD    SI,AX        ; ADD THE OFFSET TO THE OFFSET OF THE ARRAY
  121. ;
  122.     MOV    AX,[BP+X+2]    ; get y value again
  123.     MOV    CL,9
  124.     SHL    AX,CL        ; get 16 bit pointer for this bank
  125.     ADD    AX,[BP+X]    ; x value of where on screen added in
  126.     MOV    DI,AX        ; prepare for movs
  127.     MOV    CX,[BP+X+10]    ; how many bytes?
  128. BLAST:
  129.     REP    MOVSB
  130.  
  131.     POP    ES
  132.     POP    DS
  133.     POP    BP
  134.     RET
  135. BANK    DB    0FFH        ; current bank number
  136. NO9LINE    ENDP
  137.  
  138. ;
  139. ;    showpal9(&palstore,pal_xoff,pal_yoff);
  140. ;
  141. SHOWPAL9        PROC    FAR
  142.     PUSH    BP
  143.     MOV        BP,SP
  144.     PUSH    DS
  145.     PUSH    ES
  146.  
  147.     MOV    CX,16        ; COUNT THE NUMBER OF LINES TO SAVE
  148.     PUSH    CX        ; AND SAVE THE COUNT
  149. SHOWTOP:
  150.     MOV    AX,0C000H    ; control regs
  151.     MOV    ES,AX
  152.     MOV    BX,[BP+X+6]    ; y location on screen
  153.     INC    WORD PTR [BP+X+6]    ; GET THE Y VALUE OF THE NEXT LINE
  154.     SETBANK            ; CALL MACRO TO SET THE CORRECT MEMORY BANK FOR THE Y POSITION
  155.     MOV    AX,0A000H    ; data buffer
  156.     MOV    DS,AX
  157.     MOV    AX,BX        ; get y value again
  158.     MOV    CL,9
  159.     SHL    AX,CL        ; get 16 bit pointer for this bank
  160.     ADD    AX,[BP+X+4]    ; ADD IN THE X OFFSET
  161.     MOV    SI,AX        ; prepare for movs
  162.     MOV    DI,[BP+X]    ; GET OFFSET OF ARRAY
  163.     MOV    AX,[BP+X+2]    ; GET SEGMENT OF STORAGE ARRAY
  164.     MOV    ES,AX            
  165.     MOV    CX,0        ; how many bytes?
  166. ZING:
  167.     MOVSB            ; SAVE THE OLD VALUE
  168.     DEC    SI            ; GO BACK TO PUT THE PALETTE IN MEMORY
  169.     MOV    DS:BYTE PTR [SI],CL    ; PUT THE PALETTE VALUE THERE
  170.     INC    SI
  171.     INC    CX            ; INCREMENT THE LOOP COUNTER
  172.     CMP    CH,1        ; CHECK FOR THE END OF THE LINE
  173.     JNE    ZING        ; FINISH THE PALETTE  FOR THAT LINE
  174.  
  175.     POP    CX            ; RECOVER THE COUNT OF LINES
  176.     DEC    CX            ; 
  177.     PUSH    CX        ; KEEP THE COUNT AROUND STILL
  178.     MOV    [BP+X],DI    ; SAVE MODIFIED OFFSET
  179.     CMP    CX,0        ; CHECK FOR THE COUNT BEING DONE
  180.     JNE    SHOWTOP
  181.  
  182.     POP    CX        ; GET RID OF EXTRANEOUS PUSH
  183.  
  184.     POP    ES
  185.     POP    DS
  186.     POP    BP
  187.     RET
  188. SHOWPAL9    ENDP
  189. ;
  190. ;    nopal9(&palstore,pal_xoff,pal_yoff);
  191. ;
  192. NOPAL9        PROC    FAR
  193.     PUSH    BP
  194.     MOV        BP,SP
  195.     PUSH    DS
  196.     PUSH    ES
  197.  
  198.     MOV    CX,16        ; THE NUMBER OF LINES TO REPLACE
  199.     PUSH    CX        ; SAVE THE NUMBER OF LINES
  200. NOTOP:
  201.     MOV    AX,0C000H    ; control regs
  202.     MOV    ES,AX
  203.     MOV    BX,[BP+X+6]    ; y location on screen
  204.     INC    WORD PTR [BP+X+6]    ; MAKE Y POSITION FOR NEXT LINE
  205.     SETBANK            ; CALL MACRO TO SET THE CORRECT MEMORY BANK FOR THE Y POSITION
  206.  
  207.     MOV    AX,0A000H    ; data buffer
  208.     MOV    ES,AX
  209.     MOV    AX,[BP+X+2]    ; ds of buffer
  210.     MOV    DS,AX
  211.     MOV    SI,[BP+X]    ; where data will come from
  212.  
  213.     MOV    AX,BX        ; get y value again
  214.     MOV    CL,9
  215.     SHL    AX,CL        ; get 16 bit pointer for this bank
  216.     ADD    AX,[BP+X+4]    ; x value of where on screen added in
  217.     MOV    DI,AX        ; prepare for movs
  218.  
  219.     MOV    CX,256        ; how many bytes?
  220. ZOOM:
  221.     REP    MOVSB
  222.  
  223.     POP    CX            ; RECOVER THE COUNT OF LINES
  224.     DEC    CX            ; 
  225.     PUSH    CX        ; KEEP THE COUNT AROUND STILL
  226.     MOV    [BP+X],SI    ; SAVE MODFIED OFFSET
  227.     CMP    CX,0        ; CHECK FOR THE COUNT BEING DONE
  228.     JNE     NOTOP
  229.  
  230.     POP    CX            ; GET RID OF EXTRANEOUS CX PUSH
  231.     
  232.     POP    ES
  233.     POP    DS
  234.     POP    BP
  235.     RET
  236. NOPAL9    ENDP
  237. ifdef QAK
  238. ;
  239. ;    no9pt(x,y,color);
  240. ;
  241. NO9PT        PROC    FAR
  242.     PUSH    BP
  243.     MOV        BP,SP
  244.     PUSH    DS
  245.     PUSH    ES
  246.     MOV    AX,0C000H    ; control regs
  247.     MOV    ES,AX
  248.  
  249.     MOV    BX,[BP+X+2]    ; GET LINE TO COPY SCREEN BACK ONTO
  250.     SETBANK
  251.  
  252.     MOV    AX,0A000H    ; data buffer
  253.     MOV    ES,AX
  254.  
  255.     MOV    AX,[BP+X+2]    ; get y value again
  256.     MOV    CL,9
  257.     SHL    AX,CL        ; get 16 bit pointer for this bank
  258.     ADD    AX,[BP+X]    ; ADD IN THE X OFFSET
  259.  
  260.     MOV    DI,AX        ; prepare for movs
  261.     MOV    AL,[BP+X+4]    ; GET THE VALUE TO PUT THERE
  262.  
  263.     STOSB            ; PUT COLOR ON THE SCREEN
  264.  
  265.     POP    ES
  266.     POP    DS
  267.     POP    BP
  268.     RET
  269. NO9PT    ENDP
  270. endif
  271.  
  272. Y_COUNT    DW    0        ; THE NUMBER OF Y LINES TO INVERT
  273. ;
  274. ;  Invert A BOX ON THE SCREEN
  275. ;
  276. ;   usage : outline9(x1,y1,x2,y2)
  277. ;
  278. OUTLINE9    PROC    FAR
  279.     PUSH    BP
  280.     MOV    BP,SP
  281.     PUSH    DS
  282.     PUSH    ES
  283.  
  284. ;    INT    3            ; PERFORM AN INTERUPT FOR DEBUGGER
  285.     MOV    AX,[BP+X+2]    ; GET FIRST Y VALUE
  286.     CMP    AX,[BP+X+6]    ; COMPARE WITH THE SECOND Y - VALUE
  287.     JLE    CHECKX        ; OK ORDER GOTO CHECKING THE X VALUES
  288.     MOV    CX,AX        ; SWAP THE TWO VALUES
  289.     MOV    AX,[BP+X+6]    ;
  290.     MOV    [BP+X+2],AX    ;
  291.     MOV    AX,CX        ;
  292.     MOV    [BP+X+6],AX    ;
  293. CHECKX:
  294.     MOV    AX,[BP+X]    ; GET FIRST X VALUE
  295.     CMP    AX,[BP+X+4]    ; COMPARE WITH THE SECOND X - VALUE
  296.     JLE    MAKELEN        ; OK ORDER GOTO COMPUTING THE LENGTHS
  297.     MOV    CX,AX        ; SWAP THE TWO VALUES
  298.     MOV    AX,[BP+X+4]    ;
  299.     MOV    [BP+X],AX    ;
  300.     MOV    AX,CX        ;
  301.     MOV    [BP+X+4],AX    ;
  302. MAKELEN:            ; COMPUTE THE X AND Y WIDTHS FOR THE BOX TO BE INVERTED
  303.     MOV    AX,[BP+X+4]    ; GET THE LARGER OF THE TWO X VALUES
  304.     SUB    AX,[BP+X]    ; SUBTRACT THE SMALLER VALUE TO FIND THE LENGTH
  305.     MOV    [BP+X+4],AX    ; STORE IT IN THE OLD LOCATION FOR THE 2ND X VALUE
  306.     MOV    AX,[BP+X+6]    ; GET THE LARGER OF THE TWO Y VALUES
  307.     SUB    AX,[BP+X+2]    ; SUBTRACT THE SMALLER VALUE TO FIND THE LENGTH
  308.     SUB    AX,1        ; SUBTRACT TWO FOR THE TOP AND BOTTOM EDGES
  309.     CMP    AX,0        ; CHECK IF IT IS LESS THAN ZERO
  310.     JG     POSITIVE    ; JUMP AROUND ZEROING THE ACC.
  311.     MOV    AX,0
  312. POSITIVE:
  313.     MOV    [BP+X+6],AX    ; STORE IT IN THE OLD LOCATION FOR THE 2ND Y VALUE
  314.     MOV    AX,0C000H    ; control regs
  315.     MOV    ES,AX
  316.     MOV    BX,[BP+X+2]    ; GET THE Y LOCATION FOR THE TOP LINE
  317.     SETBANK            ; CALL MACRO TO SET THE CORRECT MEMORY BANK FOR THE Y POSITION
  318.     MOV    AX,0A000H    ; SET THE DATA BUFFER
  319.     MOV    ES,AX
  320.     MOV    AX,[BP+X+2]    ; GET THE Y POSITION FOR THE TOP LINE AGAIN
  321.     MOV    CL,9
  322.     SHL    AX,CL
  323.     ADD    AX,[BP+X]    ; ADD IN THE X OFFSET
  324.     MOV    DI,AX        ; STORE THE OFFSET
  325.     MOV    CX,[BP+X+4]    ; THE NUMBER OF BYTES TO INVERT
  326.     INC    CX
  327. BLASTA:
  328.     MOV    AL,ES:[DI]    ; GET THE BYTE TO INVERT
  329.     NOT    AL        ; INVERT THE BYTE
  330.     MOV    ES:[DI],AL    ; REPLACE THE BYTE
  331.     INC    DI        ; GO TO THE NEXT BYTE
  332.     LOOP    BLASTA        ; FINISH THE LINE OUT
  333.  
  334.     MOV    AX,0C000H    ; control regs
  335.     MOV    ES,AX
  336.     ADD    BX,[BP+X+6]    ; ADD IN THE Y SIZE TO GET TO THE LAST LINE
  337.     ADD    BX,1        ;
  338.     SETBANK            ; CALL MACRO TO SET THE CORRECT MEMORY BANK FOR THE Y POSITION
  339.     MOV    AX,0A000H    ; SET THE DATA BUFFER
  340.     MOV    ES,AX
  341.     MOV    AX,BX        ; GET THE Y POSITION FOR THE TOP LINE AGAIN
  342.     MOV    CL,9
  343.     SHL    AX,CL
  344.     ADD    AX,[BP+X]    ; ADD IN THE X OFFSET
  345.     MOV    DI,AX        ; STORE THE OFFSET
  346.     MOV    CX,[BP+X+4]    ; THE NUMBER OF BYTES TO INVERT
  347.     INC    CX
  348. BLASTB:
  349.     MOV    AL,ES:[DI]    ; GET THE BYTE TO INVERT
  350.     NOT    AL            ; INVERT THE BYTE
  351.     MOV    ES:[DI],AL    ; REPLACE THE BYTE
  352.     INC    DI            ; GO TO THE NEXT BYTE
  353.     LOOP    BLASTB    ; FINISH THE LINE OUT
  354.  
  355.     MOV    CX,[BP+X+6]    ; GET THE NUMBER OF LINES IN THE MIDDLE
  356.     MOV    Y_COUNT,CX    ; STORE IT IN THE PROPER PLACE
  357. OUTTOP:
  358.     MOV    AX,0C000H    ; control regs
  359.     MOV    ES,AX
  360.     INC    WORD PTR [BP+X+2]    ; INCREMENT THE LINE TO INVERT
  361.     MOV    BX,[BP+X+2]    ; GET THE LINE TO MODIFY
  362.     SETBANK            ; CALL MACRO TO SET THE CORRECT MEMORY BANK FOR THE Y POSITION
  363.     MOV    AX,0A000H    ; SET THE DATA BUFFER
  364.     MOV    ES,AX
  365.     MOV    AX,[BP+X+2]    ; GET THE Y POSITION FOR THE TOP LINE AGAIN
  366.     MOV    CL,9
  367.     SHL    AX,CL
  368.     ADD    AX,[BP+X]    ; ADD IN THE X OFFSET
  369.     MOV    DI,AX        ; STORE THE OFFSET
  370.     MOV    AL,ES:[DI]    ; GET THE BYTE TO INVERT
  371.     NOT    AL            ; INVERT THE BYTE
  372.     MOV    ES:[DI],AL    ; REPLACE THE BYTE
  373.     ADD    DI,[BP+X+4]    ; GET TO THE END OF THE LINE        
  374.     MOV    AL,ES:[DI]    ; GET THE BYTE TO INVERT
  375.     NOT    AL            ; INVERT THE BYTE
  376.     MOV    ES:[DI],AL    ; REPLACE THE BYTE
  377.     DEC    Y_COUNT        ; DECREMENT THE COUNT
  378.     CMP    Y_COUNT,0    ; CHECK FOR THE END OF THE BOX
  379.     JG    OUTTOP        ; JUMP BACK TO THE BEGINNING
  380.  
  381.     POP    ES
  382.     POP    DS
  383.     POP    BP
  384.     RET
  385. OUTLINE9    ENDP
  386.  
  387. X_SIZE    EQU    16        ; X WIDTH OF THE CURSOR
  388. Y_SIZE    EQU    32        ; TWICE THE Y HEIGHT OF THE CURSOR
  389. X_HOT    EQU    7        ; HORIZONTAL HOT SPOT FOR THE CURSOR
  390. Y_HOT    EQU    7        ; VERTICAL HOT SPOT FOR THE CURSOR
  391. X_START    DW    ?        ; THE X POSITION TO START THE ARRAY ON
  392. ;
  393. ;    EACH BIT PLACE IN THE CURSOR ARRAY STANDS FOR A BYTE ON THE SCREEN
  394. ;    IF THE BIT IS ON, THEN THAT BYTE ON THE SCREEN WILL BE INVERTED
  395. ;    IF NOT, THEN THE BYTE WILL BE UNTOUCHED.
  396. ;    THE NUMBER OF WORDS FOR THE CURSOR ARRAY, AND THE NUMBER OF BITS
  397. ;    IN EACH IS CONTROLLED BY THE X_SIZE AND Y_SIZE VARIABLES.
  398. CURSOR    LABEL    WORD        ; LABEL FOR THE BEGINNING OF THE CURSOR ARRAY
  399.         DW    0000000000000000B
  400.         DW    0000000000000000B
  401.         DW    0000000110000000B
  402.         DW    0000000110000000B
  403.         DW    0000000110000000B
  404.         DW    0000000110000000B
  405.         DW    0000000110000000B
  406.         DW    0011111111111100B
  407.         DW    0011111111111100B
  408.         DW    0000000110000000B
  409.         DW    0000000110000000B
  410.         DW    0000000110000000B
  411.         DW    0000000110000000B
  412.         DW    0000000110000000B
  413.         DW    0000000000000000B
  414.         DW    0000000000000000B
  415. ;
  416. ;
  417. ;    Routine to make a cursor on the screen
  418. ;    makecur9(x,y);
  419. ;
  420. MAKECUR9    PROC    FAR
  421.     PUSH    BP
  422.     MOV    BP,SP
  423.     PUSH    DS
  424.     PUSH    ES
  425.  
  426.     MOV    AX,[BP+X+2]    ; GET THE Y VALUE TO MODIFY FOR THE HOT SPOT
  427.     SUB    AX,Y_HOT    ; SUBTRACT THE HOT SPOT VALUE
  428.     MOV    [BP+X+2],AX    ; REPLACE THE Y VALUE
  429.  
  430.     MOV    AX,[BP+X]    ; GET THE X VALUE TO MODIFY FOR THE HOT SPOT
  431.     SUB    AX,X_HOT    ; SUBTRACT THE HOT SPOT VALUE
  432.     MOV    [BP+X],AX    ; REPLACE THE X VALUE
  433.  
  434.     MOV    X_START,0    ; INITIALIZE THE X_START TO BE IN THE 0 POSITION
  435.     MOV    SI,0        ; INITIALIZE THE Y COUNTER
  436. CURTOP:
  437.     MOV    AX,0C000H    ; control regs
  438.     MOV    ES,AX
  439.     MOV    BX,[BP+X+2]    ; GET LINE TO COPY SCREEN BACK ONTO
  440.     CMP    BX,0        ; CHECK FOR NEGATIVE COORDINATES
  441.     JL    CUREND        ; IF NEGATIVE COORDINATES THEN JUMP TO END OF LOOP
  442.     SETBANK
  443.  
  444.     MOV    AX,0A000H    ; data buffer
  445.     MOV    ES,AX
  446.  
  447.     MOV    DX,X_START    ; INITIALIZE THE X COUNTER
  448.     MOV    BX,CURSOR[SI]    ; GET THE CURRENT CURSOR INFORMATION
  449.     MOV    CX,X_START    ; GET THE INITIAL NUMBER OF BITS TO SHIFT THE ARRAY
  450.     SHL    BX,CL        ; SHIFT THE ARRAY THAT MANY BYTES
  451. TRYAGAIN:
  452.     MOV    AX,[BP+X]    ; GET THE X POSITION
  453.     CMP    AX,0        ; CHECK FOR NEGATIVE POSITION
  454.     JGE    OKFINE        ; NOT A NEGATIVE VALUE
  455.     INC    WORD PTR [BP+X]    ; INCREMENT THE X POSITION
  456.     INC    DX            ; AND THE POSITION IN THE ARRAY
  457.     INC    WORD PTR X_START    ; INCREMENT THE POSITION TO START IN THE ARRAY FOR NEXT LOOP THRU
  458.     SHL    BX,1        ; GET RID OF A BIT OF THE CURSOR INFORMATION
  459.     JMP    TRYAGAIN    ; JUMP BACK TO TRY FOR ANOTHER X POSITION
  460. OKFINE:
  461.     MOV    AX,[BP+X+2]    ; get y value again
  462.     MOV    CL,9
  463.     SHL    AX,CL        ; get 16 bit pointer for this bank
  464.     ADD    AX,[BP+X]    ; ADD IN THE X OFFSET
  465.     MOV    DI,AX        ; prepare for movs
  466.  
  467. LOOPTOP:
  468.     SHL    BX,1        ; GET THE BIT FOR THIS CURSOR POSITION
  469.     JNC    LOOPBOT        ; IF IT NOT SET THEN JUMP TO BOTTOM OF LOOP
  470.     MOV    AL,ES:[DI]    ; GET THE BYTE TO INVERT
  471.     NOT    AL            ; INVERT THE BYTE
  472.     MOV    ES:[DI],AL    ; REPLACE THE INVERTED BYTE
  473. LOOPBOT:
  474.     INC    DI            ; INCREMENT FOR NEXT BYTE ON THE SCREEN
  475.     INC    DX            ; INCREMENT THE POSITION IN THE ARRAY
  476.     CMP    DX,X_SIZE    ; CHECK TO SEE IF THE END OF THE LINE HAS BEEN FOUND
  477.     JNE    LOOPTOP        ; IF NOT END THEN JUMP TO BEGINNING OF THE LOOP
  478.  
  479. CUREND:
  480.     INC    WORD PTR [BP+X+2]    ; INCREMENT Y VALUE FOR THE NEXT LINE
  481.     INC    SI            ; INCREMENT THE Y POSITION IN THE ARRAY
  482.     INC    SI
  483.     CMP    SI,Y_SIZE    ; CHECK TO SEE IF THE BOOTOM OF THE ARRAY HAS BEEN REACHED
  484.     JE    KLUDGE        ; JUMP AROUND JUMP BACK IF AT END
  485.     JMP    CURTOP        ; IF NOT THEN JUMP TO BEGINNING OF A NEW LINE
  486. KLUDGE:
  487.  
  488.     POP    ES
  489.     POP    DS
  490.     POP    BP
  491.     RET
  492. MAKECUR9    ENDP
  493.  
  494.     ENDPS
  495.     END
  496.