Last modified on 7 October 2015, at 07:08

Programming:Overscan

Overscan simply means increasing the screen size past the normal 640×200 resolution by extending the screen into the borders.

This can be achieved in a number of ways, the simplest of which is to simply change some values in the CRTC registers and take advantage of a 32K screen.

In order to set up the CRTC properly you need to change registers 1 (Horizontal displayed), a full width screen would be around 48 characters, but you may like to use 50 to make sure you cover the left/right edges of the screen. Register 2 (HSYNC position) is then used to align the screen left/right so the picture appears in the middle. Register 6 (Vertical displayed) is used to extend the screen vertically, and register 7 (VSYNC position) to adjust the vertical position of the display.

Try the following from BASIC:

cls 
out &bc00,1:out &bd00,50 
out &bc00,2:out &bd00,51 
out &bc00,6:out &bd00,34 
out &bc00,7:out &bd00,35 

The final step is to set the screen base address to cover 32K. This is done by exploiting a feature of the address decoding from the 6845 to the Gate Array. Address lines MA10 and MA11 from the 6845 are not used for screen address decoding and if you set them both to 1, at the address wrap-around they will increment address line MA12, providing the next bank of RAM as the screen base. This means the screen base address offset will wrap from #07FF to #4000 for the first scan line, #0FFF to #4800 for the second scan line and so forth.

out &bc00,12:out &bd00,&2c will give a screen that starts in bank 2 (#8000..#bfff) and then wraps into bank 3 (#c000..#ffff). Similarly, you can wrap from banks 0..1 with out &bd00,&0c, banks 1 and 2 with out &bd00,&1c and bank 3 back to bank 0 with out &bd00,&3c.

Unfortunately, all of these options mean that the screen either overlaps the restart block of memory at #0000..#003f or the high kernal jumpblock at #b900..#bfff. In order to get around this problem, I usually like to use banks 0 and 1, and offset the screen by #40 bytes by setting register 13 to #20. This will ensure that the screen memory used is #40..#3fff and #4000..?

Executioner


Source code from the The Unofficial Amstrad WWW Resource to achieve overscan in assembler

;; This example shows a simple method for a overscan
;; screen. 
;;
;; This example will work on CPC, CPC+ and KC Compact.
;;
;; This example uses the 6845 CRTC, and shows how
;; 32k of pixel data can be displayed by the CRTC.
;; This example is compatible with CRTC type 2. (MC6845)
;;
;; the screen is 48x35 visible characters in dimension,
;; and each character is 8 scanlines tall.
;; the visible window is moved so that the display
;; will fill the entire monitor screen. 
;; The screen base address is initialised, so that
;; MA11=MA10=1, and the internal MA counter of the CRTC will 
;; change MA12 during the display, and cause the CRTC to display
;; data from a 32k range. The actual visible display uses approx
;; 24k of RAM. After this setup, the screen does not need to
;; re-initialised for the overscan to be maintained.
;;
;; the screen is setup for a PAL display.
;;
;; This example will compile with the MAXAM assembler
;; or the built-in assembler of WinAPE32.
;;
;; Kevin Thacker 2002

;; the origin of this source code is not important
org &4000

;; initialise a display window of 48x35 characters
;; each character is 8 scanlines tall

;; set character height to 8 scanlines
ld bc,&bc09
out (c),c
ld bc,&bd00+7
out (c),c

;; set default horizontal total (set horizontal total to 64 CRTC characters
;; = 64 microseconds)
ld bc,&bc00
out (c),c
ld bc,&bd00+&3f
out (c),c

;; set default vertical total (set vertical total to 39 CRTC character-lines)
ld bc,&bc04
out (c),c
ld bc,&bd00+38
out (c),c

;; setup default horizontal and vertical sync widths
ld bc,&bc03
out (c),c
ld bc,&bd00+&8e
out (c),c

;; setup default vertical adjust
ld bc,&bc05
out (c),c
ld bc,&bd00
out (c),c

;; setup default interlace & skew
ld bc,&bc08
out (c),c
ld bc,&bd00
out (c),c

;; set width of display window
ld bc,&bc01
out (c),c
ld bc,&bd00+48
out (c),c

;; set horizontal sync position; and therefore the
;; horizontal position of the display window
;; within the monitor display
ld bc,&bc02
out (c),c
ld bc,&bd00+48
out (c),c

;; set height of display window
ld bc,&bc06
out (c),c
ld bc,&bd00+35
out (c),c

;; set vertical sync position; and therefore the
;; vertical position of the display window
;; within the monitor display
ld bc,&bc07
out (c),c
ld bc,&bd00+35
out (c),c

;; set display start
;; force MA11=MA10=1, so that the internal MA
;; counter will increment enough to change MA12.

;; the displayed data is &0000-&7fff
ld bc,&bc0c
out (c),c
ld bc,&bd00+&0c
out (c),c
ld bc,&bc0d
out (c),c
ld bc,&bd00+0
out (c),c

ret