Express Specialist

    Do you remember your first computer? I remember. It was a ZX compatible PC Spectrum. That was in '89. I don’t know for sure if his father bought it or changed it for something, but a PC appeared in the house and it all started. It was on it that I wrote my first programs and mastered BASIC. Then, when I was in grades 7-9, there were also PK-01 Lviv and Vector 06C.

    In grade 11, there was an attempt to assemble Orion-128. After school, I went to study in Tomsk, and all I managed to do at that time was to drill holes and paint paths with paint. That didn’t reach the board etching. Already at the university I had PC compatible PCs and old computers became generally unnecessary. But the idea to build your own PC continued to fly in the air for almost 14 years. The idea was then fueled by a dispute with Orion's father from the time of assembly. Apparently to motivate me to build, he said that I would not be able to assemble it.

    In the fall of 2014, while assembling another construction on the Arduino, I wondered if it would be possible to assemble the same Orion-128 on it, or, more simply, Radio 86RK for example. Pondering this idea, he decided to realize his old school dream - a PC assembled on his own. No sooner said than done. Confidence was given by Alexei Morozov’s videos on repairing old computers and articles on various retro-PC forums. On these forums there were people who constantly collected retro PCs.

    And I started looking for a suitable circuit, without scarce details - ideally, only small logic, a processor and an input / output port. At first I was looking at PC Leningrad, but could not find the Z80 in the city, but it was a long wait to order. As a result, I stopped at the Specialist Express PC circuit. The scheme, I think, is ideal for a beginner, since it contains a minimum of parts, and is easy to assemble and commission.

    A very high-quality diagram was found on the site www.spetsialist-mx.ru , the man with the nickname Fifan redrawn it, for which many thanks to him.

    The next question is whether to make a printed circuit board using LUT technology, or to plunge into the past, and assemble it by wall-mounted installation using MGTF wire, as most fans did in the 80s. Since the main idea was to assemble the device, and not find it a great practical application, due to low productivity, I settled on the second option.

    All parts for assembly cost about 4000 tenge (about 1000 rubles). I decided to put all the microchips in the sockets.



    On the first day I assembled a clock generator and counters. Soldering with MGTF turned out to be very simple. Someone writes on the Internet that you need to clean the ends, I just bit off the wire with wire cutters, after which I applied a small amount of rosin to the tip and heated it with a soldering iron with a drop of tin. At the same time, the braid slid about 0.5 mm, which is just enough to solder it.

    Hands scratched to give power, and make sure that the generator and meters are working. But there was neither a frequency meter nor an oscilloscope at hand, so it was decided to complete the installation, and only then debug it.

    The second session was outlined only a week later on the weekend. For 2 days off, I added a sync generator, registers for image formation, multiplexers and RAM.



    After another working week, he sat down again for soldering. Over the weekend, I dubbed almost the entire scheme. Only the keyboard and tape recorder ports were not soldered. There was also a problem with connecting power to the processor, there were conflicting information on the diagram.

    By that time, I met Alexei Morozov (VINXRU) and Andrey Anishcheko. Aleksey helped to deal with the conclusions of the processor. Looking ahead, I’ll say that the guys helped a lot in the process of building and debugging the PC. Thank you very much for that!

    At this point, the computer had an almost finished look.



    Hands scratched rather turn it on. Therefore, as soon as the stabilizers are soldered, decide to check the formation of -5 Volts. To do this, I installed a clock generator, counters and an inverter on 155LA3 in the sockets. He turned on the power, and here they are, honest -5.6 Volts on the microprocessor leg! Joy that day knew no bounds.



    Only one moment made me think - the 7805 stabilizer (even the one mounted on the radiator) was warmed up so that it could not be touched. And these are just 4 microchips in the power circuit.

    The second stabilization option was not original. I just planted 2 7805 cases in parallel on a larger radiator. They started to bask less, but still it was impossible to touch them after 10 minutes of work. This circumstance forced us to buy an external power supply for + 5V (4A) and + 12V (1A). After that, there were no longer any problems with the power supply, besides this, the presence of a 12V voltage allowed the 7812 stabilizer to be abandoned.

    After the entire circuit was assembled, it remained to write the loader and monitor in the ROM. It was not as simple as it seemed before.

    I did not have a programmer. I began to assemble a hand-held programmer, but once again having looked at the code of the Bootloader and the Monitor, I decided to leave this unfortunate undertaking, although in the 80s many went this way. It was not possible to find the programmer of such an ancient ROM in Almaty, but I did not want to order and lose a month. Therefore, he began experimenting with Arduino. First, the shield was soldered, and learned to read the contents of the ROM. Both chips were not empty. And judging by the code, it was most likely firmware from caller IDs. Another problem arose - they must be erased. At school age, my father constantly told me that it is impossible for light to get on the ROM crystal, they are erased from this. I put both ROMs for a few days in the sun. On the weekend I checked the contents again - not a bit of information was erased.

    Messages on the forums, as well as Alexey Morozov, spoke of two ways of erasing - this is the inner bulb from the DRL lamp with a choke, which emits a large amount of harmful ozone, and a UV bactericidal medical lamp. Erasing the DRL-coy takes about 3 hours, with a UV lamp for about 15 minutes. Without thinking twice, I bought OUFK-09-1, especially since the houses were cold, and quartzing the room would be welcome. Both chips were cleaned in 10 minutes. Now you need to somehow teach the shield to write in ROM. It took a little more time. Initially, I planned to make a programmer programmer in Visual Basic with sending data to Arduinka through a COM port, but having walked with this thought for a day or two, I decided to simplify the scheme, namely, connect an SD card to Arduinka that would contain the necessary firmware, but on the shield there would be 2 buttons - Read and Write.

    The result was such a shield: I



    downloaded the bootloader and the monitor in the ROM, which were also found on the Fifan-a website. Turned on the power, and the computer did not work. Well, this was to be expected. By that time, a frequency meter had already been found, and it quickly became clear that the RAS signal was not formed correctly, its frequency should have been about 2 MHz, or maybe 6 or 4. The soldering of the panel from IR12 gave its results, the signal began to form correctly. This problem took about a week. But there was still no image.

    On Andrei’s advice, I requested a test program in the ROM, and sounds began to come from the speaker. This meant that the processor, buffers, ROM, and I / O port were working correctly.

    After a short trial, it turned out that the output transistor gives the signal level that the TV did not have for operation. Having made small changes to the circuit of this node, the image finally appeared! But the screen was divided into 6 sections, and the image was displayed only in 3 of them.



    Suspicions fell on the multiplexers. But no matter how I rearranged them, the image did not change. The tester didn’t give a call to the board - all the connections were in place. Having spent a few more days on this problem and sorted out a couple more options (selection of capacitors in the divider circuits and SYNC of the processor), I found the reason - nevertheless there was a non-soldering of one contact in the multiplexer. The image went, but with interference in the form of vertical lines, in addition, 2 RAM shone as defective.



    Rearrangement of the microcircuits in places did not give a result, which means another non-drinking. And so it turned out. There was no food on them. Apparently the solder melted when it soldered smoothing capacitors.

    After that, the picture became what it should have been. The test program showed that everything is normal - the image is being formed, RAM is normal.



    The next step is the keyboard. The easiest way would be to take a keyboard with a PS / 2 interface and connect it through an AVR controller. But having walked with this idea until the end of the working week, I decided to assemble the keyboard according to the original scheme. As a result, the final look of the PC turned out like this:



    And the view from the installation side:



    It remains to put it in a human case, and remake the keyboard connector (the idea of ​​a 25-foot connector was cumbersome, therefore not very successful) and I will assume that the assembly is completed. The computer will take a shelf space next to the old ZX-Spectrum, PK01-Lviv, Vector-06C and Mikrosha, which I was recently presented with, and which require a little repair.

    On the one hand, it’s sad that one old dream has become less, but on the other hand, they are needed to come true. It is also sad that my father did not live up to the moment when he lost the argument.

    Conclusion? Itching, or when your hands were itching - go for it, it's worth it!

    Appendix 1. Programmer
    The programmer diagram is shown in the figure.


    I did not try to make a universal programmer for different types of ROMs (although this is easy to do), I also did not try to make the firmware code optimal. The tasks of this shield are to read and write down the ROM, and he copes with them.
    As a 25V power supply, I used a universal laptop power supply. It provides voltages from 12 to 24 Volts, with an incoming voltage of 12V or 110-220V. 24 V for recording was enough.
    Arduino Mega connects via USB to a computer. As part of the Arduino development environment, there is a utility - Port Monitor. It will display the entire process of the programmer.
    The program code for writing to the ROM must be stored in the root folder of the SD card under the name code.hex.
    After turning on the power, the programmer offers to enter the command - Read or Write.
    An example of reading data from a ROM (Monitor recorded)


    The record looks similar. After clicking the Record button, the address and the recorded data are displayed in the port monitor.

    Program source
    #include 
    int nMode = 0; //0-ожидание команды, 1-чтение, 2-запись
    void WriteByte(int adr, int data){  
      int i;
      String sAdr, sData;
      // чтение
      digitalWrite(42, LOW);
      pinMode(24, OUTPUT);
      pinMode(25, OUTPUT);
      pinMode(26, OUTPUT);
      pinMode(27, OUTPUT);
      pinMode(28, OUTPUT);
      pinMode(29, OUTPUT);
      pinMode(30, OUTPUT);
      pinMode(31, OUTPUT);
      // сформируем строку адреса и данных
      sAdr = "";
      sData = "";
      for (i = sizeof(adr) * 8 - 1; i >= 0; --i)
      {
         sAdr = sAdr + (String)((adr >> i) & 1);
      }  
      for (i = sizeof(data) * 8 - 1; i >= 0; --i)
      {
         sData = sData + (String)((data >> i) & 1);
      }  
      // выберем адрес
      if (sAdr.substring(15) == "1")
        digitalWrite(39, HIGH);
      else 
        digitalWrite(39, LOW);
      if (sAdr.substring(14, 15) == "1")
        digitalWrite(38, HIGH);
      else 
        digitalWrite(38, LOW);    
      if (sAdr.substring(13, 14) == "1")
        digitalWrite(37, HIGH);
      else 
        digitalWrite(37, LOW);    
      if (sAdr.substring(12, 13) == "1")
        digitalWrite(36, HIGH);
      else 
        digitalWrite(36, LOW);    
      if (sAdr.substring(11, 12) == "1")
        digitalWrite(35, HIGH);
      else 
        digitalWrite(35, LOW);    
      if (sAdr.substring(10, 11) == "1")
        digitalWrite(34, HIGH);
      else 
        digitalWrite(34, LOW);    
      if (sAdr.substring(9, 10) == "1")
        digitalWrite(33, HIGH);
      else 
        digitalWrite(33, LOW);    
      if (sAdr.substring(8, 9) == "1")
        digitalWrite(32, HIGH);
      else 
        digitalWrite(32, LOW);    
      if (sAdr.substring(7, 8) == "1")
        digitalWrite(43, HIGH);
      else 
        digitalWrite(43, LOW);    
      if (sAdr.substring(6, 7) == "1")
        digitalWrite(41, HIGH);
      else 
        digitalWrite(41, LOW);    
      if (sAdr.substring(5, 6) == "1")
        digitalWrite(40, HIGH);
      else 
        digitalWrite(40, LOW);    
      // установим значение байта
      if (sData.substring(15) == "1")
        digitalWrite(24, HIGH);
      else 
        digitalWrite(24, LOW);
      if (sData.substring(14, 15) == "1")
        digitalWrite(25, HIGH);
      else 
        digitalWrite(25, LOW);    
      if (sData.substring(13, 14) == "1")
        digitalWrite(26, HIGH);
      else 
        digitalWrite(26, LOW);    
      if (sData.substring(12, 13) == "1")
        digitalWrite(27, HIGH);
      else 
        digitalWrite(27, LOW);    
      if (sData.substring(11, 12) == "1")
        digitalWrite(28, HIGH);
      else 
        digitalWrite(28, LOW);    
      if (sData.substring(10, 11) == "1")
        digitalWrite(29, HIGH);
      else 
        digitalWrite(29, LOW);    
      if (sData.substring(9, 10) == "1")
        digitalWrite(30, HIGH);
      else 
        digitalWrite(30, LOW);    
      if (sData.substring(8, 9) == "1")
        digitalWrite(31, HIGH);
      else 
        digitalWrite(31, LOW);    
      // подождем 10мс для выбора адреса
      delay(10);
      //запись
      digitalWrite(42, HIGH);
      digitalWrite(44, HIGH);
      delay(60); // задерживаем высокий уровень на 60мс для записи данных
      digitalWrite(44, LOW);
      digitalWrite(42, LOW);
    }
    void writeChip() {
      nMode = 0;
      int adr, dat;
      adr = 0;
      // открываем файл только для чтения
      File myFile = SD.open("code.hex");
      if (myFile) {
        // читаем файл посимвольно до конца:
        while (adr < 2048 && myFile.available()) {
            dat = myFile.read();
            Serial.print((String)adr+" - "+(String)dat+" - ");
            Serial.println(dat, HEX);
            WriteByte(adr, dat);
            adr++;
        }
        // закрываем файл:
        myFile.close();
      } else {
        // если файл не открылся, сообщает об ошибке:
        Serial.println("No file code.hex found!!!");
      }
    }
    void readChip() {
    int r, i, adr = 0;
    String sAdr, sData;
    // чтение
      digitalWrite(42, LOW);
      pinMode(24, INPUT);
      pinMode(25, INPUT);
      pinMode(26, INPUT);
      pinMode(27, INPUT);
      pinMode(28, INPUT);
      pinMode(29, INPUT);
      pinMode(30, INPUT);
      pinMode(31, INPUT);
      adr = 0;
      while (adr < 2048) {
        // сформируем строку адреса
        sAdr = "";
        sData = "";
        for (i = sizeof(adr) * 8 - 1; i >= 0; --i)
        {
           sAdr = sAdr + (String)((adr >> i) & 1);
        }  
        // выберем адрес
        if (sAdr.substring(15) == "1")
          digitalWrite(39, HIGH);
        else 
          digitalWrite(39, LOW);
        if (sAdr.substring(14, 15) == "1")
          digitalWrite(38, HIGH);
        else 
          digitalWrite(38, LOW);    
        if (sAdr.substring(13, 14) == "1")
          digitalWrite(37, HIGH);
        else 
          digitalWrite(37, LOW);    
        if (sAdr.substring(12, 13) == "1")
          digitalWrite(36, HIGH);
        else 
          digitalWrite(36, LOW);    
        if (sAdr.substring(11, 12) == "1")
          digitalWrite(35, HIGH);
        else 
          digitalWrite(35, LOW);    
        if (sAdr.substring(10, 11) == "1")
          digitalWrite(34, HIGH);
        else 
          digitalWrite(34, LOW);    
        if (sAdr.substring(9, 10) == "1")
          digitalWrite(33, HIGH);
        else 
          digitalWrite(33, LOW);    
        if (sAdr.substring(8, 9) == "1")
          digitalWrite(32, HIGH);
        else 
          digitalWrite(32, LOW);    
        if (sAdr.substring(7, 8) == "1")
          digitalWrite(43, HIGH);
        else 
          digitalWrite(43, LOW);    
        if (sAdr.substring(6, 7) == "1")
          digitalWrite(41, HIGH);
        else 
          digitalWrite(41, LOW);    
        if (sAdr.substring(5, 6) == "1")
          digitalWrite(40, HIGH);
        else 
          digitalWrite(40, LOW);    
        // подождем 10мс для выбора адреса и прочтем данные
        delay(10);
        r = 0;
        if (digitalRead(24) == HIGH){
          sData = "1" + sData;
          r = r + pow(2, 0); } 
        else
          sData = "0" + sData; 
        if (digitalRead(25) == HIGH){
          sData = "1" + sData;
          r = r + pow(2, 1); } 
        else
          sData = "0" + sData; 
        if (digitalRead(26) == HIGH){
          sData = "1" + sData;
          r = r + pow(2, 2); } 
        else
          sData = "0" + sData;
        if (digitalRead(27) == HIGH){
          sData = "1" + sData;
          r = r + pow(2, 3); } 
        else
          sData = "0" + sData; 
        if (digitalRead(28) == HIGH){
          sData = "1" + sData;
          r = r + pow(2, 4); } 
        else
          sData = "0" + sData; 
        if (digitalRead(29) == HIGH){
          sData = "1" + sData;
          r = r + pow(2, 5); } 
        else
          sData = "0" + sData; 
        if (digitalRead(30) == HIGH){
          sData = "1" + sData;
          r = r + pow(2, 6); } 
        else
          sData = "0" + sData; 
        if (digitalRead(31) == HIGH){
          sData = "1" + sData;
          r = r + pow(2, 7); } 
        else
          sData = "0" + sData; 
        Serial.print(sAdr+" - "); 
        Serial.print(sData+" - ");
        Serial.println(r, HEX);
        adr++; 
      }
      nMode = 0;
    }
    void setup() {
      nMode = 0;
      Serial.begin(9600);
      pinMode(4, INPUT);
      pinMode(5, INPUT);
      pinMode(53, OUTPUT);
      if (!SD.begin(53)) {
        Serial.println("Card failed, or not present");
        return;
      }
      Serial.println("start...");
      pinMode(44, OUTPUT);
      digitalWrite(44, LOW);
      pinMode(42, OUTPUT);
      digitalWrite(42, LOW);  
      pinMode(39, OUTPUT);
      pinMode(38, OUTPUT);
      pinMode(37, OUTPUT);
      pinMode(36, OUTPUT);
      pinMode(35, OUTPUT);
      pinMode(34, OUTPUT);
      pinMode(33, OUTPUT);
      pinMode(32, OUTPUT);
      pinMode(43, OUTPUT);
      pinMode(41, OUTPUT);
      pinMode(40, OUTPUT);
      Serial.println("Init...done!");
      Serial.println("Waiting command...");
    }
    void loop() {
      if (digitalRead(4) == LOW && nMode == 0){
        delay(20); // защита от дребезга контактов
        if (digitalRead(4) == LOW && nMode == 0){
          Serial.println("Start writing chip...");
          nMode = 2;  
          writeChip();
          Serial.println("Writing complete!!!");
          delay(5000);
        }
      }
      if (digitalRead(5) == LOW && nMode == 0){
        delay(20); // защита от дребезга контактов
        if (digitalRead(5) == LOW && nMode == 0){
          Serial.println("Start reading chip...");
          nMode = 1;
          readChip();
          Serial.println("Reading complete!!!");
          delay(5000);
        }
      }  
      delay(100);
    }
    



    Also popular now: