Close

CRTC register modification

A project log for Applix 1616 Documentation

OCRd and typeset as html where possible. A work in progress.

keithKeith a day ago0 Comments

The pixels are a little off to the left of my TV screen, so I wondered if the CRTC was properly programmed for PAL TV. The CRTC registers are copied from a block of ROM defined in crtcint.c like so:

uchar crtc_tab[] =
{
  119,       /* Horizontal total: 15625 Hz line rate */
  80,        /* Horizontal displayed */
  96,        /* Hsync position */
  10,        /* Hsync width */
  77,        /* Vertical total: 312/4 - 1 */
  0,         /* Vertical total adjust */
  50,        /* Vertical displayed: 200/4 char lines */
  63,        /* Vsync position */
  0,         /* No interlace */
  3,         /* Max scan line address: 4 rows/char */
  0x20,      /* No cursor */
  0,         /* Cursor end */
  0,         /* Start address high */
  0,         /* Start address low */
  (uchar)(CRTC_SAVE/256),    /* Cursor register high */
  (uchar) CRTC_SAVE    /* Cursor register low */
};

The standard square-pixel resolution for PAL video is 768 × 576 at a sampling rate of 14.75 MHz.

This was not a common oscillator back in the 1980s, so Applix used 15 MHz derived from a 30 MHz master clock. They could have used the 29.4912 MHz baud rate generator frequency, which is only 0.03% out.

I bought some 29.5 MHz oscillators which can be halved to 14.75 MHz. This is exactly right for PAL video and very good for setting baud rates.

Using the online tool for calculating CRTC registers: https://mrboot.de/mc6845.php, select PAL-DVD and the following:

pixel clock = 14.75 MHz
columns per character = 8 pixel/character
rows per character = 4 lines per character

and we get horizontally:

front porch   1.6 µs =   3 chars =  1.63 µs
sync length   4.7 µs =   8 chars =  4.34 µs
back porch    5.7 µs =  11 chars =  5.97 µs
total vsync  12.0 µs =  22 chars = 11.93 µs
active video 52.0 µs =  96 chars = 52.07 µs ; 96*8=768 pixels
total line   64.0 µs = 118 chars = 64.00 µs ; 15.625 kHz

 and vertically:

visible lines        288   lines = 72 chars * 4 lines each =288
vertical front porch   8   lines 2 
vertical sync length   8   lines 16 lines 
vertical back porch    8.5 lines 0 lines  
total lines          312.5 lines 78 characters + 0 lines
VSYNC is 15.625 kHz
HSYNC ideally 50 Hz is actually 50.08 Hz

but the computer screen is not a full TV-screen, so there are still 80 displayed characters (not 96) and 200 lines (not 288). (96-80)/2 = 8 off each side and (288-200)/2 = 44 off top and bottom. Well, I did a spreadsheet and to the best of my knowledge this is what the CRTC table should be:

uchar crtc_tab[] =
{
  117,   /* Horizontal total: 15625 Hz line rate (Exact for 29.5 MHz)*/
  80,    /* Horizontal displayed (unchanged) */
  91,    /* Hsync position (moves pixels 5 characters to the right) */
  8,     /* Hsync width = 4.34 µs (slightly shorter than ideal) */
  77,    /* Vertical total: 312/4 - 1 (unchanged) */
  0,     /* Vertical total adjust     (unchanged) */
  50,    /* Vertical displayed: 200/4 char lines (unchanged) */
  63,    /* Vsync position (unchanged) */
// unchanged hereafter:
  0,     /* No interlace */
  3,     /* Max scan line address: 4 rows/char */
  0x20,  /* No cursor */
  0,     /* Cursor end */
  0,     /* Start address high */
  0,     /* Start address low */
  (uchar)(CRTC_SAVE/256),  /* Cursor register high */
  (uchar) CRTC_SAVE        /* Cursor register low */
};

The CRTC table begins at 51d872 hex. Only 3 bytes change

Original:
51D872  77  DB  119   ; Horizontal total: 15625 Hz line rate
51D873  50  DB  80   ; Horizontal displayed
51D874  60  DB  96   ; Hsync position
51D875  0A  DB  10   ; Hsync width

Modified:
51D872  75  DB  117  ; Horizontal total: 15625 Hz line rate 
                     ; (Exact for 29.5 MHz)
51D873  50  DB  80   ; Horizontal displayed (unchanged)
51D874  5B  DB  91   ; Hsync position (moves pixels right a bit)
51D875  08  DB  8    ; Hsync width = 4.34 µs
                     ; (slightly shorter than ideal)

The bytes are spread over two  ROM chips, so the ROM address offset is 51D872/2 = 28EC39.

The chips are on a 128K boundary, so the offset from the start of ROM is just EC39.

In the Low byte ROM, the changes are thus:

0000ec30: 7875 3a25 203e 250d 0050 0a00 3f03 0000  Original
                                    |
0000ec30: 7875 3a25 203e 250d 0050 0800 3f03 0000  Mods

In the High byte ROM, the changes are thus: 

0000ec30: 2073 6d20 782d 2078 0a77 604d 3200 2000  Original
                                 | ||
0000ec30: 2073 6d20 782d 2078 0a75 5b4d 3200 2000  Mods

 I modified the ROM chips and the display is much more central, with a 29.5 or 30 MHz oscillator.

Discussions