[img] Fast Screen Printout Routines
 MDFS::Info.Comp.Spectrum.ProgTips.FastScreen Search  

The Spectrum screen is a simple memory-mapped display. The Spectum ROM provides a comprehensive
redirectable screen printout routine via RST &10. However because of this flexibility and functionality, the ROM
code is slow and bulky. If you don't need this functionality it is easy to write a short and fast screen printout
routine.
fastprn1.asm The simplest character printout routine just copies the character bitmap from a character set pointed
to by CHARS to screen, keeping a note of the screen output address in DFCC (Display File Current
Character) and incrementing it after each character.
  • Code size: 36 bytes
  • Code speed: 456T per character, +10T if print position goes over a screen third boundary
  • On entry, A=character
  • On exit, AF/BC/DE/HL corrupted
  • No colour setting, uses current screen colours
  • No checking for characters out of range
  • No check for wrapping past the bottom of the screen
  • fastprn2.asm A simple calculation converts the character output address to the address of the corresponding
    attribute location, then the colours can be set for the character just printed.
  • Code size: 49 bytes
  • Code speed: 524T per character, +10T if print position goes over a screen third boundary
  • On entry, A=character
  • On exit, AF/BC/DE/HL corrupted
  • Uses selectable colours
  • No checking for characters out of range
  • No check for wrapping past the bottom of the screen
  • fastprn3.asm So far the code just indexes straight into the character definitions without any checking for
    non-printable characters. Adding a check for character 32 lets control codes be ignored, and a
    check for characters over 127 lets block graphics and User Defined Characters be used. As
    there is a bug in the Spectrum's colour commands, if this code is attached to a stream it has to
    exit with Carry clear when called with control codes. Also, this code treats all characters from
    144 to 255 as User Defined Characters pointed to by UDC.

    There is a subroutine in the ROM that generates the block graphics bitmaps which can be called
    directly. Otherwise, the code can be duplicated and used inline in the code.

  • Code size: 74 bytes
  • Code speed: 559T per character (CHARS), 996T per character (block graphics), 593T per
       character (UDC), +10T if print position goes over a screen third boundary
  • On entry, A=character
  • On exit, AF/BC/DE/HL corrupted
  • Uses selectable colours
  • Filters out and ignores control codes
  • Prints block graphics and User Defined Characters
  • No check for wrapping past the bottom of the screen
  • fastprn4.asm It is a simple addition is to preserve all the registers so the code doesn't effect the calling code.
    This is not needed if the code is attached to a Spectrum stream as the stream handler preserves
    the main register set.
  • Code size: 84 bytes
  • Code speed: 559T per character (CHARS), 996T per character (block graphics), 593T per
    character (UDC), +10T if print position goes over a screen third boundary +111T if registers
    preserved
  • On entry, A=character
  • On exit, All registers preserved
  • Uses selectable colours
  • Filters out and ignores control codes
  • Prints block graphics and User Defined Characters
  • No check for wrapping past the bottom of the screen
  • fastprn5.asm We've now almost got a complete screen driver. It is simple to add movement control characters
    which add or subtract 1 or 32 to the current output position, character 13 to move to the start of
    the next line, and character 12 to clear the screen. These more than doubles the size of the code
    to implement, though we save some code by using the CHR$9 code to update the print position
    after printing a character.
  • Code size: 149 bytes
  • Code speed: 592T per character (CHARS), 1031T per character (block graphics), 626T per
       character (UDC), +2T if print position goes over a screen third boundary +111T if registers
       preserved
  • On entry, A=character
  • On exit, AF/BC/DE/HL corrupted
  • Uses selectable colours
  • Filters out and ignores control codes
  • Prints block graphics and User Defined Characters
  • No check for wrapping past the bottom of the screen
  • fastprn6.asm All the previous code assumes the character output position was on the screen and didn't check if
    it moved off the top or bottom. A few more bytes adds a simple check which moves the output
    position back onto the screen if it has moved off. A further improvement would be to scroll the
    screen when the output position moved off.
  • Code size: 168 bytes
  • Code speed: 635T per character (CHARS), 1075T per character (block graphics), 669T per
       character (UDC), +2T if print position goes over a screen third boundary, +111T if registers
       preserved
  • On entry, A=character
  • On exit, AF/BC/DE/HL corrupted
  • Uses selectable colours
  • Implements movement control codes
  • Prints block graphics and User Defined Characters
  • Checks for wrapping past the bottom of the screen
  • fastprn7.asm Further improvements would be to implement colour control codes and the AT position control
    code. This code includes a subroutine to set the character output position.
  • Code size: 200 bytes
  • Code speed: 635T per character (CHARS), 1075T per character (block graphics), 669T per
       character (UDC), +2T if print position goes over a screen third boundary, +111T if registers
       preserved
  • On entry, A=character
  • On exit, AF/BC/DE/HL corrupted
  • Uses selectable colours
  • Implements movement control codes
  • Prints block graphics and User Defined Characters
  • Checks for wrapping past the bottom of the screen
  • Routine to set output position
  • On entry, L=X position, H=Y position
  • prnattr2.asm
    prnattr7.asm
    Instead of storing the current print output position as the address in the screen bitmap memory
    (DFCC), the method used by Jet Set Willy can be used, storing the address in the attributes
    memory of the current print output position. The advantage of this is that stepping from one
    character cell to the next is a simple case of adding one, there is are no steps over screen thirds.
    Also, converting from attribute address to display address is slightly shorter and faster than the
    other way around.

    These two source files are the equivalent of their similar numbered DFCC-based source files,
    using the attribute memory address as the output address.

  • prnattr2.asm: 41 bytes, 493T per character
  • prnattr7.asm: 189 bytes, 511T/1089T/545T per character

  • Best viewed with Any Browser Valid HTML 4.0! Authored by J.G.Harston
    Last update: 12-Jun-2012