[img] Fast Printout Routines
 MDFS::Info.Comp.Spectrum.ProgTips.Printout 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
  • Registers corrupted
  • 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
  • Registers corrupted
  • 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
  • Registers corrupted
  • 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
  • All registers preserved
  • 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: 193 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 once 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: 182 bytes, xxxT per character

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