Arduino ZX рд╕реНрдкреЗрдХреНрдЯреНрд░рдо рдПрдП рдкреНрд▓реЗрдпрд░

рдХрдо рд╕реЗ рдХрдо рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рд╕рд╛рде Arduino рдкрд░ ZX рд╕реНрдкреЗрдХреНрдЯреНрд░рдо рдХрдВрдкреНрдпреВрдЯрд░ рд╕реЗ рдзреБрдиреЛрдВ рдХреЗ рд╕реНрдЯреИрдВрдбрдЕрд▓реЛрди рдЦрд┐рд▓рд╛рдбрд╝реАред




рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕реНрдкреЗрдХреНрдЯреНрд░рдо рдХреА рдзреБрди рд╣рдореЗрд╢рд╛ рдХреЗ рд▓рд┐рдП рдореЗрд░реЗ рджрд┐рд▓ рдореЗрдВ рд░рд╣реЗрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдЕрджреНрднреБрдд рдмрд▓реНрдм рдкреНрд▓реЗрдпрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ рдкрд╕рдВрджреАрджрд╛ рдЧрд╛рдиреЗ рд╕реБрдирддрд╛ рд╣реВрдВ ред



рд▓реЗрдХрд┐рди рдХрдВрдкреНрдпреВрдЯрд░ рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реЛрдирд╛ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд╣реАрдВ рд╣реИред рдореИрдВ рдЕрд╕реНрдерд╛рдпреА рд░реВрдк рд╕реЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдирд╣реАрдВ рдХрдо рдЕрджреНрднреБрдд EEE рдкреАрд╕реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ред рд▓реЗрдХрд┐рди рдореИрдВ рдФрд░ рднреА рдЫреЛрдЯрд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред



рдЗрдВрдЯрд░рдиреЗрдЯ рдЦреЛрдЬреЛрдВ рдиреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реБрдВрджрд░рд┐рдпреЛрдВ рдХреЛ рдЬрдиреНрдо рджрд┐рдпрд╛:




рд╡реЗ рдЕрдкрдиреЗ рдореМрд▓рд┐рдХ рдЖрдзрд╛рд░ рдХреЗ рд▓рд┐рдП рд░рдордгреАрдп рд╣реИрдВ, рдЬреЛ рдЙрджрд╛рд╕реАрди рдпрд╛рджреЛрдВ рдХреЛ рдЙрджреНрдШрд╛рдЯрд┐рдд рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ рдХрд┐ рдореЗрд░рд╛ рдЖрд▓рд╕реНрдп рдореБрдЭреЗ рдЗрд╕ рддрд░рд╣ рдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрдЧрд╛ред

рдореБрдЭреЗ рдХреБрдЫ рдЫреЛрдЯрд╛ рдЪрд╛рд╣рд┐рдП рдерд╛ред рдФрд░ рдЕрдм - рд▓рдЧрднрдЧ рдПрдХ рдЖрджрд░реНрд╢ рдЙрдореНрдореАрджрд╡рд╛рд░:

AVR
AY- рдЦрд┐рд▓рд╛рдбрд╝реА - * .PSG рдлрд╛рдЗрд▓реЗрдВ
- рд╕рдорд░реНрдерд┐рдд рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо FAT16
- рдбрд┐рд╕реНрдХ рдХреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреА
рд╕рдВрдЦреНрдпрд╛ 32 - рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ 42 (рдХреБрд▓ 32 * 42 = 1344 рдлрд╛рдЗрд▓реЗрдВ)
- рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдФрд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЫрд╛рдВрдЯрдирд╛ рдирд╛рдо рдХреЗ рдкрд╣рд▓реЗ рджреЛ рдЕрдХреНрд╖рд░реЛрдВ рд╕реЗ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛



рдпреЛрдЬрдирд╛ рдЖрдХрд╛рд░ рдореЗрдВ рдХрд╛рдлреА рд╕реНрд╡реАрдХрд╛рд░реНрдп рджрд┐рдЦрддреА рд╣реИ:


