Previous Thread
Next Thread
Print Thread
Page 4 of 11 1 2 3 4 5 6 10 11
Joined: Feb 2014
Posts: 1,100
Likes: 172
G
Very Senior Member
OP Online Content
Very Senior Member
G
Joined: Feb 2014
Posts: 1,100
Likes: 172
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.




Joined: Feb 2014
Posts: 1,100
Likes: 172
G
Very Senior Member
OP Online Content
Very Senior Member
G
Joined: Feb 2014
Posts: 1,100
Likes: 172
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.

Joined: Feb 2014
Posts: 1,100
Likes: 172
G
Very Senior Member
OP Online Content
Very Senior Member
G
Joined: Feb 2014
Posts: 1,100
Likes: 172
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]

Joined: Feb 2014
Posts: 1,100
Likes: 172
G
Very Senior Member
OP Online Content
Very Senior Member
G
Joined: Feb 2014
Posts: 1,100
Likes: 172
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]

Joined: Feb 2014
Posts: 1,100
Likes: 172
G
Very Senior Member
OP Online Content
Very Senior Member
G
Joined: Feb 2014
Posts: 1,100
Likes: 172

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

Joined: Feb 2014
Posts: 1,100
Likes: 172
G
Very Senior Member
OP Online Content
Very Senior Member
G
Joined: Feb 2014
Posts: 1,100
Likes: 172
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]

Joined: Feb 2014
Posts: 1,100
Likes: 172
G
Very Senior Member
OP Online Content
Very Senior Member
G
Joined: Feb 2014
Posts: 1,100
Likes: 172
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]


Joined: Feb 2014
Posts: 1,100
Likes: 172
G
Very Senior Member
OP Online Content
Very Senior Member
G
Joined: Feb 2014
Posts: 1,100
Likes: 172
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]


Joined: Jan 2012
Posts: 1,179
Likes: 17
Very Senior Member
Offline
Very Senior Member
Joined: Jan 2012
Posts: 1,179
Likes: 17
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
Joined: Feb 2014
Posts: 1,100
Likes: 172
G
Very Senior Member
OP Online Content
Very Senior Member
G
Joined: Feb 2014
Posts: 1,100
Likes: 172
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.


Page 4 of 11 1 2 3 4 5 6 10 11

Link Copied to Clipboard
Who's Online Now
1 members (MrBogi), 303 guests, and 1 robot.
Key: Admin, Global Mod, Mod
ShoutChat
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics9,320
Posts121,929
Members5,074
Most Online1,283
Dec 21st, 2022
Our Sponsor
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!

Superior Solitaire
Forum hosted by www.retrogamesformac.com