Previous Thread
Next Thread
Print Thread
Page 4 of 10 1 2 3 4 5 6 9 10
Re: Ap2000 signs of life [Re: R. Belmont] #117677 08/16/20 12:47 PM
Joined: Feb 2014
Posts: 485
G
Golden Child Online Content OP
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 485
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: 485
G
Golden Child Online Content OP
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 485
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: 485
G
Golden Child Online Content OP
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 485
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: 485
G
Golden Child Online Content OP
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 485
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: 485
G
Golden Child Online Content OP
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 485

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: 485
G
Golden Child Online Content OP
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 485
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: 485
G
Golden Child Online Content OP
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 485
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: 485
G
Golden Child Online Content OP
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 485
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: 485
G
Golden Child Online Content OP
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 485
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 10 1 2 3 4 5 6 9 10

Who's Online Now
2 registered members (RColtrane, Golden Child), 48 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,821
Posts116,119
Members4,921
Most Online890
Jan 17th, 2020
Powered by UBB.threads™ PHP Forum Software 7.7.3