Need help by getting my v9958 to work

Page 1/3
| 2 | 3

By alexo_92

Supporter (14)

alexo_92's picture

16-08-2013, 18:13

Hello,

first I want to say this is my first project with a v9958 or similar ICs and I am not really sure if I am right at this forum.
But I hope that you can help me.

First I would like to tell the background information. I bought a Z80 kit with a v9958 a while ago and I want to test the v9958 with an breadboard building and the Arduino 2560.
But it doesn't work there is no signal at the TV and I don't know what's wrong.
I can't say if it is the schematic or the software.
I hope you can help me.

The schematic:

Software for the Arduino Mega2560:


  byte pinCSR    = 31;
  byte pinCSW    = 33;
  byte pinWAIT   = 35;
  byte pinINT    = 37;
  byte pinRESET  = 39;
  byte pinCPUCLK = 41;
  byte pinMODE0  = 53;
  byte pinMODE1  = 52;

void setup() {
  
  DDRA = B11111111; //CD Bus
  PORTA = 0x00;
  
  pinMode(pinCSR, OUTPUT);
  pinMode(pinCSW, OUTPUT);
  pinMode(pinRESET, OUTPUT);
  pinMode(pinMODE0, OUTPUT);
  pinMode(pinMODE1, OUTPUT);
  
  pinMode(pinWAIT, INPUT);
  pinMode(pinINT, INPUT);
  pinMode(pinCPUCLK, INPUT);
  
  digitalWrite(pinCSR, HIGH);
  digitalWrite(pinCSW, HIGH);
  digitalWrite(pinRESET, HIGH);
  digitalWrite(pinMODE0, LOW);
  digitalWrite(pinMODE1, LOW);


  //Reset
  digitalWrite(pinRESET, LOW);
  delay(5);
  digitalWrite(pinRESET, HIGH);

}

void writedata(byte Mode, byte wData) {
  DDRA = B11111111; //CD Bus
  PORTA = 0x00;
  switch (Mode) {
    case 0:
      digitalWrite(pinMODE0, LOW);
      digitalWrite(pinMODE1, LOW);
      break;
    case 1:
      digitalWrite(pinMODE0, HIGH);
      digitalWrite(pinMODE1, LOW);
      break;
    case 2:
      digitalWrite(pinMODE0, LOW);
      digitalWrite(pinMODE1, HIGH);
      break;
    case 3:
      digitalWrite(pinMODE0, HIGH);
      digitalWrite(pinMODE1, HIGH);
      break;
    default:
      digitalWrite(pinMODE0, LOW);
      digitalWrite(pinMODE1, LOW);
  }
  delayMicroseconds(1);
  digitalWrite(pinCSW, LOW);
  delayMicroseconds(0.6);
  PORTA = wData;
  delayMicroseconds(0.1);
  digitalWrite(pinCSW, HIGH);
  delayMicroseconds(0.1);
  PORTA = 0x00;
}

byte readdata(byte Mode) {
  DDRA = B00000000; //CD Bus
  PORTA = 0x00;
  byte input;
  switch (Mode) {
    case 0:
      digitalWrite(pinMODE0, LOW);
      digitalWrite(pinMODE1, LOW);
      break;
    case 1:
      digitalWrite(pinMODE0, HIGH);
      digitalWrite(pinMODE1, LOW);
      break;
    case 2:
      digitalWrite(pinMODE0, LOW);
      digitalWrite(pinMODE1, HIGH);
      break;
    case 3:
      digitalWrite(pinMODE0, HIGH);
      digitalWrite(pinMODE1, HIGH);
      break;
    default:
      digitalWrite(pinMODE0, LOW);
      digitalWrite(pinMODE1, LOW);
  }
  delayMicroseconds(1);
  digitalWrite(pinCSR, LOW);
  delayMicroseconds(0.10);
  input = PORTA;
  delayMicroseconds(0.1);
  digitalWrite(pinCSR, HIGH);
  delayMicroseconds(0.1);
  return input;
}

