TMS9918A RomWBW Video Driver revisited - VRAM Memory Map

445 views
Skip to first unread message

positron (Jose L. Collado)

unread,
Nov 16, 2023, 5:57:04 PM11/16/23
to RC2014-Z80
While using the TMS9918A video card as a VDU Console in CP/M, I noticed that J.B. Langstron's example programs worked fine but on exit they corrupted the screen, even the ones that use Text mode. 

Looking at the code and comparing it with RomWBW HBIOS tms.asm driver, I noticed that the VRAM memory maps are different, causing this effect (specially corrupting the Font Table). This is not a fault on RomWBW's side, but the mappings differ from the ones documented in TI's TMS9918 Programmers Guide that are used in the mentioned example programs.

So I decided to modify tms.asm to make it compatible with the documented definitions for Mode II, that also work fine with Mode I (Text mode used in the VDU Console).

Screen Shot 2023-11-16 at 18.53.48.png
I also created a very simple CP/M program that changes the screen colors for Text and Background, for the default Text mode used at console level. I hope to create additional utility programs for graphic modes, so the video card can be used for more than playing Colecovion games :-)

You can find documentation, source code and the binary for the TMSCOLOR.COM utility at my Github Repository  https://github.com/MorfeoMatrixx/RCBUS-TMS9918A-Dev


Wayne Warthen

unread,
Nov 16, 2023, 11:10:35 PM11/16/23
to RC2014-Z80
This is interesting Jose.  I will compare your work with RomWBW when I can.

Thanks,

Wayne

positron (Jose L. Collado)

unread,
Nov 17, 2023, 8:09:50 AM11/17/23
to RC2014-Z80
Thanks Wayne ! You can spot my changes easily since they include comments with the words "### JLC Mod".

I will also try to modify the ANSI emulation module ansi.asm to handle the escape sequences for changing text colors. I know that due to chip limitations this affects the whole screen as you previously commented, but IMHO could be better than nothing.

Cheers, JL.

Alan Cox

unread,
Nov 17, 2023, 9:41:42 AM11/17/23
to rc201...@googlegroups.com

Looking at the code and comparing it with RomWBW HBIOS tms.asm driver, I noticed that the VRAM memory maps are different, causing this effect (specially corrupting the Font Table). This is not a fault on RomWBW's side, but the mappings differ from the ones documented in TI's TMS9918 Programmers Guide that are used in the mentioned example programs.

The TMS99xx using systems I'm aware of that used CP/M all seem to just reset the registers on a warm restart so that when programs
exit they video registers are put back. Being write only it's hard to do much else and there isn't a portable place or way to provide the existing values.

The second problem then is interrupts. Some machines used the VDP interrupt for timing so if you turn it off you lose, and if you leave it on you have to be careful to disable ints around operations on the VDP. If it uses NMI then it's a car-crash anyway as CP/M and Z80 NMI cannot co-exist.

For RomWBW just putting the proper values and font back so a program exit at worst leaves you with a messy display might be the best option perhaps ?

Alan

positron (Jose L. Collado)

unread,
Nov 17, 2023, 5:00:50 PM11/17/23
to RC2014-Z80
Thanks Alan for your clarification, you're right about the write-only limitation of registers that define the chips's configuration. In part because of that, I just wanted to propose a quasi-standard for the memory map, to somehow decrease the uncertainty of not knowing the config state left by a program. And I think that maybe the best place to start is with RomWBW's VDU driver.

This memory map is also used in JB's modified version of BBC BASIC for Z80-CP/M that implements some limited graphic commands for the TMS9918A. It's a very promising project, and as I recall the only CP/M BASIC version available for RCBUS Zx80+TMS9918A with some sort of graphic capabilities. Maybe JB can comment about his plans (https://github.com/jblang/bbcbasic-z80) because it looks stalled since 2020.

Cheers, JL.

Alan Cox

unread,
Nov 18, 2023, 6:38:47 AM11/18/23
to rc201...@googlegroups.com
On Fri, 17 Nov 2023 at 22:00, positron (Jose L. Collado)
<joseluis...@gmail.com> wrote:
>
> Thanks Alan for your clarification, you're right about the write-only limitation of registers that define the chips's configuration. In part because of that, I just wanted to propose a quasi-standard for the memory map, to somehow decrease the uncertainty of not knowing the config state left by a program. And I think that maybe the best place to start is with RomWBW's VDU driver.

I think MSX beat you to it. I am not sure if MSX follows the manual on
the register settings but if it does that certainly makes things
tidier for porting etc. Hopefully nothing relies on the existing
setup.

The reload on a warm boot in the BIOS is IMHO worth doing anyway, it
gets you back to a prompt if an app doesn't restore correctly or dies
and you are using the VDP as your console (e.g. on the N8).

Alan

positron (Jose L. Collado)

unread,
Nov 18, 2023, 1:50:36 PM11/18/23
to RC2014-Z80
Thanks again Alan I completly agree. Let's hope Wayne can accomodate this reload of registers and font table, in a future dev release maybe, without having to rely on much platform-specific code in the BIOS (I woudn't know how to do it...)