рдмреЗрд╢рдХ, рдПрдХ рдШрд╛рддрдХ рджреЛрд╖ рдерд╛ рдЬрд┐рд╕рдиреЗ рдореВрд░реНрддрд┐ рдХреЛ рдЦрд░рд╛рдм рдХрд░ рджрд┐рдпрд╛ рдерд╛: рд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЪрдпрди рдореЛрдб рдирд╣реАрдВ рд╣реИред (рд╢рд╛рдпрдж рдЖрдкрдХреЛ рдмрд╕ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдлрд░реНрдорд╡реЗрдпрд░ рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд▓реЗрдЦрдХ рд╕реЗ рдкреВрдЫрдирд╛ рдЪрд╛рд╣рд┐рдП?)ред

рд╡рд░реНрд╖ рдХрд╛ рдЬреЗрд╡реАрдП, рдореИрдВ рдПрдХ рдЙрдкрдпреБрдХреНрдд рд╡рд┐рдХрд▓реНрдк рдХреА рддрд▓рд╛рд╢ рдореЗрдВ рдерд╛, рдореЗрд░рд╛ рдзреИрд░реНрдп рдЦрддреНрдо рд╣реЛ рдЧрдпрд╛ рдФрд░ рдореИрдВрдиреЗ рдЕрднрд┐рдирдп рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред

рдореЗрд░реЗ рд╢рд╛рдирджрд╛рд░ рдЖрд▓рд╕реНрдп рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдореИрдВрдиреЗ рдиреНрдпреВрдирддрдо рдЗрд╢рд╛рд░реЛрдВ рдХреЛ рдЪреБрдирд╛:
1. рд╣рдо Arduino Mini Pro рд▓реЗрддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ рд╣рд╛рд░реНрдиреЗрд╕ рдХреЗ рд╕рд╛рде рдЧрдбрд╝рдмрдбрд╝ рди рд╣реЛред
2. рдЖрдкрдХреЛ рдХрд╣реАрдВ рд╕рдВрдЧреАрдд рд╕рдВрдЧреНрд░рд╣ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрд╕рдбреА рдХрд╛рд░реНрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рдПрд╕рдбреА-рд╢реАрд▓реНрдб рд▓реЗрдВред
3. рдПрдХ рд╕рдВрдЧреАрдд рдХреЙрдкреЛрд╕рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдЫреЛрдЯрд╛ рдЖрдпреБ-3-8912 рд╣реИред

рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЛ рдЕрдиреБрдХрд░рдгреАрдп рд░реВрдк рд╕реЗ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рд╡рд┐рдХрд▓реНрдк рдерд╛, рд▓реЗрдХрд┐рди рдореИрдВ "рд╡рд╛рд░реНрдо рдЯреНрдпреВрдм рд╕рд╛рдЙрдВрдб" рдЪрд╛рд╣рддрд╛ рдерд╛, рд▓рдЧрднрдЧ рд╡реИрд╕реЗ рднреАред

рдкреНрд▓реЗрдмреИрдХ рдХреЗ рд▓рд┐рдП, рд╣рдо PSG рдкреНрд░рд╛рд░реВрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред

рдкреАрдПрд╕рдЬреА рдкреНрд░рд╛рд░реВрдк рд╕рдВрд░рдЪрдирд╛
Offset Number of byte Description
+0 3 Identifier 'PSG'
+3 1 Marker тАЬEnd of TextтАЭ (1Ah)
+4 1 Version number
+5 1 Player frequency (for versions 10+)
+6 10 Data

Data тАФ .
тАФ ( 0 0x0F), тАФ .
: 0xFF, 0xFE 0xFD
0xFD тАФ .
0xFF тАФ 20 .
0xFE тАФ 80 .

PSG рдореЗрдВ рдХреИрд╕реЗ рдХрдиреНрд╡рд░реНрдЯ рдХрд░реЗрдВ
1. .
2. [PL].
3. .
4. , , Convert to PSG...
5. 8 , ~1..

рдЪрд▓рд┐рдП рдПрд╕рдбреА рдХрд╛рд░реНрдб рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░рдХреЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдЖрд▓рд╕реНрдп рдиреЗ рдПрдХ рдорд╛рдирдХ рдПрд╕рдбреА-рд╢реАрд▓реНрдб рдХрдиреЗрдХреНрд╢рди рд▓реЗрдиреЗ рдФрд░ рдХрд╛рд░реНрдб рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ ред

рдПрдХрдорд╛рддреНрд░ рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ рдХрд╛рд░реНрдб рдЪреБрдирдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рдЧреНрдирд▓ рдХреЗ рд░реВрдк рдореЗрдВ 10 рд╡реЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛:


рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдорд╛рдирдХ рд╕реНрдХреЗрдЪ рд▓реЗрддреЗ рд╣реИрдВ :

рдорд╛рдирдЪрд┐рддреНрд░ рдкрд░ рд╕реНрдХреЗрдЪ рдлрд╝рд╛рдЗрд▓ рд╕реВрдЪреА
#include <SPI.h>
#include <SD.h>

void setup() {
  Serial.begin(9600);
  Serial.print("Initializing SD card...");

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  File root = SD.open("/");
  printDirectory(root);

  Serial.println("done!");
}

void loop() {
}

void printDirectory(File dir) {
  while (true) {
    File entry =  dir.openNextFile();
    if (!entry)  break;
    Serial.print(entry.name());
    if (!entry.isDirectory()) {
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}

рд╣рдо рдХрд╛рд░реНрдб рдХреЛ рдкреНрд░рд╛рд░реВрдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рд╡рд╣рд╛рдВ рдХрдИ рдлрд╛рдЗрд▓реЗрдВ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рд▓реЙрдиреНрдЪ рдХреЗ рд▓рд┐рдП ... рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ!
рдпрд╣рд╛рдВ рдореЗрд░реЗ рдкрд╛рд╕ рд╣рдореЗрд╢рд╛ рдпрд╣ рд╣реИ - рд╕рдмрд╕реЗ рдорд╛рдирдХ рдХрд╛рд░реНрдп - рдФрд░ рддреБрд░рдВрдд рдЬрд╛рдоред

рд╣рдо рдПрдХ рдФрд░ рдлреНрд▓реИрд╢ рдбреНрд░рд╛рдЗрд╡ рд▓реЗрддреЗ рд╣реИрдВ - (рдпрд╣ 32 рдПрдордмреА рдкрд░ рдПрдХ рдкреБрд░рд╛рдирд╛ рдерд╛, рд╣рдо 2 рдЬреАрдмреА рдкрд░ рдПрдХ рдирдпрд╛ рд▓реЗрддреЗ рд╣реИрдВ) - рд╣рд╛рдБ, рдпрд╣ рдХрд╛рдо рдХрд┐рдпрд╛, рд▓реЗрдХрд┐рди рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рджред рдорд╛рдереЗ рдХреЛ рдЦрд░реЛрдВрдЪрдиреЗ рдХреЗ рдЖрдзреЗ рдШрдВрдЯреЗ, рдирдХреНрд╢реЗ рдХреЗ рдХрд░реАрдм рдХрдиреЗрдХреНрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдирд╛ (рддрд╛рдХрд┐ рдХрдВрдбрдХреНрдЯрд░ рдХрдо рд╣реЛ), рдкреЛрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧрд╛рд╡ рд╕рдВрдзрд╛рд░рд┐рддреНрд░ - рдФрд░ рдпрд╣ 100% рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ред рдареАрдХ рд╣реИ,

рдЪрд▓реЛ рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ ... рдЕрдм рд╣рдореЗрдВ рдПрдХ рдХреЛрдкреНрд░реЛрд╕реЗрд╕рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ - рдЗрд╕реЗ 1.75 рдореЗрдЧрд╛рд╣рд░реНрдЯреНрдЬ рдХреА рдШрдбрд╝реА рдЖрд╡реГрддреНрддрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред 14 рдореЗрдЧрд╛рд╣рд░реНрдЯреНрдЬ рдХреНрд╡рд╛рд░реНрдЯреНрдЬ рдкрд░ рдПрдХ рдЬрдирд░реЗрдЯрд░ рдХреЛ рдЯрд╛рдВрдХрд╛ рд▓рдЧрд╛рдиреЗ рдФрд░ рдПрдХ рд╡рд┐рднрдХреНрдд рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдЖрдзрд╛ рджрд┐рди рд░реАрдбрд┐рдВрдЧ рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рдкрд░ рдмрд┐рддрд╛рддреЗ рд╣реИрдВ рдФрд░ рдкрддрд╛ рд▓рдЧрд╛рддреЗ рд╣реИрдВ рдХрд┐ рддреЗрдЬ рдкреАрдбрдмреНрд▓реВрдПрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрдард┐рди 1.77 (7) рдореЗрдЧрд╛рд╣рд░реНрдЯреНрдЬ рдмрдирд╛рдирд╛ рд╕рдВрднрд╡ рд╣реИ :

  pinMode(3, OUTPUT);
  TCCR2A = 0x23;
  TCCR2B = 0x09;
  OCR2A = 8;
  OCR2B = 3; 


рдЕрдЧрд▓рд╛, рд╣рдо рдореНрдпреВрдЬрд┐рдХ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЛ 2 рдкрд┐рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░реАрд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдбреЗрдЯрд╛ рдмрд╕ рдХреЗ рдирд┐рдЪрд▓реЗ рдиреАрдм рдХреЛ A0-A3, рдКрдкрд░реА рдПрдХ рдХреЛ 4,5,6,7, BC1 рдХреЛ рдкрд┐рди 8, BDIR рдХреЛ рдкрд┐рди 9ред рд╣рдо рдСрдбрд┐рдпреЛ рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рд╕рд░рд▓рддрд╛ рд╕реЗ рдореЛрдиреЛ рдореЛрдб рдореЗрдВ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВрдЧреЗ: рдмреНрд░реЗрдбрдмреЛрд░реНрдб



рдкрд░:


рдЯреНрд░рд╛рдпрд▓ рд╕реНрдХреЗрдЪ рднрд░реЗрдВ (рдореБрдЭреЗ рдпрд╛рдж рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдХрд╣рд╛рдБ рд╕реЗ рдХрд╣рд╛рдВ рддрдХ тАЛтАЛрдШрд╕реАрдЯрд╛ рд╣реИ)
void resetAY(){
  pinMode(A0, OUTPUT); // D0
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT); // D3
  
  pinMode(4, OUTPUT); // D4
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT); // D7
  
  pinMode(8, OUTPUT);  // BC1
  pinMode(9, OUTPUT);  // BDIR
  
  digitalWrite(8,LOW);
  digitalWrite(9,LOW);
  
  pinMode(2, OUTPUT);
  digitalWrite(2, LOW);
  delay(100);
  digitalWrite(2, HIGH);
  delay(100);
  
  for (int i=0;i<16;i++) ay_out(i,0);
}

