home *** CD-ROM | disk | FTP | other *** search
- ;
- ; Number Nine Revolution 512x8
- ; support routines for raster oriented graphics
- ;
- ; Tim Krauskopf July 1986
- ;
- ; National Center for Supercomputing Applications, University of Illinois
- ; 153 Water Resources Building
- ; 605 E. Springfield Ave.
- ; Champaign, IL 61820
- ; (217)244-0072
- ;
- ;
- TITLE NUMBER 9 GRAPHICS SUPPORT
- INCLUDE DOS.MAC
- SETX
- PSEG
- PUBLIC PUTMAP9,NO9LINE,SHOWPAL9,NOPAL9,OUTLINE9,MAKECUR9;,NO9PT
- ;
- SETBANK MACRO
- LOCAL NO706
- LOCAL NO705
- LOCAL OKBANK ; A MACRO TO SET THE BANK FOR THE LINE OF THE NO9 MONITOR
- ; BX MUST CONTAIN THE Y POSITION
- MOV AX,BX ; y location on screen
- MOV CL,7 ; divide by 128
- SHR AX,CL
- MOV CL,AL ; make a copy
- CMP AL,CS:BANK ; is it the same bank?
- JZ OKBANK
-
- MOV CS:BANK,AL ; bank will be this one
- MOV DH,00H ; default, might be changed
- AND AL,02H ; is high bit on?
- JZ NO706
-
- MOV DH,0FFH ; setting for new bank
- NO706:
- MOV DL,00H ; default setting for 705
- MOV AL,CL ; get back copy
- AND AL,01H ; is low bit on?
- JZ NO705
-
- MOV DL,0FFH ; other portion of new bank
- NO705:
- MOV DI,0705H ; where bank reg is
- MOV AX,DX
- STOSW ; sets both bytes, lo then hi
- ;
- ; READY TO PUT THE LINE
- ;
- OKBANK:
- ENDM ; END OF THE COMPUTE BANK MACRO
- ;
- ; take three arrays of color table entries and transfer them to the
- ; board's registers
- ;
- ; usage: putmap9(rmap,gmap,bmap);
- ;
- PUTMAP9 PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- MOV AX,[BP+X+2]
- MOV DS,AX ; where to get maps (seg)
- MOV SI,[BP+X] ; where to get red
- MOV AX,0C000H ; control seg for #9
- MOV ES,AX
- MOV DI,0100H ; red map
- MOV CX,256 ; length of map
- REP MOVSB ; mov red
- ;
- MOV SI,[BP+X+4]
- MOV DI,0200H ; green map
- MOV CX,256
- REP MOVSB
- ;
- MOV SI,[BP+X+8] ; blue map
- MOV DI,0300H
- MOV CX,256
- REP MOVSB
- ;
- POP ES
- POP DS
- POP BP
- RET
-
- PUTMAP9 ENDP
- ;
- ; Transfer line to #9 screen, one byte per pixel
- ;
- ; usage : no9line(x,y,buf,xoff,nbytes)
- ;
- NO9LINE PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- MOV AX,0C000H ; control regs
- MOV ES,AX
-
- MOV AX,[BP+X+6] ; ds of buffer
- MOV DS,AX
- MOV BX,[BP+X+2] ; y location on screen
- SETBANK ; CALL MACRO TO SET THE CORRECT MEMORY BANK FOR THE Y POSITION
- MOV AX,0A000H ; data buffer
- MOV ES,AX
- MOV SI,[BP+X+4] ; where data will come from
- MOV AX,[BP+X+8] ; GET THE X OFFSET INTO THE ARRAY
- CMP AX,0 ; CHECK FOR NEGATIVE OFFSET
- JGE OKSIGN ; JUMP AROUND FIXING THE WINDOW
- NEG AX ; TAKE THE OPPOSITE VALUE
- ADD AX,[BP+X] ; AND ADD IT TO THE POSITION ON THE SCREEN
- MOV [BP+X],AX ; AND RE-STORE THE POSITION
- MOV AX,[BP+X+8] ; GET THE NEGATIVE OFFSET AGAIN
- ADD AX,[BP+X+10] ; REDUCE THE NUMBER OF BYTES TO COPY TO THE SCREEN
- MOV [BP+X+10],AX ; AND STORE THE NUMBER OF BYTES AGAIN
- OKSIGN:
- ADD SI,AX ; ADD THE OFFSET TO THE OFFSET OF THE ARRAY
- ;
- MOV AX,[BP+X+2] ; get y value again
- MOV CL,9
- SHL AX,CL ; get 16 bit pointer for this bank
- ADD AX,[BP+X] ; x value of where on screen added in
- MOV DI,AX ; prepare for movs
- MOV CX,[BP+X+10] ; how many bytes?
- BLAST:
- REP MOVSB
-
- POP ES
- POP DS
- POP BP
- RET
- BANK DB 0FFH ; current bank number
- NO9LINE ENDP
-
- ;
- ; showpal9(&palstore,pal_xoff,pal_yoff);
- ;
- SHOWPAL9 PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
-
- MOV CX,16 ; COUNT THE NUMBER OF LINES TO SAVE
- PUSH CX ; AND SAVE THE COUNT
- SHOWTOP:
- MOV AX,0C000H ; control regs
- MOV ES,AX
- MOV BX,[BP+X+6] ; y location on screen
- INC WORD PTR [BP+X+6] ; GET THE Y VALUE OF THE NEXT LINE
- SETBANK ; CALL MACRO TO SET THE CORRECT MEMORY BANK FOR THE Y POSITION
- MOV AX,0A000H ; data buffer
- MOV DS,AX
- MOV AX,BX ; get y value again
- MOV CL,9
- SHL AX,CL ; get 16 bit pointer for this bank
- ADD AX,[BP+X+4] ; ADD IN THE X OFFSET
- MOV SI,AX ; prepare for movs
- MOV DI,[BP+X] ; GET OFFSET OF ARRAY
- MOV AX,[BP+X+2] ; GET SEGMENT OF STORAGE ARRAY
- MOV ES,AX
- MOV CX,0 ; how many bytes?
- ZING:
- MOVSB ; SAVE THE OLD VALUE
- DEC SI ; GO BACK TO PUT THE PALETTE IN MEMORY
- MOV DS:BYTE PTR [SI],CL ; PUT THE PALETTE VALUE THERE
- INC SI
- INC CX ; INCREMENT THE LOOP COUNTER
- CMP CH,1 ; CHECK FOR THE END OF THE LINE
- JNE ZING ; FINISH THE PALETTE FOR THAT LINE
-
- POP CX ; RECOVER THE COUNT OF LINES
- DEC CX ;
- PUSH CX ; KEEP THE COUNT AROUND STILL
- MOV [BP+X],DI ; SAVE MODIFIED OFFSET
- CMP CX,0 ; CHECK FOR THE COUNT BEING DONE
- JNE SHOWTOP
-
- POP CX ; GET RID OF EXTRANEOUS PUSH
-
- POP ES
- POP DS
- POP BP
- RET
- SHOWPAL9 ENDP
- ;
- ; nopal9(&palstore,pal_xoff,pal_yoff);
- ;
- NOPAL9 PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
-
- MOV CX,16 ; THE NUMBER OF LINES TO REPLACE
- PUSH CX ; SAVE THE NUMBER OF LINES
- NOTOP:
- MOV AX,0C000H ; control regs
- MOV ES,AX
- MOV BX,[BP+X+6] ; y location on screen
- INC WORD PTR [BP+X+6] ; MAKE Y POSITION FOR NEXT LINE
- SETBANK ; CALL MACRO TO SET THE CORRECT MEMORY BANK FOR THE Y POSITION
-
- MOV AX,0A000H ; data buffer
- MOV ES,AX
- MOV AX,[BP+X+2] ; ds of buffer
- MOV DS,AX
- MOV SI,[BP+X] ; where data will come from
-
- MOV AX,BX ; get y value again
- MOV CL,9
- SHL AX,CL ; get 16 bit pointer for this bank
- ADD AX,[BP+X+4] ; x value of where on screen added in
- MOV DI,AX ; prepare for movs
-
- MOV CX,256 ; how many bytes?
- ZOOM:
- REP MOVSB
-
- POP CX ; RECOVER THE COUNT OF LINES
- DEC CX ;
- PUSH CX ; KEEP THE COUNT AROUND STILL
- MOV [BP+X],SI ; SAVE MODFIED OFFSET
- CMP CX,0 ; CHECK FOR THE COUNT BEING DONE
- JNE NOTOP
-
- POP CX ; GET RID OF EXTRANEOUS CX PUSH
-
- POP ES
- POP DS
- POP BP
- RET
- NOPAL9 ENDP
- ifdef QAK
- ;
- ; no9pt(x,y,color);
- ;
- NO9PT PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- MOV AX,0C000H ; control regs
- MOV ES,AX
-
- MOV BX,[BP+X+2] ; GET LINE TO COPY SCREEN BACK ONTO
- SETBANK
-
- MOV AX,0A000H ; data buffer
- MOV ES,AX
-
- MOV AX,[BP+X+2] ; get y value again
- MOV CL,9
- SHL AX,CL ; get 16 bit pointer for this bank
- ADD AX,[BP+X] ; ADD IN THE X OFFSET
-
- MOV DI,AX ; prepare for movs
- MOV AL,[BP+X+4] ; GET THE VALUE TO PUT THERE
-
- STOSB ; PUT COLOR ON THE SCREEN
-
- POP ES
- POP DS
- POP BP
- RET
- NO9PT ENDP
- endif
-
- Y_COUNT DW 0 ; THE NUMBER OF Y LINES TO INVERT
- ;
- ; Invert A BOX ON THE SCREEN
- ;
- ; usage : outline9(x1,y1,x2,y2)
- ;
- OUTLINE9 PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
-
- ; INT 3 ; PERFORM AN INTERUPT FOR DEBUGGER
- MOV AX,[BP+X+2] ; GET FIRST Y VALUE
- CMP AX,[BP+X+6] ; COMPARE WITH THE SECOND Y - VALUE
- JLE CHECKX ; OK ORDER GOTO CHECKING THE X VALUES
- MOV CX,AX ; SWAP THE TWO VALUES
- MOV AX,[BP+X+6] ;
- MOV [BP+X+2],AX ;
- MOV AX,CX ;
- MOV [BP+X+6],AX ;
- CHECKX:
- MOV AX,[BP+X] ; GET FIRST X VALUE
- CMP AX,[BP+X+4] ; COMPARE WITH THE SECOND X - VALUE
- JLE MAKELEN ; OK ORDER GOTO COMPUTING THE LENGTHS
- MOV CX,AX ; SWAP THE TWO VALUES
- MOV AX,[BP+X+4] ;
- MOV [BP+X],AX ;
- MOV AX,CX ;
- MOV [BP+X+4],AX ;
- MAKELEN: ; COMPUTE THE X AND Y WIDTHS FOR THE BOX TO BE INVERTED
- MOV AX,[BP+X+4] ; GET THE LARGER OF THE TWO X VALUES
- SUB AX,[BP+X] ; SUBTRACT THE SMALLER VALUE TO FIND THE LENGTH
- MOV [BP+X+4],AX ; STORE IT IN THE OLD LOCATION FOR THE 2ND X VALUE
- MOV AX,[BP+X+6] ; GET THE LARGER OF THE TWO Y VALUES
- SUB AX,[BP+X+2] ; SUBTRACT THE SMALLER VALUE TO FIND THE LENGTH
- SUB AX,1 ; SUBTRACT TWO FOR THE TOP AND BOTTOM EDGES
- CMP AX,0 ; CHECK IF IT IS LESS THAN ZERO
- JG POSITIVE ; JUMP AROUND ZEROING THE ACC.
- MOV AX,0
- POSITIVE:
- MOV [BP+X+6],AX ; STORE IT IN THE OLD LOCATION FOR THE 2ND Y VALUE
- MOV AX,0C000H ; control regs
- MOV ES,AX
- MOV BX,[BP+X+2] ; GET THE Y LOCATION FOR THE TOP LINE
- SETBANK ; CALL MACRO TO SET THE CORRECT MEMORY BANK FOR THE Y POSITION
- MOV AX,0A000H ; SET THE DATA BUFFER
- MOV ES,AX
- MOV AX,[BP+X+2] ; GET THE Y POSITION FOR THE TOP LINE AGAIN
- MOV CL,9
- SHL AX,CL
- ADD AX,[BP+X] ; ADD IN THE X OFFSET
- MOV DI,AX ; STORE THE OFFSET
- MOV CX,[BP+X+4] ; THE NUMBER OF BYTES TO INVERT
- INC CX
- BLASTA:
- MOV AL,ES:[DI] ; GET THE BYTE TO INVERT
- NOT AL ; INVERT THE BYTE
- MOV ES:[DI],AL ; REPLACE THE BYTE
- INC DI ; GO TO THE NEXT BYTE
- LOOP BLASTA ; FINISH THE LINE OUT
-
- MOV AX,0C000H ; control regs
- MOV ES,AX
- ADD BX,[BP+X+6] ; ADD IN THE Y SIZE TO GET TO THE LAST LINE
- ADD BX,1 ;
- SETBANK ; CALL MACRO TO SET THE CORRECT MEMORY BANK FOR THE Y POSITION
- MOV AX,0A000H ; SET THE DATA BUFFER
- MOV ES,AX
- MOV AX,BX ; GET THE Y POSITION FOR THE TOP LINE AGAIN
- MOV CL,9
- SHL AX,CL
- ADD AX,[BP+X] ; ADD IN THE X OFFSET
- MOV DI,AX ; STORE THE OFFSET
- MOV CX,[BP+X+4] ; THE NUMBER OF BYTES TO INVERT
- INC CX
- BLASTB:
- MOV AL,ES:[DI] ; GET THE BYTE TO INVERT
- NOT AL ; INVERT THE BYTE
- MOV ES:[DI],AL ; REPLACE THE BYTE
- INC DI ; GO TO THE NEXT BYTE
- LOOP BLASTB ; FINISH THE LINE OUT
-
- MOV CX,[BP+X+6] ; GET THE NUMBER OF LINES IN THE MIDDLE
- MOV Y_COUNT,CX ; STORE IT IN THE PROPER PLACE
- OUTTOP:
- MOV AX,0C000H ; control regs
- MOV ES,AX
- INC WORD PTR [BP+X+2] ; INCREMENT THE LINE TO INVERT
- MOV BX,[BP+X+2] ; GET THE LINE TO MODIFY
- SETBANK ; CALL MACRO TO SET THE CORRECT MEMORY BANK FOR THE Y POSITION
- MOV AX,0A000H ; SET THE DATA BUFFER
- MOV ES,AX
- MOV AX,[BP+X+2] ; GET THE Y POSITION FOR THE TOP LINE AGAIN
- MOV CL,9
- SHL AX,CL
- ADD AX,[BP+X] ; ADD IN THE X OFFSET
- MOV DI,AX ; STORE THE OFFSET
- MOV AL,ES:[DI] ; GET THE BYTE TO INVERT
- NOT AL ; INVERT THE BYTE
- MOV ES:[DI],AL ; REPLACE THE BYTE
- ADD DI,[BP+X+4] ; GET TO THE END OF THE LINE
- MOV AL,ES:[DI] ; GET THE BYTE TO INVERT
- NOT AL ; INVERT THE BYTE
- MOV ES:[DI],AL ; REPLACE THE BYTE
- DEC Y_COUNT ; DECREMENT THE COUNT
- CMP Y_COUNT,0 ; CHECK FOR THE END OF THE BOX
- JG OUTTOP ; JUMP BACK TO THE BEGINNING
-
- POP ES
- POP DS
- POP BP
- RET
- OUTLINE9 ENDP
-
- X_SIZE EQU 16 ; X WIDTH OF THE CURSOR
- Y_SIZE EQU 32 ; TWICE THE Y HEIGHT OF THE CURSOR
- X_HOT EQU 7 ; HORIZONTAL HOT SPOT FOR THE CURSOR
- Y_HOT EQU 7 ; VERTICAL HOT SPOT FOR THE CURSOR
- X_START DW ? ; THE X POSITION TO START THE ARRAY ON
- ;
- ; EACH BIT PLACE IN THE CURSOR ARRAY STANDS FOR A BYTE ON THE SCREEN
- ; IF THE BIT IS ON, THEN THAT BYTE ON THE SCREEN WILL BE INVERTED
- ; IF NOT, THEN THE BYTE WILL BE UNTOUCHED.
- ; THE NUMBER OF WORDS FOR THE CURSOR ARRAY, AND THE NUMBER OF BITS
- ; IN EACH IS CONTROLLED BY THE X_SIZE AND Y_SIZE VARIABLES.
- CURSOR LABEL WORD ; LABEL FOR THE BEGINNING OF THE CURSOR ARRAY
- DW 0000000000000000B
- DW 0000000000000000B
- DW 0000000110000000B
- DW 0000000110000000B
- DW 0000000110000000B
- DW 0000000110000000B
- DW 0000000110000000B
- DW 0011111111111100B
- DW 0011111111111100B
- DW 0000000110000000B
- DW 0000000110000000B
- DW 0000000110000000B
- DW 0000000110000000B
- DW 0000000110000000B
- DW 0000000000000000B
- DW 0000000000000000B
- ;
- ;
- ; Routine to make a cursor on the screen
- ; makecur9(x,y);
- ;
- MAKECUR9 PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
-
- MOV AX,[BP+X+2] ; GET THE Y VALUE TO MODIFY FOR THE HOT SPOT
- SUB AX,Y_HOT ; SUBTRACT THE HOT SPOT VALUE
- MOV [BP+X+2],AX ; REPLACE THE Y VALUE
-
- MOV AX,[BP+X] ; GET THE X VALUE TO MODIFY FOR THE HOT SPOT
- SUB AX,X_HOT ; SUBTRACT THE HOT SPOT VALUE
- MOV [BP+X],AX ; REPLACE THE X VALUE
-
- MOV X_START,0 ; INITIALIZE THE X_START TO BE IN THE 0 POSITION
- MOV SI,0 ; INITIALIZE THE Y COUNTER
- CURTOP:
- MOV AX,0C000H ; control regs
- MOV ES,AX
- MOV BX,[BP+X+2] ; GET LINE TO COPY SCREEN BACK ONTO
- CMP BX,0 ; CHECK FOR NEGATIVE COORDINATES
- JL CUREND ; IF NEGATIVE COORDINATES THEN JUMP TO END OF LOOP
- SETBANK
-
- MOV AX,0A000H ; data buffer
- MOV ES,AX
-
- MOV DX,X_START ; INITIALIZE THE X COUNTER
- MOV BX,CURSOR[SI] ; GET THE CURRENT CURSOR INFORMATION
- MOV CX,X_START ; GET THE INITIAL NUMBER OF BITS TO SHIFT THE ARRAY
- SHL BX,CL ; SHIFT THE ARRAY THAT MANY BYTES
- TRYAGAIN:
- MOV AX,[BP+X] ; GET THE X POSITION
- CMP AX,0 ; CHECK FOR NEGATIVE POSITION
- JGE OKFINE ; NOT A NEGATIVE VALUE
- INC WORD PTR [BP+X] ; INCREMENT THE X POSITION
- INC DX ; AND THE POSITION IN THE ARRAY
- INC WORD PTR X_START ; INCREMENT THE POSITION TO START IN THE ARRAY FOR NEXT LOOP THRU
- SHL BX,1 ; GET RID OF A BIT OF THE CURSOR INFORMATION
- JMP TRYAGAIN ; JUMP BACK TO TRY FOR ANOTHER X POSITION
- OKFINE:
- MOV AX,[BP+X+2] ; get y value again
- MOV CL,9
- SHL AX,CL ; get 16 bit pointer for this bank
- ADD AX,[BP+X] ; ADD IN THE X OFFSET
- MOV DI,AX ; prepare for movs
-
- LOOPTOP:
- SHL BX,1 ; GET THE BIT FOR THIS CURSOR POSITION
- JNC LOOPBOT ; IF IT NOT SET THEN JUMP TO BOTTOM OF LOOP
- MOV AL,ES:[DI] ; GET THE BYTE TO INVERT
- NOT AL ; INVERT THE BYTE
- MOV ES:[DI],AL ; REPLACE THE INVERTED BYTE
- LOOPBOT:
- INC DI ; INCREMENT FOR NEXT BYTE ON THE SCREEN
- INC DX ; INCREMENT THE POSITION IN THE ARRAY
- CMP DX,X_SIZE ; CHECK TO SEE IF THE END OF THE LINE HAS BEEN FOUND
- JNE LOOPTOP ; IF NOT END THEN JUMP TO BEGINNING OF THE LOOP
-
- CUREND:
- INC WORD PTR [BP+X+2] ; INCREMENT Y VALUE FOR THE NEXT LINE
- INC SI ; INCREMENT THE Y POSITION IN THE ARRAY
- INC SI
- CMP SI,Y_SIZE ; CHECK TO SEE IF THE BOOTOM OF THE ARRAY HAS BEEN REACHED
- JE KLUDGE ; JUMP AROUND JUMP BACK IF AT END
- JMP CURTOP ; IF NOT THEN JUMP TO BEGINNING OF A NEW LINE
- KLUDGE:
-
- POP ES
- POP DS
- POP BP
- RET
- MAKECUR9 ENDP
-
- ENDPS
- END
-