How stuff works: MSX tR CPU modes

By NYYRIKKI

Enlighted (6089)

NYYRIKKI's picture

04-01-2011, 12:51

There seems to be lot of missunderstanding of how MSX tR CPU modes work.

Here are few of the most common WRONG assumptions with corrections:

LED always indicates wich CPU is in use.

CPU LED has nothing to do with the CPU mode it self. This is software controlled LED that is connected to I/O port #A7 bit 7.

R800 mode = MSX-DOS2

Operating system and CPU mode don't have any link. It is true that MSX tR selects R800 as default CPU when MSX-DOS2 is started, but MSX-DOS2 works just as well with Z80 and although for example MSX-DOS1 boots with Z80, it can be used with R800 just as well. These are just sotware defaults that can be changed.

Old software can't be run on R800

R800 and Z80 are very similar CPU's. Although R800 and Z80 have some minor differences, most of Z80 software can run also on R800 without CPU related problems. R800 is how ever much faster CPU and that may cause software to look or sound different. The problems are usually pretty much same as with other MSX computers 7MHz upgrade kits that hobbyists have made. The CPU it self is much more rarely the cause of problem.

Z80, R800, R800 DRAM = Slow, Faster, Fastest

Although this is true in most cases there are also exeptions. R800 DRAM mode is faster than R800 mode only if the application uses BIOS calls. If you use for example SymbOS then you will not gain any speed but just loose 64KB of RAM. Also if application is extremely VDP intensive the R800 may actually run slower than Z80. EVA-player is good example of this.

DRAM mode can't be used on MSX-DOS1 or other older applications, only on DOS2

It is true that DRAM mode uses 4 last pages of memory mapper to store copy of ROM and therefore applications can't use this are when DRAM mode is in use. How ever DRAM mode was designed so that it looks like there is no RAM at all on these pages. This means that writing to these addresses don't have any effect and if you try to read this memory area you get only #FF as return. This means that usually programs just detect the mapper smaller than it actually is and don't even try to use this area. So, usually older applications work as well. On MSX tR MSX-DOS2 always reserves this space for DRAM mode by default and if you want to use it for other purposes, you need to request DOS2 to free it. (See DOS2 mapper support routines)

S1990 copies the BIOS to 4 last pages of mapper

No it doesn't. This is done by CPU during boot. The routine can be found from SUB-ROM address #3F1C

Z80 DRAM mode is a rumour