By the way, I recall there was a trick in CP/M 2.2 to auto-exec a program with the reload of CCP, by filling the buffer with the desired file name I think... that program could do the proper text mode init... or am I wrong ? In the meantimer, could this be a quick and dirty hack ?

Cheers, JL.

Wayne Warthen

unread,
Nov 18, 2023, 6:38:17 PM11/18/23
to RC2014-Z80

positron (Jose L. Collado)

unread,
Nov 19, 2023, 12:13:31 PM11/19/23
to RC2014-Z80
That's excellent news, thanks Wayne !

Wayne Warthen

unread,
Nov 24, 2023, 10:05:39 PM11/24/23
to rc201...@googlegroups.com
Jose,

Your updates to the TMS driver (tms.asm) have been published with RomWBW Development Snapshot v3.4.0-dev.24.  Let me know if you have any questions or issues.

Thanks,

Wayne
Message has been deleted

positron (Jose L. Collado)

unread,
Nov 25, 2023, 4:26:49 PM11/25/23
to RC2014-Z80
Many thanks Wayne. I'll update to the last dev and test. 
Now trying to decipher the hbios, tty, ansi & tms entanglement (at least for my limited experience with HAL drivers) to implement text color change via ansi sequence (within the very limited posibilities of the chip, per-screen only). I think I'm almost there...

Cheers, JL

Wayne Warthen

unread,
Nov 25, 2023, 7:57:31 PM11/25/23
to RC2014-Z80
Are you inventing new ANSI escape sequences to do this?

Thanks,

Wayne

Jose Luis Collado