void setupAYclock(){
  pinMode(3, OUTPUT);
  TCCR2A = 0x23;
  TCCR2B = 0x09;
  OCR2A = 8;
  OCR2B = 3; 
}

void setup() {
  setupAYclock();
  resetAY();
}

void ay_out(unsigned char port, unsigned char data){
  PORTB = PORTB & B11111100;

  PORTC = port & B00001111;
  PORTD = PORTD & B00001111;

  PORTB = PORTB | B00000011;
  delayMicroseconds(1);
  PORTB = PORTB & B11111100;

  PORTC = data & B00001111;
  PORTD = (PORTD & B00001111) | (data & B11110000);

  PORTB = PORTB | B00000010;
  delayMicroseconds(1);
  PORTB = PORTB & B11111100;
}

unsigned int cb = 0;

byte rawData[] = {
    0xFF, 0x00, 0x8E, 0x02, 0x38, 0x03, 0x02, 0x04, 0x0E, 0x05, 0x02, 0x07, 
    0x1A, 0x08, 0x0F, 0x09, 0x10, 0x0A, 0x0E, 0x0B, 0x47, 0x0D, 0x0E, 0xFF, 
    0x00, 0x77, 0x04, 0x8E, 0x05, 0x03, 0x07, 0x3A, 0x08, 0x0E, 0x0A, 0x0D, 
    0xFF, 0x00, 0x5E, 0x04, 0x0E, 0x05, 0x05, 0x0A, 0x0C, 0xFF, 0x04, 0x8E, 
    0x05, 0x06, 0x07, 0x32, 0x08, 0x00, 0x0A, 0x0A, 0xFF, 0x05, 0x08, 0x0A, 
    0x07, 0xFF, 0x04, 0x0E, 0x05, 0x0A, 0x0A, 0x04, 0xFF, 0x00, 0x8E, 0x04, 
    0x8E, 0x05, 0x00, 0x07, 0x1E, 0x08, 0x0F, 0x0A, 0x0B, 0x0D, 0x0E, 0xFF, 
    0x00, 0x77, 0x08, 0x0E, 0x0A, 0x06, 0xFF, 0x00, 0x5E, 0x07, 0x3E, 0x0A, 
    0x00, 0xFF, 0x07, 0x36, 0x08, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x8E, 0x07, 
    0x33, 0x08, 0x0B, 0x0A, 0x0F, 0x0D, 0x0E, 0xFF, 0x04, 0x77, 0x08, 0x06, 
    0x0A, 0x0E, 0xFF, 0x04, 0x5E, 0x07, 0x3B, 0x08, 0x00, 0xFF, 0x07, 0x1B, 
    0x0A, 0x00, 0xFF, 0xFF, 0xFF, 0x02, 0x1C, 0x03, 0x01, 0x04, 0x8E, 0x07, 
    0x33, 0x08, 0x0B, 0x0A, 0x0B, 0x0B, 0x23, 0x0D, 0x0E, 0xFF, 0x04, 0x77, 
    0x08, 0x06, 0x0A, 0x0A, 0xFF, 0x04, 0x5E, 0x07, 0x3B, 0x08, 0x00, 0x0A, 
    0x09, 0xFF, 0x07, 0x1B, 0x0A, 0x00, 0xFF, 0xFF, 0xFF, 0x02, 0x8E, 0x03, 
    0x00, 0x04, 0x0E, 0x05, 0x01, 0x07, 0x18, 0x08, 0x0F, 0x09, 0x0B, 0x0A, 
    0x0E, 0xFF, 0x00, 0x77, 0x02, 0x77, 0x04, 0x8E, 0x06, 0x01, 0x08, 0x0E, 
    0x09, 0x0A, 0x0A, 0x0D, 0xFF, 0x00, 0x5E, 0x02, 0x5E, 0x04, 0x0E, 0x05, 
    0x02, 0x06, 0x02, 0x09, 0x09, 0x0A, 0x0C, 0xFF, 0x02, 0x8E, 0x04, 0x8E, 
    0x07, 0x30, 0x08, 0x00, 0x09, 0x08, 0x0A, 0x0A, 0xFF, 0x02, 0x77, 0xFF,
    0xFF
}

void pseudoInterrupt(){
  while (rawData[cb]<0xFF) {
   ay_out(rawData[cb],rawData[cb+1]);
   cb++;
   cb++;
 }
 if (rawData[cb]==0xff) cb++;
 
 if (cb>20*12)  cb=0;
}

void loop() {
  delay(20);
  pseudoInterrupt();
}

рдФрд░ рд╣рдо рдХреБрдЫ рд╕реБрдВрджрд░ рд░рд╛рдЧ рдХрд╛ рдЖрдзрд╛ рд╕реЗрдХрдВрдб рд╕реБрдирддреЗ рд╣реИрдВ! (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдореИрдВ рдПрдХ рдФрд░ рджреЛ рдШрдВрдЯреЗ рдХреЗ рд▓рд┐рдП рдпрд╣рд╛рдВ рд╣реВрдВ рдХрд┐ рдореИрдВ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдХреИрд╕реЗ рдореИрдВ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬреЗрд╢рди рдХреЗ рдмрд╛рдж рд░рд┐рд╕реЗрдЯ рдЬрд╛рд░реА рдХрд░рдирд╛ рднреВрд▓ рдЧрдпрд╛)ред

рдЗрд╕ рдкрд░, рд▓реЛрд╣реЗ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдореЗрдВ рд╣рдо 50 рд╣рд░реНрдЯреНрдЬ рдХреЗ рд░реБрдХрд╛рд╡рдЯ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдлрд╛рдЗрд▓ рдХреЛ рдкрдврд╝рддреЗ рд╣реИрдВ рдФрд░ рдХреЛрдкрд░реЛрд╕реЗрд╕рд░ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЛ рд▓рд┐рдЦрддреЗ рд╣реИрдВред

рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг
#include <SPI.h>
#include <SD.h>

void resetAY(){
  pinMode(A0, OUTPUT); // D0
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT); // D3
  
  pinMode(4, OUTPUT); // D4
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT); // D7
  
  pinMode(8, OUTPUT);  // BC1
  pinMode(9, OUTPUT);  // BDIR
  
  digitalWrite(8,LOW);
  digitalWrite(9,LOW);
  
  pinMode(2, OUTPUT);
  digitalWrite(2, LOW);
  delay(100);
  digitalWrite(2, HIGH);
  delay(100);
  
  for (int i=0;i<16;i++) ay_out(i,0);
}


