Computers Overview
Commodore PET
Sinclair ZX80
Sinclair ZX81
BBC Micro
Sinclair Spectrum
Memotech MTX
    About
    Library
        Adverts
        Memotech
        Miscellaneous
        Program Code
        Reviews
        Technical

            Component Data

            Data Books
            Data Sheets
            Design Guides
            Tutorials

            MTX Specific

            Firmware
            Tech Notes
    Manuals
    Options
    Photos
    Projects
    Repairs
    Software
    Tools
    User Groups
    Video Wall
Memotech CP/M
Atari ST
Commodore Amiga
PDAs
DEC 3000 AXP
OpenVMS
Raspberry Pi

 

 
 
 

The Memotech MTX Series

80 Column Card CP/M Firmware

Introduction

The 80 column card in the Memotech FDX and SDX disk systems is controlled by the CP/M BIOS using the BOOTCRT.MAC driver module in the SDX/FDX Boot ROM.

Andy Key has an excellent page on his website which describes the structure of the CP/M boot ROM and provides the source files to facilitate building various implementations of the ROM. The original Memotech source files include a minimal set of comments, but the functions of the code are not particularly well described.

Bill Brendling has been analysing the BOOTCRT module as part of his work to create an 80 Column card add-on to work in tandem with CFX for Memotech owners who do not have access to SDX or FDX disk drive hardware.

"There are a few gaps and ambiguities in the existing documentation, so I have been reverse engineering the CP/M driver and attempting to produce a more complete definition."

BOOTCRT.MAC Annotated with additional comments by Bill

BOOTCRT.MAC Annotated with additional comments by Bill

MTX 80 Column CP/M Driver Description by Bill (Text below)

CP/M Driver for MTX 80 Column Card

 

W Brendling

22 Jan 2017

 

In order to develop a new 80 column display card for the MTX which is compatible with the existing one, it is necessary to know what the existing one does. While this has been documented by Memotech there are some gaps and ambiguities. Therefore this documentation has been developed by reverse engineering the CP/M driver source code “BOOTCTR.MAC” downloaded from Andy Key’s website. In the process of developing this documentation, I have produced a more heavily annotated version of this source.

Printable Characters (0x20 – 0xFF)

Typically a printable character will be displayed upon the screen, using the current printing attributes, and the cursor advanced one space. This may be affected by the write mask (Esc “W”). If this is set, the character may be updated, without changing the existing on-screen attributes, or the attributes may be updated without changing the displayed character.

If the cursor goes beyond the bottom of the screen, either the display will scroll (scroll mode) or the cursor will return to the top of the screen (page mode). There is nothing in the driver to pause and wait for a key press at the end of a page. This functionality must be at a higher level.

Assuming that a character is output, the glyph displayed depends upon the font selected, and whether or not the graphics mode bit is set in the attribute byte.

If the graphics mode bit is clear, then the following table gives the glyph displayed:

Character Code

Standard Font

Alternate Font

Special Graphics Font

0x20 - 0x3F

Standard numerals

Alternate numerals

Standard numerals

0x40 - 0x5F

Standard upper case

Alternate upper case

Special graphics (upper)

0x60 - 0x7F

Standard lower case

Alternate lower case

Special graphics (lower)

0x80 - 0x9F

Special graphics (lower)

Special graphics (lower)

Special graphics (upper)

0xA0 - 0xBF

Alternate numerals

Alternate numerals

Standard numerals

0xC0 - 0xDF

Alternate upper case

Alternate upper case

Special graphics (upper)

0xE0 - 0xFF

Alternate lower case

Alternate lower case

Special graphics (lower)

 

Each of the entries in the table above should be taken to include the symbol glyphs adjacent to the numerals or letters.

It should be noted that character code 0x7F is printable. It does not delete the character under the cursor.

If the graphics mode attribute is set, then the corresponding glyph from the graphics PROM is displayed:

Character Code

Standard Font

Alternate Font

Special Graphics Font

0x20 - 0x3F

Graphic 0x20 - 0x3F

Graphic 0xA0 - 0xBF

Graphic 0x20 - 0x3F

