Previous Thread
Next Thread
Print Thread
#119698 09/17/21 02:35 PM
Joined: Feb 2014
Posts: 676
Likes: 9
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 676
Likes: 9
So I thought I'd try the coco2 with the imagewriter, and ran into a few problems.

One interesting thing about the coco2 is that it has a built in serial port and the processor has to do all the work.

But it didn't print at all, hanging up on reading $ff22.

After much fiddling around I tried inverting it and connecting it to rs232->rxd_r().
// bool serial_in = (m_rs232 != nullptr) && (m_rs232->rxd_r() ? false : true); // for imagewriter

That seemed to work, but only because it set the value high.

Later I found this: https://www.lomont.org/software/misc/coco/Lomont_CoCoHardware.pdf
Code
Serial I/O 
Software 
The 4-pin DIN connector on the CoCo back is a serial port. This must be operated from software; a 
loop reads and writes bits to this port as needed. 
 
Set baud rate (values in decimal):     POKE 150,180    [300 bps] 
    POKE 150,88     [600 bps] 
    POKE 150,41     [1200 bps] 
    POKE 150,18     [2400 bps] 
    POKE 150,7      [4800 bps] 
    POKE 150,1      [9600 bps] 
 
Others have used assembly routines to support much faster rates. 
Hardware 
The  Color  Computer  has  a  four-pin  DIN  connector  on  its  back  panel  for  its  serial  port.  There  is  
very  little  internal  hardware  dedicated  to  supporting  this,  so  most  of  the  work  of  sending  and  
receiving bits is done in software; the CPU goes into a loop either setting the output bit or reading 
the input bit. 
 
As  you  might  imagine,  doing  both  at  the  same  time  can  be  tricky,  since  you  don't  have  any  
guarantees  about  when  the  first  bit  of  a  byte  will  arrive;  it  might  be  while  you  are  right  in  the  
middle of sending a byte. The result is a limited baud rate; the CPU can only do so many bits per 
second.  
 
Here  is  a  drawing  of  that  connector,  including  a  pinout  and  showing  how  the  pins  are  numbered.  
The drawing is of the back-panel connector, looking at it from the back of the machine. So if you 
are looking at the pins of the connector at the end of a cable, it is backwards. 
         ------       Pin#  RS-232 signal            Printer signal 
      /  \__/  \     ----  ----------------------   --------------- 
     /          \      
    / 4      1   \    1    CD - carrier detect      ignored 
       o      o        
   |              |   2    RS232IN - input data     printer status 
   |              |                                 (high == ready) 
   |  3      2    |    
       o      o       3    GND - ground             ground 
    \            /     
     \          /     4    RS232OUT - output data   data to printer   
      \        /        
        ------          
Color Computer 1/2/3 Hardware Programming, Chris Lomont, v0.82 
36 
 
Note  that  pins  of  connector  are  not  always  used  the  same  way!  This  is  possible  because  most  
everything is done in software; pins 1 and 2 are required by the hardware to be inputs, but it is up to 
the program to decide how to use those inputs. While any sort of communications program should 
use  the  RS-232  pin-out,  the  built-in  BASIC  printer  routines  use  pin  2  as  "printer  status"  and  
completely ignore pin 1. So the cable you wire up for a printer has to be different from the one you 
wire up for a mod


so that's basically cts (clear to send) and if I hook that up as
Code
uint8_t coco_state::pia1_pb_r()
{
	// Port B: lines in output mode are handled automatically by the PIA object.
	// We only need to specify the input lines here
	uint32_t ram_size = m_ram->size();

	//  For the CoCo 1, the logic has been changed to only select 64K rams
	//  if there is more than 16K of memory, as the Color Basic 1.0 rom
	//  can only configure 4K or 16K ram banks (as documented in "Color
	//  Basic Unreveled"), doing this allows this  allows the coco driver
	//  to access 32K of ram, and also allows the cocoe driver to access
	//  the full 64K, as this uses Color Basic 1.2, which can configure 64K rams
	bool memory_sense = (ram_size >= 0x4000 && ram_size <= 0x7FFF)
		|| (ram_size >= 0x8000 && (pia_0().b_output() & 0x40));

	// serial in (PB0)
//	bool serial_in = (m_rs232 != nullptr) && (m_rs232->rxd_r() ? true : false);
	bool serial_in = (m_rs232 != nullptr) && (m_rs232->cts_r() ? true : false);  // for printer
	// composite the results
	return (memory_sense ? 0x04 : 0x00)
		| (serial_in ? 0x01 : 0x00);
}



and once you poke 150,1 you can use 9600 baud.

but the fun doesn't stop there, because the imagewriter has a strange behavior: long lines cause the printhead to overwrite the same line.

