|
Joined: Feb 2014
Posts: 1,100 Likes: 172
Very Senior Member
|
OP
Very Senior Member
Joined: Feb 2014
Posts: 1,100 Likes: 172 |
Hi RB, I think it's pretty much the "default" DIP settings I'm using now: 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. 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
Very Senior Member
|
OP
Very Senior Member
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
Very Senior Member
|
OP
Very Senior Member
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. 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.)
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
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: 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.)
|
|
|
|
Joined: Feb 2014
Posts: 1,100 Likes: 172
Very Senior Member
|
OP
Very Senior Member
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! 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.
|
|
|
|
Joined: Feb 2014
Posts: 1,100 Likes: 172
Very Senior Member
|
OP
Very Senior Member
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. 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.
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:
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
And it wouldn't be hard at all to do color:
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
Very Senior Member
|
OP
Very Senior Member
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: And the lua code looks like this:
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:
|
|
|
|
Joined: Feb 2014
Posts: 1,100 Likes: 172
Very Senior Member
|
OP
Very Senior Member
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.
|
|
|
|
Joined: Feb 2014
Posts: 1,100 Likes: 172
Very Senior Member
|
OP
Very Senior Member
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.
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:
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:
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.
|
|
|
|
Joined: Jan 2012
Posts: 1,179 Likes: 17
Very Senior Member
|
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
Very Senior Member
|
OP
Very Senior Member
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.
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: Oddly, printing out of the serial port seems faster than out of the parallel port.
|
|
|
1 members (MrBogi),
303
guests, and
1
robot. |
Key:
Admin,
Global Mod,
Mod
|
|
Forums9
Topics9,320
Posts121,929
Members5,074
|
Most Online1,283 Dec 21st, 2022
|
|
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!
|
|
|
|