0x40 - 0x5F

Graphic 0x40 - 0x5F

Graphic 0xC0 - 0xDF

Graphic 0x00 - 0x1F

0x60 - 0x7F

Graphic 0x60 - 0x7F

Graphic 0xE0 - 0xFF

Graphic 0x80 - 0x9F

0x80 - 0x9F

Graphic 0x80 - 0x9F

Graphic 0x80 - 0x9F

Graphic 0x00 - 0x1F

0xA0 - 0xBF

Graphic 0xA0 - 0xBF

Graphic 0xA0 - 0xBF

Graphic 0x20 - 0x3F

0xC0 - 0xDF

Graphic 0xC0 - 0xDF

Graphic 0xC0 - 0xDF

Graphic 0x00 - 0x1F

0xE0 - 0xFF

Graphic 0xE0 - 0xFF

Graphic 0xE0 - 0xFF

Graphic 0x80 - 0x9F

 

Control Codes (0x00 – 0x1F)

Control codes may be followed by one or more data bytes update the display in various ways, as detailed in the following table. Any screen updates are affected by the settings of the write mask, as for the printable characters.

Control Code

Data Bytes

Action

^@ (0x00)

 

Does nothing

^A (0x01)

m, n

Plot a point:

x = m – 32, y = n – 32

If x < 0, x > 159, y < 0 or y > 95 do nothing.

If existing character cell containing point does not have graphics mode attribute bit set, zero the character, and set the graphics mode attribute bit.

If the 3 lsb of the non-printing attributes byte are zero (Black foreground), then un-plot the selected point (clear the corresponding bit in the character cell) and retain the existing attributes for the character cell (except setting graphics mode if not previously set).

Otherwise, plot the selected point (set the corresponding bit in the character cell) and update the attributes of the character cell, using the non-printing attributes byte, with the graphics mode bit set.

^B (0x02)

m1, n1, m2, n2

Draws a line. See section below on the line drawing algorithm.

^C (0x03)

m, n

Sets cursor position: x = m – 32, y = n - 32

If 0 <= x <= 79 sets horizontal position, otherwise unchanged.

If 0 <= y <= 23 sets vertical position, otherwise unchanged.

^D (0x04)

m

Set background colour. Sets bits 3-5 of both printing and non-printing attributes to 3 lsb of m.

^E (0x05)

 

Erase to end of line. Fill from cursor position to end of line with space character and non-printing attribute.

^F (0x06)

m

Set attributes. Set both the printing and non-printing attribute bytes to the value of m.

^G (0x07)

 

Sounds the Bell

^H (0x08)

 

Moves the cursor back one space. If at the beginning of a line, moves back to the end of the previous line. If at top of screen, does nothing. Does not erase the character.

^I (0x09)

 

Tab. Moves the cursor forward to the next multiple of 8 columns. If in the last 7 columns of a line moves to the start of the next line.  If in last 7 characters of screen, either scrolls a line, or moves to top of screen, depending upon scroll / page mode.

^J (0x0A)

 

Cursor down. Moves the cursor down one line. If on last line of screen, either scrolls a line, or moves to top of screen, depending upon scroll / page mode.

^K (0x0B)

 

Move cursor up one line. If already at top of screen, do nothing.

^L (0x0C)

 

Fill entire video RAM with space character and non-printing attribute (depending upon write mask). Sets top of screen to top of video RAM.

^M (0x0D)

 

Carriage return. Sets cursor position to beginning of line.

^N (0x0E)

 

Blink on. Sets the blink bit (bit 6) in the printing attributes byte only.

^O (0x0F)

 

Blink off.  Clears the blink bit (bit 6) in the printing attributes byte only.

^P (0x10)

 

Sets the 3 lsb of the printing attributes byte to 0x0. Black foreground.

^Q (0x11)

 

Sets the 3 lsb of the printing attributes byte to 0x1. Red foreground (colour) or underline (mono).

^R (0x12)

 

Sets the 3 lsb of the printing attributes byte to 0x2. Green foreground (colour).

^S (0x13)

 

Sets the 3 lsb of the printing attributes byte to 0x3. Yellow foreground (colour) or underline (mono).