void loop() {
  //Text 1 mode
  
  
  writedata(1, 0);          /*                                   */
  writedata(1, 0x80 + 17);  /* Set Pointer of Register #17 to #0 */
  
  writedata(3, B00000000);  /* Set Register #1                   */
  writedata(3, B01010000);  /* Set Register #2                   */
  
  writedata(1, 8);          /*                                   */
  writedata(1, 0x80 + 17);  /* Set Pointer of Register #17 to #8 */
  
  writedata(3, B00001010);  /* Set Register #8                   */
  writedata(3, B00000010);  /* Set Register #9                   */
  
  
  writedata(1, B00000000);  /*                                   */
  writedata(1, 0x80 + 16);  /* Set Palette Register 0            */
  writedata(2, B00000000);  /*  R=000 , B=000 , G=000            */
  writedata(2, B00000000);  /*  => Schwarz                       */
  
  writedata(1, B00000001);  /*                                   */
  writedata(1, 0x80 + 16);  /* Set Palette Register 1            */
  writedata(2, B01110111);  /*  R=111 , B=111 , G=111            */
  writedata(2, B00000111);  /*  => Weiß                          */
  
  writedata(1, B00010000);  /*                                   */
  writedata(1, 0x80 +  7);  /* Set Pattern color                 */
  
  
  
  writedata(1, B00000000);  /*                                   */
  writedata(1, 0x80 + 45);  /* Set to Video Ram                  */
  
  
  writedata(1, B00000000);  /*                                   */
  writedata(1, 0x80 + 45);  /* Set to Video Ram                  */
  
  
  
  writedata(1, B00000000);  /* A16-A14                           */
  writedata(1, B00000000);  /* A7-A0                             */
  writedata(1, B01000000);  /* A13-A8 , R/W                      */
                            /* Set the address 00000h            */
                            /* Pattern layout table 0            */
  writedata(1, 0x80 + 14);  /* to Register #14                   */
  
                            /* Write to VRAM                     */
  writedata(0, 0);          /* Pattern #0 => H                   */
  writedata(0, 1);          /* Pattern #1 => A                   */
  writedata(0, 2);          /* Pattern #2 => L                   */
  writedata(0, 2);          /* Pattern #3 => L                   */
  writedata(0, 3);          /* Pattern #4 => O                   */
  
  
  writedata(1, B00000000);  /* A16-A14                           */
  writedata(1, B00000000);  /* A7-A0                             */
  writedata(1, B01001000);  /* A13-A8 , R/W                      */
                            /* Set the address 00800h            */
                            /* Pattern generator table 0         */
  writedata(1, 0x80 + 14);  /* to Register #14                   */
  
                            /* Write to VRAM                     */
                            /* Pattern "H"                       */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B11111000);  /* XXXXX                             */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B00000000);  /*                                   */
                            /* Pattern "A"                       */
  writedata(0, B00100000);  /*   X                               */
  writedata(0, B01010000);  /*  X X                              */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B11111000);  /* XXXXX                             */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B00000000);  /*                                   */
                            /* Pattern "L"                       */
  writedata(0, B10000000);  /* X                                 */
  writedata(0, B10000000);  /* X                                 */
  writedata(0, B10000000);  /* X                                 */
  writedata(0, B10000000);  /* X                                 */
  writedata(0, B10000000);  /* X                                 */
  writedata(0, B10000000);  /* X                                 */
  writedata(0, B11111000);  /* XXXXX                             */
  writedata(0, B00000000);  /*                                   */
                            /* Pattern "O"                       */
  writedata(0, B01110000);  /*  XXX                              */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B10001000);  /* X   X                             */
  writedata(0, B01110000);  /*  XXX                              */
  writedata(0, B00000000);  /*                                   */
  
  
  
  writedata(1, B00000000);  /*                                   */
  writedata(1, 0x80 +  2);  /* Set Pattern nametable to 0        */
  
  writedata(1, B00000001);  /*                                   */
  writedata(1, 0x80 +  4);  /* Set Pattern Generator table to 0  */
  
}

