Previous Thread
Next Thread
Print Thread
Page 5 of 8 1 2 3 4 5 6 7 8
Joined: Feb 2014
Posts: 816
Likes: 30
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 816
Likes: 30
So weird, fired it up today and for some reason, the alignment seems more consistent. I'm not sure I changed anything...

edit: I think it was an uninitialized variable giving non deterministic behavior.


I think it's actually an FX-80+.

[Linked Image from i.imgur.com]
[Linked Image from i.imgur.com]

Also was perusing the upd7801 tables and noticed that the skipping for CALB should be 1 byte since the argument is implied (in the register BC).

Code
const struct upd7810_device::opcode_s upd7810_device::s_opXX_7801[256] =
{
       /* 0x60 - 0x7F */  // should CALB be 1 instead of 2?
        {&upd7810_device::PRE_60,        1, 0, 0,L0|L1}, {&upd7810_device::DAA,           1, 4, 4,L0|L1},
        {&upd7810_device::RETI,          1,15,15,L0|L1}, {&upd7810_device::CALB,          1,13,13,L0|L1},
        {&upd7810_device::PRE_64,        1, 0, 0,L0|L1}, {&upd7810_device::NEIW_wa_xx,    3,13,13,L0|L1},
        {&upd7810_device::SUI_A_xx,      2, 7, 7,L0|L1}, {&upd7810_device::NEI_A_xx,      2, 7, 7,L0|L1},
        {&upd7810_device::MVI_V_xx,      2, 7, 7,L0|L1}, {&upd7810_device::MVI_A_xx,      2, 7, 7,L0   },
        {&upd7810_device::MVI_B_xx,      2, 7, 7,L0|L1}, {&upd7810_device::MVI_C_xx,      2, 7, 7,L0|L1},
        {&upd7810_device::MVI_D_xx,      2, 7, 7,L0|L1}, {&upd7810_device::MVI_E_xx,      2, 7, 7,L0|L1},
        {&upd7810_device::MVI_H_xx,      2, 7, 7,L0|L1}, {&upd7810_device::MVI_L_xx,      2, 7, 7,   L1},

Joined: Feb 2014
Posts: 816
Likes: 30
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 816
Likes: 30
I was looking at the Amstrad lq3500di and it apparently uses a upd78310, which is interesting.

Mame has a upd78310 driver but it's just a disassembler right now. The disassembly looks sane. What's cool is that the lq5000di manual shows a lot of details that the lq3500 manual doesn't. They use the same i/o chips. In the lq5000di manual, addresses for the io chip are given, 7FE0 to 7FE7 which handles 8 x 4-bit io ports, and the printhead chip which is at 7FF4, 7FF5, 7FF7 AND 7FF6. for 24 pins (2 pairs of 8/4 bits) .

They're not hooked up identically, but the pin addresses for the ports should be the same which makes it so much easier to figure out.

Joined: Feb 2014
Posts: 816
Likes: 30
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 816
Likes: 30
The epson fx-80 sometimes used a SUMI board which connected via a ribbon cable to the socket for the 8042ah.

Onboard was an 8039 and a 2716 rom, which basically emulated the 8042ah.

There's flipflops to handle the flags OBF IBF and F0 and F1, along with an LS374 for the IN BUF and an LS374 for the OUT BUF.

I wonder if they couldn't get enough 8042AH chips and came up with the board as a workaround. So instead of a single chip, there's a board with 14 chips on it.

Joined: Feb 2014
Posts: 816
Likes: 30
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 816
Likes: 30
So the 8039 on the SUMI board will access addresses with movx to do certain functions corresponding to the 8042:

A 74LS138 decodes the function based on A2, A1, and A0.

0 = read input buffer (8042: IN A,DBB)
1 = write ST3-ST0 bits into LS374 (8042: MOV STS,A)
2 = write output buffer (8042: OUT DBB, A)
3 = read status bits F1 F0 IBF OBF
4 = set F0
5 = clear F0
6 = set F1
7 = clear F1

and a couple of examples:

Code
0:20b: b9 03  mov  r1,#$03
0:20d: 81     movx a,@r1            <<<  read memory 3, get status
0:20e: 12 0b  jb0  $20B              <<< busy wait on OBF flag

some routines that do various functions:
Code
0:3be: d5     sel  rb1
0:3bf: b8 00  mov  r0,#$00        0 = read input buffer
0:3c1: 80     movx a,@r0
0:3c2: 93     retr
0:3c3: d5     sel  rb1
0:3c4: b8 02  mov  r0,#$02        2 = write output buffer
0:3c6: 90     movx @r0,a
0:3c7: 93     retr
0:3c8: d5     sel  rb1
0:3c9: b8 07  mov  r0,#$07             7 = resets f1
0:3cb: 90     movx @r0,a
0:3cc: 93     retr
0:3cd: d5     sel  rb1
0:3ce: b8 06  mov  r0,#$06             6 = sets f1
0:3d0: 90     movx @r0,a
0:3d1: 93     retr

And a routine that sets/clears the status bits:

Code
0:403: 23 20  mov  a,#$20         set status bit  20
0:405: 84 15  jmp  $415
0:407: 23 df  mov  a,#$DF       reset status bit 20
0:409: 84 0d  jmp  $40D
0:40b: 23 ef  mov  a,#$EF       reset status bit 10
0:40d: b9 59  mov  r1,#$59
0:40f: 51     anl  a,@r1
0:410: a1     mov  @r1,a
0:411: 91     movx @r1,a
0:412: 83     ret
0:413: 23 10  mov  a,#$10             set status bit 10
0:415: b9 59  mov  r1,#$59
0:417: 41     orl  a,@r1
0:418: a1     mov  @r1,a
0:419: 91     movx @r1,a          <<< lower bits of 59 is an address of 1  #$59 = 0101 1001   lower 3 bits = 001
0:41a: 83     ret

Joined: Feb 2014
Posts: 816
Likes: 30
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 816
Likes: 30
I was able to find a table which gives all of the combinations of different chips for FX RX and MX printers:

Note that 78010BD is actually a upd7811 which has 4k of rom onboard and J1 is installed to pull MODE0 to ground. That's why location 4A is empty for the FX-80 and FX-100 that use it. The FX-80+ has a RAM installed in 4A and also has a different fuse rom (which handles the memory mapping).

(there is a typo, the FX-100 78010BD should use the M02011GA as the fuse I think)

This also explains why some FX-80 dumps seem incomplete, they don't have that 4k of internal rom.

[Linked Image from i.imgur.com]

and also a mention that SUMI boards (and any slave chip) can be replaced directly with C42040KB

[Linked Image from i.imgur.com]


The fuse rom TBP18S030 is just a 32 byte x 8 rom, it takes the upper 5 bits of the address (32 possibilities) and activates a single chip select (out of 8 possible chip selects) to route memory accesses in the memory map. That gives a 2k resolution out of the 64kb memory map.

Different printer versions can have the same basic design, but have different ram/rom combination installed and change the fuse rom for the corresponding memory map.

Joined: Feb 2014
Posts: 816
Likes: 30
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 816
Likes: 30
The TBP18S030 isn't supported by the TL866, so I have an arduino mega 2560 and a breadboard, let's see if we can dump the contents with the help of the datasheet:


[Linked Image from i.imgur.com]

so hookup is:
28 -> not G
30-34 -> A0..A4
40-47 -> Q0..Q7
and hooking up the GND and 5V to the arduino 5V

I chose those pins as I had some other stuff hooked up (an LCD) that I didn't want to disconnect, and the mega's got lots of pins.

Code
void setup() {
  Serial.begin(9600);

	pinMode(28,OUTPUT);
	pinMode(30,OUTPUT);
	pinMode(31,OUTPUT);
	pinMode(32,OUTPUT);	
	pinMode(33,OUTPUT);	
	pinMode(34,OUTPUT);	
}

char buffer[32];

void loop() {

for (int i=0;i<32;i++) 
{
  digitalWrite(28,LOW);
  for (int j=0;j<5;j++) digitalWrite(30+j,(i & (1<<j)));
  delay(10);
  int outval = 0;
  for (int j=0;j<8;j++) outval |= (digitalRead(40+j) ? (1<<j) : 0);
 
  dumparray[i]=outval;

  snprintf(buffer, sizeof(buffer), "%x: %x\n", i,outval);
  Serial.write(buffer);
}


for (int i=0;i<32;i++) 
{

  snprintf(buffer, sizeof(buffer), "%x ", dumparray[i]);
  Serial.write(buffer);
}
Serial.println();


delay(10000);
}
}



