1. ememcopy.e update
Hi all,
Here's the newest update to ememcopy.e, containing a bug fix
and a new routine several people have requested - the ability to
change the mask color, previously always zero. It's called like
this:
set_mask_color(KIND, COLOR) where KIND is the type (2 or 3) of the
two display methods that use masks, and COLOR is the new mask
color. (!)
BTW, I'm considering a few additions and will add them if
anybody is interested and says so: writing a documentation file
describing all the features, and adding a routine for true-collision
detection between two objects (not just bounding-box detection, but
pixel-overlap.) If anybody would like these, please reply.
Regards,
Michael Bolin
-------------------------------- start ememcopy.e
include machine.e
sequence code
atom copy_address,single_ad
global function set_up_emc()
copy_address=allocate(length(code))
if copy_address=0 then
return 0
end if
single_ad=allocate(26)
if single_ad then
poke(copy_address,code)
poke(single_ad,repeat(0,26))
return 1
else
free(copy_address)
return 0
end if
end function
global procedure set_emc_address(atom address)
poke4(copy_address+2,address)
end procedure
global procedure e_mem_copy()
call(copy_address)
end procedure
global procedure se_mem_copy(integer kind,atom src,atom dest,atom width,
atom height,atom src_add,atom dest_add)
poke4(copy_address+2,single_ad) -- set data address
poke(single_ad,kind)
poke4(single_ad+1,{src,dest,width,height,src_add,dest_add})
call(copy_address)
end procedure
global procedure set_mask_color(integer kind,integer color)
if kind=2 then
poke(copy_address+332,color)
poke(copy_address+373,color)
elsif kind=3 then
poke(copy_address+416,color)
poke(copy_address+457,color)
end if
end procedure
code={
#60,#B8,#00,#00,#00,#00,#8A,#18,#80,#FB,#00,#74,#45,#50,#8B,#50,#05,
#8B,#48,#09,#89,#0D,#2A,#02,#00,#00,#8B,#48,#0D,#89,#0D,#2E,#02,#00,
#00,#8B,#48,#11,#89,#0D,#32,#02,#00,#00,#8B,#48,#15,#89,#0D,#36,#02,
#00,#00,#8B,#40,#01,#80,#FB,#01,#74,#17,#80,#FB,#02,#74,#22,#E8,#47,
#01,#00,#00,#58,#05,#19,#00,#00,#00,#E9,#B4,#FF,#FF,#FF,#61,#C3,#E8,
#1B,#00,#00,#00,#58,#05,#19,#00,#00,#00,#E9,#A2,#FF,#FF,#FF,#E8,#CE,
#00,#00,#00,#58,#05,#19,#00,#00,#00,#E9,#92,#FF,#FF,#FF,#8B,#2D,#2E,
#02,#00,#00,#39,#D0,#7C,#4C,#8B,#0D,#2A,#02,#00,#00,#81,#F9,#04,#00,
#00,#00,#7C,#23,#81,#E9,#04,#00,#00,#00,#8B,#18,#05,#04,#00,#00,#00,
#89,#1A,#81,#C2,#04,#00,#00,#00,#81,#E9,#04,#00,#00,#00,#79,#E9,#81,
#C1,#04,#00,#00,#00,#74,#09,#8A,#18,#40,#88,#1A,#42,#49,#75,#F7,#03,
#05,#32,#02,#00,#00,#03,#15,#36,#02,#00,#00,#4D,#75,#B5,#C3,#E8,#16,
#01,#00,#00,#2D,#03,#00,#00,#00,#81,#EA,#03,#00,#00,#00,#8B,#0D,#2A,
#02,#00,#00,#81,#F9,#04,#00,#00,#00,#7C,#23,#81,#E9,#04,#00,#00,#00,
#8B,#18,#2D,#04,#00,#00,#00,#89,#1A,#81,#EA,#04,#00,#00,#00,#81,#E9,
#04,#00,#00,#00,#79,#E9,#81,#C1,#04,#00,#00,#00,#05,#03,#00,#00,#00,
#81,#C2,#03,#00,#00,#00,#81,#F9,#00,#00,#00,#00,#74,#09,#8A,#18,#48,
#88,#1A,#4A,#49,#75,#F7,#2B,#05,#32,#02,#00,#00,#2B,#15,#36,#02,#00,
#00,#4D,#75,#99,#C3,#8B,#2D,#2E,#02,#00,#00,#39,#D0,#7C,#24,#8B,#0D,
#2A,#02,#00,#00,#8A,#18,#40,
#80,#FB,#00, -- cmp bl,0 : 332
#74,#02,#88,#1A,#42,#49,#75,
#F2,#03,#05,#32,#02,#00,#00,#03,#15,#36,#02,#00,#00,#4D,#75,#DD,#C3,
#E8,#7B,#00,#00,#00,#8B,#0D,#2A,#02,#00,#00,#8A,#18,#48,
#80,#FB,#00, -- cmp bl,0 : 373
#74,#02,#88,#1A,#4A,#49,#75,#F2,#2B,#05,#32,#02,#00,#00,#2B,#15,#36,
#02,#00,#00,#4D,#75,#DD,#C3,#8B,#2D,#2E,#02,#00,#00,#39,#D0,#7C,#24,
#8B,#0D,#2A,#02,#00,#00,
#80,#3A,#00, -- cmp byte [edx],0 : 416
#75,#04,#8A,#18,#88,#1A,#42,#40,
#49,#75,#F2,#03,#05,#32,#02,#00,#00,#03,#15,#36,#02,#00,#00,#4D,#75,
#DD,#C3,#E8,#24,#00,#00,#00,#8B,#0D,#2A,#02,#00,#00,
#80,#3A,#00, -- cmp byte [edx],0 : 457
#75,#04,#8A,#18,#88,#1A,#4A,#48,#49,#75,#F2,#2B,#05,#32,#02,#00,#00,#2B,
#15,#36,#02,#00,#00,#4D,#75,#DD,#C3,#89,#C6,#A1,#2A,#02,#00,#00,#03,
#05,#32,#02,#00,#00,#8B,#3D,#2E,#02,#00,#00,#4F,#52,#F7,#E7,#5A,#03,
#05,#2A,#02,#00,#00,#48,#01,#F0,#50,#A1,#2A,#02,#00,#00,#03,#05,#36,
#02,#00,#00,#8B,#3D,#2E,#02,#00,#00,#4F,#52,#F7,#E7,#5A,#03,#05,#2A,
#02,#00,#00,#48,#01,#D0,#89,#C2,#58,#C3,#00,#00,#00,#00,#00,#00,#00,
#00,#00,#00,#00,#00,#00,#00,#00,#00
}
include graphics.e
object temp
sequence regs,bank_lines,address_lines
integer buffer,granularity,gran_multiply,x_size,y_size
buffer=allocate_low(256)
if buffer=0 then
puts(1,"Could not allocate memory!")
abort(1)
end if
regs=repeat(0,10)
global function set_svga_mode(integer mode)
integer split
if mode<256 or mode>263 then
return 1
end if
regs[REG_AX]=#4F01
regs[REG_CX]=mode
regs[REG_ES]=floor(buffer/16)
regs[REG_DI]=and_bits(buffer,15)
regs=dos_interrupt(#10,regs)
granularity=peek(buffer+4)+peek(buffer+5)*256
if granularity=0 or granularity>64 then
return 1
end if
if graphics_mode(mode) then
return 1
end if
clear_screen()
gran_multiply=64/granularity
temp={640,640,800,800,1024,1024,1280,1280}
x_size=temp[mode-255]
temp={400,480,600,600,768,768,1024,1024}
y_size=temp[mode-255]
bank_lines={}
address_lines={}
for t=0 to x_size*y_size-1 by x_size do
temp=floor(t/65535)
if temp!=floor((t+x_size-1)/65535) then
split=65536-and_bits(t,65535)
bank_lines=append(bank_lines,-split)
split=split+32768
else
split=temp*gran_multiply
bank_lines=append(bank_lines,split)
end if
address_lines=append(address_lines,#A0000+t-temp*65536)
end for
bank_lines=append(bank_lines,0)
address_lines=append(address_lines,0)
return 0
end function
procedure set_bank(integer num)
regs[REG_AX]=#4F05
regs[REG_BX]=#0000
regs[REG_DX]=num
regs=dos_interrupt(#10,regs)
end procedure
global procedure display_svga_image(integer kind,atom source,sequence size,
sequence pos)
atom dest,start,start_line
integer width,c_bank,xpos,finish,flag,src_add,dest_add,o_width
integer split,max,min
width=size[1]
o_width=width
xpos=pos[1]
start_line=pos[2]
src_add=0
if start_line<0 then
source=source-width*start_line
size[2]=size[2]+start_line
if size[2]<1 then
return
end if
start_line=0
end if
if start_line>=y_size then
return
end if
if xpos<0 then
source=source-xpos
width=width+xpos
if width<1 then
return
end if
size[1]=width
src_add=-xpos
xpos=0
pos[1]=0
end if
max=xpos+width
if max>x_size then
width=width-(max-x_size)
if width<1 then
return
end if
size[1]=width
src_add=src_add+(max-x_size)
end if
c_bank=bank_lines[start_line+1]
if c_bank>=0 then
set_bank(c_bank)
else
c_bank=0
end if
start=source
finish=y_size+1
if start_line+size[2]+1<finish then
finish=start_line+size[2]+1
end if
flag=0
dest_add=x_size-width
for y=start_line+1 to finish do
if bank_lines[y]!=c_bank or y=finish then
if flag then
dest=address_lines[start_line+1]+xpos
max=y-start_line-1
if max<1 then
max=1
end if
se_mem_copy(kind,start,dest,width,max,src_add,dest_add)
end if
if bank_lines[y]<0 then
split=-bank_lines[y]
if xpos<split then
set_bank(bank_lines[y-1])
dest=address_lines[y]+xpos
min=split-xpos
if width<min then
min=width
end if
se_mem_copy(kind,source,dest,min,1,0,0)
end if
if xpos+width>split then
set_bank(bank_lines[y+1])
max=xpos-split
if max<0 then
max=0
end if
dest=#A0000+max
max=split-xpos
if max<0 then
max=0
end if
se_mem_copy(kind,source+max,dest,width-max,1,0,0)
end if
start=source+o_width
start_line=y
c_bank=bank_lines[y+1]
else
start=source
start_line=y-1
c_bank=bank_lines[y]
end if
set_bank(c_bank)
end if
source=source+o_width
pos[2]=y-1
flag=1
end for
set_bank(0)
end procedure
-------------------------------------------
2. ememcopy.e update
- Posted by Michael Bolin <michaeltom at GEOCITIES.COM>
Apr 19, 1998
-
Last edited Apr 20, 1998
Hi all,
Included with this message is the updated version of my
ememcopy.e. It is slightly faster than the original and includes two
new functions for VESA-compatible graphics cards (n.b. you must use
the use_vesa(1) command before calling these functions:
x = set_svga_mode(MODE) : this function is used just like the
ordinary graphics_mode() - returns 0 if success, 1 if failure. The
argument MODE should be the number of a SVGA graphics mode. This
function must be called before using the next procedure:
display_svga_image(KIND , SOURCE , {X_SIZE , Y_SIZE} ,
{X_POS , Y_POS })
KIND is just like for se_mem_copy(), i.e. 1, 2, or 3 for the three
different types of display. SOURCE is the address of the image to be
displayed, again like se_mem_copy(). X_SIZE and Y_SIZE are the width
and height of the image (what else?
, and the last two arguments
are the x/y coordinates for the display of the image. Clipping of
partially/completely off-screen images is handled automatically.
Regards,
Michael Bolin
--------------------- begin ememcopy.e ------------------------
include machine.e
sequence code
atom copy_address,single_ad
global function set_up_emc()
copy_address=allocate(length(code))
if copy_address=0 then
return 0
end if
single_ad=allocate(26)
if single_ad then
poke(copy_address,code)
poke(single_ad,repeat(0,26))
return 1
else
free(copy_address)
return 0
end if
end function
global procedure set_emc_address(atom address)
poke4(copy_address+2,address)
end procedure
global procedure e_mem_copy()
call(copy_address)
end procedure
global procedure se_mem_copy(integer kind,atom src,atom dest,atom width,
atom height,atom src_add,atom dest_add)
poke4(copy_address+2,single_ad) -- set data address
poke(single_ad,kind)
poke4(single_ad+1,{src,dest,width,height,src_add,dest_add})
call(copy_address)
end procedure
code={
#60,#B8,#00,#00,#00,#00,#8A,#18,#80,#FB,#00,#74,#45,#50,#8B,#50,#05,
#8B,#48,#09,#89,#0D,#2A,#02,#00,#00,#8B,#48,#0D,#89,#0D,#2E,#02,#00,
#00,#8B,#48,#11,#89,#0D,#32,#02,#00,#00,#8B,#48,#15,#89,#0D,#36,#02,
#00,#00,#8B,#40,#01,#80,#FB,#01,#74,#17,#80,#FB,#02,#74,#22,#E8,#47,
#01,#00,#00,#58,#05,#19,#00,#00,#00,#E9,#B4,#FF,#FF,#FF,#61,#C3,#E8,
#1B,#00,#00,#00,#58,#05,#19,#00,#00,#00,#E9,#A2,#FF,#FF,#FF,#E8,#CE,
#00,#00,#00,#58,#05,#19,#00,#00,#00,#E9,#92,#FF,#FF,#FF,#8B,#2D,#2E,
#02,#00,#00,#39,#D0,#7C,#4C,#8B,#0D,#2A,#02,#00,#00,#81,#F9,#04,#00,
#00,#00,#7C,#23,#81,#E9,#04,#00,#00,#00,#8B,#18,#05,#04,#00,#00,#00,
#89,#1A,#81,#C2,#04,#00,#00,#00,#81,#E9,#04,#00,#00,#00,#79,#E9,#81,
#C1,#04,#00,#00,#00,#74,#09,#8A,#18,#40,#88,#1A,#42,#49,#75,#F7,#03,
#05,#32,#02,#00,#00,#03,#15,#36,#02,#00,#00,#4D,#75,#B5,#C3,#E8,#16,
#01,#00,#00,#2D,#03,#00,#00,#00,#81,#EA,#03,#00,#00,#00,#8B,#0D,#2A,
#02,#00,#00,#81,#F9,#04,#00,#00,#00,#7C,#23,#81,#E9,#04,#00,#00,#00,
#8B,#18,#2D,#04,#00,#00,#00,#89,#1A,#81,#EA,#04,#00,#00,#00,#81,#E9,
#04,#00,#00,#00,#79,#E9,#81,#C1,#04,#00,#00,#00,#05,#03,#00,#00,#00,
#81,#C2,#03,#00,#00,#00,#81,#F9,#00,#00,#00,#00,#74,#09,#8A,#18,#48,
#88,#1A,#4A,#49,#75,#F7,#2B,#05,#32,#02,#00,#00,#2B,#15,#36,#02,#00,
#00,#4D,#75,#99,#C3,#8B,#2D,#2E,#02,#00,#00,#39,#D0,#7C,#24,#8B,#0D,
#2A,#02,#00,#00,#8A,#18,#40,#80,#FB,#00,#74,#02,#88,#1A,#42,#49,#75,
#F2,#03,#05,#32,#02,#00,#00,#03,#15,#36,#02,#00,#00,#4D,#75,#DD,#C3,
#E8,#7B,#00,#00,#00,#8B,#0D,#2A,#02,#00,#00,#8A,#18,#48,#80,#FB,#00,
#74,#02,#88,#1A,#4A,#49,#75,#F2,#2B,#05,#32,#02,#00,#00,#2B,#15,#36,
#02,#00,#00,#4D,#75,#DD,#C3,#8B,#2D,#2E,#02,#00,#00,#39,#D0,#7C,#24,
#8B,#0D,#2A,#02,#00,#00,#80,#3A,#00,#75,#04,#8A,#18,#88,#1A,#42,#40,
#49,#75,#F2,#03,#05,#32,#02,#00,#00,#03,#15,#36,#02,#00,#00,#4D,#75,
#DD,#C3,#E8,#24,#00,#00,#00,#8B,#0D,#2A,#02,#00,#00,#80,#3A,#00,#75,
#04,#8A,#18,#88,#1A,#4A,#48,#49,#75,#F2,#2B,#05,#32,#02,#00,#00,#2B,
#15,#36,#02,#00,#00,#4D,#75,#DD,#C3,#89,#C6,#A1,#2A,#02,#00,#00,#03,
#05,#32,#02,#00,#00,#8B,#3D,#2E,#02,#00,#00,#4F,#52,#F7,#E7,#5A,#03,
#05,#2A,#02,#00,#00,#48,#01,#F0,#50,#A1,#2A,#02,#00,#00,#03,#05,#36,
#02,#00,#00,#8B,#3D,#2E,#02,#00,#00,#4F,#52,#F7,#E7,#5A,#03,#05,#2A,
#02,#00,#00,#48,#01,#D0,#89,#C2,#58,#C3,#00,#00,#00,#00,#00,#00,#00,
#00,#00,#00,#00,#00,#00,#00,#00,#00
}
include graphics.e
object temp
sequence regs,bank_lines,address_lines
integer buffer,granularity,gran_multiply,x_size,y_size
buffer=allocate_low(256)
if buffer=0 then
puts(1,"Could not allocate memory!")
abort(1)
end if
regs=repeat(0,10)
global function set_svga_mode(integer mode)
integer split
if mode<256 or mode>263 then
return 1
end if
regs[REG_AX]=#4F01
regs[REG_CX]=mode
regs[REG_ES]=floor(buffer/16)
regs[REG_DI]=and_bits(buffer,15)
regs=dos_interrupt(#10,regs)
granularity=peek(buffer+4)+peek(buffer+5)*256
if granularity=0 or granularity>64 then
return 1
end if
if graphics_mode(mode) then
return 1
end if
clear_screen()
gran_multiply=64/granularity
temp={640,640,800,800,1024,1024,1280,1280}
x_size=temp[mode-255]
temp={400,480,600,600,768,768,1024,1024}
y_size=temp[mode-255]
bank_lines={}
address_lines={}
for t=0 to x_size*y_size-1 by x_size do
temp=floor(t/65535)
if temp!=floor((t+x_size-1)/65535) then
split=65536-and_bits(t,65535)
bank_lines=append(bank_lines,-split)
split=split+32768
else
split=temp*gran_multiply
bank_lines=append(bank_lines,split)
end if
address_lines=append(address_lines,#A0000+t-temp*65536)
end for
bank_lines=append(bank_lines,0)
address_lines=append(address_lines,0)
return 0
end function
procedure set_bank(integer num)
regs[REG_AX]=#4F05
regs[REG_BX]=#0000
regs[REG_DX]=num
regs=dos_interrupt(#10,regs)
end procedure
function max2(integer a,integer b)
if a>b then
return a
else
return b
end if
end function
function min2(integer a,integer b)
if a<b then
return a
else
return b
end if
end function
global procedure display_svga_image(integer kind,atom source,sequence size,
sequence pos)
atom dest,start,start_line
integer width,c_bank,xpos,finish,flag,src_add,dest_add,o_width
integer split
width=size[1]
o_width=width
xpos=pos[1]
start_line=pos[2]
src_add=0
if start_line<0 then
source=source-width*start_line
size[2]=size[2]+start_line
if size[2]<1 then
return
end if
start_line=0
end if
if start_line>=y_size then
return
end if
if xpos<0 then
source=source-xpos
width=width+xpos
if width<1 then
return
end if
size[1]=width
src_add=-xpos
xpos=0
pos[1]=0
end if
temp=xpos+width
if temp>x_size then
width=width-(temp-x_size)
if width<1 then
return
end if
size[1]=width
src_add=src_add+(temp-x_size)
end if
c_bank=bank_lines[start_line+1]
if c_bank>=0 then
set_bank(c_bank)
else
c_bank=0
end if
start=source
finish=min2(start_line+size[2],y_size)
flag=0
dest_add=x_size-width
for y=start_line+1 to finish do
if bank_lines[y]!=c_bank or y=finish then
if flag then
dest=address_lines[start_line+1]+xpos
se_mem_copy(kind,start,dest,width,max2(1,y-start_line-1),src_add,dest_add)
end if
if bank_lines[y]<0 then
split=-bank_lines[y]
if xpos<split then
set_bank(bank_lines[y-1])
dest=address_lines[y]+xpos
se_mem_copy(kind,source,dest,min2(width,split-xpos),1,0,0)
end if
if xpos+width>split then
set_bank(bank_lines[y+1])
dest=#A0000+max2(0,xpos-split)
temp=max2(0,split-xpos)
se_mem_copy(kind,source+temp,dest,width-temp,1,0,0)
end if
start=source+o_width
start_line=y
c_bank=bank_lines[y+1]
else
start=source
start_line=y-1
c_bank=bank_lines[y]
end if
set_bank(c_bank)
end if
source=source+o_width
pos[2]=y-1
flag=1
end for
set_bank(0)
end procedure
---------------------------------------------------------------------