^T (0x14)

 

Sets the 3 lsb of the printing attributes byte to 0x4. Blue foreground (colour) or bright (mono).

^U (0x15)

 

Sets the 3 lsb of the printing attributes byte to 0x5. Magenta foreground (colour) or bright & underline (mono).

^V (0x16)

 

Sets the 3 lsb of the printing attributes byte to 0x6. Cyan foreground (colour) or bright (mono).

^W (0x17)

 

Sets the 3 lsb of the printing attributes byte to 0x7. White foreground (colour) or bright & underline (mono).

^X (0x18)

 

Initialise display:

Turns on scroll mode.

Sets both printing and non-printing attribute bytes to 0x02 (green foreground on black background).

Turns on the cursor.

Enables both character and attribute writes.

Performs a carriage return and line feed.

Selects the standard font.

^Y (0x19)

 

Cursor forward. If in the last column of a line moves to the start of the next line.  If in last character of screen, either scrolls a line, or moves to top of screen, depending upon scroll / page mode.

^Z (0x1A)

 

Home cursor. Moves cursor position to first character of top row.

^[ (0x1B)

 

Start of an escape sequence. See next section.

^\ (0x1C)

 

Sets scroll mode. If cursor flows off the bottom of the screen, then all text is moved up one line, bottom line is cleared (using space character and non-printing attribute, depending upon write mask), and cursor is positioned on the new bottom line. Moving text up is performed by updating video RAM address of top of screen, and is therefore not affected by write mask.

^] (0x1D)

 

Sets page mode. If cursor flows off bottom of screen it re-appears at the top of the screen. None of the screen is cleared. There is no code in the driver to wait for a key press.

^^ (0x1E)

 

Turn on display of the flashing cursor.

^_ (0x1F)

 

Turn off display of the flashing cursor.

 

Escape Sequences

Escape sequences are similar to control codes. They consist of the ESC character (0x1B), followed by the command character and then possibly one or more data bytes.

In the Memotech implementation, if the character following the ESC is in the range 0x00 – 0x1F then the sequence is terminated and does nothing. Otherwise the 5 lsb of the command character are used to select the command to be executed. Therefore the sequence (ESC, 0x01) does nothing while each of the sequences (ESC, “!”), (ESC, “a”), (ESC, 0x81), (ESC, 0xA1), (ESC, 0xC1) and (ESC, 0xE1) all do the same as (ESC, “A”). In the table below, the standard upper case command character is listed, but the descriptions are applicable to all the other equivalents.

 

Command Character

Data Bytes

Action

“@” (0x40)

 

Does nothing.

“A” (0x41)

 

Selects alternate font (see section on printable characters)

“B” (0x42)

m

If m = “0” (0x30) then zeros both printing and non-printing attribute bytes. Otherwise sets bit (m-1)&0x07 in both attribute bytes, leaving any other bit unchanged. Intended that “1” - “8” should be used to select the bit to set, but any character other than “0” results in a bit being set. Note that m = 0x00 will result in bit 7 being set, not bit 0.

“C” (0x43)

 

Sets scroll mode. If cursor flows off the bottom of the screen, then all text is moved up one line, bottom line is cleared (using space character and non-printing attribute, depending upon write mask), and cursor is positioned on the new bottom line. Moving text up is performed by updating video RAM address of top of screen, and is therefore not affected by write mask.

“D” (0x44)

 

Sets page mode. If cursor flows off bottom of screen it re-appears at the top of the screen. None of the screen is cleared. There is no code in the driver to wait for a key press.

“E” (0x45)

 

Turn on display of the flashing cursor.

“F” (0x46)

 

Turn off display of the flashing cursor.

“G” (0x47)

 

Selects special graphics font (see section on printable characters)

“H” (0x48)

 

Does nothing

“I” (0x49)

 

Moves all the text on the line containing the cursor and below down one line. The bottom line is lost. The line containing the cursor is cleared (using space character and non-printing attribute). The cursor retains its previous position (on the now blank line).

“J” (0x4A)

 