Login or register to post comments

By RetroTechie

Paragon (1563)

RetroTechie's picture

18-08-2013, 12:32

Welcome here, alexo_92! Running Naked in a Field of Flowers

Shouldn't /HRESET (pin 27) and /VRESET (pin 4) be connected to something? According to V9958 databook those are inputs. Maybe hook up to a pull-up/pull-down resistor, or check how an MSX2+ / Turbo-R computer wires those pins?

SCART wiring is incomplete. Connect pin 8 to +12V via a 1 kOhm resistor, that will tell TV there's a 4:3 aspect ratio signal coming in. Also connect pin 16 (fast blanking) to +5V via 100 Ohm or so. With the 75 Ohm on monitor side, that will give ~2V, which tells monitor there's an RGB signal coming in.

Your TV output is lacking a sync signal? oO I assume D4/D5/D6 are meant to pull R/G/B to black level when sync is active? Shouldn't be necessary, I think V9958 is smart enough to do that by itself. I suggest you remove D4/D5/D6.

C31/C32/C33 should be on output side of the transistors. Like shown, you're pulling the transistor base below 0V at times, which may not work as intended. Perhaps even test without series capacitors in the R/G/B outputs, TV's are pretty forgiving as long as the DC levels aren't excessive.

Moreover: composite sync signal (V9958 pin 6) doesn't make it to the SCART connector! A monitor/TV really needs this to produce an image!

As for the software: why do you (re)set PORTA to 0x00 in between writes? Just set the mode pins, set the data, toggle /CSW (while observing required delays).

Dunno if it makes sense to (try to) write VRAM as long as you don't have anything on screen. Perhaps it's easier to set the VDP to a blank screen, and change background color in a loop? That should tell you whether R/G/B outputs are okay & TV is able to lock onto the sync signal etc. See R#1 bit 6 (BL) in V9938 databook. If set to disabled, VDP outputs background color, which is a single internal register - R#7 bit 0-3 (BD0-BD3 = back drop color). Perhaps you need to set the corresponding pallette registers too, but this way you can produce some colors on screen without touching VRAM. Move on to text output when R/G/B/sync output works.

By alexo_92

Supporter (14)

alexo_92's picture

18-08-2013, 18:09

thank you,
I already lost the hope that anyone will answer.

I made the changes on the circuit and the code.

The new schematic:

The new code:



  byte pinCSR    = 31;
  byte pinCSW    = 33;
  byte pinWAIT   = 35;
  byte pinINT    = 37;
  byte pinRESET  = 39;
  byte pinCPUCLK = 41;
  byte pinMODE0  = 53;
  byte pinMODE1  = 52;

void setup() {
  
  DDRA = B11111111; //CD Bus
  PORTA = 0x00;
  
  pinMode(pinCSR, OUTPUT);
  pinMode(pinCSW, OUTPUT);
  pinMode(pinRESET, OUTPUT);
  pinMode(pinMODE0, OUTPUT);
  pinMode(pinMODE1, OUTPUT);
  
  pinMode(pinWAIT, INPUT);
  pinMode(pinINT, INPUT);
  pinMode(pinCPUCLK, INPUT);
  
  digitalWrite(pinCSR, HIGH);
  digitalWrite(pinCSW, HIGH);
  digitalWrite(pinRESET, HIGH);
  digitalWrite(pinMODE0, LOW);
  digitalWrite(pinMODE1, LOW);


  //Reset
  digitalWrite(pinRESET, LOW);
  delay(5);
  digitalWrite(pinRESET, HIGH);

}

