-- svga.e -- faster routines for pixel manipulation in Euphoria -- by Pete Eberlein -- Feb 16, 1998 include machine.e integer bank_start, bytes_per_line, bank_granularity bank_start = 0 constant bank_proc = allocate(17) constant bank_regs = allocate(#32) -- Offset Size Description (Table 2819) -- 00h DWORD EDI -- 04h DWORD ESI -- 08h DWORD EBP -- 0Ch DWORD reserved (00h) -- 10h DWORD EBX -- 14h DWORD EDX -- 18h DWORD ECX -- 1Ch DWORD EAX -- 20h WORD flags -- 22h WORD ES -- 24h WORD DS -- 26h WORD FS -- 28h WORD GS -- 2Ah WORD IP -- 2Ch WORD CS -- 2Eh WORD SP -- 30h WORD SS 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 poke4(bank_regs + #14, floor(offset / bank_granularity)) bank_start = peek4u(bank_regs + #14) * bank_granularity call(bank_proc) 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 poke4(bank_regs + #14, floor(offset / bank_granularity)) bank_start = peek4u(bank_regs + #14) * bank_granularity call(bank_proc) 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 poke4(bank_regs + #14, floor(offset / bank_granularity)) bank_start = peek4u(bank_regs + #14) * bank_granularity call(bank_proc) end if return peek({#A0000 + offset - bank_start, p[3]}) end if end function global function svga_mode(integer mode) atom data, win_func_ptr sequence regs regs = repeat(0,10) data = allocate_low(256) regs[REG_AX] = #4F02 regs[REG_BX] = mode regs = dos_interrupt(#10, regs) if regs[REG_AX] != #4F or data = 0 then poke(bank_proc, #C3) -- ret return 1 end if 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 = peek4u(data+12) free_low(data) poke4(bank_regs + #2A, win_func_ptr) -- CS:IP poke4(bank_regs + #10, 0) -- BX poke4(bank_regs + #14, 1) -- DX poke(bank_proc, {#60, -- pusha #B8,#02,#FF,#00,#00, -- mov eax, #FF02 #1E, -- push ds #07, -- pop es #BF}&int_to_bytes(bank_regs)&{ -- mov edi, bank_regs #CD,#31, -- int #31 #61, -- popa #C3}) -- ret return 0 end function global constant wait_retrace = allocate(20) poke(wait_retrace, { #50, -- PUSH EAX #52, -- PUSH EDX #BA,#DA,3,0,0,-- MOV EDX, 0x03DA #EC, -- IN AL, DX #24,#08, -- AND AL, 0x08 #75,#FB, -- JNZ -5 #EC, -- IN AL, DX #24,#08, -- AND AL, 0x08 #74,#FB, -- JZ -5 #5A, -- POP EDX #58, -- POP EAX #C3 } ) -- RET