|
Joined: Apr 2012
Posts: 343 Likes: 60
Senior Member
|
Senior Member
Joined: Apr 2012
Posts: 343 Likes: 60 |
The heart of the CH376 is a 28-pin SOIC chip also labeled "CH376". There is no external ROM on the module (which is actually pretty tiny). So I've made it an HLE device which directs accesses to a directory on MAME's host system. My current idea is to add a share_directory to mame.ini which this and potentially other host file sharing implementations can use. With the existing firmware, this isn't exactly host file access, but the card has 64K of flash ROM space available, and it's fully rewritable from software (I've even tested reflashing the card in MAME, it works fine). I'll be following how you implement this as it's something I can use in similar devices for the Acorn machines.
BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, etc.
|
|
|
|
Joined: Jun 2001
Posts: 520 Likes: 33
Senior Member
|
Senior Member
Joined: Jun 2001
Posts: 520 Likes: 33 |
In parallel I'm trying to make it easy to whip up a readable image with the contents you want on the fly. Between these two our UX should get significantly better...
|
|
|
|
Joined: Feb 2014
Posts: 1,102 Likes: 173
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,102 Likes: 173 |
I managed to get the AE Parallel Pro working: First step was to trace out the board: c080 read gets status: d0 : sw1 d1 : sw2 d2 : sw3 d3: sw4 d4: perror d5 : busy d6: buffer status (if bufferpro is attached) d7: ack status c080 write data to printer c082 write command to bufferpro c087 write sets bank (d0-d3 = bank bits a11-a13) (only a11,a12 used) c088 write unknown It seems to pass the self test and print graphics.
DEFINE_DEVICE_TYPE(A2BUS_PARALLELPRO, a2bus_parallelpro_device, "parallelpro", "AE Parallel Pro")
#define PARALLELPRO_ROM_REGION "parallelpro_rom"
#define PARALLELPRO_CENTRONICS_TAG "parallelpro_ctx"
ROM_START( parallelpro )
ROM_REGION(0x002000, PARALLELPRO_ROM_REGION, 0)
ROM_LOAD( "applied_engineering_parallel_pro_27c64.bin",0x000000, 0x002000, CRC(c116bf91) SHA1(cb233ff9511056083397dde033e9601ca2008a81))
ROM_END
static INPUT_PORTS_START( parallelpro )
PORT_DIPNAME( 0x0f, 0x0f, "Printer Type ID (SW1-4)" )
PORT_DIPSETTING( 0x0f, "Epson" )
PORT_DIPSETTING( 0x0e, "IBM" )
PORT_DIPSETTING( 0x0d, "NEC 8023A" )
PORT_DIPSETTING( 0x0c, "C.Itoh" )
PORT_DIPSETTING( 0x0b, "Toshiba" )
PORT_DIPSETTING( 0x0a, "Okidata" )
PORT_DIPSETTING( 0x09, "Okimate" )
PORT_DIPSETTING( 0x08, "Apple DMP" )
PORT_DIPSETTING( 0x00, "Unused" )
INPUT_PORTS_END
uint8_t a2bus_parallelpro_device::read_cnxx(uint8_t offset)
{
return m_rom[offset + 0x1800 + (0x100 * slotno())];
}
/*-------------------------------------------------
read_c0nx - called for reads from this card's c0nx space
-------------------------------------------------*/
uint8_t a2bus_parallelpro_device::read_c0nx(uint8_t offset)
{
switch(offset){
case 0: return (m_ack == 0 ? 0x0 : 0x80) |
0x40 |
((m_busy ==0 ? 0x00 : 0x01) << 5) |
((m_perror==0 ? 0x00 : 0x01) << 4) |
((m_dsw1->read()&0x0f)^0x0f);
default: return 0;
}
}
uint8_t a2bus_parallelpro_device::read_c800(uint16_t offset)
{
return m_rom[offset+(0x800)*m_rombank];
}
/*-------------------------------------------------
write_c0nx - called for writes to this card's c0nx space
-------------------------------------------------*/
void a2bus_parallelpro_device::write_c0nx(uint8_t offset, uint8_t data)
{
switch(offset){
case 0:
m_ctx_data_out->write(data);
m_ack = 0x80;
start_strobe();
break;
case 7:
m_rombank = data & 0x0f;
break;
}
}
hexdump -C parallel_pro_27c64.bin | grep [7f]f0
000007f0 ff ff ff ff ff ff ff ff ff ff ff ff 8f 7b 00 ff |.............{..|
00000ff0 ff ff ff ff ff ff ff ff ff ff ff ff bb 3d 01 ff |.............=..|
000017f0 ff ff ff ff ff ff ff ff ff ff ff ff b4 58 02 ff |.............X..|
00001ff0 ff ff ff ff ff ff ff ff ff ff ff ff c8 03 ae 12 |................|
Reading cffe gets you the current bank so you can come back to it. I think the two bytes preceding are checksum bytes, and the ae in the last bank refers to the company and 12 refers to the version maybe. Interestingly, the cnxx code uses hardcoded addresses: comparing the code for different slots: s=0x1900 o = 0x100 for i=0,0x100-1 do if a:byte(s+1+i) ~= a:byte(s+1+i+o) then io.write(string.format("%x",s+i).." ") for n=0,6 do io.write(string.format("%x",a:byte(s+1+i+n*0x100)).." ")end print() end end
1913 c1 c2 c3 c4 c5 c6 c7
1919 c1 c2 c3 c4 c5 c6 c7
1924 c1 c2 c3 c4 c5 c6 c7
192a c1 c2 c3 c4 c5 c6 c7
1936 c1 c2 c3 c4 c5 c6 c7
194b c1 c2 c3 c4 c5 c6 c7
1951 c1 c2 c3 c4 c5 c6 c7
1958 97 a7 b7 c7 d7 e7 f7 (c087 + slot * 0x10)
195e 97 a7 b7 c7 d7 e7 f7
1965 c1 c2 c3 c4 c5 c6 c7
196f c1 c2 c3 c4 c5 c6 c7
1975 97 a7 b7 c7 d7 e7 f7
1984 97 a7 b7 c7 d7 e7 f7
1987 c1 c2 c3 c4 c5 c6 c7
1989 10 20 30 40 50 60 70
1995 97 a7 b7 c7 d7 e7 f7
19ab c1 c2 c3 c4 c5 c6 c7
19b0 97 a7 b7 c7 d7 e7 f7
19c0 c1 c2 c3 c4 c5 c6 c7
19c9 c1 c2 c3 c4 c5 c6 c7
19fc 61 1d d8 94 50 c c8 (checksum bytes)
19fd 5b 22 e8 af 76 3d 3
|
|
|
|
Joined: Feb 2014
Posts: 1,102 Likes: 173
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,102 Likes: 173 |
So if I change the value returned in c080 bit 6 to return 0 instead of 1, it thinks that the bufferpro is attached:
uint8_t a2bus_parallelpro_device::read_c0nx(uint8_t offset)
{
switch(offset){
case 0: return (m_ack == 0 ? 0x0 : 0x80) |
// 0x40 |
((m_busy ==0 ? 0x00 : 0x01) << 5) |
((m_perror==0 ? 0x00 : 0x01) << 4) |
((m_dsw1->read()&0x0f)^0x0f);
default: return 0;
}
return 0;
}
If you take the printer off line, it will display "PRINTER BUSY". Then by trying out the different commands to the buffer pro, we can establish what commands write to which addresses: ^IZ clear buffer = write c088,00 ^IQ disable buffer = write c082, 44 ^IR enable buffer = write c082, 45 ^IU pause printing = write c082, 50 ^IY resume printing = write c082, 52 test buffer = write C082, 56 Issuing the test buffer command doesn't seem to do anything, probably the buffer will output text to the printer giving the results.
|
|
|
|
Joined: Feb 2014
Posts: 1,102 Likes: 173
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,102 Likes: 173 |
Just for giggles, I wanted to see if the self test updated in real time. While it's waiting for a Y/N to print a test pattern, it updates the messages in real time. Also it updates the graphics printer selection bits display, so if you change the printer from the dip switch control panel you can see the bits change. for i=1,#a do c = a:byte(i) c=c&0x7f if c<32 then c=32 end if (i-1)%0x40 ==0 then print() io.write(string.format("%4x",i-1)..": ") end io.write(string.char(c)) end print()
5c0: }N(L0M` AE PARALLEL PRO SELF TEST ROM VERSION 1.2 CHECKSUM GOOD
600: BAD GRAPHICS PRINTER: WAITING FOR ACKNOWLEDGE BUFFER ATTA
640: CHED PRINTER BUSY OUT OF PAPER PRINT TEST PATTERN? (Y/N) T
680: EST BUFFER OPTION? (Y/N) TEST PATTERN PRINTED H) 0 }NhJ Ps`
6c0: .x H) H` H)qH` %(I (0 f)%)I J )%(i( (Ix` VJ0 9 OH9 OH`9 O '.
Quick and dirty code to toggle the values at 5 second intervals:
uint8_t a2bus_parallelpro_device::read_c0nx(uint8_t offset)
{
switch(offset){
case 0: return (m_ack == 0 ? 0x0 : 0x80) |
( (((int) (machine().time().as_double() / 5.0)) % 2) == 0 ? (1 << 7) : 0) | // waiting for acknowledge
( (((int) (machine().time().as_double() / 5.0)) % 2) == 0 ? 0 : (1 << 6) ) | // (buffer attached bit)
((m_busy ==0 ? 0x00 : 0x01) << 5) |
( (((int) (machine().time().as_double() / 5.0)) % 2) == 0 ? (1 << 4) : 0) | // paper out bit
((m_dsw1->read()&0x0f)^0x0f);
default: return 0;
}
return 0;
}
|
|
|
|
Joined: Mar 2001
Posts: 17,217 Likes: 234
Very Senior Member
|
Very Senior Member
Joined: Mar 2001
Posts: 17,217 Likes: 234 |
I believe Bob Sander-Cederlof (of S-C Assembler fame) wrote a lot of AE's firmware, so I'm not surprised it's pretty good.
|
|
|
|
Joined: Feb 2014
Posts: 1,102 Likes: 173
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,102 Likes: 173 |
And the ParallelPro is supposed to do color graphic dumps: Unfortunately, there's no pixel doubling or emphasized graphics on the ParallelPro so I've stretched it out to fill the space, but you can see the color. One thing that's a little odd is that the imagewriter has ESC K 0 black ESC K 1 yellow ESC K 2 red ESC K 3 blue but the hexdump has K3 K3 K2 K1 I would expect it to be K0 K3 K2 K1 and if I select the Apple DMP as the printer and try color, it just omits the ESC K code to select the color. Something is off with some of the other color printers as well. I wonder if there were some bugs with the color printing routines. It's like the color ribbon selection codes are mismatched to the type of printer. The ESC b ESC c ESC m ESC y IBM style gets matched to a different printer. Somehow I wonder if the color capabilities weren't exercised that much as not many people had color printers. It took me a long time to find manuals for the okimate 20 and the IBM Color Printer (IBM 5182) https://my.okidata.com/om20ibm.nsf/MOCContentshttps://ibm.retropc.se/oa/oa.htmlhttps://ibm.retropc.se/oa/OA%20-%20IBM%20PC%20Color%20Printer.pdfToshiba P351C, P351SX, P321SLC manuals are nowhere to be found on the net. 14c0: K} r r r r A 2 K L0 L} K0 K| L} K~ K} 1500: A 2 A 2@ S0280 QS0560 QS0640 S0560 S0192 QS0384 S0400 S0384 1540: NT16 NA@ S0280 QS0560 QS0640 S0560 S0192 QS0384 S0400 S038 1580: 4 C7 C4 C2 C1 NT16 NA ;0280 0560 0640 ;0560 ;0192 0384 ; 15c0: 0400 ;0384 b c m y L07 L18 P Q Q P P Q P P r r r r 1600: #A 6 nG0280 pG0560 pG0640 nG0560 nG0192 pG0384 nG0400 nW0384 K 1640: 3 K3 K2 K1 T16 A@ G0280 QG0560 QG0640 G0560 G0192 QG0384 G04 1680: 00 G0384 NT16 NA@@$0! @ s@3 p 0 @p4s003 L @ # 16c0: !
|
|
|
|
Joined: Apr 2012
Posts: 343 Likes: 60
Senior Member
|
Senior Member
Joined: Apr 2012
Posts: 343 Likes: 60 |
Here's preview emulation of one of the newest Apple II mass storage cards, the BOOTI. The heart of the CH376 is a 28-pin SOIC chip also labeled "CH376". I've taken a quick look at implementing a similar BBC device, but failing to get the expected results on some commands: 06H CHECK_EXIST - must return last data EOR 255. 15H SET_USB_MODE - sending 06H and 07H seems to want 0x51 (Operation successful) returned. 16H ? - expecting 0x15 returned. Looks like I need to do some research to implement these correctly.
BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, etc.
|
|
|
|
Joined: Mar 2001
Posts: 17,217 Likes: 234
Very Senior Member
|
Very Senior Member
Joined: Mar 2001
Posts: 17,217 Likes: 234 |
The Apple II firmware for the CH376 is admittedly pretty permissive. I also need to have it filter out filenames that aren't 8.3, because there's no way to pass them back for loading. I used a combination of the official data sheet: https://www.mpja.com/download/ch376ds1.pdfand also this Arduino C++ interfacing code, which explains things in better English: https://github.com/djuseeq/Ch376msc/blob/master/src/CommDef.h
|
|
|
|
Joined: Feb 2014
Posts: 1,102 Likes: 173
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,102 Likes: 173 |
Got the prograppler kinda working, it's weird becuase I can get the 1.0 rom working with menus but not 2.0. It's kinda cool, you type +MENU to get a menu system. Like having Zoom Grafix built into the printer card. Quite touchy about the DIP switches. If it doesn't see a setting it likes, the menus won't come up.
|
|
|
3 members (AJR, Olivier Galibert, 1 invisible),
353
guests, and
4
robots. |
Key:
Admin,
Global Mod,
Mod
|
|
Forums9
Topics9,320
Posts121,944
Members5,074
|
Most Online1,283 Dec 21st, 2022
|
|
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!
|
|
|
|