No, it is not. This mode is not supported by the BIOS routine, but most easy way to access it is to execute:

	XOR A
	CALL #180
	LD A,#20
	OUT (#E5),A

This will not increase the speed, but it can be used to enable running modified BIOS. (Modifications need to be done in some ROM-mode because otherways the memory is not available)

R800 and Z80 share some registers / S1990 handles the PC-register

No they don't share any registers. When CPU is switched the CPU simply stops and keeps all the registers unchanged. The BIOS routine takes care that registers are copied from one CPU to another but in order to do that both CPU's must be guided to the same routine as they both start execution from address 0 when they are powered on for first time.

When MSX tR boots, S1990 will automatically select Z80 ROM CPU mode. I/O port #F4 is used to keep track if R800 CPU has been initialized or not. Only the actual CPU select process is handled by S1990.

The CPU change is very complex thing and you need magic power to master it

Actually this is not that complex... The whole CPU control is handled by only two bits on S1990.
S1990 works so that you write register number to I/O port #E4 and then you read/write data using
I/O port #E5. CPU mode handling is located in register 6.

Here is the meaning of the bits or register 6:
bit 5: Processor mode (0=R800, 1=Z80)
bit 6: ROM mode (0=DRAM, 1=ROM)

When you access Processor mode bit directly the most important thing is that you keep track where both of the CPU's PC-registers point to. Also when you change from Z80 to R800 there seems to be a trick that should be used: In case of Z80 the code in BIOS uses OTIR to move wanted CPU mode to E5, but it also moves Z80 ROM mode request inside same command (2 byte move). I think the reason for this might be that when R800 switches back to Z80 it does not leave busses fast enough and this trick is used to prevent conflict situation on data- and address bus. (OTIR it self makes sure that PC does not get increased too early and Z80 ROM was same request that was made by R800 anyway) This is how ever pure speculation.

If you want to know more about CPU change, here is how the CPU initialization & change happens in MSX tR BIOS:


J0000:	DI				; Both Z80 and R800 will start execution from here (address 0)
	JP	J126B

;----------------------------------------

J126B:	NOP
	IN	A,(0F4H)
	BIT	7,A			; ´cold´ boot ?
	JR	Z,J127A			; yep,
	LD	A,80H
	CALL	C046A			; CHGCPU: Z80 mode, led changed
	DI
	JR	J1292			; start init

J127A:	BIT	5,A			; R800 initialized ?
	JR	NZ,J1295		; yep, continue
	OR	20H
	OUT	(0F4H),A

	LD	A,02H			; (A1ST has also PCM init here)
	OUT	(0A7H),A		; pause led off, turbo led off, b1=1

	LD	A,6
	OUT	(0E4H),A
	LD	HL,I04E5
	LD	BC,02E5H
	OTIR				; R800 ROM mode, Z80 waits here for the R800 to complete
J1292:	JP	J0416			; orginal init like in other MSX-computers

J1295:	IM	1
	XOR	A			; Z80 mode, led unchanged
	JP	J0489			; jump in CHGCPU to halt R800 and resume the Z80


----------------------------------------
;	Subroutine	CHGCPU
;	Inputs		A(b6-b0) = cpumode, A(b7) = update turboled
;	Outputs		________________________

; JP on #180 points to this address

C046A:	PUSH	AF
	AND	7FH
	CP	03H
	JR	NC,J0468		; invalid cpumode, quit
	POP	AF
	DI
	PUSH	HL
	PUSH	DE
	PUSH	BC
	PUSH	AF
	PUSH	IX
	PUSH	IY
	EXX
	EX	AF,AF'
	PUSH	HL
	PUSH	DE
	PUSH	BC
	PUSH	AF			; save all Z80 registers
	LD	A,I
	PUSH	AF			; save interrupttable pointer
	LD	(D.FFFD),SP		; save stackpointer
	EX	AF,AF'
J0489:	AND	83H
	LD	C,A
	LD	B,00H
	LD	HL,CASPRV
	LD	A,(HL)
	SLA	C
	RES	1,A
	JR	NZ,J049A		; R800, b1=0
	SET	1,A			; Z80, b1=1
J049A:	JR	NC,J04A2		; flag update turboled not set, turboled unchanged
	RES	7,A
	JR	Z,J04A2			; Z80, turboled off
	SET	7,A			; R800, turboled on
J04A2:	LD	(HL),A
	OUT	(0A7H),A
	LD	HL,I04E3
	ADD	HL,BC
	LD	A,6
	OUT	(0E4H),A
	IN	A,(0E5H)
	INC	B
	BIT	5,A
	JR	Z,J04B5
	INC	B
J04B5:	LD	C,0E5H
	OTIR
	DI
	NOP
	LD	SP,(D.FFFD)		; restore stackpointer
	POP	AF
	LD	I,A			; restore interrupttable pointer
	POP	AF
	POP	BC
	POP	DE
	POP	HL
	EXX
	EX	AF,AF'
	POP	IY
	POP	IX
	POP	AF
	POP	BC
	POP	DE
	POP	HL			; restore all Z80 registers
	EI
	RET
;----------------------------------------

I04E3:	DEFB	060H,060H		; Z80
I04E5:	DEFB	040H,060H		; R800 ROM
	DEFB	000H,060H		; R800 RAM
Login or register to post comments

By Edwin

Paragon (1182)

Edwin's picture

04-01-2011, 14:48

Great stuff! There were some misconceptions there that I've never even heard myself.

Z80, R800, R800 DRAM = Slow, Faster, Fastest

Although this is true in most cases there are also exeptions. R800 DRAM mode is faster than R800 mode only if the application uses BIOS calls. If you use for example SymbOS then you will not gain any speed but just loose 64KB of RAM. Also if application is extremely VDP intensive the R800 may actually run slower than Z80. EVA-player is good example of this.

Note that the reason why DRAM mode is faster is because every access outside the main memory of the turbo R gets a 3 (IIRC) cycle delay. This means that every routine that runs directly in ROM would get a 3 cycle penalty for every byte of every instruction. That stacks up pretty quickly. DRAM avoids that penalty.

Also the reason that intensive VDP access is slower on R800 is not actually because of the R800, but because the S1990 adds overly conservative delays to every access to the VDP. The z80 doesn't get this delay and can is fact allowed to access the VDP quicker than the R800.

By Huey

Prophet (2694)

Huey's picture

04-01-2011, 19:47

Good work NYYRIKKI! Thanks.Cool

By zeilemaker54

Champion (355)

zeilemaker54's picture

04-01-2011, 22:12

Good work NYYRIKKI!
It is good to see that you even have quoted my source file at msxsyssrc. No problem at all.

By snout

Ascended (15187)

snout's picture

04-01-2011, 23:06

Thank you so much for this clear information, NYYRIKKI! A valuable source of info...

By Maggoo

Paragon (1218)

Maggoo's picture

05-01-2011, 00:33

Very good article. Just out of curiosity, why isn't there (or perhaps I missed it) a WIKI site to cover MSX programming with code snipets and documentation ? It would make it easy for various programmers to contribute and find code of constantly re-inventing the wheel.

By NYYRIKKI

Enlighted (6089)

NYYRIKKI's picture

05-01-2011, 05:26

@zeilemaker54: Yes, sorry that I forgot to include greetings to you. You have done really great job with the sources. I always keep them near in case I want to check something out.

@Maggoo: Amen. It has been on my wish list as well for many years now, but I guess Santa has been busy with the nice kids. Crying Forum is not a best place to put up this kind of information because once you make a mistake, it will haunt you back forever. Sad

By Jorito

Mr. Ambassadors (1802)

Jorito's picture

05-01-2011, 07:49

Wait a bit longer for the MSX wiki, as it will be part of the new MRC site, due for release this year.

I also already nominated this article for a wiki page.

By coldbreeze

Master (141)

coldbreeze's picture

06-01-2011, 13:56

Great job, NYYRIKKI!