Previous Thread
Next Thread
Print Thread
Page 1 of 10 1 2 3 9 10
Ap2000 signs of life #117564 07/17/20 08:14 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Hi guys,

I thought I'd start a separate thread for this.

There's something strange about how the upd7810 does the analog/digital conversion.

08 is written to the ANM register, which is supposed to do scan mode on inputs AN4 - AN7 and write them to CR0-CR3, but instead of getting the proper value for AN5, 0xFF gets written to CR1.

Code
 
               if (m_adcnt > m_adtot)
                {
                        m_adcnt -= m_adtot;
                        switch (m_adout)
                        {
//                              case 0: CR0 = m_tmpcr ? 0xff:0x00; break;
//                              case 1: CR1 = m_tmpcr ? 0xff:0x00; break;
//                              case 2: CR2 = m_tmpcr ? 0xff:0x00; break;
//                              case 3: CR3 = m_tmpcr ? 0xff:0x00; break;
                                case 0: CR0 = m_tmpcr; break;
                                case 1: CR1 = m_tmpcr; break;
                                case 2: CR2 = m_tmpcr; break;
                                case 3: CR3 = m_tmpcr; break;
                        }
                        m_adin  = (m_adin  + 1) & 0x07;
                        m_adout = (m_adout + 1) & 0x03;
                        if (m_adout == 0)
                                {IRR |= INTFAD;
                                printf(".IRR=%x ",IRR);}

                        m_shdone = 0;


With that mangling above, CR1 gets the expected value, 0xCB.


Code
focus 1
bp 1dee
g

Stopped at breakpoint 1
[MAME]> 

>history 1,10
1DF0: LXI     EA,$0000
1DEE: MOV     A,CR1
1DEB: MVI     EOM,$07
1DE7: SHLD    $C005
1DE3: LHLD    $9925
981A: JMP     $1DE3
001A: JMP     $981A
0019: EXA     
0018: EXX     
2091: RET     
208E: OFFIW   VV:11,$02
208D: RET     
208B: BIT     6,VV:14
2089: BIT     7,VV:11
3162: CALT    ($009A)
3168: JR      $3162
[MAME]> 

>print anm
8
>print a
CB


Before this, I would get 5 beeps which according to the service manual is a voltage error. Now it shows a little bit more life, not working properly yet.

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117565 07/17/20 01:04 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
[Linked Image from i.imgur.com]

I got it to print some data, but it seems to drop characters while it's printing, probably some handshaking problem.

It should print PRINT "DATA TO PRINTER" and have DATA TO PRINTER underneath each line.

But it's a little closer 8-)

The Apple parallel interface sends 8 bit data, and the high bit is set, I just cleared the high bit and the printer liked that data a lot better.

Re: Ap2000 signs of life [Re: Golden Child] #117572 07/19/20 01:47 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
More fiddling around, it seems that the timing for the AD conversion is somehow inconsistent, and setting the conversion delay to a very high value actually makes the online and lf buttons usable.

It also seems that data sent by the Apple parallel interface card doesn't bother to check the acknowledge, it just hits the strobe, so there isn't any flow control.

There's still some characters being dropped by the ap2000, haven't been able to figure that out yet.

I added some blinkenlights to show writes to the portABC and C000-C00F, and it helps to see what's going on. Man, I love blinkenlights.

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117573 07/19/20 08:39 PM
Joined: Mar 2001
Posts: 16,590
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,590
The source for the parallel card's ROM is available; it's possible the ACK isn't hooked up properly.

Re: Ap2000 signs of life [Re: R. Belmont] #117575 07/20/20 10:01 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I looked at the PIC manual, and there's a source code listing for both the ROMs but neither one bothers to look at the ACK, they just seem to write to C0x0 and assume it gets read.

I guess the apple was slow enough that it wasn't a problem but theoretically that could cause dropped characters.

This really surprised me that there's no real flow control as it wouldn't have been hard to add.

[Linked Image from i.imgur.com]

I wrote a little crap BASIC program to write data directly to the parallel card via I/O locations, it's slow enough that it doesn't go too fast for the printer.

Code
  NEW
    1  GOTO 90
    2 POKE PO,C : ? C,PEEK(PI),PEEK(PI)  : RETURN  :   REM PRINT CHAR AND SHOW THE ACK STATUS
    90 C = PEEK(49152+256)   : REM READ FROM C100 TO ACTIVATE AUTOSTROBE
   100 PO = 49152 + 9*16 : PI =  PO+4   : REM C090 FOR OUTPUT C094 FOR ACK INPUT
   105 FOR J = 1 TO 24
   106 C=64+J : GOSUB 2 : Z$=STR$(J) :GOSUB 3000
   110 C = 27:GOSUB 2 : C = ASC("L") : GOSUB 2  : REM ESC L TO ACTIVATE GRAPHICS
   111 C = 127:GOSUB 2
   112 C = 0  : GOSUB 2
   120 FOR I=0 TO 127 : C = I : GOSUB 2 :NEXT
   150 C=13:GOSUB 2:C=10:GOSUB 2
   160 NEXT
   1999 END
   3000 FOR Z = 1 TO LEN(Z$) : C=ASC(MID$(Z$,Z,1)): GOSUB 2 : NEXT : RETURN

RUN


[Linked Image from i.imgur.com]

Another thing that was totaly puzzling me was why the LF wasn't working right, it seemed like I had to hit it twice, and then I noticed that it had PORT_TOGGLE set. Man, that was really baffling to me. I guess it pays to read the code 8-)


Code
        PORT_START("FORMFEED")
        PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Form Feed") PORT_CODE(KEYCODE_7_PAD) //PORT_TOGGLE
        PORT_START("LINEFEED")
        PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Line Feed") PORT_CODE(KEYCODE_9_PAD) //PORT_TOGGLE


Re: Ap2000 signs of life [Re: Golden Child] #117576 07/20/20 11:10 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I modified the basic program to wait until ACK goes low, printing a dot every time it checks and the high bit is set. It's interesting that when it's printing that the acks doesn't finish right away.

Code
NEW
   1 GOTO 90
   2 POKE PO,C : ? C" ";:X = PEEK(PI) 
   3  IF  X < 128 GOTO 5
   4 ?".";:X=PEEK(PI):GOTO 3
   5 ? : RETURN

    90 C=PEEK(49152+256)   : REM READ FROM C100 TO ACTIVATE AUTOSTROBE
   100 PO = 49152 + 9*16 : PI =  PO+4
   105 FOR J = 1 TO 24
   106 C=64+J : GOSUB 2 : Z$=STR$(J) :GOSUB 3000
   110 C = 27:GOSUB 2 : C = ASC("L") : GOSUB 2
   111 C = 127:GOSUB 2
   112 C = 0  : GOSUB 2
   120 FOR I=0 TO 127 : C = I : GOSUB 2 :NEXT
   150 C=13:GOSUB 2:C=10:GOSUB 2
   160 NEXT
   1999 END
   3000 FOR Z = 1 TO LEN(Z$) : C=ASC(MID$(Z$,Z,1)): GOSUB 2 : NEXT : RETURN

RUN


It sends the 13 and 10 (CR LF)
then ESC L
then num of chars as two bytes

and you can see the dots get very long there, probably very likely to drop chars there if you're not checking the ACK.

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117578 07/21/20 03:07 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I got really aggravated trying to get it to print graphics because it kept dropping characters. So I thought, why not cheat a little and make a little buffer to hold the data.

And so I finally got some graphics to print. It's still glitching here and there, more to solve, but it was really gratifying to finally see something that looks halfway normal.

Some zoom grafix:

[Linked Image from i.imgur.com]

Trying Triple Dump (some glitching):

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117579 07/21/20 04:04 PM
Joined: Mar 2001
Posts: 16,590
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,590
Interesting. I would assume Triple Dump actually does watch the handshaking, but maybe not.

The card itself apparently does some clever Woz stuff where it changes the PROM address mapping after STROBE is set until ACK comes in. Will need to investigate further.

Last edited by R. Belmont; 07/21/20 04:12 PM.
Re: Ap2000 signs of life [Re: R. Belmont] #117580 07/21/20 05:58 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Yes, it's puzzling because you'd think there would be some kind of flow control.

I saw that my "minibuffer" was getting overrun and that was causing the glitches, so let's boost the size. The buffer has gone from mini to maxi: 8 bytes to 16k and now I said what the heck, 1 meelllion bytes.


Paper Graphics
[Linked Image from i.imgur.com]
Using the 144 vertical dpi (which overprints in multiple passes looks kinda odd) but 72 dpi looks good.

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




Re: Ap2000 signs of life [Re: Golden Child] #117581 07/21/20 09:14 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Thought I'd give it a spin with PrintMaster on the Amiga.

I tried with the cpc6128 and I was able to start Printmaster using the cpm startup disk with typing "|cpm", but it required a thousand disk swaps and it seemed to have trouble handshaking and dropping characters (even with my buffer). Oddly on the 6128, the arrow keys wouldn't work with Printmaster unless I held down the left arrow key and keeping it pressed, pressed the right arrow key.

As far as I can tell, the Amiga does watch the ack and busy lines and won't send any data while the printer isn't ready.

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117582 07/21/20 11:53 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Making calendars with Printmaster:

(I wonder how many people in the world are still using Printmaster and Dot Matrix Printers?)

[Linked Image from i.imgur.com]

While fiddling around with the cpc6128 I did encounter a strange bug. For some reason when running with the cpc6128 some of the ap2000's input ports all of a sudden went from active low to active high. This makes the printer boot up into "Data Dump Mode" because it thinks I'm holding down the Line Feed and Form Feed buttons when it starts. It's really weird that the cpc6128's doing that, because the apple2 and the amiga don't have that problem.

I'm doing a subtarget/sources build, could that be causing a problem?

Re: Ap2000 signs of life [Re: Golden Child] #117583 07/22/20 03:48 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
So let's see if the ibm5150 will work with print shop.

Testing the printer gives an error.

[Linked Image from i.imgur.com]

So let's see if we can figure out where it's hanging up.

We'll set an i/o watchpoint with wpi 378,8,r and then when it hits, set al=df (ack is active low) and then printshop will continue.
After doing that we disable the watchpoint.

[Linked Image from i.imgur.com]

This diagram from art of asm shows the status register.

So going into src/devices/machine/pc_lpt.cpp and adding an xor on STATUS_ACK seems to fix the error message.
Code
int8_t pc_lpt_device::status_r()
{
        return m_cent_status_in->read() ^ STATUS_BUSY ^ STATUS_ACK;
}



[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117623 08/05/20 10:46 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Just for fun, I thought I'd play with svgedit and inkscape to see if I could make something that looks like the control panel.

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117652 08/11/20 02:38 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
More silly fun:

I was thinking about having the printer make some noise while it was printing and I was able to get it to squawk a little.


[video:youtube]https://youtu.be/nXu1cxIHsZc[/video]

I think my "pin-firing" detection is missing half of the pin firings so it's pretty quiet when printing some areas.

Re: Ap2000 signs of life [Re: Golden Child] #117659 08/14/20 09:41 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
So I wanted to see what kind of waveforms were being generated by mame audio. With ubuntu, I had to use pavucontrol to select the monitor of Built-in audio to get the system-generated sound for Audacity to record.

[Linked Image from i.imgur.com]



I did discover something interesting, that the 1-bit DAC was generating a signal when it wasn't actually doing anything. I suppose this is correct behavior, but it does answer why I am always hearing pops and crackles. When there's an audio dropout, the waveform drops to zero and there's a "click" sound.


The dac corresponds to this code:
Code

   /* audio hardware */
        SPEAKER(config, "speaker").front_center();
        DAC_1BIT(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 0.25);
        voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref"));
        vref.add_route(0, "dac", 1.0, DAC_VREF_POS_INPUT);





Lowering the volume slider to zero for the 1 bit DAC makes the clicking disappear and the VU meters go down to no signal.

[Linked Image from i.imgur.com]

[Linked Image from i.imgur.com]


If you look at the recorded waveform, there's no actual sound being played, there's just a bunch of "dropouts" where other tasks are grabbing the cpu (probably because I'm doing a bunch of printf's)

Audacity's monitor shows -46 db on the VU meter.

[Linked Image from i.imgur.com]


It's interesting when I have the mockingboard enabled as there are multiple outputs which can contribute to the clicking.
If you change the volume on the different channel volumes, the biasing can constructively and destructively interfere and audacity's VU meters will go up and down.

Re: Ap2000 signs of life [Re: Golden Child] #117660 08/14/20 09:51 AM
Joined: May 2009
Posts: 1,875
J
Just Desserts Offline
Very Senior Member
Offline
Very Senior Member
J
Joined: May 2009
Posts: 1,875
Why not just use -wavwrite

Re: Ap2000 signs of life [Re: Golden Child] #117661 08/14/20 01:44 PM
Joined: Mar 2001
Posts: 16,590
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,590
The speaker click device the A2 uses simulates capacitive coupling because otherwise it was impossible to mix its output with a Mockingboard AY-3 or the GS's ES5503. After all, the definition of a speaker click device is that the voltage is either 0 or 5 volts, nothing in between.

Can we get back to what exactly made the AP2000 work? It was the NMI-at-startup and then something with the ADCs?

Re: Ap2000 signs of life [Re: R. Belmont] #117662 08/14/20 02:41 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Ok, sorry I tend to go off on tangents. 8-)

I think that the NMI would be fixed if it didn't hit right as it starts up, maybe delayed by a little bit.


I found the ADC conversion wasn't timing correctly.

Making some crap macros to help me see how many cycles and how much time ran in between.

Code

#define LASTPASSDIFFERENCE(t, name, func, str) \
  static t staticlast##name; \
  t last##name = staticlast##name; \
  t diff##name; \
  t cur##name = func; \
  diff##name = cur##name - staticlast##name;  diff##name=diff##name;\
  printf(#name": "); \
  printf(str "\n",cur##name-last##name);\
  printf("\n");\
  staticlast##name = cur##name;

#define LASTPASSPRINT(name, str, item) \
  printf(str "\n",item##name);




so I could do

Code
LASTPASSDIFFERENCE(long int, ADCONVSCANEACH_CYCLES, total_cycles(), "T cycles = %ld   expected to see 192");
LASTPASSDIFFERENCE(double,  ADCONVSCAN_TIME,   machine().time().as_double(), "time = %e");
LASTPASSDIFFERENCE(long int, ADCONVSCAN_CYCLES, total_cycles(), "T cycles = %ld   expected to see 768");

LASTPASSDIFFERENCE(double,   ADCONVSCAN_TIME,   machine().time().as_double(), "time = %e");
LASTPASSDIFFERENCE(long int, ADCONVSCAN_CYCLES, total_cycles(), "T cycles = %ld   expected to see 768");
//printf("m_adcnt = %d\n",m_adcnt);
//LASTPASSPRINT(ADCONVSCAN_CYCLES, "T last = %ld", last);
//LASTPASSPRINT(ADCONVSCAN_CYCLES, "T cur = %ld", cur);
//LASTPASSPRINT(ADCONVSCAN_CYCLES, "T diff = %ld", diff);




so now I get something that looks pretty good and it fixes the super fast beeping when you press a control panel button.


Code
ADCONVSCANEACH_CYCLES: T cycles = 190   expected to see 192

ADCONVSCANEACH_CYCLES: T cycles = 195   expected to see 192

ADCONVSCANEACH_CYCLES: T cycles = 194   expected to see 192

ADCONVSCANEACH_CYCLES: T cycles = 190   expected to see 192

ADCONVSCANEACH_CYCLES: T cycles = 188   expected to see 192



I'll try to work up a patch, it doesn't change very much in the code.

Re: Ap2000 signs of life [Re: Golden Child] #117663 08/14/20 03:38 PM
Joined: Mar 2001
Posts: 16,590
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,590
Ok, that's useful, thanks!

AJR, any thoughts on the ADC timing GC observed?

Re: Ap2000 signs of life [Re: Golden Child] #117664 08/14/20 04:31 PM
Joined: Dec 2015
Posts: 119
A
AJR Offline
Senior Member
Offline
Senior Member
A
Joined: Dec 2015
Posts: 119
I'm not AWJ, but I'll add a few thoughts anyway.

If this really is a problem with inexact timing, then that exemplifies a common problem with MAME's MCU cores, many of which just execute each instruction all at once and then go back and run the timers and timer-based peripherals for the same number of cycles. This works fine for purely internal interrupt timers but often fails for more sensitive cases such as serial ports.

In the past, Vas Crabb has suggested "separate icount and bcount" as the one proper solution to this problem, but much like the modern floppy system (which at least does have some readable technical documentation), only Olivier Galibert seems to have fully mastered its implementation details. While I only half-understand how it works, I'm not convinced of its effectiveness as a solution, especially after finding that Olivier Galibert's MCS-96 core, despite having this thing called "bcount" (not defined in MAME's execution core), triggers high-speed outputs at the wrong times.

Re: Ap2000 signs of life [Re: AJR] #117665 08/14/20 08:02 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Oh, I don't think it needs to be exactly 192 T-states, (the upd7810 has 3 clock cycles to a T-state I think) it just has to be around that. The timing doesn't need to be anywhere that exact. Once it does 4 analog measurements (4 * 192) it should be around 768 T states before it will fire an INTAD interrupt.

Re: Ap2000 signs of life [Re: Golden Child] #117667 08/15/20 12:44 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Ok, I looked at it again, and the original code doesn't seem to have timing problems. I possibly (probably) screwed up the code while I was doing some experiments and trying to figure out what it actually does. (and then thought it was the original code)


I made a pull request for a few things on the upd7810 and the ap2000, if it's horrible let me know.

The NMI problem is still there, but the ap2000 controls seem to be working with just minor changes. It starts up in the "offline" mode so if you hit keypad 0 it will put it online.


Re: Ap2000 signs of life [Re: Golden Child] #117669 08/15/20 11:30 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I fiddled and fiddled and couldn't get the ap2000 to go past the initialization. It was totally baffling. I put in delays and delays and hit the NMI multiple times.

Then I read the datasheet over and over again and I got a clue:

[Linked Image from i.imgur.com]

It says that you can sample the NMI input by using SKIT and SKNIT.

So it hits the SKIT NMI at $011E and never skips past the JMP $0000.

Code
010A: 48 48       SKIT    FAD
010C: 48 48       SKIT    FAD
010E: FD          JR      $010C
010F: 53          DCR     C
0110: FB          JR      $010C
0111: 4C E1       MOV     A,CR1
0113: 74 4A 02    ONI     B,$02
0116: C5          JR      $011C
0117: 37 CA       LTI     A,$CA
0119: 6A FD       MVI     B,$FD
011B: E8          JR      $0104
011C: 37 CA       LTI     A,$CA
011E: 48 40       SKIT    NMI
0120: 54 00 00    JMP     $0000


Code
--- a/src/devices/cpu/upd7810/upd7810_opcodes.cpp
+++ b/src/devices/cpu/upd7810/upd7810_opcodes.cpp
@@ -343,7 +343,7 @@ void upd7810_device::DIV_C()
 /* 48 40: 0100 1000 0100 0000 */
 void upd7810_device::SKIT_NMI()
 {
-       if (IRR & INTNMI)
+       if (IRR & INTNMI || m_nmi)
                PSW |= SK;
        IRR &= ~INTNMI;
 }
@@ -487,7 +487,7 @@ void upd7810_device::SKIT_SB()
 /* 48 60: 0100 1000 0110 0000 */
 void upd7810_device::SKNIT_NMI()
 {
-       if (0 == (IRR & INTNMI))
+       if (0 == (IRR & INTNMI) || !m_nmi)
                PSW |= SK;
        IRR &= ~INTNMI;
 }


So I think that would be right, setting the skip flag if m_nmi is set for SKIT_NMI and if m_nmi is not set.

This gets it past this spot so it will start up.

Re: Ap2000 signs of life [Re: Golden Child] #117670 08/15/20 05:16 PM
Joined: Dec 2015
Posts: 119
A
AJR Offline
Senior Member
Offline
Senior Member
A
Joined: Dec 2015
Posts: 119
That datasheet is a bit misleading. As a later manual explains, SKIT NMI and SKNIT NMI do not actually test INTFNMI (which makes sense since the flip-flop is cleared as soon as a NMI is taken and a NMI must always be taken), only the actual level of the NMI pin.

Re: Ap2000 signs of life [Re: AJR] #117671 08/15/20 06:56 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471

Hi AJR,

Yes, I think I understand now exactly what that means. The subtle distinctions make all the difference. Thanks for fixing this.


With my latest changes the ap2000 should start up properly and go "on-line" without having to manually hit the "on-line button".




It still drops characters though, do you guys have any objections to having a buffer to hold the incoming overflow characters until it's figured out?

Re: Ap2000 signs of life [Re: Golden Child] #117672 08/15/20 08:31 PM
Joined: Mar 2001
Posts: 16,590
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,590
If it's all working now I'd like to look at the A2 parallel cards again and see if I have the handshake wrong or something.

Re: Ap2000 signs of life [Re: Golden Child] #117673 08/15/20 09:10 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Hi RB, I think it pretty much works now except for dropping chars if my latest commit is added.

Re: Ap2000 signs of life [Re: Golden Child] #117674 08/15/20 10:20 PM
Joined: Mar 2001
Posts: 16,590
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,590
Yeah, I just saw that commit go in, great!

Re: Ap2000 signs of life [Re: R. Belmont] #117675 08/16/20 11:22 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471

Throwing in a buffer in between gets us Reggie!


Code
 
 WRITE_LINE_MEMBER( e05a30_device::centronics_input_strobe )
 {

        // using a buffer to hold the incoming data when printer can't keep up.
        // This is obviously not correct, but until the answer is found,
        // allows the ap2000 to function without dropping characters.

//     if (m_centronics_strobe == true && state == false && !m_centronics_busy) {
       if (m_centronics_strobe == true && state == false) {

           if (m_centronics_data_latched) { // will lose data, so put into buffer
               minibuffer[minibufferhead] = m_centronics_data;
               minibufferhead ++;
               minibufferhead %= minibuffersize;
           }
           else {
               m_centronics_data_latch   = m_centronics_data;
 
                m_centronics_data_latched = true;
                m_centronics_busy         = true;
                m_write_centronics_busy(m_centronics_busy);
            }
        }
 
        m_centronics_strobe = state;
@@ -203,6 +219,15 @@ uint8_t e05a30_device::read(offs_t offset)
        case 0x03:
                result = m_centronics_data_latch;
                m_centronics_data_latched = false;
+
+               if (minibufferhead != minibuffertail) {
+                       m_centronics_data_latch   = minibuffer[minibuffertail++];
+                       minibuffertail %= minibuffersize;
+                       m_centronics_data_latched = true;
+                       m_centronics_busy         = true;
+                       m_write_centronics_busy(m_centronics_busy);
+                }
+
                break;
        case 0x04:
                result |= m_centronics_busy << 0;
diff --git a/src/devices/machine/e05a30.h b/src/devices/machine/e05a30.h
index 5dfb51ac81c..d7220c4bc89 100644
--- a/src/devices/machine/e05a30.h
+++ b/src/devices/machine/e05a30.h
@@ -76,6 +76,11 @@ private:
        uint8_t m_centronics_strobe;
        uint8_t m_centronics_data_latch;
        uint8_t m_centronics_data_latched;
+
+       static const int minibuffersize=1e6;  // temporary fix for dropping characters
+       int minibuffer[minibuffersize];
+       int minibufferhead;
+       int minibuffertail;
 };
 
 DECLARE_DEVICE_TYPE(E05A30, e05a30_device)




[Linked Image from i.imgur.com]

Playing with Amiga graphic dump:

[Linked Image from i.imgur.com]

Interesting that the a2 PIC Parallel firmware seems to be slightly better than the Centronics in that you don't get it sending 9E and 1D to the printer (hardcoded in the firmware for switching a Centronics Microprinter into 40 and 80 column mode).

Appleworks apple+H screen dump:

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117676 08/16/20 12:33 PM
Joined: Mar 2001
Posts: 16,590
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,590
What are your DIP switch settings? I have some idea how to fix it without a buffer, but I can't get any program (including Triple-Dump) to print much of anything.

Re: Ap2000 signs of life [Re: R. Belmont] #117677 08/16/20 12:47 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Hi RB,

I think it's pretty much the "default" DIP settings I'm using now:

[Linked Image from i.imgur.com]

You can see what the ap2000 actually receives in its buffer by doing this in the debugger:

focus 1 (this selects the ap2000 upd7810 cpu)
ctrl+M
8000 (the internal ap2000 buffer is at $8000)


Here you can see the ap2000 getting 9E and 1D as the first characters when I've got the centronics firmware selected on the PIC.
[Linked Image from i.imgur.com]


quick and dirty: apple 2 ctrl+reset PR#1 then just type a bunch of keys and the printer will print junk:


or another idea (since the control panel keys are working now:)

when you start up mame, hold down the keypad 7 and 9 keys (LF and FF) and that will put the printer into Data Dump Mode where it displays the hex sent. It won't print anything until it gets a line of text, but you can override that by toggling keypad 0 (online/offline) and that will print the last characters sent.

Re: Ap2000 signs of life [Re: Golden Child] #117678 08/16/20 01:03 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I can't remember exactly, but I had a lot of problems getting data to the printer too:

It may even be this line in e05a30.cpp:

if (m_centronics_strobe == true && state == false && !m_centronics_busy) {

if you drop the !m_centronics_busy part, data should definitely be flowing.

Re: Ap2000 signs of life [Re: Golden Child] #117699 08/22/20 04:37 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Just for fun, I thought I'd try to hook up a rom for the Apple II Epson APL interface card using the Apple2 PIC as a model. I was able to get it working with an interesting issue. It has some really strange code that wants to read $c1c1. My workaround was to see if it had just read from that address, and if so, return 0.


so the slot number is in x so it ors with $c0, making it $c1, stores it in $01. Then stores $c1 into $00.

Then it keeps reading $c1c1 until it doesn't have the high bit set. I think this could be patched to check the busy address of the Apple2 PIC.

Code
C990: 48       pha
C991: 8A       txa
C992: 09 C0    ora #$c0
C994: 85 01    sta $01
C996: A9 C1    lda #$c1
C998: 85 00    sta $00
C99A: A0 00    ldy #$00
C99C: B1 00    lda ($00), y
C99E: 30 FC    bmi $c99c
C9A0: 8A       txa
C9A1: 0A       asl a
C9A2: 0A       asl a
C9A3: 0A       asl a
C9A4: 0A       asl a
C9A5: A8       tay
C9A6: 68       pla
C9A7: 99 80 C0 sta $c080, y
C9AA: 28       plp
C9AB: 60       rts



Otherwise, it seems to work ok, it doesn't pass 8 bits through, just 7 bits. That probably explains why Triple-Dump has such short graphical sequences, as it only sends 127 bytes of graphics data at a time so you see it doing little horizontal strips instead of a whole line at a time. It's actually super good for use with Apple II basic as it ends up stripping the high bit out.

Strangely, the CTRL+I codes don't match up with another Epson interface card manual. Anyone have an Epson APL card manual?

I can only really use CTRL+I G to do hi-res graphic dumps. So for example: CTRL+I G D I 2 space will do a graphic dump at double density, inverse and do page 2.

Also CTRL+Q by itself will dump the hi-res screen (just like the Silentype.)

Code
   100 HGR : HCOLOR = 3
   110 HPLOT 0,0 TO 279,0 : HPLOT 279,0 TO 279,191 : HPLOT 279,191 TO 0,0 : HPLOT 0,0 TO 0,191
   120 HPLOT 0,191 TO 279,191 : HPLOT 0,191 TO 279,0
   130 DATA "B","SIDE BY SIDE"
   140 DATA "A","AND PAGE 1+2"
   150 DATA "O","OR PAGE 1+2"
   160 DATA "H","XOR PAGE 1+2"
   170 DATA "I","INVERSE"
   180 DATA "E","DOUBLE SIZE"
   190 DATA "D","DOUBLE DENSITY"
   200 DATA "L","LAST LINE?"
   210 DATA "2","PAGE 2"
   220 DATA "END","END"
   300 READ A$,B$
   305 IF A$="END" THEN GOTO 400
   290 PR #1
   310 PRINT "CTRL+I G ";B$:PRINT CHR$(9)"G"A$
   320 GOTO 300

   399 REM CTRL+I G L WILL PRINT THE GFX SCREEN LINES THAT THE TEXT CURSOR IS ON
   400 ? CHR$(27)"A"CHR$(8):FOR I=0 TO 23:POKE 37,I:? CHR$(9)"GL ";:? CHR$(27)"A"CHR$(8):NEXT


[Linked Image from i.imgur.com]

Here's gfx page 1 and 2 side by side,
then gfx page 1 AND gfx page 2,
then gfx page 1 OR gfx page 2:

[Linked Image from i.imgur.com]

Seems to work ok with Triple Dump:
(discovered that the Epson FX-80 driver in Triple Dump is buggy and needed to use "Triple Dump (Beagle Bros. - 1984-10-22update).dsk" to do 80/72/90 dpi modes.)
[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117700 08/22/20 06:01 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I was able to get the Epson APL to work, why not try a Grappler Plus Parallel Interface rom that's 4K.

After not getting the bank switching right, I finally got it!

And now I can do rotated graphics with CTRL+I G R <CR>. Yay!

[Linked Image from i.imgur.com]

With the Grappler Plus, you can use an asterisk to set the Epson graphics mode from 1 to 6 so you can do 80/72/90 dpi as well as 60/120/240.

CTRL+I G * 4 <CR> will do 80 dpi.

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117787 09/06/20 09:23 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471

I was thinking about how it'd be interesting to write a "printer" simulator in lua so I could render various printer outputs that have different ESC codes... like Imagewriter ESC codes, 'cuz I'm dying to print dot matrix output in color.

I made a luaprinter class and I've got it so it can render to a bitmap.

Just a proof of concept.

Code
class luaprinter {

public:
        luaprinter(){};

        const static int BUFFERSIZE = 128000;  // a nice big size so we shouldn't have to worry
        int m_printerbuffer[BUFFERSIZE];
        int m_head = 0;
        int m_tail = 0;
        bitmap_rgb32 *m_bitmap;  // pointer to bitmap
        int m_xpos = 0;
        int m_ypos = 0;

        virtual void clearpage(){ m_bitmap->fill(0);};
        virtual void drawpixel(int x, int y, int pixelval){m_bitmap->pix32(y,x) = pixelval; };  // row major
        virtual int getpixel(int x, int y){return m_bitmap->pix32(y,x);};
        virtual void setheadpos(int x, int y){m_xpos=x;m_ypos=y;};
        virtual void savepage(){};
        virtual std::tuple<int*,int,int>  getbuffer() { return std::make_tuple(m_printerbuffer,m_head,m_tail);};   // returns the entire buffer as an integer a>
        virtual int getnextchar(){if (m_head==m_tail) return -1; else { int retval = m_printerbuffer[m_tail++]; m_tail %= BUFFERSIZE; return retval;}};
        virtual void putnextchar(int c){m_printerbuffer[m_head++]=c; m_head %= BUFFERSIZE;};
        void register_bitmap(bitmap_rgb32 &mybitmap){m_bitmap = &mybitmap;}  //
        void  testmodifybuffer(){ for (int i=0;i<10;i++){  m_printerbuffer[i]=i; m_head++;  };  };
        std::tuple<int,int>getheadpos() { return std::make_tuple(m_xpos,m_ypos); };

        static std::vector<luaprinter *> luaprinterlist;
};


and then hack on centronics/printer.cpp to inherit from luaprinter, and do a little bit of hookups in luaengine.

Code
        auto luaprinter_type = sol().registry().create_simple_usertype<luaprinter>("new", sol::no_constructor);
        luaprinter_type.set("clearpage", &luaprinter::clearpage);
        luaprinter_type.set("drawpixel", &luaprinter::drawpixel);
        luaprinter_type.set("getpixel", &luaprinter::getpixel);
        luaprinter_type.set("setheadpos", &luaprinter::setheadpos);
        luaprinter_type.set("savepage", &luaprinter::savepage);
        luaprinter_type.set("getbuffer", &luaprinter::getbuffer);
        luaprinter_type.set("getnextchar", &luaprinter::getnextchar);
        luaprinter_type.set("getheadpos", &luaprinter::getheadpos);
        sol().registry().set_usertype("luaprinter", luaprinter_type);

        machine_type.set("luaprinters", sol::property([this](running_machine &m) {
                        sol::table table = sol().create_table();
                        int i=0;
                        for(luaprinter* p : luaprinter::luaprinterlist)
                        {
                                table[i++] = &(*p);
                        };
                        return table;
                }));



I haven't worked it all out yet and I'm figuring out all this cpp stuff (and sometimes not figuring it out 8-) but I did get it to draw on my bitmap:
Code
for i=0,255 do for p=0,7 do 
if (2^p) & i ~= 0 then 
   manager:machine().luaprinters[0]:drawpixel(i,20+p,0) 
   manager:machine().luaprinters[0]:setheadpos(i,20) 
end end end

[Linked Image from i.imgur.com]

And it wouldn't be hard at all to do color:
[Linked Image from i.imgur.com]
Code
function iff(a,b,c) if a~=0 then return b else return c end end
for i=0,255 do 
for p=0,7 do 
if (2^p) & i ~= 0 then 
   manager:machine().luaprinters[0]:drawpixel(i,20+p,iff((2^1)&p,0xff0000,0)|iff((2^2)&p,0xff00,0)|iff((2^3)&p,0xff,0)) 
   manager:machine().luaprinters[0]:setheadpos(i,20) 
end end end

Re: Ap2000 signs of life [Re: Golden Child] #117790 09/07/20 04:14 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I was able to get my luaprinter to "print" something from Zoom Graphics pretending to be an Apple DMP:
[Linked Image from i.imgur.com]


And the lua code looks like this:

Code
function asc(c) return string.byte(c) end

function getnnnn()
  local i local retval=0 for i=3,0,-1 do ch=coroutine.yield() if ch >= asc('0') and ch <= asc('9') then retval = retval + (ch-asc('0'))*10^(i) end end return retval end

function getn(n)
  local i local retval=0 for i=n-1,0,-1 do ch=coroutine.yield() if ch >= asc('0') and ch <= asc('9') then retval = retval + (ch-asc('0'))*10^(i) end end return retval end

function renderhead(v) for i=0,7 do if (v & (2^i))~=0 then lp0:drawpixel(xpos,ypos+i,0) end end end

function dogfx() ch=coroutine.yield() renderhead(ch) xpos=xpos+1 lp0:setheadpos(xpos,ypos) end

function renderprt(ch) 
local xdpi,ydpi,feed,lfdir
xdpi = 144
ydpi = 72
feed=144/8
xpos=0
ypos=0
while 1 do 
ch = coroutine.yield() 
--print ("renderprt: "..ch.." "..string.char(ch)) 
if ch == 27 then
  ch = coroutine.yield()
  if ch == asc('n') then dpi=72
  elseif ch == asc('N') then xdpi=80
  elseif ch == asc('E') then xdpi=96
  elseif ch == asc('p') then xdpi=144
  elseif ch == asc('P') then xdpi=160
  elseif ch == asc('e') then xdpi=107
  elseif ch == asc('q') then xdpi=120
  elseif ch == asc('Q') then xdpi=136
  elseif ch == asc('f') then lfdir=1
  elseif ch == asc('r') then lfdir=-1
  elseif ch == asc('L') then lm=getn(3)
  elseif ch == asc('>') then bidir=0
  elseif ch == asc('<') then bidir=1
  elseif ch == asc('A') then feed=144/6  -- 24
  elseif ch == asc('B') then feed=144/8  -- 18
  elseif ch == asc('T') then feed=getn(2)
  elseif ch == asc('G') then nchars=getn(4)   for i=1,nchars do dogfx() end
  elseif ch == asc('S') then nchars=getn(4)   for i=1,nchars do dogfx() end
  elseif ch == asc('g') then nchars=getn(3)*8 for i=1,nchars do dogfx() end
  elseif ch == asc('V') then nchars=getn(4)   
                             ch=coroutine.yield() for i=1,nchars do renderhead(ch) end
  elseif ch == asc('F') then xpos = getn(4)
  elseif ch == asc('V') then -- set tof
  elseif ch == asc('O') then -- paper detect off
  elseif ch == asc('o') then -- paper detect on
  elseif ch == asc('!') then -- start bold
  elseif ch == asc('"') then -- end bold
  elseif ch == asc('X') then -- start underline
  elseif ch == asc('Y') then -- end underline
  else -- gobble char
  end
elseif ch == 13 then xpos = 0    -- cr
elseif ch == 10 then ypos = ypos + feed/144*ydpi xpos = 0  -- lf
elseif ch == 12 then  -- formfeed
end
end 
end

corenderprt = coroutine.create(renderprt)
coroutine.resume(corenderprt)

lp0 = manager:machine().luaprinters[0]

function feedchars(ch)
repeat
nextchar = lp0:getnextchar()
if nextchar >= 0 then coroutine.resume(corenderprt,nextchar) end
until nextchar < 0
end

function framedispatch() for i,j in pairs(dispatchlist) do j() end end
emu.register_frame(framedispatch)
dispatchlist={feedchars}



Printing from the NewsRoom demo:

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117794 09/08/20 01:34 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I thought, let's see if we can print color so I made some modifications to do color.

I looked high and low for a program that would print in color on the Apple II and I was able to get my luaprinter to print in color with Printographer. You can choose which Apple II hi-res colors match with specific color ribbons. Ribbon 1 being Yellow, 2 Magenta and 3 Cyan.


[Linked Image from i.imgur.com]

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117811 09/10/20 08:46 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I made a luaprinter for both centronics and rs232 and was having some trouble sorting out why it was dropping characters for the serial port.

Still sorting it out, gonna try a mutex, but I thought why not try to "replay" a print job to the lua printer.

It's pretty easy, just put chars into the buffer with putnextchar(). First I had to add putnextchar to luaengine which was trivial.

Code
        luaprinter_type.set("getnextchar", &luaprinter::getnextchar);
        luaprinter_type.set("putnextchar", &luaprinter::putnextchar);



I made a printout with the regular serial printer, and -printout test.txt to send it to a file.

Then did this from the console:
Code
dofile("../../luaprinter.lua")
f = io.open("test.txt")
filedata = f:read("*a")
print(#filedata)
for i=1,#filedata do lp0:putnextchar(string.byte(filedata,i)) end


and to "print" it again, this time with a different xdpi for instance:

Code

xpos=0 ypos=0 lp0:clearpage() paperxdpi=72 for i=1,#filedata do lp0:putnextchar(string.byte(filedata,i)) end



Of course this is only going to work if it fits entirely into the buffer.

[Linked Image from i.imgur.com]


Re: Ap2000 signs of life [Re: Golden Child] #117815 09/10/20 01:19 PM
Joined: Jan 2012
Posts: 1,081
rfka01 Offline
Very Senior Member
Offline
Very Senior Member
Joined: Jan 2012
Posts: 1,081
That's really neat stuff you're coaxing the system into doing ... major thumbs up!
Robert


NCR DMV- DEC Rainbow- Siemens PCD- ITT 3030-Oly People- Acorn A5000- Olivetti M20
Re: Ap2000 signs of life [Re: rfka01] #117816 09/10/20 04:39 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Thanks Robert!



I figured out what was wrong with my serial luaprinter, it was that I used a char variable instead of a u8 and it was converting 128-255 into a negative number. (That's what I get for growing up with Pascal CHAR types 8-) It's got to be unsigned char.

Code
void serial_luaprinter_device::rcv_complete()
{
        receive_register_extract();
        u8 recchar = get_received_char();
        m_printer->output(recchar);
        putnextchar(recchar);
}



so now the Amiga ImagewriterII driver can do this:

[Linked Image from i.imgur.com]

Oddly, printing out of the serial port seems faster than out of the parallel port.

Re: Ap2000 signs of life [Re: Golden Child] #117817 09/11/20 08:33 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Managed to get DOS Instant Artist printing, seemed to get hung up on some of the lpt status bits, specifically the paper out bit, so ^ 0x20 seemed to fix it.


[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117818 09/11/20 12:18 PM
Joined: Mar 2001
Posts: 16,590
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,590
That's cool. The IW2 was serial only though, so I'm not quite understanding the LPT aspect smile Also, I had no idea the IW2 was supported by software on non-Apple systems.

Re: Ap2000 signs of life [Re: Golden Child] #117819 09/11/20 03:03 PM
Joined: Feb 2004
Posts: 2,176
Vas Crabb Online Content
Very Senior Member
Online Content
Very Senior Member
Joined: Feb 2004
Posts: 2,176
ImageWriter II is well-supported on Windows at least until Windows XP. You can get a Bitronics-RS422 bridge to use it on an LPT port if you really want to. "Standard" Windows printer drivers assume that the same high-level byte-oriented protocol can be used to communicate with a printer whether it's on a parallel port (Bitronics or ECP), serial, or a TCP socket connection. You can thank HP for pioneering the nybble-oriented Bitronics back-channel, and their dumb print server modules that just exposed that to a TCP socket.

Re: Ap2000 signs of life [Re: Vas Crabb] #117820 09/11/20 03:39 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Since most printers are byte-oriented, perhaps we could have a parallel to serial converter and a serial to parallel converter.

Then you could use the ap2000 on a system that only supports serial, for example.

I made a serial luaprinter and added it to nano src/devices/bus/isa/com.cpp so you can do this:

(I did a MODE COM2:9600,N,8,1 before launching instant artist just for good measure)

[Linked Image from i.imgur.com]

[Linked Image from i.imgur.com]



I was going to see if I could get the coco3 to do the luaprinter (maybe getting a CGP-220 driver going) but it freezes up on a PRINT #-2. Also there's some strange double screen action going on.

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

Re: Ap2000 signs of life [Re: Golden Child] #117821 09/11/20 06:34 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I changed the baud rate of the serial printer to 2400 in the source code and could get bytes from the c64 but only on the user port channel 2.

Printers are supposed to be on channel 4 or 5 on the c64 iec bus, however there aren't any iec drivers that work, there's vic1515 but it's just a skeleton.

I was really keen on trying to get an okimate 20 print going, since its graphics commands are pretty simple and I had always wanted an oki.

I can get the user port to connect and send bytes.

[Linked Image from i.imgur.com]

[Linked Image from i.imgur.com]

But the c64 wants printers on 4...

[Linked Image from i.imgur.com]

I did find an okimate 20 apple2 disc on archive but it was in a2r format.

Re: Ap2000 signs of life [Re: Golden Child] #117828 09/13/20 03:46 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I found an article that mentioned printer drivers for Atari ST Degas and it has a bunch of different drivers for different dot matrix printers.

Hacking on a lua script made it output something recognizable for an Okimate 20.

Consulting the document "MCS-820_Printer_Handbook_(aka_Okimate_20).pdf" was indispensable.

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117829 09/13/20 02:26 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
So let's see if we can get windows 3.1 to print something.

After some fits and starts, win 3.1 installed with "SETUP /I" which disables the hardware detection.

And the ap2000 works with the Epson FX-80 driver. Cool!

[Linked Image from i.imgur.com]

and I tried the luaprinter with the c-itoh 8510 driver as I couldn't find an imagewriter II driver anywhere for windows 3.1. Unfortunately the 8510 driver doesn't do color.

[Linked Image from i.imgur.com]

Interestingly, it complained about paper being out for the luaprinter but not the ap2000, so I did the ^0x20 to the status just to get it to work.

Re: Ap2000 signs of life [Re: Golden Child] #117830 09/13/20 04:06 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Just for fun, I added a buffer indicator to the ap2000. The buffer size is shown by the little green bars in the upper left of the printout. Each bar represents a hex digit of the size. It's kinda fun to watch the bars grow and shrink as the buffer fills and clears.

It's also a good indicator of whether the system is properly respecting the busy/ack signals as it will never use the buffer if so.

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117832 09/14/20 01:07 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Adding output_perror(0) seems to fix the paper out problems:

Code
void centronics_luaprinter_device::device_reset()
{
        printf("DEVICE RESET CALLED\n");
        m_busy = false;
        output_busy(m_busy);
        output_fault(1);
        output_ack(1);
        output_ack(0);
        output_select(1);
        output_perror(0); // added paper out
}


So let's see if Geos 2.0 will print something:

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117836 09/14/20 04:10 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471

And if win3.1 works, why not try win 95?

(installing from floppies and using the file manager is so tedious! but it works!)

Luaprinter:

[Linked Image from i.imgur.com]

Ap2000:

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117837 09/14/20 06:03 PM
Joined: Mar 2001
Posts: 16,590
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,590
Neat.

Re: Ap2000 signs of life [Re: R. Belmont] #117848 09/15/20 11:14 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Thanks, RB!

I think I've got the saving the printed page nearly figured out. Here's some samples from apple II printographer printing to the Apple Scribe.

(The colors don't quite match up to the apple's color palette)

Printographer wants violet to be ribbons 2+3 but that makes it dark purple, just ribbon 2 (magenta) makes a good purple.

Apple from Zoom Graphics Disk:

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

Olympics from Joe Drish pictures:

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117855 09/16/20 03:36 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I was trying to clean up my code and put some things into the luaprinter constructor so they would be done automatically done, but it seems to make it not work. So strange. And printfs in the constructor don't appear until I exit mame.


The printfs that make "Scooby 8510" and "Scooby 8511" don't appear until exiting mame, yet the initvalue gets set properly to 3333.

But if I move routines into the constructor all sorts of weird things happen. So I'll leave it outside for now since I've been fiddling with this for a day...gcc problems on Ubuntu?


Code
luaprinter(device_t & thisdevice, int testvalue){ 
        m_lp_mydevice = &thisdevice; 
        time(&m_lp_session_time);  
        initvalue = testvalue;
        printf("\n\nInit Luaprinter Scooby %d\n",testvalue);
        initvalue = 33333;
        };




Code
[MAME]> lp = manager:machine().printers for i=1,#lp do print( lp[i]:getprintername(), #lp, lp[i]:getinitvalue(), lp[i]:simplename()) end
2020-09-16 08-25-19 apple2p-sl1-parallel-pic_ctx-luaprinter	3	33333	apple2p a2bus_slot a2pic centronics centronics_luaprinter centronics
2020-09-16 08-25-19 apple2p-sl2-ssc-ssc_rs232-luaprinter	3	33333	apple2p a2bus_slot a2ssc rs232 serial_luaprinter rs232
2020-09-16 08-25-19 apple2p-sl4-parallel-pic_ctx-ap2000	3	33333	apple2p a2bus_slot a2pic centronics ap2000 centronics


(exit mame here)

[MAME]> 

Init Luaprinter Scooby 8510

Init Luaprinter Scooby 8511

Init Luaprinter Scooby 810
Average speed: 100.00% (31 seconds)
sdl_kill: closing audio
Enter sdlwindow_exit
Leave sdlwindow_exit


after putting code in the constructor I get strange behavior:

Code
[MAME]> print( manager:machine().luaprinters[1]:getprintername(), #manager:machine().luaprinters)
error: 	std::bad_alloc
[MAME]> print( #manager:machine().luaprinters)
56

Re: Ap2000 signs of life [Re: Golden Child] #117858 09/16/20 07:06 PM
Joined: Mar 2006
Posts: 1,046
L
Lord Nightmare Online Content
Very Senior Member
Online Content
Very Senior Member
L
Joined: Mar 2006
Posts: 1,046
Does the lua interface allow you to force fflush on stdout and stderr? I know there's some really bizarre issues in mingw/msys2 with stderr not fflush()ing itself instantly (like it does on POSIX systems) on windows.

LN


"When life gives you zombies... *CHA-CHIK!* ...you make zombie-ade!"
Re: Ap2000 signs of life [Re: Lord Nightmare] #117860 09/16/20 08:32 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Hi LN,

Yes, fflush(stdout); does the trick. Thanks.

so I'm just curious now why there's so many printf's when I should only have 3 luaprinter devices
Code
luaprinter::luaprinter(device_t& thisdevice, int testvalue){ 
	m_lp_mydevice = &thisdevice; 
	time(&m_lp_session_time);  
	initvalue = testvalue;
	printf("yes you can");        // putting in a printf here
	fflush(stdout);
	
	};


Code
 ./mame64 apple2p  -sl1 parallel -sl1:parallel:pic_ctx luaprinter -flop1 ../../printographer.dsk -sl2 ssc -sl2:ssc:ssc_rs232 luaprinter -sl4 parallel -sl4:parallel:pic_ctx ap2000 -verbose

yes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canyes you canAttempting load of mame.ini
...

    _/      _/    _/_/    _/      _/  _/_/_/_/
   _/_/  _/_/  _/    _/  _/_/  _/_/  _/       
  _/  _/  _/  _/_/_/_/  _/  _/  _/  _/_/_/    
 _/      _/  _/    _/  _/      _/  _/         
_/      _/  _/    _/  _/      _/  _/_/_/_/    

mame 0.224	
Copyright (C) Nicola Salmoria and the MAME team

Lua 5.3	
Copyright (C) Lua.org, PUC-Rio

...
yes you canyes you canyes you canAttempting load of raster.ini
Attempting load of source/apple2.ini
Attempting load of apple2.ini
Attempting load of apple2p.ini
yes you canyes you canyes you canAvailable videodrivers: x11 wayland dummy 

Re: Ap2000 signs of life [Re: Golden Child] #117861 09/16/20 09:11 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
So my concept is to use the luaprinter class to provide a way to save the bitmap from a driver that doesn't really need the lua parts, just the printing parts. The lua stuff is there, but the driver doesn't need to use them.


So we can inheirit from luaprinter:

Code
class epson_lx810l_device :
public device_t, 
public device_centronics_peripheral_interface, 
public luaprinter
{
...

epson_lx810l_device::epson_lx810l_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
        device_t(mconfig, type, tag, owner, clock),
        device_centronics_peripheral_interface(mconfig, *this),
        luaprinter(*this, 810),
... 


and then we can do some things in the device_start:

Code
void epson_lx810l_device::device_start()
{
	m_online_led.resolve();

	m_cr_timer = timer_alloc(TIMER_CR);

	m_screen->register_screen_bitmap(m_bitmap);
	m_bitmap.fill(0xffffff); /* Start with a clean white piece of paper */


// do the luaprinter stuff, I would like to do more in the constructor, but it seems to cause problems.

	register_bitmap(m_bitmap);  // register with luaprinter
	luaprinterlist.emplace_back(static_cast<luaprinter *>(this));
	setprintername(sessiontime()+std::string(" ")+tagname());




and then you can save the bitmap with:

MAME]> print(manager:machine().lp[3]:pageheight())
576
[MAME]> print(manager:machine().lp[3]:pagewidth())
1024
[MAME]> manager:machine().lp[3]:savepage()
[MAME]> print(manager:machine().lp[3]:getprintername())
2020-09-16 13-53-53 apple2p-sl4-parallel-pic_ctx-ap2000
[MAME]>

So here's the page saved out:
[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117862 09/16/20 09:30 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
and the luaprinter code is actually pretty short:

Code

#ifndef MAME_LUAPRINTER_H
#define MAME_LUAPRINTER_H

#pragma once

#include "emu.h"
#include "png.h"
#include "emuopts.h"

class luaprinter {

public:

	int initvalue;
	device_t * m_lp_mydevice;
	luaprinter(device_t & thisdevice, int testvalue);

	static std::vector<luaprinter *> luaprinterlist;

	const static int BUFFERSIZE = 128000;
	std::array<unsigned char, BUFFERSIZE>  m_printerbuffer;
	int m_lp_head = 0;
	int m_lp_tail = 0;
	bitmap_rgb32 *m_lp_bitmap;  // pointer to bitmap
	int m_xpos = 0;
	int m_ypos = 0;
	std::string m_luaprintername;
	int m_page_count;
	static time_t m_lp_session_time;

	void addtolist(luaprinter & myprinter){ luaprinterlist.emplace_back(& myprinter);}
	void setprintername(std::string name){ m_luaprintername = name; }
	std::string getprintername(){ return m_luaprintername; }

	int getinitvalue(){ return initvalue; }

	void clearpage(){ m_lp_bitmap->fill(0xffffff);};
	void drawpixel(int x, int y, int pixelval) { m_lp_bitmap->pix32(y,x) = pixelval; };
	int getpixel(int x, int y){return m_lp_bitmap->pix32(y,x);};
	void setheadpos(int x, int y){m_xpos=x;m_ypos=y;};

	int pagewidth() { return m_lp_bitmap->width(); }
	int pageheight() { return m_lp_bitmap->height(); }

	device_t* getrootdev();
	void savepage();
	
	std::tuple<std::array<unsigned char,BUFFERSIZE>&,int,int>  getbuffer() { return std::make_tuple(std::ref(m_printerbuffer),m_lp_head,m_lp_tail);};   
	int getnextchar();
	void putnextchar(int c);
	void register_bitmap(bitmap_rgb32 &mybitmap){m_lp_bitmap = &mybitmap;}
	std::tuple<int,int>getheadpos() { return std::make_tuple(m_xpos,m_ypos); };
	int count(){ return luaprinterlist.size();}
	std::string fixcolons(std::string in);
	std::string sessiontime();
	std::string tagname();
	std::string simplename();
};


#endif  // MAME_LUAPRINTER_H


luaprinter.cpp:
Code

#include "luaprinter.h"

luaprinter::luaprinter(device_t& thisdevice, int testvalue){ 
	m_lp_mydevice = &thisdevice; 
	time(&m_lp_session_time);  
	initvalue = testvalue;
	printf("yes you can");
	fflush(stdout);
	
	};

int luaprinter::getnextchar() {
	if (m_lp_head==m_lp_tail) return -1; 
	else {
		int retval = m_printerbuffer.at(m_lp_tail++); 
		m_lp_tail %= BUFFERSIZE; 
		return retval;
	}
}

void luaprinter::putnextchar(int c) {
	m_printerbuffer.at(m_lp_head++)=c; 
	m_lp_head %= BUFFERSIZE;
}

std::string luaprinter::fixcolons(std::string in) {
    std::string final;
    for(std::string::const_iterator it = in.begin(); it != in.end(); ++it)
    {
        if((*it) != ':')
        {
            final += *it;
        }
        else final += '-';
    }
    return final;
}

std::string luaprinter::sessiontime() {
   struct tm *info;
   char buffer[120];
   info = localtime( &m_lp_session_time );
   strftime(buffer,120,"%Y-%m-%d %H-%M-%S", info);
   return std::string(buffer);
}

std::string luaprinter::tagname() {
	device_t * dev;
	device_t * lastdev;
	dev = m_lp_mydevice;
	std::string s(dev->owner()->shortname());
	while (dev) {
		lastdev = dev;
		dev=dev->owner();
	}
	lastdev=lastdev; // complains about non use
	return fixcolons(std::string(lastdev->shortname())+std::string(m_lp_mydevice->tag()));
}

std::string luaprinter::simplename() {
	device_t * dev;
	device_t * lastdev;
	dev = m_lp_mydevice;
	std::string s(dev->owner()->shortname());
	while (dev){
		s=std::string(dev->shortname())+std::string(" ")+s;
		lastdev = dev;
		dev=dev->owner();
	}
	lastdev=lastdev; // complains about non use
	return s;
}

device_t* luaprinter::getrootdev(){
	device_t* dev;
	device_t* lastdev = NULL;
	dev = m_lp_mydevice;
	while (dev){
		lastdev = dev;
		dev=dev->owner();
	}
	lastdev=lastdev; // complains about non use
	return lastdev;
}

void luaprinter::savepage(){
    emu_file file(std::string(m_lp_mydevice->machine().options().snapshot_directory()) + std::string("/") +
				std::string(getrootdev()->shortname() ) + std::string("/"), 
				OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
    auto const filerr = file.open(std::string(getprintername())+" Page "+std::to_string(m_page_count++)+".PNG");

    if (filerr == osd_file::error::NONE)
        {
            static const rgb_t png_palette[] = { rgb_t::white(), rgb_t::black() };
            // save the paper into a png
            png_write_bitmap(file, nullptr, (bitmap_t &) (* m_lp_bitmap), 2, png_palette);
        }
}




in luaengine.cpp:
Code
        auto luaprinter_type = sol().registry().create_simple_usertype<luaprinter>("new", sol::no_constructor);
        luaprinter_type.set("clearpage", &luaprinter::clearpage);
        luaprinter_type.set("drawpixel", &luaprinter::drawpixel);
        luaprinter_type.set("getpixel", &luaprinter::getpixel);
        luaprinter_type.set("setheadpos", &luaprinter::setheadpos);
        luaprinter_type.set("savepage", &luaprinter::savepage);
        luaprinter_type.set("getbuffer", &luaprinter::getbuffer);
        luaprinter_type.set("getnextchar", &luaprinter::getnextchar);
        luaprinter_type.set("putnextchar", &luaprinter::putnextchar);
        luaprinter_type.set("getheadpos", &luaprinter::getheadpos);
        luaprinter_type.set("setprintername", &luaprinter::setprintername);
        luaprinter_type.set("getprintername", &luaprinter::getprintername);
        luaprinter_type.set("fixcolons", &luaprinter::fixcolons);
        luaprinter_type.set("sessiontime", &luaprinter::sessiontime);
        luaprinter_type.set("simplename", &luaprinter::simplename);
        luaprinter_type.set("tagname", &luaprinter::tagname);
        luaprinter_type.set("count", &luaprinter::count);
        luaprinter_type.set("getinitvalue", &luaprinter::getinitvalue);
        luaprinter_type.set("pagewidth", &luaprinter::pagewidth);
        luaprinter_type.set("pageheight", &luaprinter::pageheight);

	sol().registry().set_usertype("luaprinter", luaprinter_type);




         machine_type.set("lp", sol::property([this](running_machine &m) {
                        sol::table table = sol().create_table();
                        int i=1;
                        for(auto p : luaprinter::luaprinterlist)
                        {
                        	table[i++] = p;
                        };
                        return table;
                }));

Re: Ap2000 signs of life [Re: Golden Child] #117876 09/18/20 04:15 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471

I thought, why not try to send the printed PNG to the printer:


dofile('../../luaprinter2.lua') -- start up my imagewriter interpreter

(print something to the page)

manager:machine().lp[1]:savepage()
print(manager:machine().lp[1]:getprintername())
os.execute('lpr ~/"Downloads/mamegit/mame/snap/ct486/2020-09-18 08-59-47 ct486-board4-lpt-lpt-centronics-luaprinter Page 0.PNG"')

and lpr sends the PNG file to the printer.

Ubuntu uses cups, I don't know how it would work on windows.

Re: Ap2000 signs of life [Re: Golden Child] #117877 09/18/20 06:34 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
So if I add to my list of printers in the constructor, I get a whole bunch of devices in my list.

It seems to be initializing a bunch of devices that don't actually get used. It must be enumerating every possible device that uses the luaprinter.

Code
luaprinter::luaprinter(device_t& thisdevice, int testvalue){ 
	m_lp_mydevice = &thisdevice; 
	time(&m_lp_session_time);  
	initvalue = testvalue;

	addtoprinterlist( *this);
	printf("yes you can");
	printf(" device = %s ",thisdevice.tag());
	fflush(stdout);
	printf("count = %d\n",count());  // the size of the printerlist
	fflush(stdout);
	
	};


with one luaprinter device I get 19 items:

Code
./mame64 ct486   -hard1 hd128MB  -debug  -board4:lpt:lpt:centronics luaprinter -confirm_quit -ramsize 64M 
-board3:ide:ide:1 hdd -hard2 hd128MBpt -board3:ide:ide:1 hdd
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 1
...
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 9
    _/      _/    _/_/    _/      _/  _/_/_/_/
   _/_/  _/_/  _/    _/  _/_/  _/_/  _/       
  _/  _/  _/  _/_/_/_/  _/  _/  _/  _/_/_/    
 _/      _/  _/    _/  _/      _/  _/         
_/      _/  _/    _/  _/      _/  _/_/_/_/    

mame 0.224	
Copyright (C) Nicola Salmoria and the MAME team

Lua 5.3	
Copyright (C) Lua.org, PUC-Rio

yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 10
yes you can device = :board2:comat:serport0:luaprinter count = 11
yes you can device = :board2:comat:serport1:luaprinter count = 12
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 13
yes you can device = :board4:lpt:lpt:centronics:ap2000 count = 14
yes you can device = :board4:lpt:lpt:centronics:lx810l count = 15
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 16
Debug Build: Disabling input grab for -debug
Debug Build: Disabling input grab for -debug
Debug Build: Disabling input grab for -debug
[MAME]> 
"hd128MB" approximately matches the following
supported software items (best match first):


"hd128MBpt" approximately matches the following
supported software items (best match first):

DEVICE START CALL luaprinterlist

DEVICE START CALL luaprinterlist

DEVICE START CALL setprintername

DEVICE RESET CALLED
DEVICE RESET CALLED


MAME debugger version 0.224 (mame0224-205-g69406ddcc71-dirty)
Currently targeting ct486 (PC/AT 486 with CS4031 chipset)
[MAME]> yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 18
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 19


and if I add a second luaprinter device I get 35 total devices.


Code
/mame64 ct486  -hard1 hd128MB  -debug  -board4:lpt:lpt:centronics luaprinter -confirm_quit -ramsize 64M
 -board3:ide:ide:1 hdd -hard2 hd128MBpt -board3:ide:ide:1 hdd -board2:comat:serport1 luaprinter
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 1
...
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 8
yes you can device = :board2:comat:serport1:luaprinter count = 9
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 10
yes you can device = :board2:comat:serport1:luaprinter count = 11
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 12
yes you can device = :board2:comat:serport1:luaprinter count = 13
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 14
yes you can device = :board2:comat:serport1:luaprinter count = 15
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 16
yes you can device = :board2:comat:serport1:luaprinter count = 17
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 18
yes you can device = :board2:comat:serport1:luaprinter count = 19
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 20
    _/      _/    _/_/    _/      _/  _/_/_/_/
   _/_/  _/_/  _/    _/  _/_/  _/_/  _/       
  _/  _/  _/  _/_/_/_/  _/  _/  _/  _/_/_/    
 _/      _/  _/    _/  _/      _/  _/         
_/      _/  _/    _/  _/      _/  _/_/_/_/    

mame 0.224	
Copyright (C) Nicola Salmoria and the MAME team

Lua 5.3	
Copyright (C) Lua.org, PUC-Rio

yes you can device = :board2:comat:serport1:luaprinter count = 21
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 22
yes you can device = :board2:comat:serport0:luaprinter count = 23
yes you can device = :board2:comat:serport1:luaprinter count = 24
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 25
yes you can device = :board4:lpt:lpt:centronics:ap2000 count = 26
yes you can device = :board4:lpt:lpt:centronics:lx810l count = 27
yes you can device = :board2:comat:serport1:luaprinter count = 28
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 29
Debug Build: Disabling input grab for -debug
Debug Build: Disabling input grab for -debug
Debug Build: Disabling input grab for -debug
[MAME]> 
"hd128MB" approximately matches the following
supported software items (best match first):


"hd128MBpt" approximately matches the following
supported software items (best match first):

DEVICE START CALL luaprinterlist

DEVICE START CALL luaprinterlist

DEVICE START CALL setprintername

DEVICE RESET CALLED
DEVICE RESET CALLED
m_rs232_rxbaud read=7
rs232_rxbaud read=7


MAME debugger version 0.224 (mame0224-205-g69406ddcc71-dirty)
Currently targeting ct486 (PC/AT 486 with CS4031 chipset)
[MAME]> 

>g
[MAME]> yes you can device = :board2:comat:serport1:luaprinter count = 32
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 33
yes you can device = :board2:comat:serport1:luaprinter count = 34
yes you can device = :board4:lpt:lpt:centronics:luaprinter count = 35
Average speed: 99.93% (1 seconds)


Well, I guess as long as it works I'll keep it outside the constructor.

Re: Ap2000 signs of life [Re: Golden Child] #117880 09/19/20 02:55 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471

Just for fun, I wanted to see if I could get some color postscript output from the win95 printer drivers using the QMS Colorscript 230 drivers.

Setting the spool settings to Print directly to printer and disable bidirectional support because it would put 0x14 characters into the printout.

Using the "printer" centronics device and then using mame's File manager and setting the printout to a file to save out the data.


Once done, using gv (ghostview) under Ubuntu to view the output. (I had to apt install gv)

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

What I'd like to do is to figure out some way to have it watch the printer, when there's a long pause in the output, say 15 seconds or so, then save everything to a file, so it can run gv automatically.

Re: Ap2000 signs of life [Re: Golden Child] #117885 09/20/20 09:59 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471

I managed to get something working that would save the printer output bytes to separate files so you could launch a viewer on them, like gv for postscript output.

A delay of 30 seconds will separate files.


Code
lp0 = manager:machine().luaprinters[1]
filenamebase=lp0:getprintername()
filenamecount=0
idlewaitperiod=30*60
idlecount=0


function feedchars(ch)
local idleflag=0
repeat
nextchar = lp0:getnextchar()
if nextchar >= 0 then 
  idleflag=1
  if f == nil then
    filenamecount = filenamecount+1
    currentfilename = filenamebase..string.format("%04d",filenamecount)..".ps"
    f=io.open(currentfilename,"w")
    idlecount=0
  end
  f:write(string.char(nextchar))
 end 
until nextchar < 0
if idleflag==0 then
  if f~=nil then
    idlecount=idlecount+1 
    if idlecount%(60*5)==0 then print ("idle: "..idlecount/60) end
  end
else
  idlecount=0 -- reset idlecount
end
if idlecount > idlewaitperiod then
  idlecount=-1
  f:close()
  f=nil
  os.execute('gv "'..currentfilename..'" &')
  print('gv '..currentfilename)
end
end

function framedispatch() for i,j in pairs(dispatchlist) do j() end end
emu.register_frame(framedispatch)
dispatchlist={feedchars}



Code
idle: 5.0
idle: 10.0
idle: 15.0
idle: 20.0
idle: 25.0
idle: 30.0
gv 2020-09-20 14-14-25 ct486-board4-lpt-lpt-centronics-luaprinter0004.ps

Re: Ap2000 signs of life [Re: Golden Child] #117900 09/23/20 05:55 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I managed to convert the ap2000 driver into using my luaprinter routines to do the page saving:

They look a little "squashed" since the aspect ratio is off because it's 120x72. 120x144 would probably look more normal.

Some page samples:

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

putting the first page into gimp and stretching it to 120x144:
[Linked Image from i.imgur.com]

testing to see how many lines on a page:
[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117902 09/24/20 06:05 PM
Joined: Mar 2006
Posts: 1,046
L
Lord Nightmare Online Content
Very Senior Member
Online Content
Very Senior Member
L
Joined: Mar 2006
Posts: 1,046
This is amazing stuff! Are you going to submit this upstream as a PR soon? I kinda want to play with it...

LN


"When life gives you zombies... *CHA-CHIK!* ...you make zombie-ade!"
Re: Ap2000 signs of life [Re: Lord Nightmare] #117903 09/25/20 05:44 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Hi LN,

Thanks! Yes, I'm almost there... 8-)

I finally figured out how to blast out my screwed up github repository with "git push --force" and that completely replaced everything. Yay!

Coming soon to a theater near you 8-)

Re: Ap2000 signs of life [Re: Golden Child] #117910 09/26/20 09:44 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
If you want to have a look at luaprinter, I have a branch at:

https://github.com/goldnchild/mame/tree/luaprinter

I need to clean it up and figure out the proper way of doing things using the device_interface mix-in.


[Linked Image from i.imgur.com]


One weird thing that the ap2000 is doing is that it's missing descenders when it prints in the Roman font. I thought initially that it wasn't getting the full 9 bits of the printhead, but it prints draft just fine as well as the Sans Serif.

Ramiro Polla (the uber-hacker behind the ap2000 driver) was cool enough to send me his ap2000 disassembly so maybe I can figure out why.

Re: Ap2000 signs of life [Re: Golden Child] #117926 10/01/20 12:25 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I thought I'd make a font from the pictures in the Imagewriter manual, since I always liked that font, and it doesn't look too bad.

Code
chars = {
"        "..
"        "..
"        "..
"        "..
"        "..
"        "..
"        "..
"        "..
"        ",
"   x    "..
"   x    "..
"   x    "..
"   x    "..
"        "..
"        "..
"   x    "..
"        "..
"        ",
"  x x   "..
"  x x   "..
"  x x   "..
"        "..
"        "..
"        "..
"        "..
"        "..
"        ",
"  x  x  "..
"  x  x  "..
" xxxxxx "..
"  x  x  "..
" xxxxxx "..
"  x  x  "..
"  x  x  "..
"        "..
"        ",
...
"   x    "..
"  x x   "..
" x   x  "..
"x     x "..
"xxxxxxx "..
"x     x "..
"x     x "..
"        "..
"        ",
" xxxxx  "..
" x    x "..
" x    x "..
" xxxxx  "..
" x    x "..
" x    x "..
" xxxxx  "..
"        "..
"        ",
...
}

-- just a quick test to see if it works

rmargin=125
lmargin=5
xpos=lmargin*8
tmargin=5

function printchar(c)
  c = c & 0x7f
  if c==13 or c==10 then xpos=lmargin*8 ypos=ypos+12 return end
  if xpos > rmargin*8 then xpos=lmargin*8 ypos=ypos+12 end
  if c<32 then c=32 end
  for col=0,7 do
    headdots = 0
    for row=0,8 do
      dot = chars[c-32+1]:sub(1+row*8+col,1+row*8+col)
      if dot == " " then dot=0 else dot=1 end
      headdots = headdots | (dot << row)
    end
    renderhead(headdots)      
    print(col.."  "..headdots)
    xpos = xpos+1      
  end
end

function printstring(s) for i=1,s:len() do printchar(string.byte(s,i)) end end



[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117927 10/02/20 04:28 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I was trying to find something that would print on the BBC Master and found a BeeBug dumpmaster rom.

./mame64 bbcm -printer ap2000 -romimage1 dmpmastr


It kinda works, but it seems to get its workspace corrupted when I do a *LDPIC. You're supposed to be able to hit CTRL+SHIFT+@ (mapped to backslash) to make it dump.

*BPRINT P0 V A D will setup the hotkey but it doesn't dump properly.

*BPRINT I V will do a vertical dump in inverse.
*HELP BPRINT shows you the settings.

Still, it's kinda neat to see it work.

[Linked Image from i.imgur.com]


edit: after fiddling around, I discovered that the rom scrnprnt100 has a good hotkey setup: hit CTRL+P and it prints the screen, CTRL+SHIFT+P and it prints in inverse.

./mame64 bbcm -printer ap2000 -romimage1 scrnprnt100


[Linked Image from i.imgur.com]

Last edited by Golden Child; 10/02/20 07:26 AM.
Re: Ap2000 signs of life [Re: Golden Child] #117928 10/02/20 10:37 AM
Joined: Apr 2012
Posts: 289
Pernod Offline
Senior Member
Offline
Senior Member
Joined: Apr 2012
Posts: 289
Originally Posted by Golden Child
I was trying to find something that would print on the BBC Master and found a BeeBug dumpmaster rom.

./mame64 bbcm -printer ap2000 -romimage1 dmpmastr


It kinda works, but it seems to get its workspace corrupted when I do a *LDPIC. You're supposed to be able to hit CTRL+SHIFT+@ (mapped to backslash) to make it dump.

*LDPIC is a custom graphics loader on the Acorn User Gallery discs which runs in workspace at &900, so not too surprising there's a conflict.

The most popular printing ROMs at the time were Dumpout 3 (dumpout3) and Printmaster (prntmeps), but not sure if they have a hotkey dump feature.


BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, etc.
Re: Ap2000 signs of life [Re: Pernod] #117930 10/03/20 07:31 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471

I hacked up a lua script to render Epson JX-80 output from the BBC Dumpmaster rom and it looks pretty good. It supports the JX-80 on printer number 22. 22 is color with square pixels, 0 is black and white, and 5 is 72x72 dpi for square pixels.

The luaprinter wouldn't work unless I set the acknowledge to 1 in device_reset with output_ack(1).

Doubling the dots horizontally on the printout makes it look vivid.

[Linked Image from i.imgur.com]

The output is stretched 200% using gimp to make the aspect look right and rotated 90 degrees to be upright.

[Linked Image from i.imgur.com]


Re: Ap2000 signs of life [Re: Golden Child] #117966 10/09/20 07:05 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I was thinking, hmmmm can we make pdfs out of the dots. There's a catseye lua library that hacked on can make this:

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

It's a bit slow to be practical, gv takes a minute to render the pdf page, but still good fun.

Re: Ap2000 signs of life [Re: Golden Child] #117970 10/10/20 01:59 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
More fiddling with Color Print Shop...using a rainbow background.

I was integerizing the coordinates, and that wasn't quite right.

It looks more like dot matrix output now:

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

but the file size is huge: 515MB

515665131 Oct 9 18:41 test94.pdf

No wonder it takes a minute to render it.

Re: Ap2000 signs of life [Re: Golden Child] #117971 10/10/20 11:34 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
[Linked Image from i.imgur.com]

Reproducing this color print shop demo on youtube:

https://www.youtube.com/watch?v=z3hMOxR0n5g

It's interesting how the bitmap colors differ from the output pdf where the pdf looks more authentic.

I also got the file size a bit smaller (like 10x smaller) by not setting the color for every output dot and by using strokes instead of fills to make the dots.

Re: Ap2000 signs of life [Re: Golden Child] #117972 10/12/20 04:57 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Loading the png into gimp it's pretty easy to manually color correct by adjusting HSL:

(split view)

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #117973 10/12/20 08:36 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I just figured out how to directly access members in luaengine, just specify them directly, what could be easier?

It's shocking how easy that is...

and if you want it read only just make it a property.

Code
device_luaprinter_interface_type.set("xposprop", sol::property(&device_luaprinter_interface::m_lp_xpos));
device_luaprinter_interface_type.set("name", &device_luaprinter_interface::m_lp_luaprintername);
device_luaprinter_interface_type.set("xpos", &device_luaprinter_interface::m_lp_xpos);


So then you can modify the variables directly, like manager:machine().lp[1].xpos = 200

Code
[MAME] function listlp()
[MAME]>>   print("listlp()  list of luaprinters:")
[MAME]>>   print("------------------------------")
[MAME]>>   for i,j in pairs(manager:machine().lp) do
[MAME]>>     print("lp["..i.."] = "..j:getprintername())
[MAME]>>   end
[MAME]>>   print("------------------------------")
[MAME]>> end
[MAME]> 
[MAME]> listlp()
listlp()  list of luaprinters:
------------------------------
lp[1] = 2020-10-12 10-36-18 apple2e-sl1-parallel-pic_ctx-luaprinter
lp[:sl1:parallel:pic_ctx:luaprinter] = 2020-10-12 10-36-18 apple2e-sl1-parallel-pic_ctx-luaprinter
------------------------------
[MAME]> print(manager:machine().lp[1].name)
2020-10-12 10-36-18 apple2e-sl1-parallel-pic_ctx-luaprinter
[MAME]> manager:machine().lp[1].name = "hi_there"
[MAME]> print(manager:machine().lp[1].name)
hi_there



And I was also experimenting with being able to execute lua code from inside the ap2000 driver, so I could call a lua function to say, generate dots for a pdf. So how to execute lua code? Just call load_string.


Code
device_luaprinter_interface_type.set("loadstring", [this](char const *astr)
     { printf("Trying %s\n",astr); return lua_engine::load_string(astr);  });


Code
[MAME]> manager:machine().lp[1].loadstring('print("IT WORKS")')
Trying print("IT WORKS")
IT WORKS
[MAME]> function dude(x) print ("This is a function that prints "..x) end
[MAME]> manager:machine().lp[1].loadstring('dude("IT WORKS")')
Trying dude("IT WORKS")
This is a function that prints IT WORKS


So now I need to figure out how to make it possible to call the luaengine from inside the driver.

It'd also be cool if you could load_string a string from the debugger, so you could do something complex in lua, so do something similar to a printf but make it lua code to execute.

Re: Ap2000 signs of life [Re: Golden Child] #117974 10/13/20 01:25 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Ok, so I add this to my device_luaprinter_interface:

It's a pointer to lua_engine in m_luaengine,
and also a pointer to a member function of lua_engine.

So I can call the function by

((*m_luaengine).*lualoadstring)(astr);
where astr is the string to execute.

Code

static void (lua_engine::* lualoadstring)(const char * astr);
static lua_engine *m_luaengine;

void callloadstring(const char *astr) { 
     printf("Trying callloadstring %s\n",astr); 
     ((*m_luaengine).*lualoadstring)(astr); 
}


and then in luaengine initialize them:

Code
device_luaprinter_interface::lualoadstring = &lua_engine::load_string;
device_luaprinter_interface::m_luaengine = this; 


so now I can do this:

Code
[MAME]> l = manager:machine().lp[1]
[MAME]> l:callloadstring(" l:callloadstring('print(\"whoa!\")') ")
Trying callloadstring  l:callloadstring('print("whoa!")') 
Trying callloadstring print("whoa!")
whoa!

Re: Ap2000 signs of life [Re: Golden Child] #117975 10/13/20 07:43 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471

Modifying the dot printing routine to call lua seems to work:

Code
char buffer[128];
snprintf(buffer,128,"if drawdot then drawdot( %f, %f ) end",
           (double) m_real_cr_pos + CR_OFFSET, yd);
callloadstring( buffer );


I use the if to check if the drawdot routine has been defined.

Code
Trying callloadstring if drawdot then drawdot( 971.000000, 170.333333 ) end
Trying callloadstring if drawdot then drawdot( 971.000000, 171.333333 ) end
Trying callloadstring if drawdot then drawdot( 971.000000, 172.333333 ) end
Trying callloadstring if drawdot then drawdot( 971.000000, 173.333333 ) end
Trying callloadstring if drawdot then drawdot( 971.000000, 174.333333 ) end



and if I define the drawdot routine from the console:

Code
function drawdot(x,y) print("DRAWDOT !!! "..x.."  "..y) end

Trying callloadstring if drawdot then drawdot( 35.000000, 60.000000 ) end
DRAWDOT !!! 35.0  60.0
Trying callloadstring if drawdot then drawdot( 35.000000, 61.000000 ) end
DRAWDOT !!! 35.0  61.0


Now I need to figure out how the ap2000 does 240 dpi because the steppers seem to step at 120 dpi, perhaps you have to watch the timing of when the printhead is fired, firing it when it's moving in-between stepper positions.

Re: Ap2000 signs of life [Re: Golden Child] #117981 10/14/20 06:16 PM
Joined: Oct 2014
Posts: 2
R
Ramiro Polla Offline
Member
Offline
Member
R
Joined: Oct 2014
Posts: 2
Originally Posted by Golden Child

Now I need to figure out how the ap2000 does 240 dpi because the steppers seem to step at 120 dpi, perhaps you have to watch the timing of when the printhead is fired, firing it when it's moving in-between stepper positions.

The firmware was beautifully written and calculated down to the microseconds it takes for the printhead to hit the paper. Look for two comments which have "417 microseconds" in epson_lx810l.cpp.

In epson_lx810l_device::co0_w():
Quote
The firmware expects a 300 microseconds delay between the fire signal and the impact of the printhead on the paper. This can be verified by the timings of the steps and fire signals for the same positions with different directions (left to right or right to left). We don't simulate this delay since it is smaller than the time it takes the printhead to travel one pixel (which would be 417 microseconds), so it makes no difference to us. It is interesting to note that the vertical alignment between lines which are being printed in different directions is noticeably off in the 20+ years old printer used for testing =).


In epson_lx810l_device::device_timer()
Quote
The firmware issues two half-steps in sequence, one immediately after the other. At full speed, the motor does two half-steps at each 833 microseconds. A timer fires the printhead twice, with the same period as each half-step (417 microseconds), but with a 356 microseconds delay relative to the motor steps.

Re: Ap2000 signs of life [Re: Ramiro Polla] #117982 10/15/20 03:49 AM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Hi Raimro,

Thanks for the pointers. I stuck some instrumenting in to see the delay between changes to the stepper and the timers.

yes the write to co0_w is 417 ms apart: (2525-2107 = 418)

Code
POS = 0   DATA=0
POS = 1   DATA=0
STEPPER:d
CR_STEPPER_MSECS: time = 835.9782 microsecs

CR_STEPPER current pos: -49
POS = 0   DATA=0
POS = 1   DATA=0
CR_TIMER_MSECS: time = 835.978

POS = 0   DATA=0
POS = 1   DATA=44
Fractional time co0_w: 152107.340486 
Trying callloadstring if drawdot then drawdot( 33.000000, 25.333333 ) end
Fractional time co0_w: 152107.340486 
Trying callloadstring if drawdot then drawdot( 33.000000, 29.333333 ) end
STEPPER:8
CR_STEPPER_MSECS: time = 830.0781 microsecs

CR_STEPPER current pos: -48
POS = 0   DATA=0
POS = 1   DATA=38
Fractional time co0_w: 152525.024406 
Trying callloadstring if drawdot then drawdot( 33.000000, 26.333333 ) end
Fractional time co0_w: 152525.024406 
Trying callloadstring if drawdot then drawdot( 33.000000, 27.333333 ) end
Fractional time co0_w: 152525.024406 
Trying callloadstring if drawdot then drawdot( 33.000000, 28.333333 ) end
CR_TIMER_MSECS: time = 830.078


Gonna have to study this some more 8-)

Re: Ap2000 signs of life [Re: Golden Child] #117983 10/15/20 01:36 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
and checking the time since the last stepper change, it says 337 usec and 755 usec (755-337 usec = 418 usec) so yes very close to expected

Code
POS = 0   DATA=0
POS = 1   DATA=20
Fractional time co0_w: 110442.708325 
Time since last step: 757.446289 
Trying callloadstring if drawdot then drawdot( 83.000000, 26.333333 ) end
STEPPER:5
CR_STEPPER_MSECS: time = 833.9437 microsecs

CR_STEPPER current pos: -98
POS = 0   DATA=0
POS = 1   DATA=8
Fractional time co0_w: 110857.137036 
Time since last step: 337.931315 
Trying callloadstring if drawdot then drawdot( 83.000000, 28.333333 ) end
CR_TIMER_MSECS: time = 833.944

POS = 0   DATA=0
POS = 1   DATA=20
Fractional time co0_w: 111274.210604 
Time since last step: 755.004883 
Trying callloadstring if drawdot then drawdot( 82.000000, 26.333333 ) end
STEPPER:d
CR_STEPPER_MSECS: time = 831.5023 microsecs

CR_STEPPER current pos: -97
POS = 0   DATA=0
POS = 1   DATA=8
Fractional time co0_w: 111690.470369 
Time since last step: 339.762370 
Trying callloadstring if drawdot then drawdot( 82.000000, 28.333333 ) end
CR_TIMER_MSECS: time = 831.502

POS = 0   DATA=0
POS = 1   DATA=2
Fractional time co0_w: 112107.543937 
Time since last step: 756.835937 
Trying callloadstring if drawdot then drawdot( 81.000000, 30.333333 ) end
STEPPER:8
CR_STEPPER_MSECS: time = 833.3333 microsecs

Re: Ap2000 signs of life [Re: Golden Child] #117984 10/15/20 02:15 PM
Joined: Mar 2001
Posts: 16,590
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,590
Reading this makes me realize how much a dot-matrix printer is like a write-only floppy drive, except it controls the exact media position instead of waiting for it to come around to the right spot.

Re: Ap2000 signs of life [Re: R. Belmont] #117990 10/16/20 11:51 AM
Joined: Oct 2014
Posts: 2
R
Ramiro Polla Offline
Member
Offline
Member
R
Joined: Oct 2014
Posts: 2
Originally Posted by R. Belmont
Reading this makes me realize how much a dot-matrix printer is like a write-only floppy drive, except it controls the exact media position instead of waiting for it to come around to the right spot.

Great idea for a hackerspace project: a dot-matrix printer that spins the paper and waits for the right spot to come around for each dot.

Re: Ap2000 signs of life [Re: Golden Child] #117991 10/16/20 12:48 PM
Joined: May 2009
Posts: 1,875
J
Just Desserts Offline
Very Senior Member
Offline
Very Senior Member
J
Joined: May 2009
Posts: 1,875
True, but you would need to ensure that your paper has an index hole.

Re: Ap2000 signs of life [Re: Golden Child] #117992 10/16/20 12:50 PM
Joined: Mar 2001
Posts: 16,590
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,590
Or write some kind of a sync mark and watch for it to come around.

Re: Ap2000 signs of life [Re: R. Belmont] #117997 10/16/20 11:44 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I liked being able to call lua so much I made a class called luacall:

Code
/***************************************************************************
    luacall.h
    Utility class for calling lua
***************************************************************************/

#ifndef MAME_LUACALL_H
#define MAME_LUACALL_H

#pragma once

class lua_engine;

class luacall {
	public:
		static lua_engine *m_luaengine;
		static void        (lua_engine::* lualoadstringf)  (const char * astr);
		static int         (lua_engine::* luagetintvarf)   (const char * astr);
		static double      (lua_engine::* luagetdoublevarf)(const char * astr);
		static std::string (lua_engine::* luagetstringvarf)(const char * astr);

	static void lualoadstring(const char *astr) { 
			((*m_luaengine).*lualoadstringf)(astr); 
		}

	static int luagetintvar(const char *astr) {
			int retval =  ((*m_luaengine).*luagetintvarf)(astr); 
			return retval;
		}

	static double luagetdoublevar(const char *astr) {
			double retval =  ((*m_luaengine).*luagetdoublevarf)(astr); 
			return retval;
		}

	static std::string luagetstringvar(const char *astr) {
			std::string retval =  ((*m_luaengine).*luagetstringvarf)(astr); 
			return retval;
		}

}; // end class luacall  

#endif  // MAME_LUACALL_H

/***************************************************************************
    luacall.cpp
    Utility class for calling lua functions
***************************************************************************/

#include "emu.h"
#include "luacall.h"

lua_engine *luacall::m_luaengine;
void      (lua_engine::* luacall::lualoadstringf)  (const char * astr);
int         (lua_engine::* luacall::luagetintvarf)   (const char *astr);
double      (lua_engine::* luacall::luagetdoublevarf)(const char *astr);
std::string (lua_engine::* luacall::luagetstringvarf)(const char *astr);

luaengine.h:
Code
	int luagetintvar( const char *astr);
	double luagetdoublevar( const char *astr);
	std::string luagetstringvar( const char *astr);

and in luaengine.cpp:
Code
		luacall::m_luaengine = this; 
		luacall::lualoadstringf   = &lua_engine::load_string;
		luacall::luagetintvarf    = &lua_engine::luagetintvar;
		luacall::luagetdoublevarf = &lua_engine::luagetdoublevar;
		luacall::luagetstringvarf = &lua_engine::luagetstringvar;

	int         lua_engine::luagetintvar   ( const char *astr) { return sol()[astr]; };
	double      lua_engine::luagetdoublevar( const char *astr) { return sol()[astr]; };
	std::string lua_engine::luagetstringvar( const char *astr) { return sol()[astr]; };


so then I can do stuff like:

Code
// call lua with a string to execute:
	char buffer[128];
	snprintf(buffer,128,"if drawdot then drawdot( %f, %f ) end", xcoord, ycoord);
	luacall::lualoadstring(buffer);

// get the value from a double var:

printf("Get Double %f\n",luacall::luagetdoublevar("testdouble"));

//some indirection: get a double var from the name stored in the variable named by teststring2

printf("Testing luagetstring:   value for %s %f\n",
                luacall::luagetstringvar("teststring2").c_str(),
		luacall::luagetdoublevar(luacall::luagetstringvar(luacall::luagetstringvar("teststring2").c_str()).c_str()));

// get the value from a integer var:
printf("Get Int %d\n",luacall::luagetdoublevar("testint"));



If the variable isn't defined, it seems to just return 0, 0.0 or the empty string.

Code
Testing luagetstring:   value for  0.000000
Get Double 0.000000
Get Int 0
[MAME]> testdouble=5.29
[MAME]> testint=300
[MAME]> teststring2="orange"
[MAME]> orange="grape"
[MAME]> grape=777
[MAME]> 
Testing luagetstring:   value for orange 777.000000
Get Double 5.290000
Get Int 300



Re: Ap2000 signs of life [Re: Golden Child] #117998 10/17/20 09:36 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I think I may have solved the mystery of the missing bottom line. The font data is stored as 8 bits, with the bottom line saved as 3 bytes. These bytes go into a shift register when written to c001,c002 and c003 and they get shifted out at c000.

So now you can see the bottom of the character [:

[Linked Image from i.imgur.com]

so at 2708 DE gets loaded with C001 and C gets 2 so we transfer 3 bytes to c001,c002,c003 with the BLOCK instruction.

then at 2714 we read the value at C000 for our 9th pin, the other 8 bits coming from LDAX (HL+).

[Linked Image from i.imgur.com]


It seems to work for the self test, anyway.




Code

void e05a30_device::write(offs_t offset, uint8_t data)
{
	LOG("%s: e05a30_w([0xC0%02x]): %02x\n", machine().describe_context(), offset, data);

	switch (offset) {
	case 0x0:
	case 0x1:
	case 0x2:
	case 0x3:
		c000_shift_register &= ~(0xff << ((3-offset)*8));
		c000_shift_register |= (data << ((3-offset)*8));
		break;

...

uint8_t e05a30_device::read(offs_t offset)
{
	uint8_t result = 0;

	LOG("%s: e05a30_r([0xC0%02x]): ", machine().describe_context(), offset);

	switch (offset) {
	case 0x0: 
			c000_shift_register <<= 1;  // put shift before the capture
			result = (c000_shift_register & 0x1000000) ? 0x80 : 0x0; 
			break;

Re: Ap2000 signs of life [Re: Golden Child] #118000 10/18/20 03:07 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
So if we can print 9 bits of the printhead, why not see if ESC ^ 9-pin graphics mode works:

[Linked Image from i.imgur.com]

According to the ESC P manual, the second byte's LSB is the 9th pin, but it's actually the MSB, just as in the printer internals.

Code

    1 GOTO 10
    5 X = PEEK( (12*16+1)*256 ) : P = 12*256*16+9*16 : FOR I=1 TO LEN(A$) : POKE P,ASC(MID$(A$,I,1)):NEXT:RETURN
   10 REM APPLE PARALLEL CARD, READ FROM C100 SETS UP STROBE, THEN POKE C090 WILL SEND CHARACTERS


     100 N = 120 * 3 : N1=((N/256)-INT(N/256))*256 :N2=INT(N/256) :? N,N1,N2:A$=CHR$(27)+"^"+CHR$(1)+CHR$(N1)+CHR$(N2) : GOSUB 5
     110 FOR J = 1 TO N/2 : A$=CHR$(1+4+(1+4)*16)+CHR$(128) : GOSUB 5 : A$=CHR$(2+8+(2+8)*16)+CHR$(128):GOSUB 5:NEXT:A$=CHR$(10):GOSUB 5




[Linked Image from i.imgur.com]

Although, come to think of it, this probably worked before the 9-pin fix since it's not going through the shift register 8-)

Re: Ap2000 signs of life [Re: Golden Child] #118001 10/18/20 04:06 PM
Joined: Mar 2001
Posts: 16,590
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,590
Can you submit a pull request for the shift register fix? That would be great smile

Re: Ap2000 signs of life [Re: R. Belmont] #118002 10/18/20 06:24 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Sure, RB!

(if I can get my git straightened up again 8-)

I managed to get the font looking improved, but it still isn't quite right.

The ap2000 does the NLQ fonts by printing one sequence of 9 bits, feeding the paper by 1/216" then printing the next sequence of 9 bits.

It's kinda hacky yet, but I do like the little "circles" look on the i and the r and the 2.


This is at 240x144 dots:

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #118003 10/18/20 07:18 PM
Joined: Mar 2001
Posts: 16,590
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,590
Neat! I love those little circles too smile

Re: Ap2000 signs of life [Re: R. Belmont] #118004 10/18/20 08:22 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Ok I made a PR:

ap2000 add shift register for c000 - fixes the missing 9th pin line #7366

I cloned a fresh repo so I wouldn't make a mess.

It's strange, testing it out but the keys stopped working, like holding keypad 7 (FF) when starting up to get it to go into self test mode. And holding down keypad 0 to toggle online doesn't work either.

Re: Ap2000 signs of life [Re: Golden Child] #118005 10/18/20 08:36 PM
Joined: Mar 2001
Posts: 16,590
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,590
Can you check if those keys not working also happened without the shift register change?

Re: Ap2000 signs of life [Re: R. Belmont] #118006 10/18/20 09:24 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Ok, I commented it out, recompiled and the keys still didn't work. So weird.

As an aside, just now when I was changing the e05a30.cpp file I accidentally opened the e05a03.h file and guess what, there's a shift register in that one also. I guess a person should go reading other similar devices for clues too 8-).

Re: Ap2000 signs of life [Re: Golden Child] #118007 10/19/20 02:13 PM
Joined: Mar 2006
Posts: 1,046
L
Lord Nightmare Online Content
Very Senior Member
Online Content
Very Senior Member
L
Joined: Mar 2006
Posts: 1,046
Can you find which commit upstream broke the keys (after stashing or committing/PRing your changes?)


"When life gives you zombies... *CHA-CHIK!* ...you make zombie-ade!"
Re: Ap2000 signs of life [Re: Golden Child] #118008 10/19/20 02:29 PM
Joined: Feb 2004
Posts: 2,176
Vas Crabb Online Content
Very Senior Member
Online Content
Very Senior Member
Joined: Feb 2004
Posts: 2,176
Is it actually broken? If the printer is using IPT_KEYBOARD then it’s intentional that it no longer responds to keys when the system keyboard is active. This is to solve the “typing on everything at once” issue you get the moment you plug a terminal into a computer with a keyboard, or plug two terminals into a computer. See https://mametesters.org/view.php?id=6320 and check the Keyboard Mode menu.

Re: Ap2000 signs of life [Re: Golden Child] #118009 10/19/20 03:25 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
Ahh, I see that it is disabled by default. I did not know that menu was there 8-)

Setting it to enabled makes it active again. Cool.

Thanks, Vas.

[Linked Image from i.imgur.com]

Re: Ap2000 signs of life [Re: Golden Child] #118010 10/19/20 09:34 PM
Joined: Feb 2014
Posts: 471
G
Golden Child Offline OP
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 471
I had a mini freakout for why the keyboard wasn't working on the ct486, but it gets the rightmost screen so it comes up initially disabled. Left screen = enabled, right screen = disabled.

Simple fix, just enable it from the Keyboard menu.


[Linked Image from i.imgur.com]

Yay! So now we can see the descenders:

[Linked Image from i.imgur.com]

Page 1 of 10 1 2 3 9 10

Who's Online Now
2 registered members (2 invisible), 55 guests, and 2 spiders.
Key: Admin, Global Mod, Mod
ShoutChat Box
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics8,818
Posts116,080
Members4,915
Most Online890
Jan 17th, 2020
Powered by UBB.threads™ PHP Forum Software 7.7.3