Dowload Text File
$if 0

  SUB V12print( Row%, Col%, Txt$, Fgrnd?, Bgrnd? )
    Row%   - starting row;    1 to 30
    Col%   - starting column; 1 to 80
    Txt$   - what you want printed
    Fgrnd? - foreground color; 0 to 15
    Bgrnd? - background color; 0 to 15

  This routine will print 8x16 characters to SCREEN 12 in any color
  combination you require regardless of the COLOR settings.

  Yes, it's a bit slow, even on my Pentium 200 (2400 chars in .11sec)
  but it DOES allow you to print text to your VGA screen using ANY
  color attributes, so, it's a bit of a trade off.

  LoadCharArray is a kludge routine to load some character data into
  the buffer. I recommend that you make a data file(s) for your font(s)
  and load directly from there into the buffer.

  Enjoy,

Don
$endif

DECLARE SUB V12print ( BYVAL Row%, BYVAL Col%, BYVAL Txt$, _
                       BYVAL Fgrnd?, BYVAL Bgrnd? )

DIM Buf(4095) AS SHARED BYTE
DIM B_ptr     AS SHARED BYTE PTR

B_ptr = VARPTR32( Buf?(0) )

' -------------------------------------------
' ---------   test code
' -------------------------------------------
DECLARE SUB LoadCharArray ()

SCREEN 12
LoadCharArray
DELAY 2

DIM Row AS INTEGER
DIM T   AS STRING
DIM T1  AS SINGLE
DIM T2  AS SINGLE

T$ = STRING$(2400,65)

CLS
T1! = TIMER
  PRINT T$;
T1! = TIMER - T1!

DELAY 1
CLS
T2! = TIMER
  V12print 1, 1, T$, 14, 1
T2! = TIMER - T2!

T$ = USING$( " ##.### ", T1! ) + _
     USING$( "##.### ", T2! )

FOR Row% = 1 TO 15
  V12print Row%+1, 2, T$, Row%, 0
NEXT

WHILE NOT INSTAT : WEND
SCREEN 0
END

' -------------------------------------------
' ---------   the routine
' -------------------------------------------

SUB V12print ( BYVAL Row   AS INTEGER, _
               BYVAL Col   AS INTEGER, _
               BYVAL Txt   AS STRING , _
               BYVAL Fgrnd AS BYTE   , _
               BYVAL Bgrnd AS BYTE     ) LOCAL PUBLIC

  DIM BgMask      AS LOCAL INTEGER    ' background mask
  DIM Boff        AS LOCAL INTEGER    ' byte offset for char buffer
  DIM ByteMask    AS LOCAL INTEGER    ' byte mask being 'put' to the screen
  DIM FgMask      AS LOCAL INTEGER    ' foreground mask
  DIM PixelRow    AS LOCAL INTEGER    ' pixel row relative to starting row
  DIM Plane       AS LOCAL INTEGER    ' pixel plane mask
  DIM S_ptr       AS LOCAL BYTE PTR   ' screen pointer
  DIM Tlen        AS LOCAL INTEGER    ' text length
  DIM Toff        AS LOCAL INTEGER    ' text index
  DIM T_ptr       AS LOCAL BYTE PTR   ' text pointer

  Tlen%  = LEN(Txt$)                           ' get the length of the $
  IF Tlen% = 0 THEN EXIT SUB                   ' oops, nothing to do
  T_ptr  = STRPTR32( Txt$ )                    ' set the pointer to the $
  DECR Tlen%                                   ' 0 based for index
  DECR Row%                                    ' 0 based
  DECR Col%                                    ' 0 based
  S_ptr = &hA0000000                           ' screen pointer
  INCR S_ptr, ( ( Row% * 1280 ) + Col% )       ' set to row/col offset
                                               '
  OUT &h03C4, 2                                ' tell VGA we're printing
  FOR Toff% = 0 TO Tlen%                       ' once for each character
    Boff% = @T_ptr[Toff%]                      '  chr$
    SHIFT LEFT Boff%, 4                        '  * 16 for buffer offset
    FOR PixelRow% = 0 TO 15                    '  once for each byte in char
      FgMask% = @B_ptr[Boff%]                  '   set foreground mask
      BgMask% = ( FgMask% XOR 255 )            '   create background mask
      Plane%  = 8                              '   set plane #
      DO                                       '   once for each plane bank
        OUT &h03C5, Plane%                     '    tell VGA to switch bank
        IF ( Plane% AND Fgrnd? ) THEN          '    if fgrnd is in this plane
            ByteMask% = FgMask%                '      make this the mask
          ELSE                                 '     else
            ByteMask% = 0                      '      set mask to 0
        END IF                                 '
        IF ( Plane% AND Bgrnd? ) THEN          '    if bgrnd in this plane
          ByteMask% = ( ByteMask% OR BgMask% ) '     or on the bgrnd bits
        END IF                                 '
        @S_ptr = ByteMask%                     '    set the VGA byte
        SHIFT RIGHT Plane%, 1                  '    previous plane
      LOOP UNTIL Plane% = 0                    '
      INCR S_ptr, 80                           '   next pixel row
      INCR Boff%                               '   next character byte
    NEXT                                       '
    INCR Col%                                  '  next column
    IF Col% < 80 THEN                          '  if not end of row
        DECR S_ptr, 1279                       '   bump screen ptr 16 rows
      ELSE                                     '  else
        DECR S_ptr, 79                         '   reset to start of row
        Col% = 0                               '
    END IF                                     '
  NEXT                                         '
                                               '
  OUT &h03C4,  2                               ' reset VGA to normal
  OUT &h03C5, 15                               '

END SUB

' --------------------------------------------------------------------------

SUB LoadCharArray () LOCAL PUBLIC

  DIM B    AS LOCAL BYTE                         ' This routine is a kludge
  DIM Boff AS LOCAL INTEGER                      ' to load character data
  DIM Bt   AS LOCAL INTEGER                      ' into the buffer array
  DIM Col  AS LOCAL INTEGER                      '
  DIM Row  AS LOCAL INTEGER                      ' I recommend that you
  DIM X    AS LOCAL INTEGER                      ' store this (or similar)
                                                 ' info in a file and load
  FOR X% = 0 TO 255                              ' it directly from there.
    LOCATE 1, 1 : PRINT CHR$(X%)                 '
    FOR Row% = 0 TO 15                           ' Yes, you can make your
      Bt% = 7                                    ' own character sets.
      FOR Col% = 0 TO 7                          '
        B? = POINT(Col%,Row%)                    '
        IF B? > 0 THEN BIT SET Buf?(Boff%), Bt%  '
        DECR Bt%                                 '
      NEXT                                       '
      INCR Boff%                                 '
    NEXT                                         '
  NEXT                                           '
                                                 '
END SUB                                          '