'=========================================================================== ' Subject: UNCHAINED MODE 13H ROUTINES Date: 07-18-98 (00:38) ' Author: Tyler Barnes Code: QB, QBasic, PDS ' Origin: Tyler.Barnes@crcn.net Packet: GRAPHICS.ABC '=========================================================================== DECLARE SUB InitUnchain () 'Initializes Library Routines DECLARE SUB ActivePage (PageNum%) 'Selects page that we write to (0 - 3) DECLARE SUB VisiblePage (PageNum%) 'Selects page visible to user (0 - 3) DECLARE SUB FlipPage () 'Swaps active and visible page DECLARE SUB Pixel (X%, Y%, Col%) 'Plots a pixel DECLARE FUNCTION Powers% (Bitval%) 'very limited. Internal use only. DIM SHARED XDivs%(0 TO 319) 'internal use only (look-up table) 'InitUnchain - Initializes the unchained mode 13h routines. Must be run ' once before running any of the other routines in this ' package. ' Format: InitUnchain 'ActivePage - Selects page that all PIXEL commands are written to. The mode ' supports four video pages numbered from 0 to 3. ' Format: ActivePage 1 ' Default: After InitUnchain is run, ActivePage is set to zero 'VisiblePage - Selects the page visible on screen. Automatically synchronizes ' the page changing to the screen's vertical retrace to avoid ' flicker. The video mode supports four video pages numbered ' from 0 to 3. ' Format: VisiblePage 1 ' Default: After InitUnchain is run, VisiblePage is set to zero 'FlipPage - Swaps the active and visible pages. For example if the ' visible page is 0 and the active page (page you've been ' writing to) is 1, it will swap it so visible is 1 and active ' is 0. ' Format: FlipPage 'Pixel - Writes a pixel to the page selected with the ActivePage ' command. Three parameters are given with this command. ' The first is the X coordinate which must be between 0 and 319 ' The second is the Y coordinate which must be between 0 and 199 ' The third is the pixel colour which must be between 0 and 255 ' Format: Pixel 319,199,4 ' 'Note: I don't really do much BASIC programming anymore, and just wrote this ' to refamiliarize myself with some of the vga registers. Because of ' this, the program hasn't been tested thoroughly and I've failed to ' include routines to draw lines, circles, output text, etc. ' You'll have to write your own :) .. have fun. ' ' Also.. I have some of the divisions and exponents and stuff in ' precalculated data tables. Goes a LOT faster like that.. especially ' when compiled. Also.. I haven't tested it, but if you want to change ' the color palette, I see no reason why QuickBasic's palette command ' wouldn't worked with this tweaked screen 13. 'Um, that's all for now.... SUB ActivePage (PageNum%) SHARED AP% AP% = PageNum% IF PageNum% > 3 OR PageNum% < 0 THEN ERROR 5 SHARED PageVal& PNum& = PageNum% PageVal& = PNum& * 16000 END SUB SUB FlipPage SHARED AP%, VP% A% = AP%: B% = VP% ActivePage B% VisiblePage A% END SUB SUB InitUnchain SCREEN 13 'screen mode 13h OUT &H3C4, 4 'Sequencer Index 4 (sequencer index port) A% = INP(&H3C5) 'A%=current value at position 4 in sequencer A% = A% AND &HFFF7 'Zero out bit#3 (bitval8) to unchain OUT &H3C4, 4 'sequencer index 4 OUT &H3C5, A% 'write new value to unchain OUT &H3C4, 2 'sequencer index 2 (color plane enable register) OUT &H3C5, &HFF 'sequencer data (enable all planes) DEF SEG = &HA000 'Video mapped here FOR I& = 0 TO 65535 POKE I&, 0 'clear entire segment NEXT I& OUT &H3D4, &H17 test% = INP(&H3D5) OR 64 OUT &H3D4, &H17 OUT &H3D5, test% OUT &H3D4, &H14 test% = INP(&H3D5) AND &HFFBF '(FFFFh xor 64d) OUT &H3D4, &H14 OUT &H3D5, test% FOR I% = 0 TO 319 'Precalculates all possible X/4 answers for the XDivs%(I%) = INT(I% / 4) 'PIXEL command NEXT I% ActivePage 0 'Page 0 default for active page VisiblePage 0 'Page 0 default for visible page END SUB SUB Pixel (X%, Y%, Col%) SHARED PageVal& STATIC OldBit%, FirstTime% IF X% > 319 OR Y% > 199 THEN ERROR 5 Bitnum% = X% AND 3 '(X% mod 4 also works but slower) IF Bitnum% <> OldBit% OR FirstTime% = 0 THEN 'modify register only if needed OUT &H3C4, 2 'Index 2 GDC (Color plane enable register) OUT &H3C5, Powers%(Bitnum%) 'output bit value that we're modifying FirstTime% = 1 'Set flag to say we've set the CPE register b4 OldBit% = Bitnum% 'Save our bitval for next time END IF DEF SEG = &HA000 'Video mapped here Y& = (Y% * 80) + PageVal& 'convert y portion to linear, mod for actpage POKE Y& + XDivs%(X%), Col% 'complete conversion, write it to mem 'Xdivs array is a data look-up table to convert X to X/4. Faster than 'calculating during pixel write.. uses quite a bit of memory, but most 'people can probably spare it END SUB FUNCTION Powers% (Bitnum%) SELECT CASE Bitnum% CASE 0: Powers% = 1 CASE 1: Powers% = 2 CASE 2: Powers% = 4 CASE 3: Powers% = 8 END SELECT 'This sub used instead of calculating exponents manually to improve speed 'Sort of a look up table to avoid one of QB's slowest routines END FUNCTION SUB VisiblePage (PageNum%) SHARED VP% VP% = PageNum% IF PageNum% > 3 OR PageNum% < 0 THEN ERROR 5 PNum& = PageNum% PageVal& = PNum& * 16000 'calculate offset val of 0,0 WAIT &H3DA, 8, 8 'sync with WAIT &H3DA, 8 'vertical retrace OUT &H3D4, &HC 'high byte offset (CRTC index) OUT &H3D5, ((PageVal& AND &HFF00) \ 256) AND &HFF OUT &H3D4, &HD 'low byte offset (CRTC index) OUT &H3D5, PageVal& AND 255 'CRTC data port END SUB