'=========================================================================== ' Subject: VESA ROUTINES W/BANK SWITCHING Date: 01-29-97 (21:29) ' Author: Nick Coons Code: QB, PDS ' Origin: FidoNet QUIK_BAS Echo Packet: GRAPHICS.ABC '=========================================================================== ' Well, I figured it was about time that I looked into the problem that 'you've been having with VESA and bank switching. So I did a few experiments 'and wrote some routines and they seem to work surprisingly well. I'll post 'the code first, then explain: ' *** BANK.BAS (01/29/97) ' *** SuperVGA VESA Routines using Bank ' *** Switching. ' *** Written By Nick Coons ' *** Based on Dave Shea's ' *** Pixel-plotting using Interrupts. ' *** Released To The Public Domain ' *** Description: ' *** A program that fills the screen ' *** with individual pixels using ' *** direct memory access in VESA ' *** Screen mode &H101 - 640x480x256. ' *** Define Default Variables DEFINT A-Z ' *** Declare Procedures DECLARE SUB Pixel (x%, y%, c%) DECLARE SUB ScreenMode (SM%) DECLARE SUB SwitchBank (NewBank%) ' *** Include Structures For Interrupts REM $INCLUDE: 'qb.bi' ' *** Dimension Variables DIM SHARED InRegs AS RegType, OutRegs AS RegType DIM SHARED Bank% DIM SHARED Table&(0 TO 479) ' *** Create Table For Vertical Reference FOR x% = 0 TO 479 Table&(x%) = x% * 640& NEXT x% ' *** Set Screen Mode ScreenMode &H101 ' *** Begin Plotting DEF SEG = &HA000 FOR x% = 0 TO 639 Col% = Col% + 1 IF Col% = 256 THEN Col% = 0 FOR y% = 0 TO 479 NewBank% = (Table&(y%) + x%) \ 65536 IF NewBank% <> Bank% THEN SwitchBank NewBank% Pixel x%, y%, Col% NEXT y% NEXT x% DEF SEG SLEEP 1 ScreenMode 3 END ' *** Pixel-Plotting Routine ' *** Set Screen Mode Routine, by Dave Shea ' *** Switch Bank Routine SUB Pixel (x%, y%, c%) POKE (Table&(y%) + x%) MOD 65536, c% END SUB SUB ScreenMode (SM) 'SM (ScreenMode) may be any one of the following: '3 = Text Mode '&H100 = 640x400x256 '&H101 = 640x480x256 '&H102 = 800x600x16 '&H103 = 800x600x256 '&H104 = 1024x768x16 '&H105 = 1024x768x256 InRegs.ax = &H4F02 InRegs.bx = SM CALL INTERRUPT(&H10, InRegs, OutRegs) END SUB SUB SwitchBank (NewBank%) InRegs.ax = &H4F05 InRegs.bx = 0 InRegs.dx = NewBank% CALL INTERRUPT(&H10, InRegs, OutRegs) Bank% = NewBank% END SUB ' First of all, try this and make sure it works on your system. I've 'only been able to try it on mine. I have a Cirrus Logic GD5430 video card, 'and I think you have a 5429, right? ' Second, here's a small chart comparing speed differences between the 'program you wrote that uses Interrupts to plot pixels and the one that I 'wrote that POKE's the pixels into memory: ' Yours Mine 'Environment 15.76 5.21 'Compiled 13.45 2.04 ' ' Granted, those times are still not as fast as you'd want them, but 'it's a start. I think the main reason is because of the division which is 'pathetically slow. There are two divisions per pixel. The first is the 'integer division that gets the bank that the coordinates reside in. The 'second one is MOD (yes, that's a division) which changes the coordinates into 'a linear address inside the current bank. ' ' If you noticed the first loop near the top of the program, that 'creates a multiplication look-up table. This eliminates the multiplication 'that would normally be needed to find each pixel (ya know, the y% * 640 +x% 'thing). I figure that we might be able to something similar for the two 'divisions, but it will be a little more complicated. ' ' The second thing I did to speed up the routine was to keep track of 'the current bank with the Bank% variable. This way, I only have to use the 'SwitchBank routine when actually needed to change the bank. If you called 'that routine every pixel to put it into the correct bank, then it slower than 'plotting the pixels with Interrupts.