and it looks like what you'd expect, a single bit low for chip select, FF for no chip select. It's nice to provide confirmation of the address map for a given chip.

Code

marked m20214ga  (I think this is actually supposed to be m02014ga, two zeros instead of 2 twos)

0: fe
1: fe
2: fe
3: fe
4: fe
5: fe
6: fe
7: fe
8: bf
9: bf
a: bf
b: bf
c: bf
d: bf
e: bf
f: bf
10: fd
11: f7
12: fb
13: ff
14: ff
15: ff
16: ff
17: ff
18: ff
19: 7f
1a: ef
1b: df
1c: ff
1d: ff
1e: ff
1f: ff
fe fe fe fe fe fe fe fe bf bf bf bf bf bf bf bf fd f7 fb ff ff ff ff ff ff 7f ef df ff ff ff ff 

So for example, rom address 0 in the TBP18S030 corresponds to memory access to 0x0 to 0x7ff, and CS0 gets activated for the ROM chip at 5A:

[Linked Image from i.imgur.com]


And also compare with a M02011GA, I believe that this one has 4K of rom on the upd7811, so you see that the first two entries are FF since it's going to the internal cpu rom instead of the rom chip.

dump of M02011GA

Code
0: ff
1: ff
2: fe
3: fe
4: fe
5: fe
6: fe
7: fe
8: fe
9: fe
a: fd
b: fd
c: fd
d: fd
e: fd
f: fd
10: fd
11: fd
12: fb
13: f7
14: fd
15: ff
16: ff
17: ff
18: ff
19: ff
1a: ef
1b: df
1c: bf
1d: 7f
1e: ff
1f: ff
ff ff fe fe fe fe fe fe fe fe fd fd fd fd fd fd fd fd fb f7 fd ff ff ff ff ff ef df bf 7f ff ff 