unread,
Nov 26, 2023, 1:30:57 PM11/26/23
to rc201...@googlegroups.com
Not really, the \ESC[...m sequence could be abused... This is my plan... Do you think it makes any sense ?
Thanks for the follow-up !

; ### JLC Mod - Change Text Color - TO DO
;
; Desired Color from ANSI Escape Sequence stored at ANSI_COLOR
; Bold (or Bright) Attribute bit stored at ANSI_ATTR only used for Bright Colors
;
; Implement the following ESC Sequence: \ESC[{NUM1};...;{NUMn}m
;  Set multiple display attributes. The following are supported here:
;  0 - Reset all attributes
;  1 - Bright
;  30..37 - Foreground color (black, red, green, yellow, blue, magenta, cyan, white)
;  40..47 - Background color
;
; Example: \ESC[1;31m sets text to Bright Red, \ESC[0m returns to default colors
;

TMS_VDASAT:                     ; Only Bold Attribute used for additional Colors
    XOR A                       ; NOT IMPLEMENTED, JUST SIGNAL SUCCESS
    RET

TMS_VDASCO:
; Insert code here...
; Shuffle bits around from ANSI_COLOR to required TMS9918A format
; Use Bold bit of ANSI_ATTR to generate additional 7 (Bright) colors
; Change Register 7 for new Text*Background Colors according to ANSI_COLOR
; This changes the whole text screen due to the chip's limitations...


Regards,
José Luis.


--
You received this message because you are subscribed to a topic in the Google Groups "RC2014-Z80" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rc2014-z80/SC4cK6FIyBA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rc2014-z80+...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/rc2014-z80/690bcb70-e3b7-4fe6-a71b-f6f907b90280n%40googlegroups.com.

Wayne Warthen

unread,
Nov 26, 2023, 6:07:40 PM11/26/23
to RC2014-Z80
Hi Jose,

On Sunday, November 26, 2023 at 10:30:57 AM UTC-8 Jose Luis Collado wrote:
Not really, the \ESC[...m sequence could be abused... This is my plan... Do you think it makes any sense ?

Oh, please don't do that!  The problem is that users will be running applications that already use those commands for their documented purpose.  If one of those applications is run on a TMS9918 video board with your proposed changes, then every time an application manipulates a character attribute, then the entire screen will change attributes.  Applications that use character colors tend to send character color changes a lot while they paint a screen.  This would result in a nightmare of screen color flipping.

Sorry,

Wayne

positron (Jose L. Collado)

unread,
Nov 26, 2023, 7:04:41 PM11/26/23
to RC2014-Z80
OK, don't worry, I wont go that path, I don't have the intention to generate any color catastrophy ;-)
I was speculating that ANSI color sequences were not used much in CP/M-80 console programs, that only attributes like bright/bold, underline and blink were actually used.

Do you agree on creating a new ad-hoc sequence instead ? I will have to read the full ANSI spec to see if there are user defined sequences that could be used.

Thanks for your recommendation.

Cheers, JL.

Wayne Hortensius

unread,
Nov 26, 2023, 7:30:20 PM11/26/23
to rc201...@googlegroups.com
On Sun, 26 Nov 2023 16:04:40 -0800 (PST)
"positron (Jose L. Collado)" wrote:

> Do you agree on creating a new ad-hoc sequence instead ? I will have
> to read the full ANSI spec to see if there are user defined sequences
> that could be used.

There's support for declaring your own private sequences. From
https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_(Control_Sequence_Introducer)_sequences

A subset of arrangements was declared "private" so that terminal
manufacturers could insert their own sequences without conflicting with
the standard. Sequences containing the parameter bytes <=>? or the
final bytes 0x70–0x7E (p–z{|}~) are private.

Regards,
Wayne

Wayne Warthen

unread,
Nov 26, 2023, 10:57:46 PM11/26/23
to RC2014-Z80

Jose Luis Collado

unread,
Nov 27, 2023, 10:09:16 AM11/27/23
to rc201...@googlegroups.com
Thanks Wayne H. for the tip and Wayne W. for your guidance, I'll get back to you soon with my thoughts.

Cheers, JL.


--
You received this message because you are subscribed to a topic in the Google Groups "RC2014-Z80" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rc2014-z80/SC4cK6FIyBA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rc2014-z80+...@googlegroups.com.

Jose Luis Collado

unread,
Nov 27, 2023, 4:40:29 PM11/27/23
to rc201...@googlegroups.com
Hi Wayne, I'm starting to understand the inner workings of the HBIOS API & VDA Driver architrecture. Hats off to you for the underlying design !

I understand that apart from having to modify ansi.asm (to add the new custom or "private" sequence), the tms.asm to actually implement the low level hw specific code (TMS register writing), I also have to update hbios.asm to add or modify an API function to link both. Am I right ?

I think we have at least 2 options that could not require a new VDA API (whose function/jump table is actually full as you suspected):

1. Extend the functionality of the VDARES function...

"8.6.3 Function 0x42 – Video Reset (VDARES)
Entry Parameters Returned Values

B: 0x42    A: Status    C: Video Unit

Performs a soft reset of the specified Video Unit (C). Will clear the screen, home the cursor, and restore active attribute/color to defaults. Keyboard will be flushed. The current video mode will not be changed. The returned Status (A) is a standard HBIOS result code."

... by adding the desired Foreground & Background combination colors passed in the E register, with the standard format used in HBIOS. This option doesn't seem so 'hackish' because we are changing the default colors that affect the whole screen, as originally  intended by the function but limited to fixed default colors set at compile time. This could be my prefered option.

2. Extend the functionality of the VDASCO function...

"8.6.8 Function 0x47 – Video Set Character Color (VDASCO) Entry Parameters Returned Values

B: 0x47    A: Status    C: Video Unit.  E: Color

Assign the specified Color (E) code to be used for all subsequent character writes/fills. This color is also used to fill new lines generated by scroll operations. Refer to the color code table above for a list of the available color codes. Note that a given video display may or may not support any/all colors. The Status (A) is a standard HBIOS result code."

... by adding a "scope" parameter passed in the D register, like D=$FF for Screen and D!=$FF for Character. This sounds more far-fetched to me.

I understand that if there are any actual user programs that use these HBIOS functions this could be disruptive if random values are unintentionally passed in the new registers... But no CP/M "commercial" programs will be affected.

Let me know you're thoughts about this.  I'm learning a lot about RomWBW and re-learning Z80... lot's of fun !

Cheers,
José Luis.


On Mon, Nov 27, 2023 at 12:57 AM Wayne Warthen <wwar...@gmail.com> wrote:
--
You received this message because you are subscribed to a topic in the Google Groups "RC2014-Z80" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rc2014-z80/SC4cK6FIyBA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rc2014-z80+...@googlegroups.com.

Wayne Warthen

unread,
Nov 28, 2023, 10:08:35 PM11/28/23
to RC2014-Z80
Hi Jose,

I think you are on the right track here.

On Monday, November 27, 2023 at 1:40:29 PM UTC-8 Jose Luis Collado wrote:
I understand that apart from having to modify ansi.asm (to add the new custom or "private" sequence), the tms.asm to actually implement the low level hw specific code (TMS register writing), I also have to update hbios.asm to add or modify an API function to link both. Am I right ?

This is exactly correct.

I think we have at least 2 options that could not require a new VDA API (whose function/jump table is actually full as you suspected):

I see where you are going with these 2 options, but I see issues with both.  I will explain the issues, then suggest an alternative.

1. Extend the functionality of the VDARES function...

"8.6.3 Function 0x42 – Video Reset (VDARES)
Entry Parameters Returned Values

B: 0x42    A: Status    C: Video Unit

Performs a soft reset of the specified Video Unit (C). Will clear the screen, home the cursor, and restore active attribute/color to defaults. Keyboard will be flushed. The current video mode will not be changed. The returned Status (A) is a standard HBIOS result code."

... by adding the desired Foreground & Background combination colors passed in the E register, with the standard format used in HBIOS. This option doesn't seem so 'hackish' because we are changing the default colors that affect the whole screen, as originally  intended by the function but limited to fixed default colors set at compile time. This could be my prefered option.

I generally like this option, but the issue I see is that the call is intended as a way to generically reset the screen.  In fact, this is the exact API call I intend to use to ensure that video is properly restored whenever CP/M does a soft reset.  Therein lies the problem.  If I need to generically reset the screen, I don't want to specify a new screen color.  I want to reuse the current screen color.  Yes, we could use another register to indicate that the current screen color should be retained, so this option is potentially workable.

2. Extend the functionality of the VDASCO function...

"8.6.8 Function 0x47 – Video Set Character Color (VDASCO) Entry Parameters Returned Values

B: 0x47    A: Status    C: Video Unit.  E: Color

Assign the specified Color (E) code to be used for all subsequent character writes/fills. This color is also used to fill new lines generated by scroll operations. Refer to the color code table above for a list of the available color codes. Note that a given video display may or may not support any/all colors. The Status (A) is a standard HBIOS result code."

... by adding a "scope" parameter passed in the D register, like D=$FF for Screen and D!=$FF for Character. This sounds more far-fetched to me.

I understand that if there are any actual user programs that use these HBIOS functions this could be disruptive if random values are unintentionally passed in the new registers... But no CP/M "commercial" programs will be affected.

Functionally, this option will work.  But I'm not fond of the semantics.  Normally, the call is intended to simply set the colors/attributes to be used for future calls.  The proposed usage would actually implement the screen color change if the scope indicated to do so.  As I said, it would functionally work, just feels odd to me.

Let me know you're thoughts about this.  I'm learning a lot about RomWBW and re-learning Z80... lot's of fun !


Glad you are enjoying this!

The alternative I would propose is to use Function 0x40, the Video Initialize function.  The purpose of this function is to set up the video from scratch.  This feels like the ideal place to establish the screen colors.  Register D does not appear to be used here.  Essentially, I am suggesting the use of this function just like you proposed to use the Video Reset function.  The value in register D would be ignored by any video driver that doesn't understand how to handle it.  The TMS driver would use it as part of the chip programming that would naturally occur in the Video Initialize function.  It would also record the value provided as the default for the Video Reset function.

The biggest issue with this approach is that existing calls to this function may leave register D undefined which would mean that the screen colors would be programmed with some random value.  However, we basically have that problem with any of these approaches.  The only way around this issue would be to create a new API function call explicitly for this capability.  Unfortunately, there are no slots left in the Video API.  The good news is that I am pretty sure no one has created any applications that are calling this API directly (at least not the Video Initialize function).  So, we probably have a reasonable opportunity to define the new parameter without causing any trouble for existing applications.

I'm not trying to dictate this solution, but I'm asking you to consider it and let me know what you think.  

Thanks,

Wayne

Jose Luis Collado

unread,
Nov 29, 2023, 3:59:04 PM11/29/23
to rc201...@googlegroups.com
Thanks Wayne for your thorough review. I agree with your alternative of using VDAINI (0x40) with the additional color parameter (following the format described in Section 8.6 of the  RomWBW System Guide) passed in reg D.
I'll get back to you via private if I have any further questions while implementing this, If you don't mind.

Regards,
José Luis.


--
You received this message because you are subscribed to a topic in the Google Groups "RC2014-Z80" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rc2014-z80/SC4cK6FIyBA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rc2014-z80+...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages