Organisation der Character-ROMs beim PC 1715.
Aus nicht ganz nachvollziehbaren Gruenden liegen nicht alle
Einzelzeilen eines Zeichens dirket nacheinander im ROM, sondern
es kommen erst die obersten Zeilen aller 128 Zeichen, dann die
zweitobersten usw.
Eventuell hat dieses Layout das Platinenlayout vereinfacht.
Um also das Bitmuster eines bestimmten Zeichens zu finden, startet
man bei der ROM-Adresse, die dem ASCII_Code des Zeichens entspricht.
Die naechste Zeile des Zeichens ist dann diese Adresse + 80h usw.
Selbstverstaendlich ist es sinnvoll, hierbei das Hex-Zahlensystem
zu verwenden.
0030 00 ........
00B0 3C ..####..
0130 42 .#....#.
01B0 46 .#...##.
0230 4A .#..#.#.
02B0 52 .#.#..#.
0330 62 .##...#.
03B0 42 .#....#.
0430 42 .#....#.
04B0 3C ..####..
0530 00 ........
0067 00 ........
00E7 00 ........
0167 00 ........
01E7 00 ........
0267 3A ..###.#.
02E7 46 .#...##.
0367 42 .#....#.
03E7 46 .#...##.
0467 3A ..###.#.
04E7 02 ......#.
0567 3C ..####..
Diskette unter Linux erstellen:
$ setfdprm /dev/fd0 QD sect=5 ssize=1024 cyl=80
$ dd if=/dev/fd0 of=robotron.img bs=1024
800+0 records in
800+0 records out
819200 bytes (819 kB) copied, 40.4986 s, 20.2 kB/s
Benötigt werden:
Nachfolgend der Schaltplan
Arduino Programm zur Emulation der PC1715 Tastatur mit einer PS/2 Tastatur.
//----------------------------------------------------------------------------------------------------------------
//Emulation Tastatur PC1715 mit PS/2 Tastatur + Arduino Nano und Paul Carpenter's PS2KeyMap+PS2KeyAdvanced library
//----------------------------------------------------------------------------------------------------------------
#include <PS2KeyAdvanced.h>
#include <PS2KeyMap.h>
//#include <Arduino.h> //nur bei VSC
#define DATAPIN 4 //PS/2 DATA
#define IRQPIN 3 //PS/2 CLK
#define PCdata 6 //PC1715 DATAPIN
#define PCclk 5 //PC1715 CLKPIN
//Variablen
uint16_t c,d,rdat;
uint8_t S,x,idx;
//von KeyMap library nicht erzeugte bzw. umdefininierte Key Codes: ,{Taste,Code}
uint16_t Map[][ 2 ] = {
{PS2_KEY_F1,0xd1},{PS2_KEY_F2,0xd2},{PS2_KEY_F3,0xd3},{PS2_KEY_F4,0xd4},{PS2_KEY_F5,0xcf},{PS2_KEY_F6,0xa0},//F1-6
{PS2_KEY_F7,0xa1},{PS2_KEY_F8,0xa2},{PS2_KEY_F9,0xa3},{PS2_KEY_F10,0x83},{PS2_KEY_F11,0xc1},{PS2_KEY_F12,0xc2},//F7-12
{PS2_ALT+PS2_KEY_F1,0xc2},{PS2_ALT+PS2_KEY_F2,0xcd},{PS2_ALT+PS2_KEY_F3,0x8e},//F13-15 Alt+F1-3
{PS2_KEY_L_ARROW,0x88},{PS2_KEY_R_ARROW,0x86},{PS2_KEY_UP_ARROW,0x8b},{PS2_KEY_DN_ARROW,0x83},//Cursor
{PS2_KEY_HOME,0x8c},{PS2_KEY_END,0xdd},{PS2_KEY_ENTER,0x9e},{PS2_SHIFT+PS2_KEY_ENTER,0x9d},//Home,S,Enter,NL
{PS2_SHIFT+PS2_KEY_3,0x00},{PS2_KEY_DIV,0x2d},{PS2_SHIFT+PS2_KEY_DIV,0x5f},//..Minus,Unterstrich
{PS2_SHIFT+PS2_KEY_F1,0xff}//S0/S1 Umschaltung Shift+F1
};
//classes
PS2KeyAdvanced keyboard;
PS2KeyMap keymap;
void setup( )
{
//Serial.begin(9600); //Debug
keyboard.begin( DATAPIN, IRQPIN );
keyboard.typematic( 11, 1);
keyboard.setNoRepeat(1);
keyboard.setNoBreak(1);
keymap.selectMap( (char *)"DE" );
pinMode(PCdata, OUTPUT);
pinMode(PCclk, OUTPUT);
}
void loop( )
{
if( keyboard.available() )
{
c = keyboard.read( );
if( c > 0 )
{
//Statusbyte setzen
x = 0xE0; //Status default E0
if(c & PS2_SHIFT)bitSet(x,1); //Status für Shift E2
else if (c & PS2_CAPS)bitSet(x,3); //Status für Caps E8
else if (c & PS2_CTRL)bitSet(x,0); //Status für CTRL E1
if (S==1)bitSet(x,2); //Status für S0/S1 E4
d=keymap.remapKey(c );
//die aus dem Remap fehlenden Tasten (s.0. codes) einfügen bzw redefinieren
for( idx = 0; idx < sizeof(Map)/sizeof(Map[0]); idx ++ )
if( rdat == Map[idx][0] ) //Taste nachschlagen
{
rdat = Map[idx][1]; d &= ~0xFF; d |= rdat; //Code zuweisen
break;
}
if(d==0xff)S=!S; //S0/S1 Umschaltung
//Ausgabe
if((d>0)&&((d & 0xff)<=0xDD))
{
Serialto_pc( x); //Statusbyte ausgeben
Serialto_pc(d & 0xff); //Tastencode ausgeben
}
}
}
}
void Serialto_pc(uint8_t i) //zum PC1715 übertragen
{
//Serial.print((i),HEX); //Debug
uint8_t z; //Bitzähler
//bith(); // original 2x sync?
//bith(); // geht auch ohne
bitl(); //Startbit
for(z=0;z<8;z++){(i & (1 << z))? bith():bitl();} //Einzelbits auswerten
bith(); //Stoppbit
bith(); //Stoppbit
}
void bith (void)
//Ausgabe 1-Bit
{
digitalWrite(PCdata, LOW); // Datenbit löschen (weil Daten negiert übertragen)
digitalWrite(PCclk, HIGH); //Taktbit setzen
_delay_us(20);
digitalWrite(PCclk, LOW); // Taktbit löschen
}
void bitl (void)
//1 Ausgabe 0-Bit
{
digitalWrite(PCdata, HIGH); // Datenbit setzen (weil Daten negiert übertragen)
digitalWrite(PCclk, HIGH); // Taktbit setzen
_delay_us(20);
digitalWrite(PCclk, LOW); // Taktbit löschen
}