This isn't a problem for the apple ii because the output routines automatically issue a cr when a line hits 40 or 80 chars.

Supposedly poking 155 with a line length will set the printer output line width but it seemed to have no effect on LLIST.

so I hacked a little thing to see if the printhead moved to the far right and if so, just move the printhead down the page.

(ugly and horrible but does seem to work, if you send an ESC > for unidirectional printing first)
Code
	static int flag;
	// auto kickdown for coco line lines printout
	if (m_xpos > m_right_edge - 80 && !flag) 
	{   flag = 1;
		m_ypos += 16;
	}
	if (m_xpos < m_right_edge -90) {
		flag = 0;
		}



I did find a couple of software that would print to the imagewriter:

cocomax 2 (used the cracked version, original just repeats the title screen)

RUN "CONFIG

and absolutely don't use your original disk since it even deletes the config program: (yikes!)

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

cocomax wouldn't load any pictures, and it's really hard to draw with the mouse:

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


printmaster

[Linked Image from i.imgur.com]


vizidump (neat little program with a GUI interface)
to load a new picture, you select quit and then type a filename and it reloads the gui interface.

[Linked Image from i.imgur.com]


vizidraw (paint program written in basic)

[Linked Image from i.imgur.com]


LLISTing the vizidraw source (note long lines get kicked down by my hack)

(no spaces in the basic code!)

[Linked Image from i.imgur.com]

Last edited by Golden Child; 09/17/21 02:56 PM.
Joined: Feb 2000
Posts: 214
T
Senior Member
Offline
Senior Member
T
Joined: Feb 2000
Posts: 214
This is super cool. I'd like to get to the bottom of the serial changes you had to make. Did I read correctly that you had to invert the RX lines?

Also with regard to the non-hacked CoCo Max. It requires a expansion slot device that you plug a mouse into. It is emulated:

./mame coco2b -flop1 max.dsk -ext multi -ext:multi:slot1 max


tim lindner
tlindner@macmess.org
Joined: Feb 2014
Posts: 676
Likes: 9
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 676
Likes: 9
Hi Tim, thanks for the tip on the max for the coco max.

[Linked Image from i.imgur.com]

I can actually draw pretty well using my Wacom tablet.


With regards to the changes to the serial:

I truncated the quote a little bit:

Quote
Note that pins of connector are not always used the same way! This is possible because most everything is done in software; pins 1 and 2 are required by the hardware to be inputs, but it is up to the program to decide how to use those inputs. While any sort of communications program should
use the RS-232 pin-out, the built-in BASIC printer routines use pin 2 as "printer status" and completely ignore pin 1. So the cable you wire up for a printer has to be different from the one you wire up for a modem.


Hmmm. Thinking about why it didn't work just hooking up the tx from the 8251 to the rs232, maybe the output from the 8251 ends up getting inverted.

The output from the imagewriter's 8251 on the TXD line is normal, but there's an inversion on the 75188 at IC27 that inverts it.

I think that rs232 devices should output a 1 when it's not sending anything, so if I invert the output from the imagewriter then it should work without changing the code in the coco driver.

Code
//-------------------------------------------------
//    i8251 txd connects to output_rxd of serial port
//-------------------------------------------------

void apple_imagewriter_printer_device::txd_handler(uint8_t data)
{
	output_rxd(!data); // output from the 8251 is inverted by 75188 IC27
}

One of the weird things is that I haven't been able to get XON/XOFF working, maybe this is the cause?


Perhaps a config option could be made to either select either cts_r or rxd_r to route to pin 2.

maybe something like:
Code
	bool serial_in = (m_rs232 != nullptr) && 
           ( ioport("SERRXD")->read() ? m_rs232->cts_r() : m_rs232->rxd_r())  ? true : false);

I'm trying hard to get my imagewriter ready, you can check out my progress if you're curious at:

http://github.com/goldnchild/mame/tree/imagewriter

Joined: Feb 2014
Posts: 676
Likes: 9
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 676
Likes: 9
I did finally figure out why xon/xoff wasn't working (I think):

The 8251 has to have its cts* driven low so after a m_uart->write_cts(0);

I can get the ct486 to print with xon/xoff:

[Linked Image from i.imgur.com]

However, the ct486 wants the output_rxd(data); non inverted. So now the coco says:

[Linked Image from i.imgur.com]

Joined: Feb 2014
Posts: 676
Likes: 9
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 676
Likes: 9
So happy to finally get xon/xoff working.

Here's a500 printing from deluxepaint at density 7 and using "very light" print: (160x144 dpi two pass)

(looks better if you zoom in)

[Linked Image from i.imgur.com]


