|
Joined: Feb 2014
Posts: 927 Likes: 75
Senior Member
|
OP
Senior Member
Joined: Feb 2014
Posts: 927 Likes: 75 |
Was able to get the self test for the Star Gemini kinda working. It prints one line, then the carriage keeps moving to the left for some reason, ignoring the home sensor... It uses the upd7800 and had to hack the SIO instruction for now, just had it set the INTFST flag in the IRR, since it was hanging up on SIO, then a SKIT FS loop. void upd7810_device::SIO() { logerror("unimplemented instruction: SIO setting IRR\n"); IRR |= INTFST; } ![[Linked Image from i.imgur.com]](https://i.imgur.com/riDeLmh.png) Had a heck of a time with the ioports, primarily because I did some copypasting from different files and didn't realize that these unused bits would cause a problem.
PORT_START("ONLINE")
PORT_BIT(0xfe, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ON LINE") PORT_CODE(KEYCODE_0_PAD)
PORT_START("FORMFEED")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FORM FEED") PORT_CODE(KEYCODE_7_PAD)
PORT_START("LINEFEED")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LINE FEED") PORT_CODE(KEYCODE_9_PAD)
The line PORT_BIT(0xfe, IP_ACTIVE_LOW, IPT_UNUSED) would cause a read to return 0xFE or 0xFF, not just 0x0 or 0x1. So this code would keep returning 0xFF or 0xFE and the line feed and form feed keys wouldn't respond.
if (offset==0)
{
retval = (ioport("ONLINE")->read() << 0) |
(ioport("LINEFEED")->read() << 1) |
(ioport("FORMFEED")->read() << 2) |
((ioport("DIPSW2")->read() & 0x1) << 3) |
((ioport("DIPSW1")->read() & 0xf) << 4);
retval = retval ^ 0xf8; // invert dip switches for active low
}
Removing that line made it work as expected.
|
|
|
|
Joined: Feb 2014
Posts: 927 Likes: 75
Senior Member
|
OP
Senior Member
Joined: Feb 2014
Posts: 927 Likes: 75 |
Got the color ribbon working on the ex800 self test: There's a stepper motor for the color ribbon positioner that moves the ribbon up and down along with a switch to tell you when you're at the home position. The stepper position goes from 0 to 70 to 142 to 216 so just divide by 70 to get an index for the ribbon color. ![[Linked Image from i.imgur.com]](https://i.imgur.com/93DZRJl.png) ![[Linked Image from i.imgur.com]](https://i.imgur.com/JCJL18U.png)
|
1 member likes this:
robcfg |
|
|
|
Joined: Feb 2014
Posts: 927 Likes: 75
Senior Member
|
OP
Senior Member
Joined: Feb 2014
Posts: 927 Likes: 75 |
I got a dump of the 8042 "associate" processor used in Epson FX-80. It handles reading the dip switches and also handles the carriage control.
It looks fairly sane, there may be a couple of bad bytes. Took me awhile to figure out that although based on the mcs48, it uses ./unidasm -arch upi41
|
|
|
|
Joined: Feb 2014
Posts: 927 Likes: 75
Senior Member
|
OP
Senior Member
Joined: Feb 2014
Posts: 927 Likes: 75 |
Making a little bit of progress on the FX-80, after hooking up the 8042 I can get the initial carriage movement to move to the left and go into the online state, then I can take it online/offline and feed a line or page. There's still some things to figure out, it won't self test or print yet, but I'm happy to see the 8042 processing the commands from the 7810. I'm trying to understand the 8042 disassembly but it really does a lot of gymnastics, so it's a bit hard to follow. One of the things that the upd7810 driver doesn't currently implement is setting the INTAN7 flag which is checked by SKIT AN7. AN7 is hooked up to the online switch so you can't switch it on or offline. I added a set_an7() function to upd7810.h to set this flag so I could get the SKIT AN7 to function. According to the datasheet, "each of these flags is set whenever a falling edge is sensed on the corresponding input line if that line is used as an edge-sensing input." void set_an7() { m_itf |= INTAN7; } INPUT_CHANGED_MEMBER(epson_fx80_device::online_switch) { if (oldval & !newval) { m_maincpu->set_an7(); } } Here's a little bit of 8042 code, this part handles the cr steppers: so port 2 bits 0 and 1 are the stepper out, and they go in a pattern like 00, 01, 11, 10, then cycle. so it shifts bit 0 left to bit position 1 and inverts the old bit 1 and puts that in bit 0. 00 becomes 01, 01 becomes 11, 11 becomes 10, and 10 becomes 00. Likewise, the opposite direction pattern is 00, 10, 11, 01, 00 so bit 1 is shifted into bit 0 and bit 1 is bit 0 inverted: 00 becomes 10, 10 becomes 11, 11 becomes 01, and 01 becomes 00
71b: b9 59 mov r1,#$59 get status
71d: f1 mov a,@r1
71e: 92 2e jb4 $72E jump if bit 4 set (so is bit 4 of status indicate direction?)
720: b9 5e mov r1,#$5E 5E <<<<<<<<<<<< 720 move carriage 1 step
722: f1 mov a,@r1
723: 77 rr a
724: f2 2a jb7 $72A
726: 43 02 orl a,#$02 0000 0010
728: e4 36 jmp $736
72a: 53 fd anl a,#$FD 1111 1101
72c: e4 36 jmp $736
72e: b9 5e mov r1,#$5E <<<<<<< 72E move carriage in opposite direction 1 step
730: f1 mov a,@r1
731: 97 clr c
732: 32 35 jb1 $735
734: a7 cpl c
735: f7 rlc a
736: 53 03 anl a,#$03 0000 0011
738: b9 5e mov r1,#$5E
73a: 21 xch a,@r1
73b: 53 fc anl a,#$FC 1111 1100
73d: 41 orl a,@r1
73e: 3a outl p2,a << update p2 STEPPERS
73f: a1 mov @r1,a
|
|
|
|
Joined: May 2009
Posts: 2,104 Likes: 143
Very Senior Member
|
Very Senior Member
Joined: May 2009
Posts: 2,104 Likes: 143 |
That's completely the wrong way of hooking up AN7. You have the logic that should be in the CPU core, outside of it. You should just be using a devcb_write_line in the CPU core for it.
|
|
|
|
Joined: Feb 2014
Posts: 927 Likes: 75
Senior Member
|
OP
Senior Member
Joined: Feb 2014
Posts: 927 Likes: 75 |
Yes, agreed. The logic should be in the cpu core. (That was a hack to see if it would work).
Howabout a WRITE_LINE_MEMBER so the change to the INTAN7 flag can be initiated from outside the cpu core and have the logic inside the WRITE_LINE_MEMBER to track if it's a falling transition?
DECLARE_WRITE_LINE_MEMBER( an7_w ) { if (!state & m_an7_state) m_itf |= INTAN7; // falling m_an7_state = state;
}
INPUT_CHANGED_MEMBER(epson_fx80_device::online_switch) { m_maincpu->set_an7(newval); }
The devcb call backs have the cpu core initiating the call back, they'd have to poll it.
|
|
|
|
Joined: Feb 2014
Posts: 927 Likes: 75
Senior Member
|
OP
Senior Member
Joined: Feb 2014
Posts: 927 Likes: 75 |
Just for fun, I was looking at the minigraf at src/devices/bus/iq151/minigraf.cpp which is a driver for the IQ151 Aritma Minigraf 0507 module emulation and it uses 3 bits for the X stepper and 3 bits for the Y stepper. So how does 3 bits map into the 4 lines of a stepper motor? There's a manual in czech jednim krokem se navodi. musi se dodrzet spojitost posloupnosti jednotlivych kroku dle tabulky 2. pri navozeni rostouci posloupnosti kroku se provadi pohyb v kladnem smeru souradnych os pisatka zleva doprava u sour. y pohyb papiru zezadu dopredu. pri navozeni klesajici posloupnosti kroku se provadi pohyb opacnym smerem. which google translated as: one step. the continuity of the sequence of individual steps according to Table 2 must be observed. y move the paper from back to front. when inducing a decreasing sequence of steps, a movement is performed in the opposite direction. The manual also had a schematic which gives the circuit: ![[Linked Image from i.imgur.com]](https://i.imgur.com/IELvLp5.png) So steppers.cpp gives the standard drive table which is an 8 value cycle: //Standard drive table is 2,6,4,5,1,9,8,a The schematic lists T105 (which must be a 74LS05 NOT inverter gate) and T103 (which should be a 74LS03 NAND gate). Each input to the 74LS03 is given as inverted, so let's treat it as a OR gate with inverted inputs (not a OR not b). so let's write some lua code to see if we can make something that looks like our "standard" drive table: We'll make a function to do a "logical not" called lnot and a function "t103" for the T103 gate: function lnot(a) if a==0 then return 1 else return 0 end end function t103(a,b) return lnot(a) | lnot(b) end Let's try the topmost set of gates: for x = 0,7 do x1 = x & 1 x2 = (x & 2) >> 1 x4 = (x&4) >> 2
print(x4,x2,x1,"", t103(lnot(x1),lnot(x2)) & (x4),"") end
0 0 0 0
0 0 1 0
0 1 0 0
0 1 1 0
1 0 0 0
1 0 1 1
1 1 0 1
1 1 1 1 then the second for x = 0,7 do x1 = x & 1 x2 = (x & 2) >> 1 x4 = (x&4) >> 2
print(x4,x2,x1,"", t103(lnot(x1),lnot(x2)) & lnot(x4)) end
0 0 0 0
0 0 1 1
0 1 0 1
0 1 1 1
1 0 0 0
1 0 1 0
1 1 0 0
1 1 1 0 so let's do all the gates and put them together: (It's a little easier to see if on multiple lines) function lnot(a) if a==0 then return 1 else return 0 end end
function t103(a,b) return lnot(a) | lnot(b) end
for x = 0,7 do
x1 = x & 1
x2 = (x & 2) >> 1
x4 = (x & 4) >> 2
a = t103(lnot(x1),lnot(x2)) & (x4)
b = t103(lnot(x1),lnot(x2)) & lnot(x4)
c = t103(lnot(x2),x4) & t103(lnot(x1),x2) & t103(x2,lnot(x4))
d = t103(x4,x2) & t103(lnot(x2),lnot(x4)) & t103(x2,lnot(x1))
print(x4,x2,x1,"",a,b,c,d,"",string.format("%x",a<<3 | b<<2 | c<<1 | d))
end
and all as one line: > for x = 0,7 do x1 = x & 1 x2 = (x & 2) >> 1 x4 = (x&4) >> 2 a = t103(lnot(x1),lnot(x2)) & (x4) b=t103(lnot(x1),lnot(x2)) & lnot(x4) c = t103(lnot(x2),x4) & t103(lnot(x1),x2) & t103(x2,lnot(x4)) d = t103(x4,x2) & t103(lnot(x2),lnot(x4)) & t103(x2,lnot(x1)) print(x4,x2,x1,"",a,b,c,d,"",string.format("%x",a<<3 | b<<2 | c<<1 | d)) end
0 0 0 0 0 1 0 2
0 0 1 0 1 1 0 6
0 1 0 0 1 0 0 4
0 1 1 0 1 0 1 5
1 0 0 0 0 0 1 1
1 0 1 1 0 0 1 9
1 1 0 1 0 0 0 8
1 1 1 1 0 1 0 a
>
which matches the standard drive table.
|
|
|
|
Joined: Feb 2014
Posts: 927 Likes: 75
Senior Member
|
OP
Senior Member
Joined: Feb 2014
Posts: 927 Likes: 75 |
![[Linked Image from i.imgur.com]](https://i.imgur.com/8ZFhtex.png) I wanted to draw some text in a bitmap and had an idea to try the 1520 plotter font. Reading some code from font2svg.rb at Project-64's webpage shows how to process the bytes. It's a very clever encoding: bit 7 = indicates last byte of character bit 6..4 = x coord bit 3..1 = y coord (from the bottom) bit 0 = draw line A little bit of lua code to make an array: p = io.open("1520_325340-03.bin","rb") a = p:read("*a") print("SIZE="..#a)
-- generate character array
function iif(a,b,c)if a then return b else return c end end
print("static constexpr u8 vector_font[96][20] =") print("{") pos = 1; for char = 32,127 do io.write (" {") c = 0 while c&0x80==0 do pos=pos+1; c = a:byte(pos) ; x = (c & 0x70) >> 4; y = (c&0xe)>>1; done = (c&0x80)>>7; line=(c&0x1); io.write(c) if done==0 then io.write(",") end end print("}"..iif(char~=127,",","").." // char "..char.." \""..string.char(char).."\"") end print("};")
and a couple of functions to do the character drawing:
void drawline(bitmap_rgb32 &bitmap, int x0, int y0, int x1, int y1, u32 pixelval)
//routine copied from void hp9845ct_base_state::draw_line
{
int dx, dy, sx, sy, x, y, err, e2;
// draw line, vector generator uses Bresenham's algorithm
x = x0;
y = y0;
dx = abs((int) (x1 - x));
sx = x < x1 ? 1 : -1;
dy = abs((int) (y1 - y));
sy = y < y1 ? 1 : -1;
err = (dx > dy ? dx : -dy) / 2;
for(;;)
{
if (!((x<0) || (x >= bitmap.width()) || (y<0) || (y >= bitmap.height())))
bitmap.pix(y,x) = pixelval;
if (x == x1 && y == y1) break;
e2 = err;
if (e2 > -dx)
{
err -= dy;
x += sx;
}
if (e2 < dy)
{
err += dx;
y += sy;
}
}
}
void draw_vector_char(bitmap_rgb32 &bitmap, u8 c, int x0, int y0, int xsize, int ysize, u32 pixelval)
{
static constexpr u8 vector_font[96][20] =
{
{128}, // char 32 " "
{34,37,53,51,35,38,47,63,55,167}, // char 33 "!"
{30,29,62,189}, // char 34 """
{20,29,60,53,70,7,10,203}, // char 35 "#"
{20,53,71,57,25,11,29,61,46,163}, // char 36 "$"
{4,77,28,13,11,27,29,54,71,69,53,183}, // char 37 "%"
{66,11,13,31,45,43,7,5,19,35,199}, // char 38 "&"
{42,175}, // char 39 "'"
{50,35,21,29,47,191}, // char 40 "("
{34,51,69,77,63,175}, // char 41 ")"
{4,77,12,69,44,165}, // char 42 "*"
{36,45,8,201}, // char 43 "+"
{32,51,53,37,35,179}, // char 44 ","
{8,201}, // char 45 "-"
{34,37,53,51,163}, // char 46 "."
{2,221}, // char 47 "/" 221 = 0xdd = (5,6)
{4,77,63,31,13,5,19,51,69,205}, // char 48 "0"
{28,47,35,18,179}, // char 49 "1"
{12,31,63,77,75,3,195}, // char 50 "2"
{12,31,63,77,75,57,41,56,71,69,51,19,133}, // char 51 "3"
{50,63,9,7,199}, // char 52 "4"
{4,19,51,69,73,59,11,15,207}, // char 53 "5"
{8,27,59,73,69,51,19,5,13,31,63,205}, // char 54 "6"
{2,75,79,143}, // char 55 "7"
{24,11,13,31,63,77,75,57,71,69,51,19,5,7,25,185}, // char 56 "8"
{4,19,51,69,77,63,31,13,11,25,57,203}, // char 57 "9"
{20,23,39,37,21,26,29,45,43,155}, // char 58 ":"
{18,37,39,23,21,37,42,45,29,27,171}, // char 59 ";"
{66,25,207}, // char 60 "<"
{22,71,26,203}, // char 61 "="
{18,73,159}, // char 62 ">"
{12,31,63,77,75,57,41,39,36,163}, // char 63 "?"
{54,59,27,21,53,71,75,61,29,11,5,19,195}, // char 64 "@"
{2,11,47,75,67,8,201}, // char 65 "A"
{2,15,63,77,75,57,8,57,71,69,51,131}, // char 66 "B"
{68,51,19,5,13,31,63,205}, // char 67 "C"
{2,15,63,77,69,51,131}, // char 68 "D"
{66,3,15,79,56,137}, // char 69 "E"
{2,15,79,8,185}, // char 70 "F"
{76,63,31,13,5,19,67,73,169}, // char 71 "G"
{2,15,78,67,8,201}, // char 72 "H"
{18,51,34,47,30,191}, // char 73 "I"
{4,19,35,53,191}, // char 74 "J"
{2,15,78,7,24,195}, // char 75 "K"
{14,3,195}, // char 76 "L"
{2,15,43,41,43,79,195}, // char 77 "M"
{2,15,12,69,78,195}, // char 78 "N"
{4,13,31,63,77,69,51,19,133}, // char 79 "O"
{2,15,63,77,75,57,137}, // char 80 "P"
{38,67,50,19,5,13,31,63,77,69,179}, // char 81 "Q"
{2,15,63,77,75,57,9,24,195}, // char 82 "R"
{4,19,51,69,71,57,25,11,13,31,63,205}, // char 83 "S"
{34,47,14,207}, // char 84 "T"
{14,5,19,51,69,207}, // char 85 "U"
{14,7,35,71,207}, // char 86 "V"
{14,3,39,40,39,67,207}, // char 87 "W"
{2,5,77,79,14,13,69,195}, // char 88 "X"
{34,41,77,79,14,13,169}, // char 89 "Y"
{14,79,77,5,3,195}, // char 90 "Z"
{34,3,15,175}, // char 91 "["
{0x0c,0xd3}, // char 92 "\"
// {92,77,59,53,35,19,5,23,51,83,40,201}, // char 92 "\"
{18,51,63,159}, // char 93 "]"
{0xa,0x2f,0xcb}, // char 94 "^"
// {34,45,8,45,201}, // char 94 "^"
{0x02,0xc3}, // char 95 "_"
// {36,9,45,8,217}, // char 95 "_"
{0x1e,0xbb}, // char 96 "`"
// {8,249}, // char 96 "`"
{52,35,19,5,7,25,41,55,10,43,57,53,195}, // char 97 "a"
{14,3,35,53,57,43,139}, // char 98 "b"
{52,35,19,5,9,27,43,185}, // char 99 "c"
{58,27,9,5,19,51,191}, // char 100 "d"
{6,55,57,43,27,9,5,19,179}, // char 101 "e"
{0x22,0x2d,0x3f,0x4f,0x08,0xc9}, // char 102 "f"
// {34,47,63,24,185}, // char 102 "f"
{2,17,33,51,57,43,27,9,7,21,37,183}, // char 103 "g"
{2,15,10,43,57,179}, // char 104 "h"
{34,41,42,173}, // char 105 "i"
{2,17,33,51,57,58,189}, // char 106 "j"
{50,23,14,3,4,187}, // char 107 "k"
{30,19,163}, // char 108 "l"
{2,11,8,27,41,35,40,59,73,195}, // char 109 "m"
{2,11,9,27,43,57,179}, // char 110 "n"
{4,9,27,43,57,53,35,19,133}, // char 111 "o"
{4,37,55,57,43,11,129}, // char 112 "p"
{64,49,59,27,9,7,21,181}, // char 113 "q"
{10,25,19,24,43,187}, // char 114 "r"
{4,19,35,53,39,23,9,27,43,185}, // char 115 "s"
{10,43,30,19,163}, // char 116 "t"
{10,0x05,0x13,51,187}, // char 117 "u"
// {10,3,51,187}, // char 117 "u"
{10,7,35,71,203}, // char 118 "v"
{10,5,19,37,39,37,51,69,203}, // char 119 "w"
{2,75,10,195}, // char 120 "x"
{10,9,37,74,73,129}, // char 121 "y"
{10,75,3,195}, // char 122 "z"
{0x3e,0x2d,0x2b,0x19,0x27,0x25,0xb3}, // char 123 "{"
// {48,191}, // char 123 "{"
{0x22,0xaf}, // char 124 "|"
// {112,129}, // char 124 "|" 0x70, 0x81
{0x1e,0x2d,0x2b,0x39,0x27,0x25,0x93}, // char 125 "}"
// {2,57,99,131}, // char 125 "}"
{0x0a,0x1d,0x2d,0x2b,0x3b,0xcd}, // char 126 "~"
// {6,25,57,51,18,25,57,203}, // char 126 "~"
{2,15,95,83,131} // char 127 ""
};
if (c >= 32 && c <= 127)
{
u8 i = 0;
u8 val = 0;
u8 xold = 0;
u8 yold = 0;
c = c - 32;
while (val < 128 && i <= 20)
{
val = vector_font[c][i];
u8 xc = (val & 0x70) >> 4;
u8 yc = (val & 0x0e) >> 1;
u8 lineto = (val & 0x1);
if (lineto) drawline(bitmap, xc * xsize + x0, (7-yc) * ysize + y0, xold * xsize + x0, (7-yold)*ysize + y0, pixelval);
xold = xc;
yold = yc;
i ++;
}
}
} // draw_vector_char
And drawing text is pretty simple: const char *teststr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnop";
for (int i=0; i<strlen(teststr); i++)
draw_vector_char(bitmap, teststr[i], 20 + i*6*3, 5, 3, 2, 0);
char buffer[128];
snprintf(buffer, 128, "%5.2f", 3.25);
for (int i=0; i<strlen(buffer); i++)
draw_vector_char(bitmap, buffer[i], 20 + i*6*3, 150, 3, 2, 0);
snprintf(buffer, 20, "xpos=%d ypos=%d", m_xpos, m_ypos);
for (int i=0; i<strlen(buffer); i++)
draw_vector_char(bitmap, buffer[i], 20 + i*6*2, 170, 2, 2, 0);
The font isn't exactly ascii, but it shouldn't be hard to fix that. (edit) It's not hard, just a bit of mental binary math to do, fixed the ascii characters. ![[Linked Image from i.imgur.com]](https://i.imgur.com/JL2CED8.png)
Last edited by Golden Child; 02/13/22 04:09 PM.
|
|
|
|
Joined: Feb 2014
Posts: 927 Likes: 75
Senior Member
|
OP
Senior Member
Joined: Feb 2014
Posts: 927 Likes: 75 |
Been quite puzzled why the fx80 isn't printing properly on the self test, I think it's because it uses the CI input on PC5 to generate INTFEIN interrupts on the upd7810. Also it uses the CI input to reset the ECNT, and currently, neither one is supported by the upd7810 driver. The fx80 has the PTS print timing sensor hooked up to the CI input of the upd7810 as well as the T1 input of the 8042. After a little bit of hacking, the self test looks somewhat recognizable. ![[Linked Image from i.imgur.com]](https://i.imgur.com/7M3ia3T.png)
|
|
|
|
Joined: Feb 2014
Posts: 927 Likes: 75
Senior Member
|
OP
Senior Member
Joined: Feb 2014
Posts: 927 Likes: 75 |
Managed to hook up the centronics interface and try out print shop. The horizontal positioning is inaccurate but it's recognizable. Regular text seems a little bit screwy still. ![[Linked Image from i.imgur.com]](https://i.imgur.com/AOeeAKS.png)
|
1 member likes this:
robcfg |
|
|
1 members (1 invisible),
16
guests, and
3
robots. |
Key:
Admin,
Global Mod,
Mod
|
|
Forums9
Topics9,171
Posts120,121
Members5,039
|
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!
|
|
|
|