以前に書いたArduinoを使った印刷用のインターフェースについて、暫定版ができた。

基板に実装するため、秋月電子のAE-ATMEGA-328 MINIを使用。
当初はプリンタ側はデジタルポートで、ポケコン側はアナログポートをデジタルとする予定だったが、ポケコン側の信号を割り込み処理で実行するため、一部の配線がめんどいことになってしまった。
仕様としては以下の通り。
インターフェース仕様
・CE-126とLPRTの両方をサポート
・リセット時に文字セット初期化を行うので、ポケコン側から初期化コマンドを送る必要なし
・プリンタへの出力が、そのままシリアルポートに出力される
・プリンタへの出力をOFFにできる(シリアルポートはそのまま出力される)
CE-126 mode
・ポケコン側の仕様に影響される
・1行24桁固定
・シリアルポートの出力は24桁で、不足分は空白で置き換わる。
・空行でも24桁の空白
・7Fh~9Fh,F0h~F4h,F8h~FFhあたりはポケコン側で空白に変換したり、別のコードに変換している
・MONモードやTEXTモードなどでも印刷できる
LPRT mode
・LPRINT CHR$コマンドで、指定したコードをそのまま出力する。
・MONモードやTEXTモードなどでは印刷できない
・プリンタが対応していればハードコピーが可能(予定)(暫定版では正常動作せず)9/14追記
・印刷が若干遅い(シフトレジスタICを使ったロジック回路でも同様)
まずはCE-126 modeで印刷してみる。

1行24桁固定で印刷され、一部の文字コードは印刷されない。
MONモードでダンプリストの印刷も行ってみる。