Moves all text in lines below the cursor up one line. The new bottom line is cleared (using space character and non-printing attribute). The cursor retains its previous position.

“K” (0x4B)

 

Does nothing.

“L” (0x4C)

 

Does nothing.

“M” (0x4D)

 

Does nothing.

“N” (0x4E)

m

If m = “0” (0x30) then zeros the non-printing attribute byte. Otherwise sets bit (m-1)&0x07 in the attribute byte, leaving any other bit unchanged. Intended that “1” - “8” should be used to select the bit to set, but any character other than “0” results in a bit being set. Note that m = 0x00 will result in bit 7 being set, not bit 0.

“O” (0x4F)

 

Does nothing.

“P” (0x50)

m

If m = “0” (0x30) then zeros the printing attribute byte. Otherwise sets bit (m-1)&0x07 in the attribute byte, leaving any other bit unchanged. Intended that “1” - “8” should be used to select the bit to set, but any character other than “0” results in a bit being set. Note that m = 0x00 will result in bit 7 being set, not bit 0.

“Q” (0x51)

 

Does nothing.

“R” (0x52)

 

Reads character and attribute at the current cursor position into two bytes of Z80 RAM within the driver. No visible effect.

“S” (0x53)

 

Selects standard font (see section on printable characters)

“T” (0x54)

m

Sets the printing attribute byte to the value of the data byte (m).

“U” (0x55)

m

Sets the non-printing attribute byte to the value of the data byte (m).

“V” (0x56)

 

Sets the both attribute bytes to the value of the data byte (m).

“W” (0x57)

 

Sets the write mask:

If m = “0” (0x30) enable both character and attribute writes.

If m = “1” (0x31) disable attribute writes.

If m = “2” (0x32) disable character writes.

Any other value of m has no effect.

“X” (0x58)

m

Simulate the effect of the control code given by m & 0x1F.

“Y” (0x59)

 

Does nothing.

“Z” (0x5A)

 

Does nothing.

“[“ (0x5B)

 

Does nothing.

“\” (0x5C)

 

Does nothing.

“]” (0x5D)

 

Does nothing.

“^” (0x5E)

 

Does nothing.

“_” (0x5F)

 

Does nothing.

 

Line Drawing Algorithm

The end points of the line to be drawn are defined in a square with coordinates in the range 0 – 255. Only a rectangle to the top left, with x in 0 – 159 and y in 0 – 95 is visible. So it is possible for these to be off the screen either to the right or below (or both). Even if the end points are off the screen, it is possible for some of the line to be visible and drawn, if it passes through the visible area.


See the description of Ctrl+A for the details of plotting each point on the line.

The algorithm used to draw the line is as follows (all divisions are unsigned integer division):

If m1 >= 32 then x1 = m1 – 32, else x1 = m1 + 224

If n1 >= 32 then y1 = n1 – 32, else y1 = n1 + 224

If m2 >= 32 then x2 = m2 – 32, else x2 = m2 + 224

If n2 >= 32 then y2 = n2 – 32, else y2 = n2 + 224

If ( ( x2 < x1 ) or ( ( x2 = x1 ) and ( y2 < y1 ) ) then

   Swap x1 and x2

   Swap y1 and y2

Endif

Push (0, 0) - Marker

Loop

   If ( ( x2 = x1 ) and ( y2 = y1 ) ) then

      Plot (x1, y1)

      Pop (x1, y1)

      If ( (x1, y1) = (0,0) ) quit

      Pop (x2, y2)

   Else

      Push (x2, y2)

      If ( x1 != x2 ) then

         x3 = ( x1 + x2 ) / 2 + 1

         x2 = ( x1 + x2 ) / 2

      Else

         x3 = x2

      Endif

      if ( y2 > y1 ) then

         y3 = ( y1 + y2 ) / 2 + 1

         y2 = ( y1 + y2 ) / 2

      Else if ( y2 < y1 ) then

         y3 = ( y1 + y2 ) / 2

         y2 = ( y1 + y2 ) / 2 + 1

      Else

         y3 = y2

      Endif

      Push (x3, y3)

   Endif

End loop

 

mailto: Webmaster

 Terms & Conditions