|
25 Years of Programming
An open source source for C, C++, OWL, BASIC, MDB, XLS, DOT, and more... |
Home Projects Up Sitemap Search Blog Forum+Chat About Us Privacy Terms of Use Feedback FAQ Images Services Payments Humor Music |
Heathkit H-100 color graphics functions to get and set color pixels in DeSmet C and speed optimized assembly languageThis DeSmet C function directly reads and writes the Heathkit H-100 computer's video RAM planes to implement color getpixel and setpixel functionality. When setting pixels, there are 5 different available modes. After writing the function in C, I compiled it to 8088/8086 assembly language and then optimized it for speed. One example of the type of optimization that can be done is that the compiler loads a variable into a register every time it is used, even if the variable is already in that register left over from a previous operation. It has no way of knowing, but a human reviewing the code can remove duplicate operations of this type. Unless you want to make changes, you would ordinarily use the code listing from pset.a further down this page, rather than pset.c. DeSmet C can assemble pset.a into object code pset.o, which you then link with the other modules of your program. This function is used extensively by my DeSmet C color graphics programs for the H-100. |
/* ===========================================================*/
/* H100 COLOR GRAPHICS PRIMITIVES FOR PIXEL MANIPULATION */
/* ===========================================================*/
/* -> These functions are highly specific to the H100 computer hardware, */
/* -> and could have disastrous consequences on any other computer. */
/* -------------------------------------------------------------- */
/* PSET() 4-28-93 COLOR PIXEL-HANDLING ROUTINES FOR H100 COMPUTER */
/* Copyright (C)1993 Steven Whitney. Published under the */
/* GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY. */
/* Initially published by http://25yearsofprogramming.com. */
/* ==> THE SOURCE FOR PSET.O IS PSET.A, THE MODIFIED FROM OUTPUT FROM THIS FILE */
/* 0=BLACK 1=BLUE 2=RED 3=MAGENTA 4=GREEN 5=CYAN 6=YELLOW 7=WHITE */
/* ONLY RESPONDS TO 0-639 & 0-224, ERROR WON'T POKE INTO ILLEGAL MEMORY */
/* RETURNS: COLOR OF POINT AT (X,Y) FOR MODE 'S', OR 0 FOR THE OTHERS */
/* RETURNS ERR (-1) IF SCREEN OR COLOR RANGES EXCEEDED, OR ILLEGAL MODE */
/* 5-22-93 TEST BYTE BEFORE POKING, SPEED IMPROVEMENT */
/* 6-8-93 DOESN'T CHANGE OR RESTORE VIDEO PORT */
/* OPERATES WITHIN MODE CURRENTLY IN EFFECT IN CALLING PROGRAM */
/* 12-5-93 PSET NOW INCORPORATES ALL OF THE FOLLOWING FUNCTIONS: */
/* (ALL FUNCTIONS CALLING PSET CAN NOW USE THE FOLLOWING MODES) */
/* MODE: */
/* S POINT - JUST RETURN (SHOW) COLOR OF POINT AT (X,Y) */
/* P PSET - SET (X,Y) TO SPECIFIED COLOR */
/* O OPSET - PSET USING "OR" */
/* X XPSET - PSET USING "XOR" */
/* + - PSET TO COLOR VALUE 1 MORE THAN FOUND AT THE POINT, MAX=7 */
/* - - PSET TO 1 LESS THAN FOUND, MIN=0 */
/* R - PSET TO 1 MORE THAN FOUND, & (R)OTATE THROUGH 0-7,0-7, ETC. */
/* OTHERS CAN BE ADDED */
/* -------------------------------------------------------------- */
#define ERR (-1)
int pset(x,y,mode,color)
int x, y; /* SCREEN COORDINATES */
char mode; /* MUST BE LOWER CASE */
int color;
{
char *offset; /* POINTS AT BYTE IN VIDEO MEMORY */
char byte; /* CONTENTS OF BYTE AT OFFSET */
unsigned segment; /* POINTS AT COLOR PLANE */
char mask, notmask; /* USED TO TURN 1 BIT IN BYTE ON OR OFF */
char _peek();
void _poke();
/* TESTS FOR INVALID COLOR OR MODE IS IN SWITCHES BELOW */
if((x < 0) || (x > 639) || (y < 0) || (y > 224))
return(ERR);
offset = (char *)(((((y/9)*16)+(y%9))*128)+(x/8)); /* CALC ADDRESS */
mask = (0x80) >> (x%8); /* MASK FOR PIXEL BIT */
notmask = ~mask;
switch(mode)
{
case 'o': /* OPSET */
/* -------------------------------------------------------------- */
/* OPSET() 6-2-93 10-12-93 */
/* LIKE PSET, BUT DOES NOT TURN OFF PLANES NOT USED FOR SPECIFIFED COLOR */
/* IT MERELY TURNS ON THE PLANES THAT MAKE THAT COLOR */
/* IT WILL OVERLAY, BUT NOT DESTROY, WHATEVER IS ALREADY ON THE SCREEN */
/* -------------------------------------------------------------- */
switch(color)
{
case 0: /* BLACK = (MEANINGLESS) */
break;
case 1: /* BLUE */
_poke(_peek(offset,0xC000) | mask,offset,0xC000); /* BLUE ON */
break;
case 2: /* RED */
_poke(_peek(offset,0xD000) | mask,offset,0xD000); /* RED ON */
break;
case 3: /* MAGENTA = RED + BLUE */
_poke(_peek(offset,0xC000) | mask,offset,0xC000); /* BLUE ON */
_poke(_peek(offset,0xD000) | mask,offset,0xD000); /* RED ON */
break;
case 4: /* GREEN */
_poke(_peek(offset,0xE000) | mask,offset,0xE000); /* GREEN ON */
break;
case 5: /* CYAN = BLUE + GREEN */
_poke(_peek(offset,0xC000) | mask,offset,0xC000); /* BLUE ON */
_poke(_peek(offset,0xE000) | mask,offset,0xE000); /* GREEN ON */
break;
case 6: /* YELLOW = RED + GREEN */
_poke(_peek(offset,0xD000) | mask,offset,0xD000); /* RED ON */
_poke(_peek(offset,0xE000) | mask,offset,0xE000); /* GREEN ON */
break;
case 7: /* WHITE = RED + BLUE + GREEN */
_poke(_peek(offset,0xC000) | mask,offset,0xC000); /* BLUE ON */
_poke(_peek(offset,0xD000) | mask,offset,0xD000); /* RED ON */
_poke(_peek(offset,0xE000) | mask,offset,0xE000); /* GREEN ON */
break;
default: /* COLOR OUT OF RANGE 0-7 */
return(ERR);
} /* END SWITCH(COLOR) IN OPSET */
return(0); /* END OPSET */
case 'x': /* XPSET */
/* -------------------------------------------------------------- */
/* XPSET() 6-2-93 10-12-93 */
/* SAME AS PSET, BUT IT PERFORMS XOR ON THE PIXEL */
/* FOR USE IN ANIMATION, SINCE XPSET() WILL ALWAYS CHANGE STATE OF THE */
/* POINT (MAKING IMAGE STAND OUT), AND DOING IT AGAIN WILL RETURN */
/* THE POINT TO ITS ORIGINAL COLOR (BACKGROUND) */
/* EXAMPLES: */
/* IF POINT IS BLACK(0) XPSET() IN YELLOW(R+G) TOGGLES POINT BLACK/YELLOW */
/* IF POINT IS WHITE(RGB) XPSET() IN MAGENTA(RB) TOGGLES POINT WHITE/GREEN */
/* IF POINT IS MAGENTA(RB) XPSET() IN GREEN(G) TOGGLES POINT WHITE/MAGENTA */
/* -------------------------------------------------------------- */
/* TOGGLE THE BIT IN ALL PLANES USED FOR THE SPECIFIED COLOR. */
/* LEAVE ALONE ANY PLANES NOT USED. */
/* -------------------------------------------------------------- */
switch(color)
{
case 0: /* BLACK = LEAVE ALONE */
break;
case 1: /* BLUE */
_poke(_peek(offset,0xC000) ^ mask,offset,0xC000);
break;
case 2: /* RED */
_poke(_peek(offset,0xD000) ^ mask,offset,0xD000);
break;
case 3: /* MAGENTA = RED + BLUE */
_poke(_peek(offset,0xC000) ^ mask,offset,0xC000);
_poke(_peek(offset,0xD000) ^ mask,offset,0xD000);
break;
case 4: /* GREEN */
_poke(_peek(offset,0xE000) ^ mask,offset,0xE000);
break;
case 5: /* CYAN = BLUE + GREEN */
_poke(_peek(offset,0xC000) ^ mask,offset,0xC000);
_poke(_peek(offset,0xE000) ^ mask,offset,0xE000);
break;
case 6: /* YELLOW = RED + GREEN */
_poke(_peek(offset,0xD000) ^ mask,offset,0xD000);
_poke(_peek(offset,0xE000) ^ mask,offset,0xE000);
break;
case 7: /* WHITE = RED + BLUE + GREEN */
_poke(_peek(offset,0xC000) ^ mask,offset,0xC000);
_poke(_peek(offset,0xD000) ^ mask,offset,0xD000);
_poke(_peek(offset,0xE000) ^ mask,offset,0xE000);
break;
default:
return(ERR);
} /* END SWITCH(COLOR) IN XPSET */
return(0); /* COULD FALL THROUGH FOR COLOR */
case 'r': /* INCREASE COLOR & ROTATE */
case '-': /* DECREASE COLOR AT POINT */
case '+': /* INCREASE COLOR AT POINT */
case 's': /* RETURN COLOR OF POINT, FORMERLY POINT() */
color = 0;
if((_peek(offset,0xC000) & mask)) color += 1; /* EACH PLANE, IF ON */
if((_peek(offset,0xD000) & mask)) color += 2; /* ADDS A SET VALUE */
if((_peek(offset,0xE000) & mask)) color += 4; /* TO OVERALL COLOR */
switch(mode)
{
case 's': /* POINT() */
return(color);
case '+': /* INCREASE, MAX=7 */
if(++color > 7)
color = 7;
break;
case '-': /* DECREASE, MIN=0 */
if(--color < 0)
color = 0;
break;
case 'r': /* INCREASE, ROTATE */
if(++color > 7)
color = 0;
break;
}
/* ALL MODES EXCEPT 'S' FALL THROUGH TO */
case 'p': /* PSET */
/* -------------------------------------------------------------- */
/* FOR EACH COLOR, FIRST TURN OFF THE PIXEL IN ANY PLANES NOT USED */
/* FOR THAT COLOR, THEN SET EACH OF THE USED COLORS SEPARATELY. */
/* USING THE SIMULTANEOUS-WRITE BITS OF PORT D8 DOES NOT WORK */
/* BECAUSE IT AFFECTS ALL THE BITS OF THE BYTE WRITTEN OUT, */
/* INADVERTENTLY CHANGING THE COLORS OF NEIGHBORING PIXELS. */
/* 5-22-93 IF ENTIRE BYTE IS EMPTY (AS WILL OFTEN BE THE CASE), DON'T */
/* BOTHER WITH TURNING THE BIT OFF. IT ALREADY IS. */
/* -------------------------------------------------------------- */
switch(color)
{
case 0: /* BLACK = TURN PIXEL OFF */
if(byte = _peek(offset,0xC000))
_poke(byte & notmask,offset,0xC000); /* BLUE OFF */
if(byte = _peek(offset,0xD000))
_poke(byte & notmask,offset,0xD000); /* RED OFF */
if(byte = _peek(offset,0xE000))
_poke(byte & notmask,offset,0xE000); /* GREEN OFF */
break;
case 1: /* BLUE */
if(byte = _peek(offset,0xD000))
_poke(byte & notmask,offset,0xD000); /* RED OFF */
if(byte = _peek(offset,0xE000))
_poke(byte & notmask,offset,0xE000); /* GREEN OFF */
_poke(_peek(offset,0xC000) | mask,offset,0xC000); /* BLUE ON */
break;
case 2: /* RED */
if(byte = _peek(offset,0xC000))
_poke(byte & notmask,offset,0xC000); /* BLUE OFF */
if(byte = _peek(offset,0xE000))
_poke(byte & notmask,offset,0xE000); /* GREEN OFF */
_poke(_peek(offset,0xD000) | mask,offset,0xD000); /* RED ON */
break;
case 3: /* MAGENTA = RED + BLUE */
if(byte = _peek(offset,0xE000))
_poke(byte & notmask,offset,0xE000); /* GREEN OFF */
_poke(_peek(offset,0xC000) | mask,offset,0xC000); /* BLUE ON */
_poke(_peek(offset,0xD000) | mask,offset,0xD000); /* RED ON */
break;
case 4: /* GREEN */
if(byte = _peek(offset,0xC000))
_poke(byte & notmask,offset,0xC000); /* BLUE OFF */
if(byte = _peek(offset,0xD000))
_poke(byte & notmask,offset,0xD000); /* RED OFF */
_poke(_peek(offset,0xE000) | mask,offset,0xE000); /* GREEN ON */
break;
case 5: /* CYAN = BLUE + GREEN */
if(byte = _peek(offset,0xD000))
_poke(byte & notmask,offset,0xD000); /* RED OFF */
_poke(_peek(offset,0xC000) | mask,offset,0xC000); /* BLUE ON */
_poke(_peek(offset,0xE000) | mask,offset,0xE000); /* GREEN ON */
break;
case 6: /* YELLOW = RED + GREEN */
if(byte = _peek(offset,0xC000))
_poke(byte & notmask,offset,0xC000); /* BLUE OFF */
_poke(_peek(offset,0xD000) | mask,offset,0xD000); /* RED ON */
_poke(_peek(offset,0xE000) | mask,offset,0xE000); /* GREEN ON */
break;
case 7: /* WHITE = RED + BLUE + GREEN */
_poke(_peek(offset,0xC000) | mask,offset,0xC000); /* BLUE ON */
_poke(_peek(offset,0xD000) | mask,offset,0xD000); /* RED ON */
_poke(_peek(offset,0xE000) | mask,offset,0xE000); /* GREEN ON */
break;
default:
return(ERR);
} /* END SWITCH(COLOR) IN PSET OPTION */
return(0);
default:
return(ERR); /* INDICATES ILLEGAL MODE REQUESTED */
} /* END SWITCH(MODE) */
} /* END FUNCTION */
/* ===========================================================*/
/* ===========================================================*/
;pset.a 12-6-93 optimization of the assembler output from pset.c
;Copyright (C)1993 Steven Whitney. Published under the
;GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY.
;Initially published by http://25yearsofprogramming.com.
;This is MUCH faster. You assemble this into an object file and use this
;INSTEAD of compiling pset.c into an object file.
;If you revise pset.c, you only compile it into assembler, then optimize
;the output similarly to how I did it here.
;includes point, pset, opset, xpset & some new options (see pset.c)
;registers aren't preserved, but c doesn't seem to preserve them, either
;[bp + i] = passed parameters, pushed onto stack from right to left
;[bp - i] = local variables, pushed in order of declaration
CSEG
PUBLIC pset_
pset_:
PUSH BP ;save calling program's base pointer
MOV BP,SP ;save stack pointer to bp before we change sp
;bp will be reference point for all variables
SUB SP,8 ;make room for locals on stack
;test for x or y off screen
mov ax,[bp+4] ;x
cmp ax,0
JL _L2 ;return(ERR)
cmp ax,639
JG _L2
mov ax,[bp+6] ;y
cmp ax,0
JL _L2
cmp ax,224
JLE _L1
_L2: ;return(ERR)
MOV AX,-1
MOV SP,BP
POP BP
RET
_L1: ;calculate offset
MOV AX,WORD [BP+6]
CWD
MOV CX,9
IDIV CX
MOV CX,16
IMUL CX
MOV DI,AX
MOV AX,WORD [BP+6]
CWD
MOV CX,9
IDIV CX
ADD DI,DX
MOV AX,DI
MOV CX,128
IMUL CX
MOV CX,WORD [BP+4]
CWD
XOR AX,DX
SUB AX,DX
SAR CX,1
SAR CX,1
SAR CX,1
XOR AX,DX
SUB AX,DX
ADD AX,CX
MOV WORD [BP-2],AX ;offset calc. done (so store it)
MOV AX,WORD [BP+4] ;use x to calc. mask
CWD
MOV CX,8
IDIV CX
MOV CX,DX
MOV AL,128
SHR AL,CL
MOV BYTE [BP-7],AL ;mask calc. done (so store it)
NOT AL
MOV BYTE [BP-8],AL ;store notmask
MOV BL,BYTE [BP+8] ;use mode for switch()
MOV BH,0
PUBLIC _SWITCH ;this switch() method used when options not consecutive
CALL _SWITCH
DW 8 ;number of switch options below
;format = ascii value, jump address
DW 111,_L5 ;o
DW 120,_L6 ;x
DW 114,_L7 ;r
DW 45,_L8 ;-
DW 43,_L9 ;+
DW 115,_L10 ;s
DW 112,_L11 ;p
DW -32768,_L12 ;default (illegal)
_L5: ;case opset
MOV BX,WORD [BP+10] ;color in preparation for switch below
CMP BX,0 ;check for within range 0-7
JL _L23 ;return(ERR)
CMP BX,7
JG _L23
SHL BX,1 ;multiply by 2 to allow for word spacing below
mov di,[bp-2] ;offset will be used repeatedly
mov cl,[bp-7] ;mask, also
;this form of switch used when options are consecutive
JMP BYTE _L25[BX] ;switch(color)
_L25:
DW _L15 ;case 0
DW _L16 ;1
DW _L17 ;2
DW _L18 ;3
DW _L19 ;4
DW _L20 ;5
DW _L21 ;6
DW _L22 ;7
_L15: ;case black (meaningless)
JMP _L24 ;return(0)
_L16: ;case blue
mov bx,0c000h ;load extra segment
mov es,bx
or es:[di],cl ;directly or vram byte with mask
jmp _L24
_L17: ;case red
mov bx,0d000h
mov es,bx
or es:[di],cl
jmp _L24
_L18: ;case magenta
mov bx,0c000h ;blue
mov es,bx
or es:[di],cl
mov bx,0d000h ;red
mov es,bx
or es:[di],cl
jmp _L24
_L19: ;case green
mov bx,0e000h ;green
mov es,bx
or es:[di],cl
jmp _L24
_L20: ;case cyan = green + blue
mov bx,0c000h ;blue
mov es,bx
or es:[di],cl
mov bx,0e000h ;green
mov es,bx
or es:[di],cl
jmp _L24
_L21: ;case yellow = green + red
mov bx,0e000h ;green
mov es,bx
or es:[di],cl
mov bx,0d000h ;red
mov es,bx
or es:[di],cl
jmp _L24
_L22: ;case white
mov bx,0c000h ;blue
mov es,bx
or es:[di],cl
mov bx,0d000h ;red
mov es,bx
or es:[di],cl
mov bx,0e000h ;green
mov es,bx
or es:[di],cl
jmp _L24
_L23: ;return(ERR)
MOV AX,-1
MOV SP,BP
POP BP
RET
_L24: ;return(0)
XOR AX,AX
MOV SP,BP
POP BP
RET ;end opset
_L6: ;case xpset
MOV BX,WORD [BP+10] ;color
CMP BX,0 ;check for out of range
JL _L34 ;return(ERR)
CMP BX,7
JG _L34
SHL BX,1
mov di,[bp-2] ;offset will be used repeatedly
mov cl,[bp-7] ;mask, also
JMP BYTE _L36[BX] ;switch(color)
_L36:
DW _L26 ;0
DW _L27 ;1
DW _L28 ;2
DW _L29 ;3
DW _L30 ;4
DW _L31 ;5
DW _L32 ;6
DW _L33 ;7
_L26: ;case black (leave unchanged)
JMP _L35 ;return(0)
_L27: ;case blue
mov bx,0c000h ;blue
mov es,bx
xor es:[di],cl
jmp _L35
_L28: ;case red
mov bx,0d000h ;red
mov es,bx
xor es:[di],cl
jmp _L35
_L29: ;case magenta
mov bx,0c000h ;blue
mov es,bx
xor es:[di],cl
mov bx,0d000h ;red
mov es,bx
xor es:[di],cl
jmp _L35
_L30: ;case green
mov bx,0e000h ;green
mov es,bx
xor es:[di],cl
jmp _L35
_L31: ;case cyan = green + blue
mov bx,0e000h ;green
mov es,bx
xor es:[di],cl
mov bx,0c000h ;blue
mov es,bx
xor es:[di],cl
jmp _L35
_L32: ;case yellow = red + green
mov bx,0d000h ;red
mov es,bx
xor es:[di],cl
mov bx,0e000h ;green
mov es,bx
xor es:[di],cl
jmp _L35
_L33: ;case white
mov bx,0c000h ;blue
mov es,bx
xor es:[di],cl
mov bx,0d000h ;red
mov es,bx
xor es:[di],cl
mov bx,0e000h ;green
mov es,bx
xor es:[di],cl
jmp _L35
_L34: ;return(ERR)
MOV AX,-1
MOV SP,BP
POP BP
RET
_L35: ;return(0)
XOR AX,AX
MOV SP,BP
POP BP
RET ;end xpset
_L7: ;case 'r'
_L8: ;case '-'
_L9: ;case '+'
_L10: ;case 's' point()
xor ax,ax ;zero ax - will be used to accumulate color value
mov di,[bp-2] ;offset will be used repeatedly
mov cl,[bp-7] ;mask, also
mov bx,0c000h ;test if bit is on in blue plane
mov es,bx
test es:[di],cl ;logical and without changing operands
jz _L37
inc ax ;bit was on, so add 1 to color
_L37:
mov bx,0d000h ;red
mov es,bx
test es:[di],cl
jz _L38
add ax,2 ;red adds 2
_L38:
mov bx,0e000h ;green
mov es,bx
test es:[di],cl
jz _L39
add ax,4 ;green adds 4
_L39:
;at this point, ax contains the color value
cmp byte [bp+8],115 ;if mode is 's', just return it without storing
jne _L40
;note: c functions return their values in ax
MOV SP,BP ;return(color), which is already in ax
POP BP
RET
_L40:
mov [bp+10],ax ;now store color, since we'll need it later
MOV BL,BYTE [BP+8] ;switch(mode)
MOV BH,0
CALL _SWITCH
DW 4 ;number of possible options
DW 43,_L41 ;+
DW 45,_L42 ;-
DW 114,_L43 ;r
DW -32768,_L44 ;default (illegal)
_L41: ;case +
INC WORD [BP+10] ;if(++color > 7) then color = 7
CMP WORD [BP+10],7
JLE _L46
MOV WORD [BP+10],7
_L46:
JMP _L44 ;fall through to pset
_L42: ;case -
DEC WORD [BP+10] ;if(--color < 0) then color = 0
CMP WORD [BP+10],0
JGE _L47
MOV WORD [BP+10],0
_L47: ;fall through to pset
JMP _L44
_L43: ;case r(otate) through the colors
INC WORD [BP+10] ;if(++color > 7) then color = 0
CMP WORD [BP+10],7
JLE _L48
MOV WORD [BP+10],0
_L48: ;fall through to pset
_L44: ;default (illegal mode won't actually get this far)
_L11: ;case pset
MOV BX,WORD [BP+10] ;check for color out of allowable range
CMP BX,0
JL _L57 ;return(ERR)
CMP BX,7
JG _L57 ;return(ERR)
SHL BX,1
mov di,[bp-2] ;offset will be used repeatedly
mov cl,[bp-7] ;mask, also
mov al,[bp-8] ;notmask, also
JMP BYTE _L59[BX] ;switch(color)
_L59:
DW _L49 ;0
DW _L50 ;1
DW _L51 ;2
DW _L52 ;3
DW _L53 ;4
DW _L54 ;5
DW _L55 ;6
DW _L56 ;7
_L49: ;case black
mov bx,0c000h ;blue off
mov es,bx
and es:[di],al ;directly and with notmask
mov bx,0d000h ;red off
mov es,bx
and es:[di],al
mov bx,0e000h ;green off
mov es,bx
and es:[di],al
jmp _L58
_L50: ;case blue
mov bx,0d000h ;red off
mov es,bx
and es:[di],al
mov bx,0e000h ;green off
mov es,bx
and es:[di],al
mov bx,0c000h ;blue on
mov es,bx
or es:[di],cl ;directly or with mask
jmp _L58
_L51: ;case red
mov bx,0c000h ;blue off
mov es,bx
and es:[di],al
mov bx,0e000h ;green off
mov es,bx
and es:[di],al
mov bx,0d000h ;red on
mov es,bx
or es:[di],cl
jmp _L58
_L52: ;case magenta
mov bx,0e000h ;green off
mov es,bx
and es:[di],al
mov bx,0c000h ;blue on
mov es,bx
or es:[di],cl
mov bx,0d000h ;red on
mov es,bx
or es:[di],cl
jmp _L58
_L53: ;case green
mov bx,0c000h ;blue off
mov es,bx
and es:[di],al
mov bx,0d000h ;red off
mov es,bx
and es:[di],al
mov bx,0e000h ;green on
mov es,bx
or es:[di],cl
jmp _L58
_L54: ;case cyan = green + blue
mov bx,0d000h ;red off
mov es,bx
and es:[di],al
mov bx,0c000h ;blue on
mov es,bx
or es:[di],cl
mov bx,0e000h ;green on
mov es,bx
or es:[di],cl
jmp _L58
_L55: ;case yellow = green + red
mov bx,0c000h ;blue off
mov es,bx
and es:[di],al
mov bx,0d000h ;red on
mov es,bx
or es:[di],cl
mov bx,0e000h ;green on
mov es,bx
or es:[di],cl
jmp _L58
_L56: ;case white
mov bx,0c000h ;blue on
mov es,bx
or es:[di],cl
mov bx,0d000h ;red on
mov es,bx
or es:[di],cl
mov bx,0e000h ;green on
mov es,bx
or es:[di],cl
jmp _L58
_L57: ;return(ERR)
MOV AX,-1
MOV SP,BP
POP BP
RET
_L58: ;return(0)
XOR AX,AX
MOV SP,BP
POP BP
RET ;end pset
_L12: ;case default (illegal mode)
MOV AX,-1
MOV SP,BP
POP BP
RET
|
|
|
|
|
|
Copyright ©2011 Steven Whitney. Last modified Tue 05/24/2011 12:27:01 -0700. |
||