Joined: Jan 2011
Posts: 248
Likes: 3
Senior Member
Offline
Senior Member
Joined: Jan 2011
Posts: 248
Likes: 3
The TBP18S030 isn't supported by the TL866

https://mikesarcade.com/cgi-bin/spies.cgi?action=url&type=info&page=PromRef.txt is your friend

It's not like you're trying to program one.

Last edited by Al Kossow; 02/22/22 01:28 PM.
Joined: Feb 2014
Posts: 816
Likes: 30
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 816
Likes: 30
Thanks for the link, Al. It's a good cross reference.


I modified my arduino program to give the upper byte addresses below the hex data to better see how the address map was arranged:

Code
void setup() {
  Serial.begin(9600);

  pinMode(28,OUTPUT);
  pinMode(30,OUTPUT);
  pinMode(31,OUTPUT);
  pinMode(32,OUTPUT);	
  pinMode(33,OUTPUT);	
  pinMode(34,OUTPUT);	
}

char buffer[32];

int dumparray[32];

void loop() 
{
  for (int i=0;i<32;i++) 
  {
    digitalWrite(28,LOW);
    for (int j=0;j<5;j++) digitalWrite(30+j,(i & (1<<j)));
    delay(10);
    int outval = 0;
    for (int j=0;j<8;j++) outval |= (digitalRead(40+j) ? (1<<j) : 0);
   
    dumparray[i]=outval;
  
    snprintf(buffer, sizeof(buffer), "%x: %x\n", i,outval);
    Serial.write(buffer);
  }
  
  for (int i=0;i<32;i++) 
  {
  
    snprintf(buffer, sizeof(buffer), "%02x ", dumparray[i]);
    Serial.write(buffer);
  }
  Serial.println();
  
 
  for (int i=0;i<32;i++) 
  {
    snprintf(buffer, sizeof(buffer), "%02x ", ((i * 0x800) >> 8) & 0xff);
    Serial.write(buffer);
  }
  Serial.println();
  
  delay(10000);
}

and the result:

Code
0: fe
1: fe
2: fe
3: fe
4: fd
5: fd
6: fd
7: fd
8: ff
9: ff
a: fe
b: fe
c: fe
d: fe
e: fe
f: fe
10: ff
11: ff
12: fb
13: f7
14: ff
15: ff
16: ff
17: ff
18: ff
19: ff
1a: ef
1b: df
1c: bf
1d: 7f
1e: ff
1f: ff
fe fe fe fe fd fd fd fd ff ff fe fe fe fe fe fe ff ff fb f7 ff ff ff ff ff ff ef df bf 7f ff ff 
00 08 10 18 20 28 30 38 40 48 50 58 60 68 70 78 80 88 90 98 a0 a8 b0 b8 c0 c8 d0 d8 e0 e8 f0 f8

This one is kind of interesting, because it maps the same chip into different ranges, wrapping the address around since it's a (16k) 27128 chip I believe.

From 0x0000 to 0x1fff and then from 0x5000 to 0x7fff.

The "fuse" rom has to match the contents of the rom, because you can flexibly map things all over the place, as long as the rom knows where to look

I think the unusual mapping here acts as a bit of a copy protection "dongle" since you also need the matching fuse rom.

Joined: Feb 2014
Posts: 816
Likes: 30
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 816
Likes: 30
This eprom chip just doesn't give a consistent read. I ran it through the TL866 multiple times and every single time it gives different results.

Do eproms go bad?

Looking at it with meld there's a couple of ranges with bad reads.

[Linked Image from i.imgur.com]