CE-126でなければ印刷できなかったものも印刷できた。
ついでにシリアルポートからの出力は以下のとおり。
!"#$%&'()*+,-./01234567
89<=>?@ABCDEFGHIJKLMNO
PQRSTUVWXYZ[\]^_`abcdefg
hijklmnopqrstuvwxyz{|}~
。「」、・ヲァィゥェォャュョッ
ーアイウエオカキクケコサシスセソタチツテトナニヌ
ネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚
10:REM OPEN "LPRT:"
11:REM LPRINT CHR$ &H1B;"t"; CHR$ 1
12:REM LPRINT CHR$ &H1B;"R"; CHR$ 8
20:FOR A=32 TO 255
29:PRINT CHR$ A;
30:LPRINT CHR$ A;
40:NEXT
50:LPRINT
0100 : AF CD 5F 11 ッヘ_.
(CB) 11 04 02 21 ...!
42 01 CD 20 B.ヘ
11 CD 8F 0A .ヘ .
0110 : 2A A2 11 56 *「.V
(E8) 23 5E 23 ED #^#
53 01 7D 7E S.}~
32 03 7D 23 2.}#
0120 : 7E B7 F4 7B ~キ
(1E) 0A 2A A4 11 .*、.
22 04 7D 3E ".}>
01 32 00 7D .2.}
次にLPRTモードで印刷した場合。

こちらは、20h以降の文字がすべて印刷されている。
また、1行も用紙の幅いっぱい印刷されている。
シリアルポートからの出力は以下の通り。
!"#$%&'()*+,-./0123456789<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚珮粤蒟跚韜・・ⅰ涇・
80h~9Fh,E0h~FFhの部分はShiftJISで使っている領域になるので文字が化けている。
10:OPEN "LPRT:"
11:REM LPRINT CHR$ &H1B;"t"; CHR$ 1
12:REM LPRINT CHR$ &H1B;"R"; CHR$ 8
20:FOR A=32 TO 255
29:PRINT CHR$ A;
30:LPRINT CHR$ A;
40:NEXT
50:LPRINT
最後に、暫定版Arduinoスケッチ。
// Emulator Sharp CE-126P fur PC-1401 u. PC-E500
const int OUT_ACK = 17; // ACK Sharp CE-126P, pin 9 der 11-pol. Buchsenleiste
const int IN_Xout = 3; // Xout Sharp PC-1401, pin 7 der 11-pol. Buchsenleiste / INT1
const int IN_Dout = 16; // Dout Sharp PC-1401, pin 5 der 11-pol. Buchsenleiste
const int IN_Busy = 2; // Busy Sharp PC-1401, pin 4 der 11-pol. Buchsenleiste / INT0
const int InfoLED = 13;
// printer interface
const int Pstrb = 15; // Printer STROBE
const int PD0out = 14; // Printer D0
const int PD1out = 4; // Printer D1
const int PD2out = 5; // Printer D2
const int PD3out = 6; // Printer D3
const int PD4out = 7; // Printer D4
const int PD5out = 8; // Printer D5
const int PD6out = 9; // Printer D6
const int PD7out = 10; // Printer D7
const int Pbusy = 11; // Printer BUSY
// Mode SW
const int EMmode = 12; // Emulator mode SW (Hi:CE126P/Lo:LPRT)
const int EMsw = 18; // Emulator SW (Hi:Serial and Parallel / Lo:Serial only)
boolean Busy; // Busy signal
boolean Xout; // Xout signal
boolean Dout; // Dout signal
int DataBit; // work of CE-126P mode
int DataByte; // work of CE-126P mode
long Timeout;
int i;
byte SPif; // work of LPRT mode
boolean PrtBusy; // work of Printer interface
////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
// Serial port 98600BPS
Serial.begin(9600);
// E500/G8xx interface set
pinMode(OUT_ACK, OUTPUT);
pinMode(IN_Xout, INPUT);
pinMode(IN_Dout, INPUT);
pinMode(IN_Busy, INPUT);
pinMode(InfoLED, OUTPUT);
// Printer interface set
pinMode(PD0out, OUTPUT);
pinMode(PD1out, OUTPUT);
pinMode(PD2out, OUTPUT);
pinMode(PD3out, OUTPUT);
pinMode(PD4out, OUTPUT);
pinMode(PD5out, OUTPUT);
pinMode(PD6out, OUTPUT);
pinMode(PD7out, OUTPUT);
pinMode(Pstrb, OUTPUT);
pinMode(Pbusy, INPUT);
// Emulator mode SW
pinMode(EMmode, INPUT);
pinMode(EMsw, INPUT);
// Sirial header
Serial.println();
Serial.println("Bereit:");
Serial.println();
// Printer STROBE is HIGH
digitalWrite(Pstrb, HIGH);
// Printer BUSY pull up
digitalWrite(Pbusy, HIGH);
// sw port pull up
digitalWrite(EMmode, HIGH);
digitalWrite(EMsw, HIGH);
// ESC/POS printer init
PRTinit ();
}
////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
if (digitalRead(EMmode) == HIGH ){
ce126pemu();
} else {
lprtemu();
}
} // Ende loop
////////////////////////////////////////////////////////////////////////////////////////////
// Emulator Sharp CE-126P
void ce126pemu() {
do{
digitalWrite(InfoLED, LOW);
Xout = digitalRead(IN_Xout);
if (Xout) {
// DeviceSelect:
digitalWrite(InfoLED, HIGH);
delayMicroseconds(50);
i = 0;
do {
digitalWrite(OUT_ACK, HIGH);
Timeout = millis();
do {
Busy = digitalRead(IN_Busy);
if (millis() - Timeout > 50) break;
} while (!Busy);
delayMicroseconds(50);
digitalWrite(OUT_ACK, LOW);
do {
Busy = digitalRead(IN_Busy);
} while (Busy);
delayMicroseconds(150);
i++;
} while (i < 8);
}
Busy = digitalRead(IN_Busy);
if (Busy && !Xout) {
// Daten:
digitalWrite(InfoLED, HIGH);
i = 0;
DataByte = 0;
do {
do {
Busy = digitalRead(IN_Busy);
} while (!Busy);
delayMicroseconds(50);
DataBit = digitalRead(IN_Dout);
digitalWrite(OUT_ACK, HIGH);
do {
Busy = digitalRead(IN_Busy);
} while (Busy);
delayMicroseconds(50);
if (i != 8) digitalWrite(OUT_ACK, LOW); // add : now receve to low. but printing is high
DataByte = DataByte | (DataBit << i);
i++;
} while (i < 8);
// Ausgabe:
switch (DataByte) {
case 13:
Serial.println();
praout(0x0d); // CR
praout(0x0A); // LF
break;
case 48:
Serial.print("O"); // Buchstabe "O"
praout(0x4f);
break;
case 240:
Serial.print("0"); // Ziffer Null
praout(0x30);
break;
default:
if (DataByte >= 31 && DataByte <= 255) {
Serial.print(char(DataByte));
praout(byte(DataByte));
}
}
if (i == 8) digitalWrite(OUT_ACK, LOW); // add : print after ack low
}
} while (digitalRead(EMmode) == HIGH );
}
////////////////////////////////////////////////////////////////////////////////////////////
// Emulator LPRT:
void lprtemu() {
// Interrupt set
attachInterrupt(0,IntBusy,RISING);
attachInterrupt(1,IntXout,RISING);
do{
digitalRead(EMmode); // dummy
} while (digitalRead(EMmode) == LOW );
// Interrupt off
detachInterrupt(0);
detachInterrupt(1);
}
////////////////////////////////////////////////////////////////////////////////////////////
// Interrupt routine
// BUSY to High (strobe)
void IntBusy() {
digitalWrite(OUT_ACK, HIGH);
digitalWrite(InfoLED, HIGH);
Serial.print(char(SPif));
praout(SPif);
SPif=0;
delay(5);
digitalWrite(InfoLED, LOW);
digitalWrite(OUT_ACK, LOW);
}
// Xout to High (data clock)
void IntXout() {
SPif = SPif << 1 ;
if (digitalRead(IN_Dout) == HIGH) {
SPif++;
}
}
////////////////////////////////////////////////////////////////////////////////////////////
// init ESC/POS printer caractor set to Jananese
void PRTinit () {
// init print char set
// ESC t n : Select international character set
praout(0x1b); // ESC
praout(0x74); // t
praout(0x01); // 1:Katakana
// ESC R n : Select character code table
praout(0x1b); // ESC
praout(0x52); // R
praout(0x08); // 8:Japan
delay(10);
}
////////////////////////////////////////////////////////////////////////////////////////////
// Parallel Printer interface
void praout (byte POdata) {
// If EMsw is low as no operation
if (digitalRead(EMsw) == LOW) return;
// wait busy low
PrtBusy=digitalRead(Pbusy);
do {
PrtBusy=digitalRead(Pbusy);
} while (PrtBusy != LOW);
// Printer data output
digitalWrite(PD0out, bitRead(POdata,0));
digitalWrite(PD1out, bitRead(POdata,1));
digitalWrite(PD2out, bitRead(POdata,2));
digitalWrite(PD3out, bitRead(POdata,3));
digitalWrite(PD4out, bitRead(POdata,4));
digitalWrite(PD5out, bitRead(POdata,5));
digitalWrite(PD6out, bitRead(POdata,6));
digitalWrite(PD7out, bitRead(POdata,7));
delayMicroseconds(1);
// Strobe to low
digitalWrite(Pstrb,LOW);
// wait busy high
Timeout = millis();
do {
PrtBusy=digitalRead(Pbusy);
//if (millis() - Timeout > 50) break;
} while (PrtBusy == HIGH);
// Strobe to high
delayMicroseconds(50);
digitalWrite(Pstrb, HIGH);
// wait busy low
do {
PrtBusy=digitalRead(Pbusy);
} while (PrtBusy != LOW);
delayMicroseconds(50);
}
シリアルポートから印刷データを垂れ流しているので、少し手直しすればプリンタシールドでも利用可能かもしれない。
雑な作りなので少し手直しは必要かも。