1. ememcopy.e update
- Posted by Michael Bolin <michaeltom at GEOCITIES.COM> May 28, 1998
- 693 views
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
- 688 views
- 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 ---------------------------------------------------------------------