void writedata(byte Mode, byte wData) {
  DDRA = B11111111; //CD Bus
  //PORTA = 0x00;
  switch (Mode) {
    case 0:
      digitalWrite(pinMODE0, LOW);
      digitalWrite(pinMODE1, LOW);
      break;
    case 1:
      digitalWrite(pinMODE0, HIGH);
      digitalWrite(pinMODE1, LOW);
      break;
    case 2:
      digitalWrite(pinMODE0, LOW);
      digitalWrite(pinMODE1, HIGH);
      break;
    case 3:
      digitalWrite(pinMODE0, HIGH);
      digitalWrite(pinMODE1, HIGH);
      break;
    default:
      digitalWrite(pinMODE0, LOW);
      digitalWrite(pinMODE1, LOW);
  }
  delayMicroseconds(1);
  digitalWrite(pinCSW, LOW);
  delayMicroseconds(0.6);
  PORTA = wData;
  delayMicroseconds(0.1);
  digitalWrite(pinCSW, HIGH);
  delayMicroseconds(0.1);
  PORTA = 0x00;
}

void loop() {
  //Backcolor Test
  
  writedata(1, 0);          /*                                   */
  writedata(1, 0x80 + 17);  /* Set Pointer of Register #17 to #0 */
  
  writedata(3, B00000000);  /* Set Register #1                   */
  writedata(3, B00010000);  /* Set Register #2                   */
  
  writedata(1, 8);          /*                                   */
  writedata(1, 0x80 + 17);  /* Set Pointer of Register #17 to #8 */
  
  writedata(3, B00001010);  /* Set Register #8                   */
  writedata(3, B00000010);  /* Set Register #9                   */
  
  
  writedata(1, B00000000);  /*                                   */
  writedata(1, 0x80 + 16);  /* Set Palette Register 0            */
  writedata(2, B01110000);  /*  R=111 , B=000 , G=000            */
  writedata(2, B00000000);  /*  => Schwarz                       */
  
  writedata(1, B00000000);  /*                                   */
  writedata(1, 0x80 +  7);  /* Set Pattern color                 */
  
}

Maybe I will get the time to test the changes today.

By the way I've got an another question.
When I use the Register indirect addressing and the adressed register needs more than 1 byte ( like the Palette register needs 3 bytes) can write the 3 bytes to Port #3 or will register #17 increment after the first byte?

By sd_snatcher

Prophet (3019)

sd_snatcher's picture

18-08-2013, 19:30

I'd recommend you to take a look at the MSX Turbo-R service manual (either A1ST or A1GT), since the complete schematic is there. If I recall correctly, it was available on Han's Otten website.

You can also take a look at the Schematics for the Expert3. It shows the complete schematics of the machine, except only for the turbo clock part.

http://www.msxpro.com/esquemas.html

Last, but not least, there are similar schematics on the MSX Datapack:
http://www.konamito.es/msx-datapack/

Your code doesn't seem to deal with the /WAIT signal from the V9958. And this is a *must* on a fast CPU like the arduino. In fact, this signal in indispensable for anything faster than a 5.37MHz Z80. The /WAIT generation must be enabled in the V9958 registers. Take a look at the V9958 datasheet to learn how to enable it.

By alexo_92

Supporter (14)

alexo_92's picture

18-08-2013, 20:26

I took a look at the file VDP.pdf of the expert3b.rar archieve and it looks like there aren't any transistors.
Are the outputs really connected directly to the TV?
Can I get a composite video signal just by connecting the rgb lines via resistors?
And I don't get the sense of JUMP3 at the top center.

By sd_snatcher

Prophet (3019)

sd_snatcher's picture

18-08-2013, 22:32

Quote:

I took a look at the file VDP.pdf of the expert3b.rar archieve and it looks like there aren't any transistors.
Are the outputs really connected directly to the TV?
Can I get a composite video signal just by connecting the rgb lines via resistors?
And I don't get the sense of JUMP3 at the top center.

