Re: Faster pixel() in SVGA

new topic     » goto parent     » topic index » view thread      » older message » newer message

Lee woo seob wrote:
> I timed Pete's faster SVGA routine (display_image()) with my 486-66 machine.

Thanks, I hadn't got around to doing that.  Notice that random pixels
are not a whole lot faster than in Euphoria, but pixels that are drawn
closely in descending order are much faster.

> Pete's is faster, however, Euphoria's built-in do perform screen edge
> clipping, whereas the Pete's does'nt...
> and one more, when Pete's routine is used in my computer, a few(2 or 3)
> pixel-image lines were blackened in the middle of the runs of pixels.

That blackening is unusual.  Send me any test programs you write.

> Bye! from Lee woo seob

BABOR, JIRI wrote:
> Pete, every time I try to run your demo on my 486-66 in win95 dos window, it c
raps out
> with: A fatal exception 0D has occurred at 5453:00004406. Any ideas? Jiri

I had this happen to me once.  Has anyone else encountered this error?
I'm not sure if it's a problem with calling the vesa interrupt or
writing directly to video memory.  There is absolutely no bounds
checking or error handling, so bad data results in very bad output or
worse.  There is also a way to call the set_window_func directly,
instead of calling an interrupt, but I haven't messed around with that
yet.  It might be a little faster but I doubt it's worth the effort in
machine coding.

I also discovered that my display_image is practically the same as the
one in image.e, so my display_image procedure is unneccessary.  If I had
taken the time to look, I would have realized that display_image calls
the new pixel procedure as long as it's redefined before including
image.e.  Display_image is already optimized for the new pixel procedure
because it draws the image in a top-down fashion.

I've also noticed that using some other graphics functions in
conjunction with the modified pixel exhibits some peculiar behavior.
Text written to the screen and lines often appear in the wrong position
as well as some other undesired effects.  Apparently the graphics
library Euphoria uses expects the bank to always be reset to 0 after
each graphics procedure.  This is exactly what I was trying to avoid, so
that the bank would not have to be selected through an interrupt quite
as often.

Other enhancements might be a routine that works like Michael Bolins
extended mem copy as Ralf suggested.  I've added a complimentary
get_pixel function and a svga_mode function that should be used in place
of graphics_mode so that I still can get the necessary info on the mode.

---- code begins ----
-- svga.e
-- faster routines for SVGA pixel manipulation in Euphoria
-- by Pete Eberlein <xseal at harborside.com>

include machine.e
include graphics.e

sequence regs, dummy
integer bank_start, bytes_per_line, bank_granularity
atom win_func_ptr
bank_start = 0
regs = repeat(0, 10)
regs[REG_AX] = #4F05
regs[REG_BX] = #0000

global procedure pixel(object data, sequence p)
    integer offset, len
    if atom(data) then
        len = 1
    else
        len = length(data)
    end if
    offset = p[2] * bytes_per_line + p[1]
    if offset < bank_start or offset + len > bank_start + 65536 then
        regs[REG_DX] = floor(offset / bank_granularity)
        dummy = dos_interrupt(#10, regs)
        bank_start = regs[REG_DX] * bank_granularity
    end if
    poke(#A0000 + offset - bank_start, data)
end procedure

global function get_pixel(sequence p)
    integer offset
    offset = p[2] * bytes_per_line + p[1]
    if length(p) = 2 then
        if offset < bank_start or offset > bank_start + 65535 then
            regs[REG_DX] = floor(offset / bank_granularity)
            dummy = dos_interrupt(#10, regs)
            bank_start = regs[REG_DX] * bank_granularity
        end if
        return peek(#A0000 + offset - bank_start)
    elsif length(p) = 3 then
        if offset < bank_start or offset + p[3] > bank_start + 65536
then
            regs[REG_DX] = floor(offset / bank_granularity)
            dummy = dos_interrupt(#10, regs)
            bank_start = regs[REG_DX] * bank_granularity
        end if
        return peek({#A0000 + offset - bank_start, p[3]})
    end if
end function

global function svga_mode(integer mode)
    atom data
    sequence regs
    regs = repeat(0,10)
    data = allocate_low(256)
    if data then
        regs[REG_AX] = #4F01
        regs[REG_CX] = mode
        regs[REG_ES] = floor(data / 16)
        regs[REG_DI] = and_bits(data, 15)
        regs = dos_interrupt(#10, regs)
        bank_granularity = (peek(data + 4) + 256 * peek(data + 5)) *
1024
        bytes_per_line = peek(data + #10) + 256 * peek(data + #11)
        win_func_ptr = bytes_to_int(peek({data+12, 4}))
        free_low(data)
    end if
    return graphics_mode(mode) or (data = 0) or (regs[REG_AX] != #4F)
end function
---- code ends ----

Pete Eberlein <xseal at harborside.com>

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu