VDP Access Registers
This page was last modified 19:29, 26 May 2023 by Mars2000you. Based on work by Gdx and Hope-hunter.

Contents

Control Register 14

This register can be only written. Use the MSX-BASIC instruction VDP(15) to access it. The instruction reads the system variable REG14SAV (0FFEDh) to return the requested value.

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
R#14: 0 0 0 0 0 V16 V15 V14 (MSX2/2+/MSX turbo R)
  • This register is used to access the VRAM at the addresses higher than 3FFFH (16kB). V14-V16 bit are the three most significant bits of the address.

In all modes, except the four MSX1 screens, if there's a carry flag from A13 the value in this register is automatically incremented.

Procedure to access the VRAM

The complete procedure is as follows:

  1. Eventually switch back to normal 128kB VRAM if your application uses the 64kB expansion VRAM to read/write data

(see Control Register 45)

  1. Set the address counter by writing the A14-A16 bits in register 14 (this step is not required if the VRAM size is 16kB)
  2. Set the low-order 8 bits A0 to A7 by writing data to VDP port #1 (via CPU port 99h)
  3. Set the remaining 6 bits A8 to A13 of the address counter to VDP port #1 (via CPU port 99h) and specify in bit 6 of this port which memory operation will follow (0=data read, 1=data write)
  4. Read or write data from/to VRAM on the VDP port #0 (via CPU port 98h) - note that after every data read or write operation from this port address counter is being incremented

Example

Example in assembler to write a byte in VRAM.

;-------------------------------
; Write a byte in VRAM routine
;
; Entry : BHL = VRAM address
;         D = Value
; Modify: AF, C
;-------------------------------
WRTVRM:
	ld	a,(0007h)	; A = I/O port to access to VDP write port #0 (Main-ROM must be at page 0)
	inc a			; A = I/O port to access to the VDP write port #1
	ld  c,a			; C = I/O port to access to VDP write port #1 (99h)
 
; -> Set bits a16-a14 of VRAM address to r#14 (MSX2 or newer, remove these 9 lines if MSX1)
	ld  a,h
	and 0c0h	; A = xx000000
	or  b		; A = xx00000x
	rlca
	rlca		; A = 00000xxx
 
	di			; Interrupts must be disabled here
	out (c),a
	ld  a,080h +14		; Updates r#14 (a16-a14)
	out (c),a
; <-
 
	out (c),l		; Set bits a7-a0 of VRAM address to VDP port#1
	ld  a,h
	and 03fh	; Bits 7 and 6 set to 0 and 1 for a
	or  040h	; writing
	out (c),a		; Set bits a13-a8 of VRAM address to VDP port#1
	ei			; Interrupts can be reactivated here
 
	dec c			; C = I/O port to access to VDP write port #0 (98h)
	out (c),d		; Write the value to VDP port#0
	ret


Control Register 15

This register can be only written. Use the MSX-BASIC instruction VDP(15) to access it. The instruction reads the system variable REG15SAV (0FFEEh) to return the requested value.

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
R#15: 0 0 0 0 ST3 ST2 ST1 ST0 (MSX2/2+/MSX turbo R)
  • This register is used to specify the Status Register to read via the VDP port #1. (You can write a value from 0 to 9)

The complete procedure to access a VDP Status Register is explained on the page about the VDP Status Registers.

Control Register 17

This register can be only written. Use the MSX-BASIC instruction VDP(17) to access it. This instruction reads the system variable REG17SAV (0FFF0h) to return the requested value.

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
R#15: AII 0 RS5 RS4 RS3 RS2 RS1 RS0 (MSX2/2+/MSX turbo R)

This register is used to indirectly write another VDP Control Register via the VDP port #3.

  • AII stands for 'auto-increment inhibits'. If AII=0 R#17 will increment on each writing to port #3.
  • RS0-RS5 define the number of the control register to write. (It can be 0 to 23 and 32 to 46 on MSX2 and higher, 25 to 27 on MSX2+ and higher)

Note: R#17 cannot changes himself using the indirect access.

Procedure to Indirect Write in a VDP Control Register

  1. Setup the register number in Control Register 17 and AII bit.
  2. Send the data one after the other on VDP port #3 (generally 9BH). If AII bit is 0, the register number in Control Register 17 is incremented after each writing to the port #3. This allows data to be easly written in many registers.