void setupAYclock(){
  pinMode(3, OUTPUT);
  TCCR2A = 0x23;
  TCCR2B = 0x09;
  OCR2A = 8;
  OCR2B = 3; 
}

void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(4)+analogRead(5));

  initFile();

  setupAYclock();
  resetAY();
  setupTimer();
}

void setupTimer(){
  cli();
  
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 1250;

  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS12);
  TIMSK1 |= (1 << OCIE1A);

  sei();
}

void ay_out(unsigned char port, unsigned char data){
  PORTB = PORTB & B11111100;

  PORTC = port & B00001111;
  PORTD = PORTD & B00001111;

  PORTB = PORTB | B00000011;
  delayMicroseconds(1);
  PORTB = PORTB & B11111100;

  PORTC = data & B00001111;
  PORTD = (PORTD & B00001111) | (data & B11110000);

  PORTB = PORTB | B00000010;
  delayMicroseconds(1);
  PORTB = PORTB & B11111100;
}

unsigned int playPos = 0;
unsigned int fillPos = 0;
const int bufSize = 200;
byte playBuf[bufSize]; // 31 bytes per frame max, 50*31 = 1550 per sec, 155 per 0.1 sec

File fp;
boolean playFinished = false;

void loop() {
  fillBuffer();
  if (playFinished){
    fp.close();
    openRandomFile();
    playFinished = false;
  }
}

void fillBuffer(){
  int fillSz = 0;
  int freeSz = bufSize;
  if (fillPos>playPos) {
    fillSz = fillPos-playPos;
    freeSz = bufSize - fillSz;
  }
  if (playPos>fillPos) {
    freeSz = playPos - fillPos;
    fillSz = bufSize - freeSz;
  }
  
  freeSz--; // do not reach playPos
  while (freeSz>0){
    byte b = 0xFD;
    if (fp.available()){
      b = fp.read();
    }
    playBuf[fillPos] = b;
    fillPos++;
    if (fillPos==bufSize) fillPos=0;
    freeSz--;
  }
}

void prepareFile(char *fname){
  Serial.print("prepare [");
  Serial.print(fname);
  Serial.println("]...");
  
  fp = SD.open(fname);
  
  if (!fp){
    Serial.println("error opening music file");
    return;
  }  
    
  while (fp.available()) {
    byte b = fp.read();
    if (b==0xFF) break;
  }
 
  fillPos = 0;
  playPos = 0;
  cli();  
  fillBuffer();
  resetAY();
  sei();
}

File root;
int fileCnt = 0;

void openRandomFile(){
  int sel = random(0,fileCnt-1);

  Serial.print("File selection = ");
  Serial.print(sel, DEC);
  Serial.println();
  
  root.rewindDirectory();
  
  int i = 0;
  while (true) {
    File entry =  root.openNextFile();
    if (!entry)  break;

    Serial.print(entry.name());
    if (!entry.isDirectory()) {
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
      
      if (i==sel) prepareFile(entry.name());
      i++;
    }
    entry.close();
  }
}

void initFile(){
  Serial.print("Initializing SD card...");
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  root = SD.open("/");

  // reset AY

  fileCnt = countDirectory(root);
  Serial.print("Files cnt = ");
  Serial.print(fileCnt, DEC);
  Serial.println();
  openRandomFile();

  Serial.print("Buffer size = ");
  Serial.print(bufSize, DEC);
  Serial.println();
  
  Serial.print("fillPos = ");
  Serial.print(fillPos, DEC);
  Serial.println();

  Serial.print("playPos = ");
  Serial.print(playPos, DEC);
  Serial.println();

  for (int i=0; i<bufSize;i++){
    Serial.print(playBuf[i],HEX);
    Serial.print("-");
    if (i%16==15) Serial.println();
  }

  Serial.println("done!");
}

int countDirectory(File dir) {
  int res = 0;
  root.rewindDirectory();
  while (true) {

    File entry =  dir.openNextFile();
    if (!entry)  break;

    Serial.print(entry.name());
    if (!entry.isDirectory()) {
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
      res++;
    }
    entry.close();
  }
  
  return res;
}

int skipCnt = 0;