Ok, my fault: I forgot that detail. The Expert 1.x had a second board for that, called "analog board" that isn't shown in the schematics because the Expert3 is an upgrade board and the analog board is reused on the machine receiving the upgrade.

For the analog part of the V9958 circuit it's better for you to check the Panasonic MSX Turbo-R Service Manuals.

By alexo_92

Supporter (14)

alexo_92's picture

19-08-2013, 14:16

It seems like they used a chip instead of analog logic.
The documents "Turbo-R A1ST - Service Manual " and "Turbo-R A1GT - Service Manual " have used a IC with the description "DACXA1145TXS".
I don't have such an IC.
I have searched almost all documents.
Where can I get the schematic of the "analog board"?

By alexo_92

Supporter (14)

alexo_92's picture

19-08-2013, 23:03

The file "ddx2.0.zip" contains a schematic with an analog circuit in the bottom left corner.
And there is a signal called "VIDEO". Is this composite video for AV?
Do anyone of you know if this circuit will work?
I don't have the resistors for 12K and 27K and I don't have the 2N5401.
In that case I can't test it right now.

By Gradius2

Hero (570)

Gradius2's picture

19-08-2013, 23:31

alexo_92 wrote:

It seems like they used a chip instead of analog logic.
The documents "Turbo-R A1ST - Service Manual " and "Turbo-R A1GT - Service Manual " have used a IC with the description "DACXA1145TXS".
I don't have such an IC.
I have searched almost all documents.
Where can I get the schematic of the "analog board"?

What this "dac" does? VDP can output RGB signal and Syncs directly. Why it would need a "dac" ?

By msxholder

Champion (336)

msxholder's picture

20-08-2013, 00:02

Read it as a cxa 1145 made by sony
You will find it in a an Sega for instance

By RetroTechie

Paragon (1563)

RetroTechie's picture

21-08-2013, 12:23

+12V (via R11) should go to scart pin 8 (EIGTH LOL! ), not pin 12. Other than that the 2nd schematic seems a lot more likely to work.

My memory is hazy about logic levels needed on /HRESET and /VRESET inputs. Note they're active-low, perhaps better use a pull-up vs. a pull-down? Would be better to check with an original MSX2+ or Turbo-R (schematic).

sd_snatcher wrote:

Your code doesn't seem to deal with the /WAIT signal from the V9958. And this is a *must* on a fast CPU like the arduino. In fact, this signal in indispensable for anything faster than a 5.37MHz Z80.

As long as required delays are observed, it doesn't matter whether that's software delays or a hardware wait signal. And his code does contain several software delays. But I think it could be simplified, maybe replace the section

  delayMicroseconds(1);
  digitalWrite(pinCSW, LOW);
  delayMicroseconds(0.6);
  PORTA = wData;
  delayMicroseconds(0.1);
  digitalWrite(pinCSW, HIGH);
  delayMicroseconds(0.1);
  PORTA = 0x00;

with something like

  PORTA = wData;
  delayMicroseconds(0.1);           // adress setup time
  digitalWrite(pinCSW, LOW);
  delayMicroseconds(0.3);           // CSW pulse width
  digitalWrite(pinCSW, HIGH);
  delayMicroseconds(2);             // 2 usec delay before next register access

Nothing says you can't set data to write before lowering /CSW (and if I'm not mistaken, that's what happens when a Z80 does it). Also note you simply leave the written data on the VDP's data bus. Why change to 0x00 in between when that value isn't written anyway, that's just wasted code & time.

That 2 usec is required delay between individual register accesses. There's a similar required delay between successive VRAM reads or writes. AND: when reading/writing to VRAM, there's a longer required delay (8 usec) between setting the address and reading/writting the 1st VRAM byte. So you'd have to insert an additional delay in your code for that case. See the "CPU-MSX-Video Interface" section in V9938 databook for details.

Btw CXA1145 is a composite video encoder IIRC - not needed for RGB output.

Page 1/3
| 2 | 3