home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mega CD-ROM 1
/
megacd_rom_1.zip
/
megacd_rom_1
/
MAGAZINE
/
PROGJOUR
/
PJ_9_4.ZIP
/
CEGDAC.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-04-15
|
13KB
|
300 lines
; Assembly routines for Edsun CEG/DAC animation program.
SCREEN_SEGMENT equ 0a000h
SCREEN_WIDTH equ 320
SCREEN_HEIGHT equ 200
; Draws a frame around the screen, drawing the top scan line of the
; frame in color StartColor, the next in color StartColor+1, and so on
; up through color 190, then jumping to color 224 and continuing to
; color 255, and back around to color StartColor if the screen has
; that many scan lines.
;
; C near callable as: void DrawFrame(int StartColor, int FrameWidth);
;
; All assembly code tested with TASM 2.
parms struc
dw 2 dup (?) ;pushed BP & return address
StartColor dw ? ;color of first scan line
FrameWidth dw ? ;width of frame
parms ends
; Macro to advance to the next color, going from StartColor to 190,
; then to 224 up through 255, and then back to StartColor.
CYCLE_COLOR macro
local NoTurnover,CycleColorDone
inc al ;advance the color
jnz NoTurnover ;didn't turn over from 255 to 0
mov al,byte ptr StartColor[bp] ;did turn over; force to
jmp CycleColorDone ; StartColor
NoTurnover:
cmp al,191 ;time to jump to second block?
jnz CycleColorDone ;no, the color is fine as is
mov al,224 ;yes, jump to first color in 2nd block
CycleColorDone:
endm
.model small
.code
public _DrawFrame
_DrawFrame proc near
push bp ;preserve caller's stack frame
mov bp,sp ;point to local stack frame
push si ;preserve caller's register variables
push di
cld
mov ax,SCREEN_SEGMENT
mov es,ax
sub di,di ;point to the first byte of the frame
mov al,byte ptr StartColor[bp] ;initial color
; First, draw the top of the frame.
mov dx,FrameWidth[bp] ;height of top part of frame
mov bx,SCREEN_WIDTH ;# of bytes per scan line
DrawTopLoop:
mov cx,bx
rep stosb ;draw one scan line of the frame top
CYCLE_COLOR ;advance to the next color
dec dx ;count down frame top scan lines
jnz DrawTopLoop
; Next, draw the sides of the frame.
mov cx,FrameWidth[bp]
mov si,cx ;SI = FrameWidth for later
add cx,cx ;FrameWidth * 2
mov dx,SCREEN_HEIGHT ;height of entire frame
sub dx,cx ;height of sides =
; SCREEN_HEIGHT - (FrameWidth * 2)
sub bx,cx ;distance from one side to other =
; SCREEN_WIDTH - (FrameWidth * 2)
DrawSidesLoop:
mov cx,si ;width of each side = FrameWidth
rep stosb ;draw one scan line of the left side
add di,bx ;point to the start of the right side
mov cx,si ;width of each side = FrameWidth
rep stosb ;draw one scan line of the right side
CYCLE_COLOR ;advance to the next color
dec dx ;count down frame top scan lines
jnz DrawSidesLoop
; Finally, draw the bottom of the frame.
mov bx,SCREEN_WIDTH ;# of bytes per scan line
DrawBottomLoop:
mov cx,bx
rep stosb ;draw one scan line of frame bottom
CYCLE_COLOR ;advance to the next color
dec si ;count down frame bottom scan lines
jnz DrawBottomLoop
pop di ;restore caller's register variables
pop si
pop bp ;restore caller's stack frame
ret
_DrawFrame endp
; Sets the 5 rightmost pixels on each scan line to perform an EDP load
; of the corresponding element from AttributeSettings to the DAC
; register specified by DACRegisterToLoad. (Every scan line reloads
; DACRegisterToLoad.) Stores each EDP sequence in display memory in
; this order: DAC register #, the EDP opcode, and finally RGB color to
; load, in order to avoid accidentally loading the wrong DAC register
; if those bytes happen to be scanned just as the EDP sequence is
; half-written to memory.
;
; C near-callable as: SetEDPAtRight(int DACRegisterToLoad,
; RGB* AttributeSettings, int FirstEntryToSet, int LastEntry);
SEARparms struc
dw 2 dup (?) ;pushed BP & return address
DACRegisterToLoad dw ? ;DAC register to perform EDP load to
AttributeSettings dw ? ;palette value table to load from
; (array of RGB triplets)
FirstEntryToSet dw ? ;# of first entry in AttributeSettings
; from which to load
LastEntry dw ? ;# of last entry in AttributeSettings
SEARparms ends
public _SetEDPAtRight
_SetEDPAtRight proc near
push bp ;preserve caller's stack frame
mov bp,sp ;point to local stack frame
push si ;preserve caller's register variables
push di
cld
mov ax,SCREEN_SEGMENT
mov es,ax
mov di,SCREEN_WIDTH-5 ;point to the first byte at which to
; store EDP sequence on scan line 0
mov si,FirstEntryToSet[bp]
add si,si ;first entry index * 2
add si,FirstEntryToSet[bp] ;first entry index * 3
mov cx,AttributeSettings[bp]
add si,cx ;point to first entry to load
mov bx,LastEntry[bp]
add bx,bx ;last entry index * 2
add bx,LastEntry[bp] ;last entry index * 3
add bx,cx ;point to byte after last entry to load
mov ah,byte ptr DACRegisterToLoad[bp] ;DAC reg to load
mov cx,SCREEN_HEIGHT ;put one EDP sequence on each line
SetEDPLoop:
mov es:[di+4],ah ;set the # of the DAC register to load
mov al,191 ;EDP opcode
stosb ;put EDP opcode in bitmap
movsb ;copy over the RGB value to load with
movsb ; this EDP opcode
movsb
add di,SCREEN_WIDTH-4 ;point to the first byte of the EDP
; sequence on the next scan line
cmp si,bx ;have we wrapped off the end of the
; attribute array?
jb EDPLoopBottom ;no
mov si,AttributeSettings[bp] ;point to start of attr array
EDPLoopBottom:
loop SetEDPLoop
pop di ;restore caller's register variables
pop si
pop bp ;restore caller's stack frame
ret
_SetEDPAtRight endp
; Fills the rectangle from (StartX,StartY) to (EndX-1,EndY-1); the row
; at EndY and the column at EndX are not drawn. No clipping or error
; checking is performed.
;
; C near-callable as: FillRect(int StartX, int StartY, int EndX,
; int EndY, int FillColor);
FRparms struc
dw 2 dup (?) ;pushed BP & return address
StartX dw ? ;left edge of fill rect
StartY dw ? ;top edge of fill rect
EndX dw ? ;right edge of fill rect + 1
EndY dw ? ;bottom edge of fill rect + 1
FillColor dw ? ;color with which to fill rect
FRparms ends
public _FillRect
_FillRect proc near
push bp ;preserve caller's stack frame
mov bp,sp ;point to local stack frame
push si ;preserve caller's register variables
push di
cld
mov ax,SCREEN_SEGMENT
mov es,ax
mov bx,SCREEN_WIDTH
mov ax,StartY[bp]
mov si,EndY[bp]
sub si,ax ;# of scan lines to fill
mul bx ;start of top scan line of rect
mov dx,EndX[bp]
mov di,StartX[bp]
sub dx,di ;# of bytes across rect
add di,ax ;ES:DI = upper left byte of rect
sub bx,dx ;distance from end of one rect scan
; line to start of next
mov al,byte ptr FillColor[bp] ;color with which to fill
FillLoop:
mov cx,dx ;# of bytes across
rep stosb ;fill one scan line
add di,bx ;point to start of next line to fill
dec si ;count off scan lines
jnz FillLoop
pop di ;restore caller's register variables
pop si
pop bp ;restore caller's stack frame
ret
_FillRect endp
; Copies the image pointed to by ImagePtr with the upper left corner
; at (StartX,StartY). No clipping or error checking is performed.
;
; C near-callable as: DrawImage(int StartX, int StartY,
; Image* ImagePtr);
DIparms struc
dw 2 dup (?) ;pushed BP & return address
DIStartX dw ? ;left edge of block destination
DIStartY dw ? ;top edge of block destination
ImagePtr dw ? ;pointer to Image struc to draw
DIparms ends
Image struc
Width dw ?
Height dw ?
PixMap dw ?
Image ends
public _DrawImage
_DrawImage proc near
push bp ;preserve caller's stack frame
mov bp,sp ;point to local stack frame
push si ;preserve caller's register variables
push di
cld
mov ax,SCREEN_SEGMENT
mov es,ax
mov ax,SCREEN_WIDTH
mul DIStartY[bp] ;start of top scan line of rect
add ax,DIStartX[bp]
mov di,ax ;ES:DI = upper left byte of rect
mov si,ImagePtr[bp] ;point to Image struc to draw
mov dx,[si].Width ;# of bytes across rect to draw
mov ax,[si].Height ;# of scan lines to copy
mov si,[si].PixMap ;image bytes to copy
mov bx,SCREEN_WIDTH
sub bx,dx ;distance from end of one rect scan
; line to start of next
CopyLoop:
mov cx,dx ;# of bytes across
rep movsb ;copy one scan line
add di,bx ;point to next line to copy to
dec ax ;count off scan lines
jnz CopyLoop
pop di ;restore caller's register variables
pop si
pop bp ;restore caller's stack frame
ret
_DrawImage endp
; Puts the EDP sequence that loads the specified RGB color into the
; specified DAC register (that is, palette location, changing the
; color of the corresponding attribute) in the second through sixth
; pixels of the specified scan lines. Like SetEDPAtRight, stores EDP
; sequences in DAC register #/EDP opcode/RGB order to avoid
; accidentally loading the wrong palette register by chance timing.
;
; C near-callable as: SetEDPAtLeft(int Attribute, int Red, int Green,
; int Blue, int ScanLine);
SEALparms struc
dw 2 dup (?) ;pushed BP & return address
Attribute dw ? ;DAC register to load (attribute for which to
; change color)
Red dw ? ;red component to load
Green dw ? ;green component to load
Blue dw ? ;blue component to load
ScanLine dw ? ;scan line at start of which to put EDP load
SEALparms ends
public _SetEDPAtLeft
_SetEDPAtLeft proc near
push bp ;preserve caller's stack frame
mov bp,sp ;point to local stack frame
mov ax,SCREEN_SEGMENT
mov es,ax
mov ax,SCREEN_WIDTH
mul ScanLine[bp] ;start of scan line on which to load
mov bx,ax ;ES:BX = start of scan line
mov al,byte ptr Attribute[bp]
mov es:[bx+5],al ;DAC register to load
mov es:byte ptr [bx+1],191 ;EDP opcode
mov al,byte ptr Red[bp]
mov es:[bx+2],al ;new red value
mov al,byte ptr Green[bp]
mov es:[bx+3],al ;new green value
mov al,byte ptr Blue[bp]
mov es:[bx+4],al ;new blue value
pop bp ;restore caller's stack frame
ret
_SetEDPAtLeft endp
end