I couldn't see what was happening until I added a printf that would show CTRL+S and CTRL+Q coming from the imagewriter:

m_rx_shift = 113 (CTRL+S) (wait a minute...)
m_rx_shift = 111 (CTRL+Q) (ok, send me more...)
m_rx_shift = 113
m_rx_shift = 111
m_rx_shift = 113
m_rx_shift = 111
m_rx_shift = 113

1 member likes this: robcfg
Joined: Feb 2014
Posts: 676
Likes: 9
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 676
Likes: 9
Anyway, I thought why not add a config option to switch between printer (cts_r) and modem (rxd_r):

Code
diff --git a/src/mame/machine/coco.cpp b/src/mame/machine/coco.cpp
index 8e08656f447..5844692c8a7 100644
--- a/src/mame/machine/coco.cpp
+++ b/src/mame/machine/coco.cpp
@@ -444,8 +444,11 @@ uint8_t coco_state::pia1_pb_r()
 		|| (ram_size >= 0x8000 && (pia_0().b_output() & 0x40));
 
 	// serial in (PB0)
-	bool serial_in = (m_rs232 != nullptr) && (m_rs232->rxd_r() ? true : false);
-
+//	bool serial_in = (m_rs232 != nullptr) && (m_rs232->rxd_r() ? true : false);
+	bool serial_in = (m_rs232 != nullptr) 
+		&& ((ioport(SERIAL_RX_SELECT_TAG)->read() ? 
+				m_rs232->cts_r() : 
+				m_rs232->rxd_r()) ? true : false);
 	// composite the results
 	return (memory_sense ? 0x04 : 0x00)
 		| (serial_in ? 0x01 : 0x00);
diff --git a/src/mame/drivers/coco12.cpp b/src/mame/drivers/coco12.cpp
index 951800a5690..f6291089adb 100644
--- a/src/mame/drivers/coco12.cpp
+++ b/src/mame/drivers/coco12.cpp
@@ -181,6 +181,17 @@ INPUT_PORTS_START( coco_rtc )
 	PORT_CONFSETTING(    0x01, "Cloud-9" )
 INPUT_PORTS_END
 
+//-------------------------------------------------
+//  INPUT_PORTS( coco_serial_select )
+//-------------------------------------------------
+
+INPUT_PORTS_START( coco_serial_rx_select )
+	PORT_START(SERIAL_RX_SELECT_TAG)
+	PORT_CONFNAME( 0x01, 0x01, "Serial RX Select" )
+	PORT_CONFSETTING(    0x00, "RX (Modem)" )
+	PORT_CONFSETTING(    0x01, "CTS (Printer)" )
+INPUT_PORTS_END
+
 
 
 //-------------------------------------------------
@@ -280,6 +291,7 @@ static INPUT_PORTS_START( coco )
 	PORT_INCLUDE( coco_analog_control )
 	PORT_INCLUDE( coco_rtc )
 	PORT_INCLUDE( coco_beckerport )
+	PORT_INCLUDE( coco_serial_rx_select )
 INPUT_PORTS_END
 
 
diff --git a/src/mame/includes/coco.h b/src/mame/includes/coco.h
index 63b04da84cc..6d7810b221c 100644
--- a/src/mame/includes/coco.h
+++ b/src/mame/includes/coco.h
@@ -75,6 +75,7 @@ void coco_cart(device_slot_interface &device);
 #define DIECOM_LIGHTGUN_LY_TAG      "dclg_ly"
 #define DIECOM_LIGHTGUN_BUTTONS_TAG "dclg_triggers"
 
+#define SERIAL_RX_SELECT_TAG            "serial_rx_select"
 
 //**************************************************************************
 //  TYPE DEFINITIONS

Last edited by Golden Child; 09/19/21 01:40 PM.
Joined: Mar 2001
Posts: 16,815
Likes: 36
R
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,815
Likes: 36
This would normally be handled by the cable, which isn't something we currently have an abstraction for in MAME. I'm not sure what the right way to deal with it would be.

Joined: Feb 2004
Posts: 2,277
Likes: 17
Very Senior Member
Offline
Very Senior Member
Joined: Feb 2004
Posts: 2,277
Likes: 17
I will make an RS232 patchbay device that lets you rewire the serial connections and plug in another device downstream at some point.

2 members like this: Darkstar, R. Belmont

Link Copied to Clipboard
Who's Online Now
2 members (Dorando, 1 invisible), 30 guests, and 3 robots.
Key: Admin, Global Mod, Mod
ShoutChat
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics8,981
Posts117,966
Members5,003
Most Online890
Jan 17th, 2020
Forum Host
These forums are hosted by www.retrogamesformac.com
Forum hosted by www.retrogamesformac.com