ISR(TIMER1_COMPA_vect){
  if (skipCnt>0){
    skipCnt--;
  } else {
    int fillSz = 0;
    int freeSz = bufSize;
    if (fillPos>playPos) {
      fillSz = fillPos-playPos;
      freeSz = bufSize - fillSz;
    }
    if (playPos>fillPos) {
      freeSz = playPos - fillPos;
      fillSz = bufSize - freeSz;
    }

    boolean ok = false;
    int p = playPos;
    while (fillSz>0){
      byte b = playBuf[p];
      p++; if (p==bufSize) p=0;
      fillSz--;
      
      if (b==0xFF){ ok = true; break; }
      if (b==0xFD){ 
        ok = true; 
        playFinished = true;
        for (int i=0;i<16;i++) ay_out(i,0);
        break; 
      }
      if (b==0xFE){ 
        if (fillSz>0){
          skipCnt = playBuf[p];
          p++; if (p==bufSize) p=0;
          fillSz--;
          
          skipCnt = 4*skipCnt;
          ok = true; 
          break; 
        } 
      }
      if (b<=252){
        if (fillSz>0){
          byte v = playBuf[p];
          p++; if (p==bufSize) p=0;
          fillSz--;
          
          if (b<16) ay_out(b,v);
        } 
      }
    } // while (fillSz>0)
  
    if (ok){
      playPos = p;
    }
  } // else skipCnt 
}

рдкреВрд░реНрдг рд╕реНрд╡рд╛рдпрддреНрддрддрд╛ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ TDA2822M рдореЗрдВ рдПрдХ рдПрдореНрдкрд▓реАрдлрд╛рдпрд░ рднреА рдЬреЛрдбрд╝рд╛, рдЦрд┐рд▓рд╛рдбрд╝реА рд╕реНрд╡рдпрдВ 90 рдПрдордП рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рд╕рд╛рде рдореЗрдВ рдПрдореНрдкрд▓реАрдлрд╛рдпрд░ рдХреЗ рд╕рд╛рде рдпрд╣ рд▓рдЧрднрдЧ 200 рдПрдордП рдХреА рдЦрдкрдд рдХрд░рддрд╛ рд╣реИ, рдпрджрд┐ рд╡рд╛рдВрдЫрд┐рдд рд╣реИ, рддреЛ рдЗрд╕реЗ рдмреИрдЯрд░реА рджреНрд╡рд╛рд░рд╛ рд╕рдВрдЪрд╛рд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред



рджреЛрдиреЛрдВ рдПрдХ рд╕рд╛рде рдореЙрдХ-рдЕрдк:


рдЗрд╕ рд╕реНрддрд░ рдкрд░, рдореИрдВ рдЕрдм рдХреЗ рд▓рд┐рдП рд░реБрдХ рдЧрдпрд╛ рд╣реВрдВ, рдореЙрдХ-рдЕрдк рд╕реЗ рд╕рдВрдЧреАрдд рд╕реБрдирдирд╛, рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдирд╛ рдХрд┐ рдореИрдВ рдХрд┐рд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЗрд╕реЗ рдЗрдХрдЯреНрдард╛ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред рдореИрдВрдиреЗ рдПрдХ рд╕рдВрдХреЗрддрдХ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрд╛, рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рддрд░рд╣ рдореБрдЭреЗ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЕрднреА рднреА рдирдо рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдбрд┐рд╡рд╛рдЗрд╕ рд╡рд┐рдХрд╛рд╕ рдХреЗ рдЕрдзреАрди рд╣реИ, рд▓реЗрдХрд┐рди рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдЙрд╕реЗ рдЗрд╕ рд░рд╛рдЬреНрдп рдореЗрдВ рдХреБрдЫ рд╡рд░реНрд╖реЛрдВ рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рд╕рдХрддрд╛ рд╣реВрдВ, рдореИрдВрдиреЗ рдЧрд░реНрдо рдкреАрдЫрд╛ рдореЗрдВ рдПрдХ рд▓реЗрдЦ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдкреНрд░рд╢реНрди, рд╕реБрдЭрд╛рд╡, рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ, рд╕реБрдзрд╛рд░ - рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред

рдкреНрд░рдпреБрдХреНрдд рд╕рд╛рд╣рд┐рддреНрдп:

Source: https://habr.com/ru/post/hi392625/


All Articles