So why not try to dump it with arduino since I could read a 32x8 rom, is a 2764 that much more difficult?

The hard part is hooking up all the little wires on the breadboard to the mega2560.

Code
// Dump 2764
//
// 22,23,25 -> not PROG, not E, not G
// 40-52 -> A0..A12
// 30-37 -> Q0..Q7
// and hooking up the GND and 5V to the arduino 5V

void setup() {
  Serial.begin(9600);

  pinMode(22,OUTPUT); // not PROG
  pinMode(23,OUTPUT); // not E
  pinMode(25,OUTPUT); // not G

  for (int i=0;i<=12;i++)
  { 
    pinMode(40+i,OUTPUT); // A0-A12
  } 
}

char buffer[32];
int dumparray[32];

void loop() 
{
  int groupsize = 16;
  
  for (int base=0;base<(1<<13);base+=groupsize)
  {
  
  for (int i=0;i<groupsize;i++)   
  {
    digitalWrite(22,HIGH);  // NOT PROG
    digitalWrite(23,LOW);
    digitalWrite(25,LOW);
    
    for (int j=0;j<=12;j++) digitalWrite(40+j,((i+base) & (1<<j))!=0 );  // a0..a12
    delay(10);

    int numsamples = 50;

    int samplesarray[numsamples] = {};
    
    for (int sample = 0; sample < numsamples; sample++)
    {
    
      int outval = 0;
      for (int j=0;j<8;j++) outval |= (digitalRead(30+j) ? (1<<j) : 0);
     
      dumparray[i]=outval;
    
      samplesarray[sample] = outval;
      if ((sample > 0) && (samplesarray[sample] != samplesarray[sample-1]))
      {
        snprintf(buffer, sizeof(buffer), "%02x: %02x\n", (base+i), outval);
        Serial.write(buffer);   
      }
  
    }
  
  }
  
   snprintf(buffer, sizeof(buffer), "%08x  ", base);
   Serial.write(buffer);
  
  for (int i=0;i<groupsize;i++) 
  {
  
    snprintf(buffer, sizeof(buffer), "%02x ", dumparray[i]);
    Serial.write(buffer);
  }
  Serial.println();
 
  }  
  delay(10000);
}


[Linked Image from i.imgur.com]


And it gives pretty much the same results as the tl866, with bad reads every time, so I asked it to take 50 samples of an address and print it out every time the read was different from the previous read:

For example: memory address 802 seems to oscillate all over the place (the right digit seems ok)

802: ff
802: 2f
802: af
802: bf
802: ff
802: 7f
802: bf
802: 6f
802: bf
802: ff
802: af
802: 7f
802: 4f
802: ff
802: 4f
802: ff
802: 7f
802: ff
802: cf
802: 4f
802: bf
802: ff
802: 7f
802: bf
802: 5f
802: 7f
802: 5f
802: 4f
802: af
802: 6f
802: bf
802: ff
802: 7f
802: ff
802: 7f
802: 6f
802: df
802: cf
802: 4f
802: ef
802: af
802: cf
802: ff

location 804 seems a bit better:

804: 8a
804: 8b
804: 8a
804: 8b
804: 8a
804: 8b
804: 8a
804: 8b
804: 8a
804: 8b
804: 8a
804: 8b

808 is pretty unstable

808: e7
808: d7
808: 67
808: 77
808: 67
808: f7
808: a7
808: b7
808: 67
808: 77
808: 67
808: f7
808: e7
808: 67
808: 77
808: b7
808: 67
808: e7
808: 77
808: 67
808: d7
808: b7
808: d7
808: b7
808: 67
808: 77
808: 67
808: e7
808: 77
808: d7
808: 77
808: a7
808: 77
808: b7
808: 67
808: a7
808: 77
808: 67
808: b7
808: f7


I think these fall in noncritical areas of font data, maybe I could reconstruct them once everything else is working.

Joined: Mar 2001
Posts: 16,910
Likes: 56
R
Very Senior Member
Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,910
Likes: 56
The dedicated dumpers like Team Europe do things like increasing and decreasing the voltage to the chip slightly and that often stabilizes the reads from otherwise shaky EPROMs. I've heard of success with freezing the chip and then reading it immediately too, although I have no idea how that works smile

Page 5 of 8 1 2 3 4 5 6 7 8

Link Copied to Clipboard
Who's Online Now
1 members (Pernod), 27 guests, and 1 robot.
Key: Admin, Global Mod, Mod
ShoutChat
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics9,085
Posts119,077
Members5,014
Most Online890
Jan 17th, 2020
Our Sponsor
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!

Superior Solitaire
Forum hosted by www.retrogamesformac.com