diff --git a/Sources/AY_Emu/.vs/AY_Emu/v14/.atsuo b/Sources/AY_Emu/.vs/AY_Emu/v14/.atsuo
new file mode 100644
index 0000000..fe7e4eb
Binary files /dev/null and b/Sources/AY_Emu/.vs/AY_Emu/v14/.atsuo differ
diff --git a/Sources/AY_Emu/AY_Emu.atsln b/Sources/AY_Emu/AY_Emu.atsln
new file mode 100644
index 0000000..72a44be
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu.atsln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Atmel Studio Solution File, Format Version 11.00
+VisualStudioVersion = 14.0.23107.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{18226A42-8477-4023-8AD2-40C49DA407C9}") = "AY_Emu", "AY_Emu\AY_Emu.asmproj", "{59B1D629-9DCC-43ED-A0FD-8AB0E4D622AB}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|AVR = Debug|AVR
+ Release|AVR = Release|AVR
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {59B1D629-9DCC-43ED-A0FD-8AB0E4D622AB}.Debug|AVR.ActiveCfg = Debug|AVR
+ {59B1D629-9DCC-43ED-A0FD-8AB0E4D622AB}.Debug|AVR.Build.0 = Debug|AVR
+ {59B1D629-9DCC-43ED-A0FD-8AB0E4D622AB}.Release|AVR.ActiveCfg = Release|AVR
+ {59B1D629-9DCC-43ED-A0FD-8AB0E4D622AB}.Release|AVR.Build.0 = Release|AVR
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Sources/AY_Emu/AY_Emu/AY_Emu.asmproj b/Sources/AY_Emu/AY_Emu/AY_Emu.asmproj
new file mode 100644
index 0000000..29f4323
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/AY_Emu.asmproj
@@ -0,0 +1,89 @@
+
+
+
+ 2.0
+ 7.0
+ com.Atmel.AVRAssembler
+ 59B1D629-9DCC-43ed-A0FD-8AB0E4D622AB
+ none
+ ATmega328P
+ $(MSBuildProjectName)
+ .obj
+ $(MSBuildProjectDirectory)\$(Configuration)
+ ASSEMBLY
+ AY_Emu
+ AY_Emu
+ AY_Emu
+ Native
+ $(MSBuildProjectDirectory)\main.asm
+ true
+ false
+ true
+ true
+ 0x20000000
+
+ true
+ exception_table
+ 2
+ 0
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+ com.atmel.avrdbg.tool.simulator
+
+ 0x1E950F
+
+
+
+
+
+ com.atmel.avrdbg.tool.simulator
+
+
+ Simulator
+
+
+
+
+
+
+
+ %24(PackRepoDir)\atmel\ATmega_DFP\1.3.300\avrasm\inc
+
+
+ m328pdef.inc
+
+
+ Executable
+
+
+
+
+
+
+ %24(PackRepoDir)\atmel\ATmega_DFP\1.3.300\avrasm\inc
+
+
+ m328pdef.inc
+
+
+ Executable
+
+
+
+ Code
+
+
+
+
\ No newline at end of file
diff --git a/Sources/AY_Emu/AY_Emu/AY_Emu.componentinfo.xml b/Sources/AY_Emu/AY_Emu/AY_Emu.componentinfo.xml
new file mode 100644
index 0000000..a836e93
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/AY_Emu.componentinfo.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+ Device
+ Startup
+
+
+ Atmel
+ 1.3.0
+ C:/Program Files (x86)\Atmel\Studio\7.0\Packs
+
+
+
+
+ C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.3.300\avrasm\inc
+
+ include
+ AVRASM
+
+
+ avrasm/inc
+
+
+
+
+ C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.3.300\avrasm\inc\m328pdef.inc
+
+ header
+ AVRASM
+ YpGdK/vCoyGIUkMyqjAbKQ==
+
+ avrasm/inc/m328pdef.inc
+
+
+
+
+ C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.3.300\avrasm\templates\main.asm
+ template
+ source
+ AVRASM
+ kcl2t3QmvnUsYTi7C2+xBA==
+
+ avrasm/templates/main.asm
+ Main file (.asm)
+
+
+
+ ATmega_DFP
+ C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATmega_DFP/1.3.300/Atmel.ATmega_DFP.pdsc
+ 1.3.300
+ true
+ ATmega328P
+
+
+
+ Resolved
+ Fixed
+ true
+
+
+
\ No newline at end of file
diff --git a/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.hex b/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.hex
new file mode 100644
index 0000000..cad2990
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.hex
@@ -0,0 +1,60 @@
+:020000020000FC
+:020000007FC0BF
+:020004002AC010
+:100008004AC0000101010202030506090D11161D6F
+:10001800242D000001010101010102020202030373
+:100028000505060607090B0D0F111316191D2024C7
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B9909C01AB957B84A99FECF77B82C
+:100068007AB8F1E0BCBA1895E6B1EF734F990AC0B7
+:10007800F09904C0F1E050A010A9F3CFF3E050A02C
+:1000880010A9EFCFEF3319F0EE3319F0EACFF0985B
+:10009800E8CFF09AE6CF46B14F734A9917C059B0E6
+:1000A800DFB658204529542E5094F1E01081F0997C
+:1000B800F3E050A24123152D107C10AB408BED309E
+:1000C80009F43068DFBEF1E0FCBB1895E42F4E99C7
+:1000D8000AC0F09904C0F1E050A010A9F4CFF3E0F1
+:1000E80050A010A9F0CFEF3319F0EE3319F0EBCF91
+:1000F800F098E9CFF09AE7CF00E00093600008EDB0
+:100108000093340000E80093610008ED0093340088
+:1001180000E00093610008ED0093340004E00093D0
+:10012800050108ED0093340007E000930A0108ED8B
+:100138000093340000E000930B0108ED00933400B5
+:1001480000E000930B0103E0009307010FE7009321
+:10015800080100C005B7046005BF0FEF0DBF08E038
+:100168000EBF00E007B908B90AB90BB900E8009357
+:10017800500000E80FBDF098F198772400EC802E2D
+:1001880004E0A02E0FE1202E02E0B02E0FEF502E3B
+:10019800182DFF24DFEF20E1E0E1F1E080A2008BE1
+:1001A80071922A95D9F7B2E0A0E1EAE3F0E020E104
+:1001B800DFD0A0E2EAE0F0E020E1DAD0A0E3EAE173
+:1001C800F0E020E2D5D0AA27B1E0EAE4F0E020E1AF
+:1001D800CFD020E1E0E1F3E080A2008B71922A9574
+:1001E800D9F720E2E0E0F4E071922A95E9F721E0FE
+:1001F80020931E04F1E0EE27D2E06F2E7092890062
+:100208007092880070928B0070928A00219A229ACC
+:1002180002EA0093800009E10093810028E47092CB
+:100228008700209386000FE00093690003E00CBB71
+:1002380003E00DBBE0E13327002444241124282DDA
+:10024800992444273324CC247894C6B3C0FFFDCF27
+:10025800C6BBF1993CC0F19A88D0F7CF3A946AF4BA
+:10026800309016013A9466946E2CF794E7943863AC
+:10027800E0FE377C660C6E24669400911701032B10
+:10028800C02FCC0FC2950C23C09118010C2CC4FFB1
+:1002980008A000FF0024C09119014C2CC4FF48A0FD
+:1002A80001FF4424C0911A011C2CC4FF18A002FFAE
+:1002B8001124C42D46944694C4194694C4190C0EAE
+:1002C8001C0E52D000922004109221043CC0F198D8
+:1002D8004ED03A946AF4309016033A9466946E2C91
+:1002E800F794E7943863E0FE377C660C6E246694D6
+:1002F800D4E2C0E100911703032BC02FCC0FC295A5
+:100308000C23C09118030C2CC4FF08A000FF002484
+:10031800C09119034C2CC4FF48A001FF4424C0918C
+:100328001A031C2CC4FF18A002FF1124C42D4694E4
+:100338004694C4194694C4190C0E1C0E009222044B
+:100348001092230413D000912004C0912204C00FFE
+:100358000C2E00912104C0912304C00F1C2E009282
+:10036800880010928A0071CF08950895089508951D
+:0A03780005910D932A95E1F7089511
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.lss b/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.lss
new file mode 100644
index 0000000..7c6ba35
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.lss
@@ -0,0 +1,2172 @@
+
+AVRASM ver. 2.2.7 D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm Tue Feb 03 21:02:51 2026
+
+[builtin](2): Including file 'C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.3.300\avrasm\inc\m328pdef.inc'
+D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm(62): warning: Register r30 already defined by the .DEF directive
+[builtin](2): Including file 'C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.3.300\avrasm\inc\m328pdef.inc'
+
+ ; AY-3-8912 IC emulator version 26.0 for LGT8F328P
+
+ ;***** Created: 2011-02-09 12:03 ******* Source: ATmega328P.xml **********
+ ;*************************************************************************
+ ;* A P P L I C A T I O N N O T E F O R T H E A V R F A M I L Y
+ ;*
+ ;* Number : AVR000
+ ;* File Name : "m328Pdef.inc"
+ ;* Title : Register/Bit Definitions for the ATmega328P
+ ;* Date : 2011-02-09
+ ;* Version : 2.35
+ ;* Support E-mail : avr@atmel.com
+ ;* Target MCU : ATmega328P
+ ;*
+ ;* DESCRIPTION
+ ;* When including this file in the assembly program file, all I/O register
+ ;* names and I/O register bit names appearing in the data book can be used.
+ ;* In addition, the six registers forming the three data pointers X, Y and
+ ;* Z have been assigned names XL - ZH. Highest RAM address for Internal
+ ;* SRAM is also defined
+ ;*
+ ;* The Register names are represented by their hexadecimal address.
+ ;*
+ ;* The Register Bit names are represented by their bit number (0-7).
+ ;*
+ ;* Please observe the difference in using the bit names with instructions
+ ;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc"
+ ;* (skip if bit in register set/cleared). The following example illustrates
+ ;* this:
+ ;*
+ ;* in r16,PORTB ;read PORTB latch
+ ;* sbr r16,(1< PUD for
+0000af 6004 sbr r16,PUD
+0000b0 bf05 out MCUCR,r16
+
+ // init stack pointer at end of RAM
+0000b1 ef0f ldi r16,low(RAMEND)
+0000b2 bf0d out SPL,r16
+0000b3 e008 ldi r16,high(RAMEND)
+0000b4 bf0e out SPH,r16
+
+ ; C D HI-Z ===================
+ ; C: PC0-PC5 - , HI-Z
+ ; D: PD6,PD7 - , HI-Z
+0000b5 e000 ldi r16,0x00
+0000b6 b907 out DDRC,r16 ; C
+0000b7 b908 out PORTC,r16 ;
+0000b8 b90a out DDRD,r16 ; D
+0000b9 b90b out PORTD,r16 ;
+ ; =====================================================
+
+ ; disable Analog Comparator ==============================
+0000ba e800 ldi r16, (1<= 0
+ ;init new envelope period
+ ; ldi TabP,0x1F
+ ; sbrc TabE,b1
+ ; eor TabE,ZH ; invert envelope ATTACK bit
+ ; sbrc TabE,b2
+ ; or TabE,CC0 ; disable envelope generator until new envelope shape register recived
+ ;E_NEXT_STEP_AY0:
+ ; lds CntEL,AY_REG11
+ ; lds CntEH,AY_REG12
+ ; mov YL,TabP
+ ; sbrs TabE,b0
+ ; eor YL,C1F ; invert envelope value if ATTACK bit is not set
+ ; ldd EVal,Y+0x30 ; translate envelope value to volume, read volume value from SRAM 0x230+YL
+ ;ENVELOPE_GENERATOR_END_AY0:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// NOISE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+000132 943a dec CntN ; decrease noise period counter
+000133 f46a brpl NOISE_GENERATOR_END_AY0 ; skip if noise period is not finished (CntN>=0)
+ //init new cycle
+000134 9030 0116 lds CntN,AY_REG06 ; init noise period counter with value in AY register 6
+000136 943a dec CntN
+
+000137 9466 lsr NoiseAddon
+000138 2c6e mov NoiseAddon,RNGL
+000139 94f7 ror RNGH
+00013a 94e7 ror RNGL
+00013b 6338 ori TNLevel,0x38 ; set noise bits
+00013c fee0 sbrs RNGL,b0
+00013d 7c37 andi TNLevel,0xC7 ; reset noise bits
+ ;MAKE_INPUT_BIT_AY0:
+00013e 0c66 lsl NoiseAddon
+00013f 246e eor NoiseAddon,RNGL
+000140 9466 lsr NoiseAddon
+ NOISE_GENERATOR_END_AY0:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// TONE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ ; all counters are Int16 values (signed)
+ // Channel A -------------
+ ; subi CntAL,0x01 ; CntA - 1
+ ; sbci CntAH,0x00
+ ; brpl CH_A_NO_CHANGE_AY0 ; CntA >= 0
+ ; lds CntAL,AY_REG00 ; update channel A tone period counter
+ ; lds CntAH,AY_REG01
+ ; subi CntAL,0x01 ; CntA - 1
+ ; sbci CntAH,0x00
+ ; eor TNLevel,ZH ; TNLevel xor 1 (change logical level of channel A)
+ ;CH_A_NO_CHANGE_AY0:
+
+ // Channel B -------------
+ ; subi CntBL,0x01 ; CntB - 1
+ ; sbci CntBH,0x00
+ ; brpl CH_B_NO_CHANGE_AY0 ; CntB >= 0
+ ; lds CntBL,AY_REG02 ; update channel B tone period counter
+ ; lds CntBH,AY_REG03
+ ; subi CntBL,0x01 ; CntB - 1
+ ; sbci CntBH,0x00
+ ; eor TNLevel,YH ; TNLevel xor 2 (change logical level of channel B)
+ ;CH_B_NO_CHANGE_AY0:
+
+ // Channel C -------------
+ ; sbiw CntCL,0x01 ; CntC - 1
+ ; brpl CH_C_NO_CHANGE_AY0 ; CntC >= 0
+ ; lds CntCL,AY_REG04 ; update channel C tone period counter
+ ; lds CntCH,AY_REG05
+ ; sbiw CntCL,0x01 ; CntC - 1
+ ; eor TNLevel,C04 ; TNLevel xor 4 (change logical level of channel C)
+ ;CH_C_NO_CHANGE_AY0:
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// MIXER
+ /////////////////////////////////////////////////////////////////////////////////////
+000141 9100 0117 lds TMP,AY_REG07 ; Load Mixer AY Register from SRAM
+000143 2b03 or TMP,TNLevel ; Mixer formula = (Mixer Register Tone | TNLevel Tone) & (Mixer Register Noise | TNLevel Noise)
+000144 2fc0 mov YL,TMP
+000145 0fcc lsl YL
+000146 95c2 swap YL
+000147 230c and TMP,YL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// AMPLITUDE CONTROL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ // Channel A
+000148 91c0 0118 lds YL,AY_REG08 ; Load Channel A Amplitude register
+00014a 2c0c mov OutA,EVal ; set envelope volume as default value
+00014b ffc4 sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+00014c a008 ldd OutA,Y+0x20 ; load volume value from SRAM 0x220 + YL
+00014d ff00 sbrs TMP,b0 ; if channel is disabled in mixer - set volume to zero
+00014e 2400 clr OutA
+
+ // Channel B
+00014f 91c0 0119 lds YL,AY_REG09 ; Load Channel B Amplitude register
+000151 2c4c mov OutB,EVal ; set envelope volume as default value
+000152 ffc4 sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+000153 a048 ldd OutB,Y+0x20 ; load volume value from SRAM 0x220 + YL
+000154 ff01 sbrs TMP,b1 ; if channel is disabled in mixer - set volume to zero
+000155 2444 clr OutB
+
+ // Channel C
+000156 91c0 011a lds YL,AY_REG10 ; Load Channel C Amplitude register
+000158 2c1c mov OutC,EVal ; set envelope volume as default value
+000159 ffc4 sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+00015a a018 ldd OutC,Y+0x20 ; load volume value from SRAM 0x220 + YL
+00015b ff02 sbrs TMP,b2 ; if channel is disabled in mixer - set volume to zero
+00015c 2411 clr OutC
+00015d 2dc4 mov YL,OutB
+00015e 9446 lsr OutB ; TMP = TMP - (TMP/4 + TMP/8);
+00015f 9446 lsr OutB
+000160 19c4 sub YL,OutB
+000161 9446 lsr OutB
+000162 19c4 sub YL,OutB
+000163 0e0c add OutA,YL ; add channel B volume to channels A and C
+000164 0e1c add OutC,YL
+
+000165 d052 rcall SAVE_AY0_STATE
+000166 9200 0420 sts OutA0, OutA ; AY0
+000168 9210 0421 sts OutC0, OutC
+00016a c03c rjmp MAIN_LOOP_END
+
+ AY1_PROCESSING:
+00016b 98f1 cbi CHIP_SELECTED, b1
+00016c d04e rcall RESTORE_AY1_STATE
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// ENVELOPE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ ; sbrs TNLevel,b7
+ ; rjmp NO_ENVELOPE_CHANGED_AY1
+
+ // initialize envelope generator after change envelope shape register, only first 1/32 part of the first period!
+ ; lds YL,AY1_REG13 ; load envelope shape register value to TabE
+ ; ldd TabE,Y+0x10 ; get envelope code from SRAM
+ ; ldi TabP,0x1F ; set counter for envelope period
+ ; andi TNLevel,0x7F ; clear envelope shape change flag
+ ; rjmp E_NEXT_STEP_AY1
+
+ ;NO_ENVELOPE_CHANGED_AY1:
+ ; sbrc TabE,b7 ; alternate: cpi TabE,0x80 ; check if envelope generator is disabled
+ ; rjmp ENVELOPE_GENERATOR_END_AY1 ; alternate: brcc ENVELOPE_GENERATOR_END
+ ; sbiw CntEL,0x01
+ ; brcc ENVELOPE_GENERATOR_END_AY1
+ ;E_NEXT_PERIOD_AY1:
+ ; dec TabP
+ ; brpl E_NEXT_STEP_AY1 ; jump to next step if envelope period >= 0
+ ;init new envelope period
+ ; ldi TabP,0x1F
+ ; sbrc TabE,b1
+ ; eor TabE,ZH ; invert envelope ATTACK bit
+ ; sbrc TabE,b2
+ ; or TabE,CC0 ; disable envelope generator until new envelope shape register recived
+ ;E_NEXT_STEP_AY1:
+ ; lds CntEL,AY1_REG11
+ ; lds CntEH,AY1_REG12
+ ; mov YL,TabP
+ ; sbrs TabE,b0
+ ; eor YL,C1F ; invert envelope value if ATTACK bit is not set
+ ; ldd EVal,Y+0x30 ; translate envelope value to volume, read volume value from SRAM 0x230+YL
+ ;ENVELOPE_GENERATOR_END_AY1:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// NOISE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+00016d 943a dec CntN ; decrease noise period counter
+00016e f46a brpl NOISE_GENERATOR_END_AY1 ; skip if noise period is not finished (CntN>=0)
+ //init new cycle
+00016f 9030 0316 lds CntN,AY1_REG06 ; init noise period counter with value in AY register 6
+000171 943a dec CntN
+
+000172 9466 lsr NoiseAddon
+000173 2c6e mov NoiseAddon,RNGL
+000174 94f7 ror RNGH
+000175 94e7 ror RNGL
+000176 6338 ori TNLevel,0x38 ; set noise bitsP
+000177 fee0 sbrs RNGL,b0
+000178 7c37 andi TNLevel,0xC7 ; reset noise bits
+
+ ;MAKE_INPUT_BIT_AY1
+000179 0c66 lsl NoiseAddon
+00017a 246e eor NoiseAddon,RNGL
+00017b 9466 lsr NoiseAddon
+ NOISE_GENERATOR_END_AY1:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// TONE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ ; uDSC
+ ;ldi TMP, (1 << DSUEN) | (1 << DSMM)
+
+
+00017c e2d4 ldi YH, 0x24
+00017d e1c0 ldi YL, low(AY1_CntAL)
+ ; A
+ ; ldd r0, Y + 0x00
+ ; ldd r1, Y + 0x1F
+
+ ; sts DSIR, ZH
+ ; A
+ ; std Y + 0x00, r2
+ ; lds TMP, DSCR
+ ; sbrs TMP, DSN
+ ; rjmp CH_A_NO_CHANGE_AY1
+ ; Reload channel A counter
+ ; lds TMP, AY1_REG00
+ ; sts AY1_CntAL, TMP
+ ; lds TMP, AY1_REG01
+ ; sts AY1_CntAH, TMP
+ ; Update level
+ ; eor TNLevel, ZH
+ ;CH_A_NO_CHANGE_AY1:
+
+
+
+
+
+
+
+
+ ; all counters are Int16 values (signed)
+ // Channel A -------------
+ ; subi CntAL,0x01 ; CntA - 1
+ ; sbci CntAH,0x00
+ ; brpl CH_A_NO_CHANGE_AY1 ; CntA >= 0
+ ; lds CntAL,AY1_REG00 ; update channel A tone period counter
+ ; lds CntAH,AY1_REG01
+ ; subi CntAL,0x01 ; CntA - 1
+ ; sbci CntAH,0x00
+ ; eor TNLevel,ZH ; TNLevel xor 1 (change logical level of channel A)
+ ;CH_A_NO_CHANGE_AY1:
+
+ // Channel B -------------
+ ; subi CntBL,0x01 ; CntB - 1
+ ; sbci CntBH,0x00
+ ; brpl CH_B_NO_CHANGE_AY1 ; CntB >= 0
+ ; lds CntBL,AY1_REG02 ; update channel B tone period counter
+ ; lds CntBH,AY1_REG03
+ ; subi CntBL,0x01 ; CntB - 1
+ ; sbci CntBH,0x00
+ ; eor TNLevel,YH ; TNLevel xor 2 (change logical level of channel B)
+ ;CH_B_NO_CHANGE_AY1:
+
+ // Channel C -------------
+ ; sbiw CntCL,0x01 ; CntC - 1
+ ; brpl CH_C_NO_CHANGE_AY1 ; CntC >= 0
+ ; lds CntCL,AY1_REG04 ; update channel C tone period counter
+ ; lds CntCH,AY1_REG05
+ ; sbiw CntCL,0x01 ; CntC - 1
+ ; eor TNLevel,C04 ; TNLevel xor 4 (change logical level of channel C)
+ ;CH_C_NO_CHANGE_AY1:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// MIXER
+ /////////////////////////////////////////////////////////////////////////////////////
+00017e 9100 0317 lds TMP,AY1_REG07 ; Load Mixer AY Register from SRAM
+000180 2b03 or TMP,TNLevel ; Mixer formula = (Mixer Register Tone | TNLevel Tone) & (Mixer Register Noise | TNLevel Noise)
+000181 2fc0 mov YL,TMP
+000182 0fcc lsl YL
+000183 95c2 swap YL
+000184 230c and TMP,YL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// AMPLITUDE CONTROL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ // Channel A
+000185 91c0 0318 lds YL,AY1_REG08 ; Load Channel A Amplitude register
+000187 2c0c mov OutA,EVal ; set envelope volume as default value
+000188 ffc4 sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+000189 a008 ldd OutA,Y+0x20 ; load volume value from SRAM 0x220 + YL
+00018a ff00 sbrs TMP,b0 ; if channel is disabled in mixer - set volume to zero
+00018b 2400 clr OutA
+
+ // Channel B
+00018c 91c0 0319 lds YL,AY1_REG09 ; Load Channel B Amplitude register
+00018e 2c4c mov OutB,EVal ; set envelope volume as default value
+00018f ffc4 sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+000190 a048 ldd OutB,Y+0x20 ; load volume value from SRAM 0x220 + YL
+000191 ff01 sbrs TMP,b1 ; if channel is disabled in mixer - set volume to zero
+000192 2444 clr OutB
+
+ // Channel C
+000193 91c0 031a lds YL,AY1_REG10 ; Load Channel C Amplitude register
+000195 2c1c mov OutC,EVal ; set envelope volume as default value
+000196 ffc4 sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+000197 a018 ldd OutC,Y+0x20 ; load volume value from SRAM 0x220 + YL
+000198 ff02 sbrs TMP,b2 ; if channel is disabled in mixer - set volume to zero
+000199 2411 clr OutC
+
+00019a 2dc4 mov YL,OutB
+00019b 9446 lsr OutB ; TMP = TMP - (TMP/4 + TMP/8);
+00019c 9446 lsr OutB
+00019d 19c4 sub YL,OutB
+00019e 9446 lsr OutB
+00019f 19c4 sub YL,OutB
+0001a0 0e0c add OutA,YL ; add channel B volume to channels A and C
+0001a1 0e1c add OutC,YL
+
+0001a2 9200 0422 sts OutA1, OutA ; AY1
+0001a4 9210 0423 sts OutC1, OutC
+
+0001a6 d013 rcall SAVE_AY1_STATE
+
+ MAIN_LOOP_END:
+
+0001a7 9100 0420 lds TMP, OutA0
+0001a9 91c0 0422 lds YL, OutA1
+0001ab 0fc0 add YL, TMP
+0001ac 2e0c mov OutA, YL
+0001ad 9100 0421 lds TMP, OutC0
+0001af 91c0 0423 lds YL, OutC1
+0001b1 0fc0 add YL, TMP
+0001b2 2e1c mov OutC, YL
+
+0001b3 9200 0088 sts OCR1AL,OutA ; update PWM counters
+0001b5 9210 008a sts OCR1BL,OutC
+0001b7 cf71 rjmp _MAIN_LOOP
+ // MAIN LOOP END ====================================================================
+
+ ;
+ SAVE_AY0_STATE:
+
+ ;sts AY0_CntN, CntN
+ ;sts AY0_CntAL, CntAL
+ ;sts AY0_CntAH, CntAH
+ ;sts AY0_CntBL, CntBL
+ ;sts AY0_CntBH, CntBH
+ ;sts AY0_CntCL, CntCL
+ ;sts AY0_CntCH, CntCH
+ ;sts AY0_CntEL, CntEL
+ ;sts AY0_CntEH, CntEH
+ ;sts AY0_NoiseAddon, NoiseAddon
+ ;sts AY0_RNGH, RNGH
+ ;sts AY0_RNGL, RNGL
+ ;sts AY0_TabE, TabE
+ ;sts AY0_TabP, TabP
+ ;sts AY0_EVal, EVal
+0001b8 9508 ret
+
+ RESTORE_AY0_STATE:
+ ;lds CntN, AY0_CntN
+ ;lds CntAL, AY0_CntAL
+ ;lds CntAH, AY0_CntAH
+ ;lds CntBL, AY0_CntBL
+ ;lds CntBH, AY0_CntBH
+ ;lds CntCL, AY0_CntCL
+ ;lds CntCH, AY0_CntCH
+ ;lds CntEL, AY0_CntEL
+ ;lds CntEH, AY0_CntEH
+ ;lds NoiseAddon, AY0_NoiseAddon
+ ;lds RNGH, AY0_RNGH
+ ;lds RNGL, AY0_RNGL
+ ;lds TabE, AY0_TabE
+ ;lds TabP, AY0_TabP
+ ;lds EVal, AY0_EVal
+0001b9 9508 ret
+
+ SAVE_AY1_STATE:
+ ;sts AY1_CntN, CntN
+ ;sts AY1_CntAL, CntAL
+ ;sts AY1_CntAH, CntAH
+ ;sts AY1_CntBL, CntBL
+ ;sts AY1_CntBH, CntBH
+ ;sts AY1_CntCL, CntCL
+ ;sts AY1_CntCH, CntCH
+ ;sts AY1_CntEL, CntEL
+ ;sts AY1_CntEH, CntEH
+ ;sts AY1_NoiseAddon, NoiseAddon
+ ;sts AY1_RNGH, RNGH
+ ;sts AY1_RNGL, RNGL
+ ;sts AY1_TabE, TabE
+ ;sts AY1_TabP, TabP
+ ;sts AY1_EVal, EVal
+0001ba 9508 ret
+
+ RESTORE_AY1_STATE:
+ ;lds CntN, AY1_CntN
+ ;lds CntAL, AY1_CntAL
+ ;lds CntAH, AY1_CntAH
+ ;lds CntBL, AY1_CntBL
+ ;lds CntBH, AY1_CntBH
+ ;lds CntCL, AY1_CntCL
+ ;lds CntCH, AY1_CntCH
+ ;lds CntEL, AY1_CntEL
+ ;lds CntEH, AY1_CntEH
+ ;lds NoiseAddon, AY1_NoiseAddon
+ ;lds RNGH, AY1_RNGH
+ ;lds RNGL, AY1_RNGL
+ ;lds TabE, AY1_TabE
+ ;lds TabP, AY1_TabP
+ ;lds EVal, AY1_EVal
+0001bb 9508 ret
+
+ // copy routine from flash to SRAM
+ _COPY:
+0001bc 9105 lpm r16,Z+
+0001bd 930d st X+,r16
+0001be 952a dec r18
+0001bf f7e1 brne _COPY
+0001c0 9508 ret
+
+ /////////////////////////////////////////////////////////////////
+ /// AY REGISTERS IN SRAM
+ /////////////////////////////////////////////////////////////////
+ .dseg
+ .org 0x0110
+ ; AY
+ AY_REG00:
+000110 .byte 1
+ AY_REG01:
+000111 .byte 1
+ AY_REG02:
+000112 .byte 1
+ AY_REG03:
+000113 .byte 1
+ AY_REG04:
+000114 .byte 1
+ AY_REG05:
+000115 .byte 1
+ AY_REG06:
+000116 .byte 1
+ AY_REG07:
+000117 .byte 1
+ AY_REG08:
+000118 .byte 1
+ AY_REG09:
+000119 .byte 1
+ AY_REG10:
+00011a .byte 1
+ AY_REG11:
+00011b .byte 1
+ AY_REG12:
+00011c .byte 1
+ AY_REG13:
+00011d .byte 1
+ AY_REG14:
+00011e .byte 1
+ AY_REG15:
+00011f .byte 1
+
+ ; AY
+ .org 0x0310
+ AY1_REG00:
+000310 .byte 1
+ AY1_REG01:
+000311 .byte 1
+ AY1_REG02:
+000312 .byte 1
+ AY1_REG03:
+000313 .byte 1
+ AY1_REG04:
+000314 .byte 1
+ AY1_REG05:
+000315 .byte 1
+ AY1_REG06:
+000316 .byte 1
+ AY1_REG07:
+000317 .byte 1
+ AY1_REG08:
+000318 .byte 1
+ AY1_REG09:
+000319 .byte 1
+ AY1_REG10:
+00031a .byte 1
+ AY1_REG11:
+00031b .byte 1
+ AY1_REG12:
+00031c .byte 1
+ AY1_REG13:
+00031d .byte 1
+ AY1_REG14:
+00031e .byte 1
+ AY1_REG15:
+00031f .byte 1
+
+ ; AY0
+ .org 0x0400
+000400 AY0_CntN: .byte 1
+000401 AY0_CntAL: .byte 1
+000402 AY0_CntAH: .byte 1
+000403 AY0_CntBL: .byte 1
+000404 AY0_CntBH: .byte 1
+000405 AY0_CntCL: .byte 1
+000406 AY0_CntCH: .byte 1
+000407 AY0_CntEL: .byte 1
+000408 AY0_CntEH: .byte 1
+000409 AY0_NoiseAddon: .byte 1
+00040a AY0_RNGH: .byte 1
+00040b AY0_RNGL: .byte 1
+00040c AY0_TabE: .byte 1
+00040d AY0_TabP: .byte 1
+00040e AY0_EVal: .byte 1
+
+ ; AY1
+00040f AY1_CntN: .byte 1
+000410 AY1_CntAL: .byte 1
+000411 AY1_CntAH: .byte 1
+000412 AY1_CntBL: .byte 1
+000413 AY1_CntBH: .byte 1
+000414 AY1_CntCL: .byte 1
+000415 AY1_CntCH: .byte 1
+000416 AY1_CntEL: .byte 1
+000417 AY1_CntEH: .byte 1
+000418 AY1_NoiseAddon: .byte 1
+000419 AY1_RNGH: .byte 1
+00041a AY1_RNGL: .byte 1
+00041b AY1_TabE: .byte 1
+00041c AY1_TabP: .byte 1
+00041d AY1_EVal: .byte 1
+00041e Const_L: .byte 1
+00041f Const_H: .byte 1
+
+000420 OutA0: .byte 1
+000421 OutC0: .byte 1
+000422 OutA1: .byte 1
+000423 OutC1: .byte 1
+
+
+RESOURCE USE INFORMATION
+------------------------
+
+Notice:
+The register and instruction counts are symbol table hit counts,
+and hence implicitly used resources are not counted, eg, the
+'lpm' instruction without operands implicitly uses r0 and z,
+none of which are counted.
+
+x,y,z are separate entities in the symbol table and are
+counted separately from r26..r31 here.
+
+.dseg memory usage only counts static data declared with .byte
+
+"ATmega328P" register use summary:
+x : 1 y : 6 z : 20 r0 : 13 r1 : 13 r2 : 1 r3 : 7 r4 : 19
+r5 : 13 r6 : 11 r7 : 11 r8 : 6 r9 : 1 r10: 1 r11: 2 r12: 7
+r13: 2 r14: 8 r15: 3 r16: 88 r17: 11 r18: 16 r19: 8 r20: 8
+r21: 0 r22: 0 r23: 0 r24: 0 r25: 0 r26: 4 r27: 2 r28: 40
+r29: 3 r30: 17 r31: 18
+Registers used: 30 out of 35 (85.7%)
+
+"ATmega328P" instruction use summary:
+.lds : 0 .sts : 0 adc : 0 add : 6 adiw : 0 and : 4
+andi : 5 asr : 0 bclr : 0 bld : 0 brbc : 0 brbs : 0
+brcc : 0 brcs : 0 break : 0 breq : 4 brge : 0 brhc : 0
+brhs : 0 brid : 0 brie : 0 brlo : 0 brlt : 0 brmi : 0
+brne : 5 brpl : 2 brsh : 0 brtc : 0 brts : 0 brvc : 0
+brvs : 0 bset : 0 bst : 0 call : 0 cbi : 5 cbr : 0
+clc : 0 clh : 0 cli : 0 cln : 0 clr : 18 cls : 0
+clt : 0 clv : 0 clz : 0 com : 1 cp : 0 cpc : 0
+cpi : 5 cpse : 0 dec : 8 eor : 2 fmul : 0 fmuls : 0
+fmulsu: 0 icall : 0 ijmp : 0 in : 6 inc : 0 jmp : 0
+ld : 1 ldd : 14 ldi : 72 lds : 14 lpm : 1 lsl : 4
+lsr : 10 mov : 25 movw : 0 mul : 0 muls : 0 mulsu : 0
+neg : 0 nop : 0 or : 3 ori : 3 out : 18 pop : 0
+push : 0 rcall : 8 ret : 5 reti : 2 rjmp : 26 rol : 0
+ror : 4 sbc : 0 sbci : 0 sbi : 5 sbic : 9 sbis : 0
+sbiw : 0 sbr : 1 sbrc : 0 sbrs : 15 sec : 0 seh : 0
+sei : 1 sen : 0 ser : 0 ses : 0 set : 0 sev : 0
+sez : 0 sleep : 0 spm : 0 st : 4 std : 7 sts : 32
+sub : 4 subi : 0 swap : 2 tst : 0 wdr : 0
+Instructions used: 39 out of 113 (34.5%)
+
+"ATmega328P" memory use summary [bytes]:
+Segment Begin End Code Data Used Size Use%
+---------------------------------------------------------------
+[.cseg] 0x000000 0x000382 814 80 894 32768 2.7%
+[.dseg] 0x000100 0x000424 0 68 68 2048 3.3%
+[.eseg] 0x000000 0x000000 0 0 0 1024 0.0%
+
+Assembly complete, 0 errors, 1 warnings
diff --git a/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.map b/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.map
new file mode 100644
index 0000000..fad9f96
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.map
@@ -0,0 +1,889 @@
+
+AVRASM ver. 2.2.7 D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm Tue Feb 03 21:02:51 2026
+
+
+EQU SIGNATURE_000 0000001e
+EQU SIGNATURE_001 00000095
+EQU SIGNATURE_002 0000000f
+EQU UDR0 000000c6
+EQU UBRR0L 000000c4
+EQU UBRR0H 000000c5
+EQU UCSR0C 000000c2
+EQU UCSR0B 000000c1
+EQU UCSR0A 000000c0
+EQU TWAMR 000000bd
+EQU TWCR 000000bc
+EQU TWDR 000000bb
+EQU TWAR 000000ba
+EQU TWSR 000000b9
+EQU TWBR 000000b8
+EQU ASSR 000000b6
+EQU OCR2B 000000b4
+EQU OCR2A 000000b3
+EQU TCNT2 000000b2
+EQU TCCR2B 000000b1
+EQU TCCR2A 000000b0
+EQU OCR1BL 0000008a
+EQU OCR1BH 0000008b
+EQU OCR1AL 00000088
+EQU OCR1AH 00000089
+EQU ICR1L 00000086
+EQU ICR1H 00000087
+EQU TCNT1L 00000084
+EQU TCNT1H 00000085
+EQU TCCR1C 00000082
+EQU TCCR1B 00000081
+EQU TCCR1A 00000080
+EQU DIDR1 0000007f
+EQU DIDR0 0000007e
+EQU ADMUX 0000007c
+EQU ADCSRB 0000007b
+EQU ADCSRA 0000007a
+EQU ADCH 00000079
+EQU ADCL 00000078
+EQU TIMSK2 00000070
+EQU TIMSK1 0000006f
+EQU TIMSK0 0000006e
+EQU PCMSK1 0000006c
+EQU PCMSK2 0000006d
+EQU PCMSK0 0000006b
+EQU EICRA 00000069
+EQU PCICR 00000068
+EQU OSCCAL 00000066
+EQU PRR 00000064
+EQU CLKPR 00000061
+EQU WDTCSR 00000060
+EQU SREG 0000003f
+EQU SPL 0000003d
+EQU SPH 0000003e
+EQU SPMCSR 00000037
+EQU MCUCR 00000035
+EQU MCUSR 00000034
+EQU SMCR 00000033
+EQU ACSR 00000030
+EQU SPDR 0000002e
+EQU SPSR 0000002d
+EQU SPCR 0000002c
+EQU GPIOR2 0000002b
+EQU GPIOR1 0000002a
+EQU OCR0B 00000028
+EQU OCR0A 00000027
+EQU TCNT0 00000026
+EQU TCCR0B 00000025
+EQU TCCR0A 00000024
+EQU GTCCR 00000023
+EQU EEARH 00000022
+EQU EEARL 00000021
+EQU EEDR 00000020
+EQU EECR 0000001f
+EQU GPIOR0 0000001e
+EQU EIMSK 0000001d
+EQU EIFR 0000001c
+EQU PCIFR 0000001b
+EQU TIFR2 00000017
+EQU TIFR1 00000016
+EQU TIFR0 00000015
+EQU PORTD 0000000b
+EQU DDRD 0000000a
+EQU PIND 00000009
+EQU PORTC 00000008
+EQU DDRC 00000007
+EQU PINC 00000006
+EQU PORTB 00000005
+EQU DDRB 00000004
+EQU PINB 00000003
+EQU UDR0_0 00000000
+EQU UDR0_1 00000001
+EQU UDR0_2 00000002
+EQU UDR0_3 00000003
+EQU UDR0_4 00000004
+EQU UDR0_5 00000005
+EQU UDR0_6 00000006
+EQU UDR0_7 00000007
+EQU MPCM0 00000000
+EQU U2X0 00000001
+EQU UPE0 00000002
+EQU DOR0 00000003
+EQU FE0 00000004
+EQU UDRE0 00000005
+EQU TXC0 00000006
+EQU RXC0 00000007
+EQU TXB80 00000000
+EQU RXB80 00000001
+EQU UCSZ02 00000002
+EQU TXEN0 00000003
+EQU RXEN0 00000004
+EQU UDRIE0 00000005
+EQU TXCIE0 00000006
+EQU RXCIE0 00000007
+EQU UCPOL0 00000000
+EQU UCSZ00 00000001
+EQU UCPHA0 00000001
+EQU UCSZ01 00000002
+EQU UDORD0 00000002
+EQU USBS0 00000003
+EQU UPM00 00000004
+EQU UPM01 00000005
+EQU UMSEL00 00000006
+EQU UMSEL0 00000006
+EQU UMSEL01 00000007
+EQU UMSEL1 00000007
+EQU UBRR8 00000000
+EQU UBRR9 00000001
+EQU UBRR10 00000002
+EQU UBRR11 00000003
+EQU _UBRR0 00000000
+EQU _UBRR1 00000001
+EQU UBRR2 00000002
+EQU UBRR3 00000003
+EQU UBRR4 00000004
+EQU UBRR5 00000005
+EQU UBRR6 00000006
+EQU UBRR7 00000007
+EQU TWAM0 00000001
+EQU TWAMR0 00000001
+EQU TWAM1 00000002
+EQU TWAMR1 00000002
+EQU TWAM2 00000003
+EQU TWAMR2 00000003
+EQU TWAM3 00000004
+EQU TWAMR3 00000004
+EQU TWAM4 00000005
+EQU TWAMR4 00000005
+EQU TWAM5 00000006
+EQU TWAMR5 00000006
+EQU TWAM6 00000007
+EQU TWAMR6 00000007
+EQU TWBR0 00000000
+EQU TWBR1 00000001
+EQU TWBR2 00000002
+EQU TWBR3 00000003
+EQU TWBR4 00000004
+EQU TWBR5 00000005
+EQU TWBR6 00000006
+EQU TWBR7 00000007
+EQU TWIE 00000000
+EQU TWEN 00000002
+EQU TWWC 00000003
+EQU TWSTO 00000004
+EQU TWSTA 00000005
+EQU TWEA 00000006
+EQU TWINT 00000007
+EQU TWPS0 00000000
+EQU TWPS1 00000001
+EQU TWS3 00000003
+EQU TWS4 00000004
+EQU TWS5 00000005
+EQU TWS6 00000006
+EQU TWS7 00000007
+EQU TWD0 00000000
+EQU TWD1 00000001
+EQU TWD2 00000002
+EQU TWD3 00000003
+EQU TWD4 00000004
+EQU TWD5 00000005
+EQU TWD6 00000006
+EQU TWD7 00000007
+EQU TWGCE 00000000
+EQU TWA0 00000001
+EQU TWA1 00000002
+EQU TWA2 00000003
+EQU TWA3 00000004
+EQU TWA4 00000005
+EQU TWA5 00000006
+EQU TWA6 00000007
+EQU TOIE1 00000000
+EQU OCIE1A 00000001
+EQU OCIE1B 00000002
+EQU ICIE1 00000005
+EQU TOV1 00000000
+EQU OCF1A 00000001
+EQU OCF1B 00000002
+EQU ICF1 00000005
+EQU WGM10 00000000
+EQU WGM11 00000001
+EQU COM1B0 00000004
+EQU COM1B1 00000005
+EQU COM1A0 00000006
+EQU COM1A1 00000007
+EQU CS10 00000000
+EQU CS11 00000001
+EQU CS12 00000002
+EQU WGM12 00000003
+EQU WGM13 00000004
+EQU ICES1 00000006
+EQU ICNC1 00000007
+EQU FOC1B 00000006
+EQU FOC1A 00000007
+EQU PSRSYNC 00000000
+EQU TSM 00000007
+EQU TOIE2 00000000
+EQU TOIE2A 00000000
+EQU OCIE2A 00000001
+EQU OCIE2B 00000002
+EQU TOV2 00000000
+EQU OCF2A 00000001
+EQU OCF2B 00000002
+EQU WGM20 00000000
+EQU WGM21 00000001
+EQU COM2B0 00000004
+EQU COM2B1 00000005
+EQU COM2A0 00000006
+EQU COM2A1 00000007
+EQU CS20 00000000
+EQU CS21 00000001
+EQU CS22 00000002
+EQU WGM22 00000003
+EQU FOC2B 00000006
+EQU FOC2A 00000007
+EQU TCNT2_0 00000000
+EQU TCNT2_1 00000001
+EQU TCNT2_2 00000002
+EQU TCNT2_3 00000003
+EQU TCNT2_4 00000004
+EQU TCNT2_5 00000005
+EQU TCNT2_6 00000006
+EQU TCNT2_7 00000007
+EQU OCR2A_0 00000000
+EQU OCR2A_1 00000001
+EQU OCR2A_2 00000002
+EQU OCR2A_3 00000003
+EQU OCR2A_4 00000004
+EQU OCR2A_5 00000005
+EQU OCR2A_6 00000006
+EQU OCR2A_7 00000007
+EQU OCR2B_0 00000000
+EQU OCR2B_1 00000001
+EQU OCR2B_2 00000002
+EQU OCR2B_3 00000003
+EQU OCR2B_4 00000004
+EQU OCR2B_5 00000005
+EQU OCR2B_6 00000006
+EQU OCR2B_7 00000007
+EQU TCR2BUB 00000000
+EQU TCR2AUB 00000001
+EQU OCR2BUB 00000002
+EQU OCR2AUB 00000003
+EQU TCN2UB 00000004
+EQU AS2 00000005
+EQU EXCLK 00000006
+EQU PSRASY 00000001
+EQU PSR2 00000001
+EQU MUX0 00000000
+EQU MUX1 00000001
+EQU MUX2 00000002
+EQU MUX3 00000003
+EQU ADLAR 00000005
+EQU REFS0 00000006
+EQU REFS1 00000007
+EQU ADPS0 00000000
+EQU ADPS1 00000001
+EQU ADPS2 00000002
+EQU ADIE 00000003
+EQU ADIF 00000004
+EQU ADATE 00000005
+EQU ADSC 00000006
+EQU ADEN 00000007
+EQU ADTS0 00000000
+EQU ADTS1 00000001
+EQU ADTS2 00000002
+EQU ACME 00000006
+EQU ADCH0 00000000
+EQU ADCH1 00000001
+EQU ADCH2 00000002
+EQU ADCH3 00000003
+EQU ADCH4 00000004
+EQU ADCH5 00000005
+EQU ADCH6 00000006
+EQU ADCH7 00000007
+EQU ADCL0 00000000
+EQU ADCL1 00000001
+EQU ADCL2 00000002
+EQU ADCL3 00000003
+EQU ADCL4 00000004
+EQU ADCL5 00000005
+EQU ADCL6 00000006
+EQU ADCL7 00000007
+EQU ADC0D 00000000
+EQU ADC1D 00000001
+EQU ADC2D 00000002
+EQU ADC3D 00000003
+EQU ADC4D 00000004
+EQU ADC5D 00000005
+EQU ACIS0 00000000
+EQU ACIS1 00000001
+EQU ACIC 00000002
+EQU ACIE 00000003
+EQU ACI 00000004
+EQU ACO 00000005
+EQU ACBG 00000006
+EQU ACD 00000007
+EQU AIN0D 00000000
+EQU AIN1D 00000001
+EQU PORTB0 00000000
+EQU PB0 00000000
+EQU PORTB1 00000001
+EQU PB1 00000001
+EQU PORTB2 00000002
+EQU PB2 00000002
+EQU PORTB3 00000003
+EQU PB3 00000003
+EQU PORTB4 00000004
+EQU PB4 00000004
+EQU PORTB5 00000005
+EQU PB5 00000005
+EQU PORTB6 00000006
+EQU PB6 00000006
+EQU PORTB7 00000007
+EQU PB7 00000007
+EQU DDB0 00000000
+EQU DDB1 00000001
+EQU DDB2 00000002
+EQU DDB3 00000003
+EQU DDB4 00000004
+EQU DDB5 00000005
+EQU DDB6 00000006
+EQU DDB7 00000007
+EQU PINB0 00000000
+EQU PINB1 00000001
+EQU PINB2 00000002
+EQU PINB3 00000003
+EQU PINB4 00000004
+EQU PINB5 00000005
+EQU PINB6 00000006
+EQU PINB7 00000007
+EQU PORTC0 00000000
+EQU PC0 00000000
+EQU PORTC1 00000001
+EQU PC1 00000001
+EQU PORTC2 00000002
+EQU PC2 00000002
+EQU PORTC3 00000003
+EQU PC3 00000003
+EQU PORTC4 00000004
+EQU PC4 00000004
+EQU PORTC5 00000005
+EQU PC5 00000005
+EQU PORTC6 00000006
+EQU PC6 00000006
+EQU DDC0 00000000
+EQU DDC1 00000001
+EQU DDC2 00000002
+EQU DDC3 00000003
+EQU DDC4 00000004
+EQU DDC5 00000005
+EQU DDC6 00000006
+EQU PINC0 00000000
+EQU PINC1 00000001
+EQU PINC2 00000002
+EQU PINC3 00000003
+EQU PINC4 00000004
+EQU PINC5 00000005
+EQU PINC6 00000006
+EQU PORTD0 00000000
+EQU PD0 00000000
+EQU PORTD1 00000001
+EQU PD1 00000001
+EQU PORTD2 00000002
+EQU PD2 00000002
+EQU PORTD3 00000003
+EQU PD3 00000003
+EQU PORTD4 00000004
+EQU PD4 00000004
+EQU PORTD5 00000005
+EQU PD5 00000005
+EQU PORTD6 00000006
+EQU PD6 00000006
+EQU PORTD7 00000007
+EQU PD7 00000007
+EQU DDD0 00000000
+EQU DDD1 00000001
+EQU DDD2 00000002
+EQU DDD3 00000003
+EQU DDD4 00000004
+EQU DDD5 00000005
+EQU DDD6 00000006
+EQU DDD7 00000007
+EQU PIND0 00000000
+EQU PIND1 00000001
+EQU PIND2 00000002
+EQU PIND3 00000003
+EQU PIND4 00000004
+EQU PIND5 00000005
+EQU PIND6 00000006
+EQU PIND7 00000007
+EQU TOIE0 00000000
+EQU OCIE0A 00000001
+EQU OCIE0B 00000002
+EQU TOV0 00000000
+EQU OCF0A 00000001
+EQU OCF0B 00000002
+EQU WGM00 00000000
+EQU WGM01 00000001
+EQU COM0B0 00000004
+EQU COM0B1 00000005
+EQU COM0A0 00000006
+EQU COM0A1 00000007
+EQU CS00 00000000
+EQU CS01 00000001
+EQU CS02 00000002
+EQU WGM02 00000003
+EQU FOC0B 00000006
+EQU FOC0A 00000007
+EQU TCNT0_0 00000000
+EQU TCNT0_1 00000001
+EQU TCNT0_2 00000002
+EQU TCNT0_3 00000003
+EQU TCNT0_4 00000004
+EQU TCNT0_5 00000005
+EQU TCNT0_6 00000006
+EQU TCNT0_7 00000007
+EQU OCR0A_0 00000000
+EQU OCR0A_1 00000001
+EQU OCR0A_2 00000002
+EQU OCR0A_3 00000003
+EQU OCR0A_4 00000004
+EQU OCR0A_5 00000005
+EQU OCR0A_6 00000006
+EQU OCR0A_7 00000007
+EQU OCR0B_0 00000000
+EQU OCR0B_1 00000001
+EQU OCR0B_2 00000002
+EQU OCR0B_3 00000003
+EQU OCR0B_4 00000004
+EQU OCR0B_5 00000005
+EQU OCR0B_6 00000006
+EQU OCR0B_7 00000007
+EQU PSR10 00000000
+EQU ISC00 00000000
+EQU ISC01 00000001
+EQU ISC10 00000002
+EQU ISC11 00000003
+EQU INT0 00000000
+EQU INT1 00000001
+EQU INTF0 00000000
+EQU INTF1 00000001
+EQU PCIE0 00000000
+EQU PCIE1 00000001
+EQU PCIE2 00000002
+EQU PCINT16 00000000
+EQU PCINT17 00000001
+EQU PCINT18 00000002
+EQU PCINT19 00000003
+EQU PCINT20 00000004
+EQU PCINT21 00000005
+EQU PCINT22 00000006
+EQU PCINT23 00000007
+EQU PCINT8 00000000
+EQU PCINT9 00000001
+EQU PCINT10 00000002
+EQU PCINT11 00000003
+EQU PCINT12 00000004
+EQU PCINT13 00000005
+EQU PCINT14 00000006
+EQU PCINT0 00000000
+EQU PCINT1 00000001
+EQU PCINT2 00000002
+EQU PCINT3 00000003
+EQU PCINT4 00000004
+EQU PCINT5 00000005
+EQU PCINT6 00000006
+EQU PCINT7 00000007
+EQU PCIF0 00000000
+EQU PCIF1 00000001
+EQU PCIF2 00000002
+EQU SPDR0 00000000
+EQU SPDR1 00000001
+EQU SPDR2 00000002
+EQU SPDR3 00000003
+EQU SPDR4 00000004
+EQU SPDR5 00000005
+EQU SPDR6 00000006
+EQU SPDR7 00000007
+EQU SPI2X 00000000
+EQU WCOL 00000006
+EQU SPIF 00000007
+EQU SPR0 00000000
+EQU SPR1 00000001
+EQU CPHA 00000002
+EQU CPOL 00000003
+EQU MSTR 00000004
+EQU DORD 00000005
+EQU SPE 00000006
+EQU SPIE 00000007
+EQU WDP0 00000000
+EQU WDP1 00000001
+EQU WDP2 00000002
+EQU WDE 00000003
+EQU WDCE 00000004
+EQU WDP3 00000005
+EQU WDIE 00000006
+EQU WDIF 00000007
+EQU SREG_C 00000000
+EQU SREG_Z 00000001
+EQU SREG_N 00000002
+EQU SREG_V 00000003
+EQU SREG_S 00000004
+EQU SREG_H 00000005
+EQU SREG_T 00000006
+EQU SREG_I 00000007
+EQU CAL0 00000000
+EQU CAL1 00000001
+EQU CAL2 00000002
+EQU CAL3 00000003
+EQU CAL4 00000004
+EQU CAL5 00000005
+EQU CAL6 00000006
+EQU CAL7 00000007
+EQU CLKPS0 00000000
+EQU CLKPS1 00000001
+EQU CLKPS2 00000002
+EQU CLKPS3 00000003
+EQU CLKPCE 00000007
+EQU SELFPRGEN 00000000
+EQU SPMEN 00000000
+EQU PGERS 00000001
+EQU PGWRT 00000002
+EQU BLBSET 00000003
+EQU RWWSRE 00000004
+EQU SIGRD 00000005
+EQU RWWSB 00000006
+EQU SPMIE 00000007
+EQU IVCE 00000000
+EQU IVSEL 00000001
+EQU PUD 00000004
+EQU BODSE 00000005
+EQU BODS 00000006
+EQU PORF 00000000
+EQU EXTRF 00000001
+EQU EXTREF 00000001
+EQU BORF 00000002
+EQU WDRF 00000003
+EQU SE 00000000
+EQU SM0 00000001
+EQU SM1 00000002
+EQU SM2 00000003
+EQU GPIOR20 00000000
+EQU GPIOR21 00000001
+EQU GPIOR22 00000002
+EQU GPIOR23 00000003
+EQU GPIOR24 00000004
+EQU GPIOR25 00000005
+EQU GPIOR26 00000006
+EQU GPIOR27 00000007
+EQU GPIOR10 00000000
+EQU GPIOR11 00000001
+EQU GPIOR12 00000002
+EQU GPIOR13 00000003
+EQU GPIOR14 00000004
+EQU GPIOR15 00000005
+EQU GPIOR16 00000006
+EQU GPIOR17 00000007
+EQU GPIOR00 00000000
+EQU GPIOR01 00000001
+EQU GPIOR02 00000002
+EQU GPIOR03 00000003
+EQU GPIOR04 00000004
+EQU GPIOR05 00000005
+EQU GPIOR06 00000006
+EQU GPIOR07 00000007
+EQU PRADC 00000000
+EQU PRUSART0 00000001
+EQU PRSPI 00000002
+EQU PRTIM1 00000003
+EQU PRTIM0 00000005
+EQU PRTIM2 00000006
+EQU PRTWI 00000007
+EQU EEAR0 00000000
+EQU EEAR1 00000001
+EQU EEAR2 00000002
+EQU EEAR3 00000003
+EQU EEAR4 00000004
+EQU EEAR5 00000005
+EQU EEAR6 00000006
+EQU EEAR7 00000007
+EQU EEAR8 00000000
+EQU EEAR9 00000001
+EQU EEDR0 00000000
+EQU EEDR1 00000001
+EQU EEDR2 00000002
+EQU EEDR3 00000003
+EQU EEDR4 00000004
+EQU EEDR5 00000005
+EQU EEDR6 00000006
+EQU EEDR7 00000007
+EQU EERE 00000000
+EQU EEPE 00000001
+EQU EEMPE 00000002
+EQU EERIE 00000003
+EQU EEPM0 00000004
+EQU EEPM1 00000005
+EQU LB1 00000000
+EQU LB2 00000001
+EQU BLB01 00000002
+EQU BLB02 00000003
+EQU BLB11 00000004
+EQU BLB12 00000005
+EQU CKSEL0 00000000
+EQU CKSEL1 00000001
+EQU CKSEL2 00000002
+EQU CKSEL3 00000003
+EQU SUT0 00000004
+EQU SUT1 00000005
+EQU CKOUT 00000006
+EQU CKDIV8 00000007
+EQU BOOTRST 00000000
+EQU BOOTSZ0 00000001
+EQU BOOTSZ1 00000002
+EQU EESAVE 00000003
+EQU WDTON 00000004
+EQU SPIEN 00000005
+EQU DWEN 00000006
+EQU RSTDISBL 00000007
+EQU BODLEVEL0 00000000
+EQU BODLEVEL1 00000001
+EQU BODLEVEL2 00000002
+DEF XH r27
+DEF XL r26
+DEF YH r29
+DEF YL r28
+DEF ZH r31
+DEF ZL r30
+EQU FLASHEND 00003fff
+EQU IOEND 000000ff
+EQU SRAM_START 00000100
+EQU SRAM_SIZE 00000800
+EQU RAMEND 000008ff
+EQU XRAMEND 00000000
+EQU E2END 000003ff
+EQU EEPROMEND 000003ff
+EQU EEADRBITS 0000000a
+EQU NRWW_START_ADDR 00003800
+EQU NRWW_STOP_ADDR 00003fff
+EQU RWW_START_ADDR 00000000
+EQU RWW_STOP_ADDR 000037ff
+EQU PAGESIZE 00000040
+EQU FIRSTBOOTSTART 00003f00
+EQU SECONDBOOTSTART 00003e00
+EQU THIRDBOOTSTART 00003c00
+EQU FOURTHBOOTSTART 00003800
+EQU SMALLBOOTSTART 00003f00
+EQU LARGEBOOTSTART 00003800
+EQU INT0addr 00000002
+EQU INT1addr 00000004
+EQU PCI0addr 00000006
+EQU PCI1addr 00000008
+EQU PCI2addr 0000000a
+EQU WDTaddr 0000000c
+EQU OC2Aaddr 0000000e
+EQU OC2Baddr 00000010
+EQU OVF2addr 00000012
+EQU ICP1addr 00000014
+EQU OC1Aaddr 00000016
+EQU OC1Baddr 00000018
+EQU OVF1addr 0000001a
+EQU OC0Aaddr 0000001c
+EQU OC0Baddr 0000001e
+EQU OVF0addr 00000020
+EQU SPIaddr 00000022
+EQU URXCaddr 00000024
+EQU UDREaddr 00000026
+EQU UTXCaddr 00000028
+EQU ADCCaddr 0000002a
+EQU ERDYaddr 0000002c
+EQU ACIaddr 0000002e
+EQU TWIaddr 00000030
+EQU SPMRaddr 00000032
+EQU INT_VECTORS_SIZE 00000034
+EQU b0 00000000
+EQU b1 00000001
+EQU b2 00000002
+EQU b3 00000003
+EQU b4 00000004
+EQU b5 00000005
+EQU b6 00000006
+EQU b7 00000007
+EQU CHIP_SELECTED 0000001e
+DEF OutA r0
+DEF OutC r1
+DEF C1F r2
+DEF CntN r3
+DEF OutB r4
+DEF BusOut1 r5
+DEF NoiseAddon r6
+DEF C00 r7
+DEF CC0 r8
+DEF TabE r9
+DEF C04 r10
+DEF C02 r11
+DEF BusData r20
+DEF EVal r12
+DEF SREGSave r13
+DEF RNGL r14
+DEF RNGH r15
+DEF TMP r16
+DEF BusOut2 r17
+DEF TabP r18
+DEF TNLevel r19
+DEF ADDR r30
+EQU CCP 00000034
+EQU CLKMSR 00000105
+EQU BCR 00000107
+EQU BOOTEND 00000108
+EQU BODCR 00000104
+EQU C0SR 00000050
+EQU C0D 00000007
+EQU C0BG 00000006
+EQU C0O 00000005
+EQU C0I 00000004
+EQU C0IE 00000003
+EQU C0IC 00000002
+EQU C0IS1 00000001
+EQU C0IS0 00000000
+EQU C0XR 00000051
+EQU C0OE 00000006
+EQU C0HSYE 00000005
+EQU C0PS0 00000004
+EQU C0WKE 00000003
+EQU C0FEN 00000002
+EQU C0FS1 00000001
+EQU C0FS0 00000000
+EQU C0TR 00000052
+EQU C1SR 0000002f
+EQU C1D 00000007
+EQU C1BG 00000006
+EQU C1O 00000005
+EQU C1I 00000004
+EQU C1IE 00000003
+EQU C1IC 00000002
+EQU C1IS1 00000001
+EQU C1IS0 00000000
+EQU C1XR 0000003a
+EQU C1OE 00000006
+EQU C1HSYE 00000005
+EQU C1PS0 00000004
+EQU C1WKE 00000003
+EQU C1FEN 00000002
+EQU C1FS1 00000001
+EQU C1FS0 00000000
+EQU C1TR 0000005b
+EQU FGPIOE 0000010a
+EQU FGPIO 0000010b
+EQU DSCR 00000020
+EQU DSUEN 00000007
+EQU DSMM 00000006
+EQU DSD1 00000005
+EQU DSD0 00000004
+EQU DSN 00000002
+EQU DSZ 00000001
+EQU DSC 00000000
+EQU DSIR 00000021
+EQU DSSD 00000022
+EQU DSDX 00000030
+EQU DSDY 00000031
+EQU DSAL 00000058
+EQU DSAH 00000059
+CSEG _LGT_INIT 00000080
+CSEG _INT0_Handler 0000002d
+CSEG _INT1_Handler 0000004f
+CSEG Volumes 00000005
+CSEG EVolumes 0000000d
+CSEG Envelopes 0000001d
+CSEG RegsMask 00000025
+CSEG LATCH_REG_ADDR0 00000038
+CSEG LOOP_NOT_INACTIVE 00000031
+CSEG exit_int0 00000035
+CSEG SELECT_CHIP_ADDR0 00000046
+CSEG READ_CHIP0 00000042
+DSEG AY1_REG00 00000310
+CSEG SELECT_CHIP0_ADDR0 0000004b
+CSEG SELECT_CHIP1_ADDR0 0000004d
+CSEG LATCH_REG_ADDR1 0000006a
+CSEG NO_ENVELOPE_CHANGED_P 00000066
+CSEG exit_int1 00000067
+CSEG SELECT_CHIP_ADDR1 00000077
+CSEG READ_CHIP1 00000073
+CSEG SELECT_CHIP0_ADDR1 0000007c
+CSEG SELECT_CHIP1_ADDR1 0000007e
+CSEG _RESET 000000ae
+CSEG LOOP0 000000d2
+CSEG _COPY 000001bc
+CSEG LOOP1 000000f0
+DSEG AY0_CntN 00000400
+CSEG LOOP2 000000f8
+DSEG Const_L 0000041e
+CSEG _MAIN_LOOP 00000129
+CSEG AY1_PROCESSING 0000016b
+CSEG AY0_PROCESSING 00000130
+CSEG RESTORE_AY0_STATE 000001b9
+CSEG NOISE_GENERATOR_END_AY0 00000141
+DSEG AY_REG06 00000116
+DSEG AY_REG07 00000117
+DSEG AY_REG08 00000118
+DSEG AY_REG09 00000119
+DSEG AY_REG10 0000011a
+CSEG SAVE_AY0_STATE 000001b8
+DSEG OutA0 00000420
+DSEG OutC0 00000421
+CSEG MAIN_LOOP_END 000001a7
+CSEG RESTORE_AY1_STATE 000001bb
+CSEG NOISE_GENERATOR_END_AY1 0000017c
+DSEG AY1_REG06 00000316
+DSEG AY1_CntAL 00000410
+DSEG AY1_REG07 00000317
+DSEG AY1_REG08 00000318
+DSEG AY1_REG09 00000319
+DSEG AY1_REG10 0000031a
+DSEG OutA1 00000422
+DSEG OutC1 00000423
+CSEG SAVE_AY1_STATE 000001ba
+DSEG AY_REG00 00000110
+DSEG AY_REG01 00000111
+DSEG AY_REG02 00000112
+DSEG AY_REG03 00000113
+DSEG AY_REG04 00000114
+DSEG AY_REG05 00000115
+DSEG AY_REG11 0000011b
+DSEG AY_REG12 0000011c
+DSEG AY_REG13 0000011d
+DSEG AY_REG14 0000011e
+DSEG AY_REG15 0000011f
+DSEG AY1_REG01 00000311
+DSEG AY1_REG02 00000312
+DSEG AY1_REG03 00000313
+DSEG AY1_REG04 00000314
+DSEG AY1_REG05 00000315
+DSEG AY1_REG11 0000031b
+DSEG AY1_REG12 0000031c
+DSEG AY1_REG13 0000031d
+DSEG AY1_REG14 0000031e
+DSEG AY1_REG15 0000031f
+DSEG AY0_CntAL 00000401
+DSEG AY0_CntAH 00000402
+DSEG AY0_CntBL 00000403
+DSEG AY0_CntBH 00000404
+DSEG AY0_CntCL 00000405
+DSEG AY0_CntCH 00000406
+DSEG AY0_CntEL 00000407
+DSEG AY0_CntEH 00000408
+DSEG AY0_NoiseAddon 00000409
+DSEG AY0_RNGH 0000040a
+DSEG AY0_RNGL 0000040b
+DSEG AY0_TabE 0000040c
+DSEG AY0_TabP 0000040d
+DSEG AY0_EVal 0000040e
+DSEG AY1_CntN 0000040f
+DSEG AY1_CntAH 00000411
+DSEG AY1_CntBL 00000412
+DSEG AY1_CntBH 00000413
+DSEG AY1_CntCL 00000414
+DSEG AY1_CntCH 00000415
+DSEG AY1_CntEL 00000416
+DSEG AY1_CntEH 00000417
+DSEG AY1_NoiseAddon 00000418
+DSEG AY1_RNGH 00000419
+DSEG AY1_RNGL 0000041a
+DSEG AY1_TabE 0000041b
+DSEG AY1_TabP 0000041c
+DSEG AY1_EVal 0000041d
+DSEG Const_H 0000041f
diff --git a/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.obj b/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.obj
new file mode 100644
index 0000000..0b5daeb
Binary files /dev/null and b/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.obj differ
diff --git a/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.tmp b/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.tmp
new file mode 100644
index 0000000..79d2658
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Debug/AY_Emu.tmp
@@ -0,0 +1,130 @@
+
+ 2.2.7
+ "ATmega328P"
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\Debug
+
+ C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.3.300\avrasm\inc
+ C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avrassembler\Include
+
+
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm
+
+ C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.3.300\avrasm\inc\m328pdef.inc
+
+
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\Debug\AY_Emu.obj
+
+
+ AY_Emu.hex
+
+
+ AY_Emu.map
+ AY_Emu.lss
+
+
+ <_LGT_INIT>D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm315
+ <_INT0_Handler>D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm186
+ <_INT1_Handler>D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm240
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm161
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm163
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm178
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm182
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm204
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm193
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm199
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm224
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm217
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1030
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm231
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm235
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm278
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm271
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm273
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm297
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm290
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm304
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm308
+ <_RESET>D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm367
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm421
+ <_COPY>D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm982
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm462
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1065
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm473
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1097
+ <_MAIN_LOOP>D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm532
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm701
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm545
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm927
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm609
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1007
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1009
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1011
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1013
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1015
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm908
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1100
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1101
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm891
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm963
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm764
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1042
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1083
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1044
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1046
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1048
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1050
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1102
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1103
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm945
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm995
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm997
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm999
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1001
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1003
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1005
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1017
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1019
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1021
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1023
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1025
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1032
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1034
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1036
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1038
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1040
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1052
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1054
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1056
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1058
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1060
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1066
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1067
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1068
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1069
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1070
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1071
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1072
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1073
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1074
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1075
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1076
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1077
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1078
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1079
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1082
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1084
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1085
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1086
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1087
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1088
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1089
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1090
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1091
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1092
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1093
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1094
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1095
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1096
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1098
+
+
diff --git a/Sources/AY_Emu/AY_Emu/Release/AY_Emu.elf b/Sources/AY_Emu/AY_Emu/Release/AY_Emu.elf
new file mode 100644
index 0000000..4d2a242
Binary files /dev/null and b/Sources/AY_Emu/AY_Emu/Release/AY_Emu.elf differ
diff --git a/Sources/AY_Emu/AY_Emu/Release/AY_Emu.lss b/Sources/AY_Emu/AY_Emu/Release/AY_Emu.lss
new file mode 100644
index 0000000..734b265
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/AY_Emu.lss
@@ -0,0 +1,2156 @@
+
+AVRASM ver. 2.2.7 D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm Wed Aug 19 17:36:34 2026
+
+[builtin](2): Including file 'C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.3.300\avrasm\inc\m328pdef.inc'
+D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm(56): warning: Register r26 already defined by the .DEF directive
+D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm(57): warning: Register r27 already defined by the .DEF directive
+D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm(58): warning: Register r30 already defined by the .DEF directive
+[builtin](2): Including file 'C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.3.300\avrasm\inc\m328pdef.inc'
+
+ ; AY-3-8912 IC emulator version 26.0 for LGT8F328P
+
+ ;***** Created: 2011-02-09 12:03 ******* Source: ATmega328P.xml **********
+ ;*************************************************************************
+ ;* A P P L I C A T I O N N O T E F O R T H E A V R F A M I L Y
+ ;*
+ ;* Number : AVR000
+ ;* File Name : "m328Pdef.inc"
+ ;* Title : Register/Bit Definitions for the ATmega328P
+ ;* Date : 2011-02-09
+ ;* Version : 2.35
+ ;* Support E-mail : avr@atmel.com
+ ;* Target MCU : ATmega328P
+ ;*
+ ;* DESCRIPTION
+ ;* When including this file in the assembly program file, all I/O register
+ ;* names and I/O register bit names appearing in the data book can be used.
+ ;* In addition, the six registers forming the three data pointers X, Y and
+ ;* Z have been assigned names XL - ZH. Highest RAM address for Internal
+ ;* SRAM is also defined
+ ;*
+ ;* The Register names are represented by their hexadecimal address.
+ ;*
+ ;* The Register Bit names are represented by their bit number (0-7).
+ ;*
+ ;* Please observe the difference in using the bit names with instructions
+ ;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc"
+ ;* (skip if bit in register set/cleared). The following example illustrates
+ ;* this:
+ ;*
+ ;* in r16,PORTB ;read PORTB latch
+ ;* sbr r16,(1< PUD for
+0000ac 6004 sbr r16,PUD
+0000ad bf05 out MCUCR,r16
+
+ // init stack pointer at end of RAM
+0000ae ef0f ldi r16,low(RAMEND)
+0000af bf0d out SPL,r16
+0000b0 e008 ldi r16,high(RAMEND)
+0000b1 bf0e out SPH,r16
+
+ ; disable Analog Comparator ==============================
+0000b2 e800 ldi r16, (1< 2000*256 = 512000
+000110 eda0 ldi r26, low(2000)
+000111 e0b7 ldi r27, high(2000)
+ CALIB_WAIT:
+000112 b305 in r16, TIFR0
+000113 ff00 sbrs r16, TOV0
+000114 cffd rjmp CALIB_WAIT
+000115 e001 ldi r16, (1< ,
+000127 2344 tst r20
+000128 f411 brne CALIB_DO
+000129 2355 tst r21
+00012a f0f1 breq CALIB_END
+
+ CALIB_DO:
+ ; 4096000 / N_ref ,
+ ; ( ) -
+ ; ICR1 ~0.5% ( ICR1~200
+ ; - )
+00012b e060 ldi r22, 0x00 ; numL
+00012c e870 ldi r23, 0x80 ; numM
+00012d e32e ldi r18, 0x3E ; numH (numH:numM:numL = 4096000)
+
+ ; N_ref/2 -
+ ;
+00012e 2fa4 mov r26, r20
+00012f 2fb5 mov r27, r21
+000130 95b6 lsr r27
+000131 95a7 ror r26
+000132 0f6a add r22, r26
+000133 1f7b adc r23, r27
+000134 1d27 adc r18, C00
+
+000135 2788 clr r24 ; quotL
+000136 2799 clr r25 ; quotH
+
+ CALIB_DIV_LOOP:
+000137 2322 tst r18 ; numH == 0 ?
+000138 f419 brne CALIB_DIV_SUB ; num >= 65536 > N_ref -
+000139 1764 cp r22, r20 ; (numM:numL) (denH:denL)
+00013a 0775 cpc r23, r21
+00013b f038 brlo CALIB_DIV_DONE
+
+ CALIB_DIV_SUB:
+00013c 1b64 sub r22, r20
+00013d 0b75 sbc r23, r21
+00013e 0927 sbc r18, C00
+00013f 9583 inc r24
+000140 f7b1 brne CALIB_DIV_LOOP
+000141 9593 inc r25
+000142 cff4 rjmp CALIB_DIV_LOOP
+
+ CALIB_DIV_DONE:
+000143 5081 subi r24, 1 ; ICR1 = quotient - 1
+000144 4090 sbci r25, 0
+
+000145 2399 tst r25 ; 1
+000146 f411 brne CALIB_END ; - ,
+
+000147 2fc8 mov r28, r24 ; ICR1
+000148 9400 com r0 ; (r0 0 -> 0xFF)
+
+ CALIB_END:
+ ; ===== =====
+
+000149 ea02 ldi r16,0xA2
+00014a 9300 0080 sts TCCR1A,r16
+00014c e109 ldi r16,0x19
+00014d 9300 0081 sts TCCR1B,r16
+
+ #if INT_32MHz == 1
+ #elif INT_37MHz == 1
+00014f ea2d ldi r18, 0xAD
+ #elif EXT_40MHz == 1
+ #elif EXT_48MHz == 1
+ #elif EXT_50MHz == 1
+ #endif
+000150 2000 tst r0 ; -
+000151 f009 breq NO_CALIBRATION
+000152 2f2c mov r18, r28
+ NO_CALIBRATION:
+000153 9270 0087 sts ICR1H,C00
+000155 9320 0086 sts ICR1L,r18 ; set PWM speed
+ ; ICR1L value formula (32000000/109375/2 - 1) where 32000000 = 32MHz - AVR oscillator frequency
+ ; 109375 is for 1.75 MHz version, formula is (PSG frequency / 16) e.g. for 2MHz it is 2000000/16 = 125000
+
+ ; set INT0,INT1 ============================================
+000157 e00f ldi r16, (1<=0)
+000181 9030 0116 lds CntN,AY0_REG06 ; init noise period counter with value in AY register 6
+000183 9150 0316 lds TMP,AY1_REG06
+000185 1635 cp CntN, TMP
+000186 f40c brge LESS
+000187 2e35 mov CntN, TMP
+ LESS:
+000188 943a dec CntN
+000189 9466 lsr NoiseAddon
+00018a 2c6e mov NoiseAddon,RNGL
+00018b 94f7 ror RNGH
+00018c 94e7 ror RNGL
+00018d 6338 ori TNLevel_AY0,0x38 ; set noise bitsP
+00018e 6308 ori TNLevel_AY1,0x38 ; set noise bitsP
+00018f fee0 sbrs RNGL,b0
+000190 7c37 andi TNLevel_AY0,0xC7 ; reset noise bits
+000191 fee0 sbrs RNGL,b0
+000192 7c07 andi TNLevel_AY1,0xC7 ; reset noise bits
+000193 0c66 lsl NoiseAddon
+000194 246e eor NoiseAddon,RNGL
+000195 9466 lsr NoiseAddon
+ NOISE_GENERATOR_END:
+
+ ;============================================
+ ;=======ENVELOPE_GENERATOR_AY0===============
+ ;============================================
+000196 ff37 sbrs TNLevel_AY0, b7
+000197 c006 rjmp NO_ENVELOPE_CHANGED_AY0
+
+ ; initialize envelope generator
+000198 91c0 011d lds YL, AY0_REG13
+00019a 8898 ldd TabE_AY0, Y+0x10
+00019b e12f ldi TabP_AY0, 0x1F
+00019c 773f andi TNLevel_AY0, 0x7F
+00019d c00c rjmp E_NEXT_STEP_AY0
+
+ NO_ENVELOPE_CHANGED_AY0:
+00019e fc97 sbrc TabE_AY0, b7
+00019f c013 rjmp ENVELOPE_GENERATOR_END_AY0
+0001a0 9701 sbiw CntEL_AY0, 0x01
+0001a1 f00c brlt E_NEXT_PERIOD_AY0
+0001a2 f481 brne ENVELOPE_GENERATOR_END_AY0
+
+ E_NEXT_PERIOD_AY0:
+0001a3 952a dec TabP_AY0
+0001a4 f42a brpl E_NEXT_STEP_AY0
+0001a5 e12f ldi TabP_AY0, 0x1F
+0001a6 fc91 sbrc TabE_AY0, b1
+0001a7 269f eor TabE_AY0, ZH
+0001a8 fc92 sbrc TabE_AY0, b2
+0001a9 2898 or TabE_AY0, CC0
+
+ E_NEXT_STEP_AY0:
+0001aa 9180 011b lds CntEL_AY0, AY0_REG11
+0001ac 9190 011c lds CntEH_AY0, AY0_REG12
+0001ae 2fc2 mov YL, TabP_AY0
+0001af e15f ldi TMP, 0x1F
+0001b0 fe90 sbrs TabE_AY0, b0
+0001b1 27c5 eor YL, TMP
+0001b2 a8c8 ldd EVal_AY0, Y+0x30
+
+ ENVELOPE_GENERATOR_END_AY0:
+
+ ;============================================
+ ;=======ENVELOPE_GENERATOR_AY1===============
+ ;============================================
+0001b3 ff07 sbrs TNLevel_AY1, b7
+0001b4 c006 rjmp NO_ENVELOPE_CHANGED_AY1
+
+ ;initialize_envelope_generator_AY1:
+0001b5 91c0 031d lds YL, AY1_REG13
+0001b7 8968 ldd TabE_AY1, Y+0x10
+0001b8 e17f ldi TabP_AY1, 0x1F
+0001b9 770f andi TNLevel_AY1, 0x7F
+0001ba c00c rjmp E_NEXT_STEP_AY1
+
+ NO_ENVELOPE_CHANGED_AY1:
+0001bb fd67 sbrc TabE_AY1, b7
+0001bc c013 rjmp ENVELOPE_GENERATOR_END_AY1
+0001bd 9711 sbiw CntEL_AY1, 0x01
+0001be f00c brlt E_NEXT_PERIOD_AY1
+0001bf f481 brne ENVELOPE_GENERATOR_END_AY1
+
+ E_NEXT_PERIOD_AY1:
+0001c0 957a dec TabP_AY1
+0001c1 f42a brpl E_NEXT_STEP_AY1
+0001c2 e17f ldi TabP_AY1, 0x1F
+0001c3 fd61 sbrc TabE_AY1, b1
+0001c4 276f eor TabE_AY1, ZH
+0001c5 fd62 sbrc TabE_AY1, b2
+0001c6 2968 or TabE_AY1, CC0
+
+ E_NEXT_STEP_AY1:
+0001c7 91a0 031b lds CntEL_AY1, AY1_REG11
+0001c9 91b0 031c lds CntEH_AY1, AY1_REG12
+0001cb 2fc7 mov YL, TabP_AY1
+0001cc e15f ldi TMP, 0x1F
+0001cd ff60 sbrs TabE_AY1, b0
+0001ce 27c5 eor YL, TMP
+0001cf a8b8 ldd EVal_AY1, Y+0x30
+
+ ENVELOPE_GENERATOR_END_AY1:
+
+0001d0 9bf1 sbis CHIP_SELECTED, b1
+0001d1 c02c rjmp GENERATORS_AY1
+
+ ;============================================
+ ;=======TONE_GENERATOR_AY0===============
+ ;============================================
+ ; Channel A
+0001d2 e2d1 ldi YH, 0x21
+0001d3 e6c0 ldi YL, low(AY0_CntAL)
+0001d4 8008 ld r0, Y
+0001d5 92d0 0021 sts 0x21, C21
+0001d7 9b01 sbis 0x00, 1
+0001d8 c005 rjmp CH_A_NO_CHANGE_AY0
+0001d9 e1c0 ldi YL, low(AY0_REG00)
+0001da 8008 ld r0, Y
+0001db 92d0 0021 sts 0x21, C21
+0001dd 273f eor TNLevel_AY0, ZH
+ CH_A_NO_CHANGE_AY0:
+0001de e6c0 ldi YL, low(AY0_CntAL)
+0001df 8228 st Y, r2
+
+ ; Channel B
+0001e0 e6c2 ldi YL, low(AY0_CntBL)
+0001e1 8008 ld r0, Y
+0001e2 92d0 0021 sts 0x21, C21
+0001e4 9b01 sbis 0x00, 1
+0001e5 c006 rjmp CH_B_NO_CHANGE_AY0
+0001e6 e1c2 ldi YL, low(AY0_REG02)
+0001e7 8008 ld r0, Y
+0001e8 92d0 0021 sts 0x21, C21
+0001ea e052 ldi TMP, 0x02
+0001eb 2735 eor TNLevel_AY0, TMP
+ CH_B_NO_CHANGE_AY0:
+0001ec e6c2 ldi YL, low(AY0_CntBL)
+0001ed 8228 st Y, r2
+
+ ; Channel C
+0001ee e6c4 ldi YL, low(AY0_CntCL)
+0001ef 8008 ld r0, Y
+0001f0 92d0 0021 sts 0x21, C21
+0001f2 9b01 sbis 0x00, 1
+0001f3 c006 rjmp CH_C_NO_CHANGE_AY0
+0001f4 e1c4 ldi YL, low(AY0_REG04)
+0001f5 8008 ld r0, Y
+0001f6 92d0 0021 sts 0x21, C21
+0001f8 e054 ldi TMP, 0x04
+0001f9 2735 eor TNLevel_AY0, TMP
+ CH_C_NO_CHANGE_AY0:
+0001fa e6c4 ldi YL, low(AY0_CntCL)
+0001fb 8228 st Y, r2
+0001fc 98f1 cbi CHIP_SELECTED, b1
+0001fd c031 rjmp GENERATORS_END
+
+ GENERATORS_AY1:
+
+ ;============================================
+ ;=======TONE_GENERATOR_AY1===============
+ ;============================================
+0001fe e2d1 ldi YH, 0x21
+
+ ; Channel A
+0001ff e6c6 ldi YL, low(AY1_CntAL)
+000200 8008 ld r0, Y
+000201 92d0 0021 sts 0x21, C21
+000203 9b01 sbis 0x00, 1
+000204 c007 rjmp CH_A_NO_CHANGE_AY1
+000205 e2d3 ldi YH, 0x23
+000206 e1c0 ldi YL, low(AY1_REG00)
+000207 8008 ld r0, Y
+000208 92d0 0021 sts 0x21, C21
+00020a 270f eor TNLevel_AY1, ZH
+00020b e2d1 ldi YH, 0x21
+ CH_A_NO_CHANGE_AY1:
+00020c e6c6 ldi YL, low(AY1_CntAL)
+00020d 8228 st Y, r2
+
+ ; Channel B
+00020e e6c8 ldi YL, low(AY1_CntBL)
+00020f 8008 ld r0, Y
+000210 92d0 0021 sts 0x21, C21
+000212 9b01 sbis 0x00, 1
+000213 c008 rjmp CH_B_NO_CHANGE_AY1
+000214 e2d3 ldi YH, 0x23
+000215 e1c2 ldi YL, low(AY1_REG02)
+000216 8008 ld r0, Y
+000217 92d0 0021 sts 0x21, C21
+000219 e052 ldi TMP, 0x02
+00021a 2705 eor TNLevel_AY1, TMP
+00021b e2d1 ldi YH, 0x21
+ CH_B_NO_CHANGE_AY1:
+00021c e6c8 ldi YL, low(AY1_CntBL)
+00021d 8228 st Y, r2
+
+ ; Channel C
+00021e e6ca ldi YL, low(AY1_CntCL)
+00021f 8008 ld r0, Y
+000220 92d0 0021 sts 0x21, C21
+000222 9b01 sbis 0x00, 1
+000223 c008 rjmp CH_C_NO_CHANGE_AY1
+000224 e2d3 ldi YH, 0x23
+000225 e1c4 ldi YL, low(AY1_REG04)
+000226 8008 ld r0, Y
+000227 92d0 0021 sts 0x21, C21
+000229 e054 ldi TMP, 0x04
+00022a 2705 eor TNLevel_AY1,TMP
+00022b e2d1 ldi YH, 0x21
+ CH_C_NO_CHANGE_AY1:
+00022c e6ca ldi YL, low(AY1_CntCL)
+00022d 8228 st Y, r2
+00022e 9af1 sbi CHIP_SELECTED, b1
+
+ GENERATORS_END:
+
+ ; === MIXER AY 0===
+00022f 9150 0117 lds TMP, AY0_REG07
+000231 2b53 or TMP, TNLevel_AY0
+000232 2fc5 mov YL, TMP
+000233 0fcc lsl YL
+000234 95c2 swap YL
+000235 235c and TMP, YL
+
+ ; === AMPLITUDE CONTROL AY0===
+000236 e0d2 ldi YH, 0x02
+
+ ; Channel A
+000237 91c0 0118 lds YL, AY0_REG08
+000239 2c0c mov OutA0, EVal_AY0
+00023a ffc4 sbrs YL, b4
+00023b a008 ldd OutA0, Y+0x20
+00023c ff50 sbrs TMP, b0
+00023d 2400 clr OutA0
+
+ ; Channel B
+00023e 91c0 0119 lds YL, AY0_REG09
+000240 2c4c mov OutB, EVal_AY0
+000241 ffc4 sbrs YL, b4
+000242 a048 ldd OutB, Y+0x20
+000243 ff51 sbrs TMP, b1
+000244 2444 clr OutB
+
+ ; Channel C
+000245 91c0 011a lds YL, AY0_REG10
+000247 2c1c mov OutC0, EVal_AY0
+000248 ffc4 sbrs YL, b4
+000249 a018 ldd OutC0, Y+0x20
+00024a ff52 sbrs TMP, b2
+00024b 2411 clr OutC0
+
+ ; Mix channels
+00024c 2dc4 mov YL, OutB
+00024d 9446 lsr OutB
+00024e 9446 lsr OutB
+00024f 19c4 sub YL, OutB
+000250 9446 lsr OutB
+000251 19c4 sub YL, OutB
+000252 0e0c add OutA0, YL
+000253 0e1c add OutC0, YL
+
+ ; === MIXER AY 1===
+000254 9150 0317 lds TMP, AY1_REG07
+000256 2b50 or TMP, TNLevel_AY1
+000257 2fc5 mov YL, TMP
+000258 0fcc lsl YL
+000259 95c2 swap YL
+00025a 235c and TMP, YL
+
+ ; === AMPLITUDE CONTROL AY1===
+
+ ; Channel A
+00025b 91c0 0318 lds YL, AY1_REG08
+00025d 2c2b mov OutA1, EVal_AY1
+00025e ffc4 sbrs YL, b4
+00025f a028 ldd OutA1, Y+0x20
+000260 ff50 sbrs TMP, b0
+000261 2422 clr OutA1
+
+ ; Channel B
+000262 91c0 0319 lds YL, AY1_REG09
+000264 2c4b mov OutB, EVal_AY1
+000265 ffc4 sbrs YL, b4
+000266 a048 ldd OutB, Y+0x20
+000267 ff51 sbrs TMP, b1
+000268 2444 clr OutB
+
+ ; Channel C
+000269 91c0 031a lds YL, AY1_REG10
+00026b 2cab mov OutC1, EVal_AY1
+00026c ffc4 sbrs YL, b4
+00026d a0a8 ldd OutC1, Y+0x20
+00026e ff52 sbrs TMP, b2
+00026f 24aa clr OutC1
+
+ ; Mix channels
+000270 2dc4 mov YL, OutB
+000271 9446 lsr OutB
+000272 9446 lsr OutB
+000273 19c4 sub YL, OutB
+000274 9446 lsr OutB
+000275 19c4 sub YL, OutB
+000276 0e2c add OutA1, YL
+000277 0eac add OutC1, YL
+
+ ; === AY0 AY1 ===
+000278 0c02 add OutA0, OutA1
+000279 0c1a add OutC0, OutC1
+
+00027a 9200 0088 sts OCR1AL, OutA0
+00027c 9210 008a sts OCR1BL, OutC0
+00027e cefc rjmp _MAIN_LOOP
+ // MAIN LOOP END ====================================================================
+
+ // copy routine from flash to SRAM
+ _COPY:
+00027f 9105 lpm r16,Z+
+000280 930d st X+,r16
+000281 952a dec r18
+000282 f7e1 brne _COPY
+000283 9508 ret
+
+ /////////////////////////////////////////////////////////////////
+ /// AY REGISTERS IN SRAM
+ /////////////////////////////////////////////////////////////////
+ .dseg
+ .org 0x0110
+ ; AY
+ AY0_REG00:
+000110 .byte 1
+ AY0_REG01:
+000111 .byte 1
+ AY0_REG02:
+000112 .byte 1
+ AY0_REG03:
+000113 .byte 1
+ AY0_REG04:
+000114 .byte 1
+ AY0_REG05:
+000115 .byte 1
+ AY0_REG06:
+000116 .byte 1
+ AY0_REG07:
+000117 .byte 1
+ AY0_REG08:
+000118 .byte 1
+ AY0_REG09:
+000119 .byte 1
+ AY0_REG10:
+00011a .byte 1
+ AY0_REG11:
+00011b .byte 1
+ AY0_REG12:
+00011c .byte 1
+ AY0_REG13:
+00011d .byte 1
+ AY0_REG14:
+00011e .byte 1
+ AY0_REG15:
+00011f .byte 1
+
+ .org 0x0260
+ ; AY0
+000260 AY0_CntAL: .byte 1
+000261 AY0_CntAH: .byte 1
+000262 AY0_CntBL: .byte 1
+000263 AY0_CntBH: .byte 1
+000264 AY0_CntCL: .byte 1
+000265 AY0_CntCH: .byte 1
+
+ ; AY1
+000266 AY1_CntAL: .byte 1
+000267 AY1_CntAH: .byte 1
+000268 AY1_CntBL: .byte 1
+000269 AY1_CntBH: .byte 1
+00026a AY1_CntCL: .byte 1
+00026b AY1_CntCH: .byte 1
+
+00026c ConstL: .byte 1
+00026d ConstH: .byte 1
+
+ ; AY
+ .org 0x0310
+ AY1_REG00:
+000310 .byte 1
+ AY1_REG01:
+000311 .byte 1
+ AY1_REG02:
+000312 .byte 1
+ AY1_REG03:
+000313 .byte 1
+ AY1_REG04:
+000314 .byte 1
+ AY1_REG05:
+000315 .byte 1
+ AY1_REG06:
+000316 .byte 1
+ AY1_REG07:
+000317 .byte 1
+ AY1_REG08:
+000318 .byte 1
+ AY1_REG09:
+000319 .byte 1
+ AY1_REG10:
+00031a .byte 1
+ AY1_REG11:
+00031b .byte 1
+ AY1_REG12:
+00031c .byte 1
+ AY1_REG13:
+00031d .byte 1
+ AY1_REG14:
+00031e .byte 1
+ AY1_REG15:
+00031f .byte 1
+
+
+RESOURCE USE INFORMATION
+------------------------
+
+Notice:
+The register and instruction counts are symbol table hit counts,
+and hence implicitly used resources are not counted, eg, the
+'lpm' instruction without operands implicitly uses r0 and z,
+none of which are counted.
+
+x,y,z are separate entities in the symbol table and are
+counted separately from r26..r31 here.
+
+.dseg memory usage only counts static data declared with .byte
+
+"ATmega328P" register use summary:
+x : 1 y : 31 z : 20 r0 : 22 r1 : 8 r2 : 12 r3 : 6 r4 : 19
+r5 : 13 r6 : 6 r7 : 16 r8 : 10 r9 : 8 r10: 6 r11: 5 r12: 5
+r13: 13 r14: 5 r15: 2 r16: 94 r17: 11 r18: 23 r19: 10 r20: 14
+r21: 34 r22: 12 r23: 9 r24: 7 r25: 6 r26: 12 r27: 8 r28: 60
+r29: 13 r30: 17 r31: 22
+Registers used: 35 out of 35 (100.0%)
+
+"ATmega328P" instruction use summary:
+.lds : 0 .sts : 0 adc : 2 add : 7 adiw : 0 and : 5
+andi : 6 asr : 0 bclr : 0 bld : 0 brbc : 0 brbs : 0
+brcc : 0 brcs : 0 break : 0 breq : 6 brge : 1 brhc : 0
+brhs : 0 brid : 0 brie : 0 brlo : 1 brlt : 2 brmi : 0
+brne : 13 brpl : 3 brsh : 0 brtc : 0 brts : 0 brvc : 0
+brvs : 0 bset : 0 bst : 0 call : 0 cbi : 5 cbr : 0
+clc : 0 clh : 0 cli : 1 cln : 0 clr : 36 cls : 0
+clt : 0 clv : 0 clz : 0 com : 2 cp : 2 cpc : 1
+cpi : 5 cpse : 0 dec : 9 eor : 11 fmul : 0 fmuls : 0
+fmulsu: 0 icall : 0 ijmp : 0 in : 7 inc : 2 jmp : 0
+ld : 14 ldd : 18 ldi : 115 lds : 18 lpm : 1 lsl : 3
+lsr : 9 mov : 28 movw : 0 mul : 0 muls : 0 mulsu : 0
+neg : 0 nop : 0 or : 5 ori : 4 out : 19 pop : 0
+push : 0 rcall : 4 ret : 1 reti : 2 rjmp : 39 rol : 0
+ror : 3 sbc : 2 sbci : 1 sbi : 5 sbic : 9 sbis : 8
+sbiw : 3 sbr : 1 sbrc : 6 sbrs : 20 sec : 0 seh : 0
+sei : 1 sen : 0 ser : 0 ses : 0 set : 0 sev : 0
+sez : 0 sleep : 0 spm : 0 st : 11 std : 8 sts : 43
+sub : 5 subi : 1 swap : 2 tst : 5 wdr : 0
+Instructions used: 54 out of 113 (47.8%)
+
+"ATmega328P" memory use summary [bytes]:
+Segment Begin End Code Data Used Size Use%
+---------------------------------------------------------------
+[.cseg] 0x000000 0x000508 1204 80 1284 32768 3.9%
+[.dseg] 0x000100 0x000320 0 46 46 2048 2.2%
+[.eseg] 0x000000 0x000000 0 0 0 1024 0.0%
+
+Assembly complete, 0 errors, 3 warnings
diff --git a/Sources/AY_Emu/AY_Emu/Release/AY_Emu.map b/Sources/AY_Emu/AY_Emu/Release/AY_Emu.map
new file mode 100644
index 0000000..ef02220
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/AY_Emu.map
@@ -0,0 +1,909 @@
+
+AVRASM ver. 2.2.7 D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm Wed Aug 19 17:36:34 2026
+
+
+EQU SIGNATURE_000 0000001e
+EQU SIGNATURE_001 00000095
+EQU SIGNATURE_002 0000000f
+EQU UDR0 000000c6
+EQU UBRR0L 000000c4
+EQU UBRR0H 000000c5
+EQU UCSR0C 000000c2
+EQU UCSR0B 000000c1
+EQU UCSR0A 000000c0
+EQU TWAMR 000000bd
+EQU TWCR 000000bc
+EQU TWDR 000000bb
+EQU TWAR 000000ba
+EQU TWSR 000000b9
+EQU TWBR 000000b8
+EQU ASSR 000000b6
+EQU OCR2B 000000b4
+EQU OCR2A 000000b3
+EQU TCNT2 000000b2
+EQU TCCR2B 000000b1
+EQU TCCR2A 000000b0
+EQU OCR1BL 0000008a
+EQU OCR1BH 0000008b
+EQU OCR1AL 00000088
+EQU OCR1AH 00000089
+EQU ICR1L 00000086
+EQU ICR1H 00000087
+EQU TCNT1L 00000084
+EQU TCNT1H 00000085
+EQU TCCR1C 00000082
+EQU TCCR1B 00000081
+EQU TCCR1A 00000080
+EQU DIDR1 0000007f
+EQU DIDR0 0000007e
+EQU ADMUX 0000007c
+EQU ADCSRB 0000007b
+EQU ADCSRA 0000007a
+EQU ADCH 00000079
+EQU ADCL 00000078
+EQU TIMSK2 00000070
+EQU TIMSK1 0000006f
+EQU TIMSK0 0000006e
+EQU PCMSK1 0000006c
+EQU PCMSK2 0000006d
+EQU PCMSK0 0000006b
+EQU EICRA 00000069
+EQU PCICR 00000068
+EQU OSCCAL 00000066
+EQU PRR 00000064
+EQU CLKPR 00000061
+EQU WDTCSR 00000060
+EQU SREG 0000003f
+EQU SPL 0000003d
+EQU SPH 0000003e
+EQU SPMCSR 00000037
+EQU MCUCR 00000035
+EQU MCUSR 00000034
+EQU SMCR 00000033
+EQU ACSR 00000030
+EQU SPDR 0000002e
+EQU SPSR 0000002d
+EQU SPCR 0000002c
+EQU GPIOR2 0000002b
+EQU GPIOR1 0000002a
+EQU OCR0B 00000028
+EQU OCR0A 00000027
+EQU TCNT0 00000026
+EQU TCCR0B 00000025
+EQU TCCR0A 00000024
+EQU GTCCR 00000023
+EQU EEARH 00000022
+EQU EEARL 00000021
+EQU EEDR 00000020
+EQU EECR 0000001f
+EQU GPIOR0 0000001e
+EQU EIMSK 0000001d
+EQU EIFR 0000001c
+EQU PCIFR 0000001b
+EQU TIFR2 00000017
+EQU TIFR1 00000016
+EQU TIFR0 00000015
+EQU PORTD 0000000b
+EQU DDRD 0000000a
+EQU PIND 00000009
+EQU PORTC 00000008
+EQU DDRC 00000007
+EQU PINC 00000006
+EQU PORTB 00000005
+EQU DDRB 00000004
+EQU PINB 00000003
+EQU UDR0_0 00000000
+EQU UDR0_1 00000001
+EQU UDR0_2 00000002
+EQU UDR0_3 00000003
+EQU UDR0_4 00000004
+EQU UDR0_5 00000005
+EQU UDR0_6 00000006
+EQU UDR0_7 00000007
+EQU MPCM0 00000000
+EQU U2X0 00000001
+EQU UPE0 00000002
+EQU DOR0 00000003
+EQU FE0 00000004
+EQU UDRE0 00000005
+EQU TXC0 00000006
+EQU RXC0 00000007
+EQU TXB80 00000000
+EQU RXB80 00000001
+EQU UCSZ02 00000002
+EQU TXEN0 00000003
+EQU RXEN0 00000004
+EQU UDRIE0 00000005
+EQU TXCIE0 00000006
+EQU RXCIE0 00000007
+EQU UCPOL0 00000000
+EQU UCSZ00 00000001
+EQU UCPHA0 00000001
+EQU UCSZ01 00000002
+EQU UDORD0 00000002
+EQU USBS0 00000003
+EQU UPM00 00000004
+EQU UPM01 00000005
+EQU UMSEL00 00000006
+EQU UMSEL0 00000006
+EQU UMSEL01 00000007
+EQU UMSEL1 00000007
+EQU UBRR8 00000000
+EQU UBRR9 00000001
+EQU UBRR10 00000002
+EQU UBRR11 00000003
+EQU _UBRR0 00000000
+EQU _UBRR1 00000001
+EQU UBRR2 00000002
+EQU UBRR3 00000003
+EQU UBRR4 00000004
+EQU UBRR5 00000005
+EQU UBRR6 00000006
+EQU UBRR7 00000007
+EQU TWAM0 00000001
+EQU TWAMR0 00000001
+EQU TWAM1 00000002
+EQU TWAMR1 00000002
+EQU TWAM2 00000003
+EQU TWAMR2 00000003
+EQU TWAM3 00000004
+EQU TWAMR3 00000004
+EQU TWAM4 00000005
+EQU TWAMR4 00000005
+EQU TWAM5 00000006
+EQU TWAMR5 00000006
+EQU TWAM6 00000007
+EQU TWAMR6 00000007
+EQU TWBR0 00000000
+EQU TWBR1 00000001
+EQU TWBR2 00000002
+EQU TWBR3 00000003
+EQU TWBR4 00000004
+EQU TWBR5 00000005
+EQU TWBR6 00000006
+EQU TWBR7 00000007
+EQU TWIE 00000000
+EQU TWEN 00000002
+EQU TWWC 00000003
+EQU TWSTO 00000004
+EQU TWSTA 00000005
+EQU TWEA 00000006
+EQU TWINT 00000007
+EQU TWPS0 00000000
+EQU TWPS1 00000001
+EQU TWS3 00000003
+EQU TWS4 00000004
+EQU TWS5 00000005
+EQU TWS6 00000006
+EQU TWS7 00000007
+EQU TWD0 00000000
+EQU TWD1 00000001
+EQU TWD2 00000002
+EQU TWD3 00000003
+EQU TWD4 00000004
+EQU TWD5 00000005
+EQU TWD6 00000006
+EQU TWD7 00000007
+EQU TWGCE 00000000
+EQU TWA0 00000001
+EQU TWA1 00000002
+EQU TWA2 00000003
+EQU TWA3 00000004
+EQU TWA4 00000005
+EQU TWA5 00000006
+EQU TWA6 00000007
+EQU TOIE1 00000000
+EQU OCIE1A 00000001
+EQU OCIE1B 00000002
+EQU ICIE1 00000005
+EQU TOV1 00000000
+EQU OCF1A 00000001
+EQU OCF1B 00000002
+EQU ICF1 00000005
+EQU WGM10 00000000
+EQU WGM11 00000001
+EQU COM1B0 00000004
+EQU COM1B1 00000005
+EQU COM1A0 00000006
+EQU COM1A1 00000007
+EQU CS10 00000000
+EQU CS11 00000001
+EQU CS12 00000002
+EQU WGM12 00000003
+EQU WGM13 00000004
+EQU ICES1 00000006
+EQU ICNC1 00000007
+EQU FOC1B 00000006
+EQU FOC1A 00000007
+EQU PSRSYNC 00000000
+EQU TSM 00000007
+EQU TOIE2 00000000
+EQU TOIE2A 00000000
+EQU OCIE2A 00000001
+EQU OCIE2B 00000002
+EQU TOV2 00000000
+EQU OCF2A 00000001
+EQU OCF2B 00000002
+EQU WGM20 00000000
+EQU WGM21 00000001
+EQU COM2B0 00000004
+EQU COM2B1 00000005
+EQU COM2A0 00000006
+EQU COM2A1 00000007
+EQU CS20 00000000
+EQU CS21 00000001
+EQU CS22 00000002
+EQU WGM22 00000003
+EQU FOC2B 00000006
+EQU FOC2A 00000007
+EQU TCNT2_0 00000000
+EQU TCNT2_1 00000001
+EQU TCNT2_2 00000002
+EQU TCNT2_3 00000003
+EQU TCNT2_4 00000004
+EQU TCNT2_5 00000005
+EQU TCNT2_6 00000006
+EQU TCNT2_7 00000007
+EQU OCR2A_0 00000000
+EQU OCR2A_1 00000001
+EQU OCR2A_2 00000002
+EQU OCR2A_3 00000003
+EQU OCR2A_4 00000004
+EQU OCR2A_5 00000005
+EQU OCR2A_6 00000006
+EQU OCR2A_7 00000007
+EQU OCR2B_0 00000000
+EQU OCR2B_1 00000001
+EQU OCR2B_2 00000002
+EQU OCR2B_3 00000003
+EQU OCR2B_4 00000004
+EQU OCR2B_5 00000005
+EQU OCR2B_6 00000006
+EQU OCR2B_7 00000007
+EQU TCR2BUB 00000000
+EQU TCR2AUB 00000001
+EQU OCR2BUB 00000002
+EQU OCR2AUB 00000003
+EQU TCN2UB 00000004
+EQU AS2 00000005
+EQU EXCLK 00000006
+EQU PSRASY 00000001
+EQU PSR2 00000001
+EQU MUX0 00000000
+EQU MUX1 00000001
+EQU MUX2 00000002
+EQU MUX3 00000003
+EQU ADLAR 00000005
+EQU REFS0 00000006
+EQU REFS1 00000007
+EQU ADPS0 00000000
+EQU ADPS1 00000001
+EQU ADPS2 00000002
+EQU ADIE 00000003
+EQU ADIF 00000004
+EQU ADATE 00000005
+EQU ADSC 00000006
+EQU ADEN 00000007
+EQU ADTS0 00000000
+EQU ADTS1 00000001
+EQU ADTS2 00000002
+EQU ACME 00000006
+EQU ADCH0 00000000
+EQU ADCH1 00000001
+EQU ADCH2 00000002
+EQU ADCH3 00000003
+EQU ADCH4 00000004
+EQU ADCH5 00000005
+EQU ADCH6 00000006
+EQU ADCH7 00000007
+EQU ADCL0 00000000
+EQU ADCL1 00000001
+EQU ADCL2 00000002
+EQU ADCL3 00000003
+EQU ADCL4 00000004
+EQU ADCL5 00000005
+EQU ADCL6 00000006
+EQU ADCL7 00000007
+EQU ADC0D 00000000
+EQU ADC1D 00000001
+EQU ADC2D 00000002
+EQU ADC3D 00000003
+EQU ADC4D 00000004
+EQU ADC5D 00000005
+EQU ACIS0 00000000
+EQU ACIS1 00000001
+EQU ACIC 00000002
+EQU ACIE 00000003
+EQU ACI 00000004
+EQU ACO 00000005
+EQU ACBG 00000006
+EQU ACD 00000007
+EQU AIN0D 00000000
+EQU AIN1D 00000001
+EQU PORTB0 00000000
+EQU PB0 00000000
+EQU PORTB1 00000001
+EQU PB1 00000001
+EQU PORTB2 00000002
+EQU PB2 00000002
+EQU PORTB3 00000003
+EQU PB3 00000003
+EQU PORTB4 00000004
+EQU PB4 00000004
+EQU PORTB5 00000005
+EQU PB5 00000005
+EQU PORTB6 00000006
+EQU PB6 00000006
+EQU PORTB7 00000007
+EQU PB7 00000007
+EQU DDB0 00000000
+EQU DDB1 00000001
+EQU DDB2 00000002
+EQU DDB3 00000003
+EQU DDB4 00000004
+EQU DDB5 00000005
+EQU DDB6 00000006
+EQU DDB7 00000007
+EQU PINB0 00000000
+EQU PINB1 00000001
+EQU PINB2 00000002
+EQU PINB3 00000003
+EQU PINB4 00000004
+EQU PINB5 00000005
+EQU PINB6 00000006
+EQU PINB7 00000007
+EQU PORTC0 00000000
+EQU PC0 00000000
+EQU PORTC1 00000001
+EQU PC1 00000001
+EQU PORTC2 00000002
+EQU PC2 00000002
+EQU PORTC3 00000003
+EQU PC3 00000003
+EQU PORTC4 00000004
+EQU PC4 00000004
+EQU PORTC5 00000005
+EQU PC5 00000005
+EQU PORTC6 00000006
+EQU PC6 00000006
+EQU DDC0 00000000
+EQU DDC1 00000001
+EQU DDC2 00000002
+EQU DDC3 00000003
+EQU DDC4 00000004
+EQU DDC5 00000005
+EQU DDC6 00000006
+EQU PINC0 00000000
+EQU PINC1 00000001
+EQU PINC2 00000002
+EQU PINC3 00000003
+EQU PINC4 00000004
+EQU PINC5 00000005
+EQU PINC6 00000006
+EQU PORTD0 00000000
+EQU PD0 00000000
+EQU PORTD1 00000001
+EQU PD1 00000001
+EQU PORTD2 00000002
+EQU PD2 00000002
+EQU PORTD3 00000003
+EQU PD3 00000003
+EQU PORTD4 00000004
+EQU PD4 00000004
+EQU PORTD5 00000005
+EQU PD5 00000005
+EQU PORTD6 00000006
+EQU PD6 00000006
+EQU PORTD7 00000007
+EQU PD7 00000007
+EQU DDD0 00000000
+EQU DDD1 00000001
+EQU DDD2 00000002
+EQU DDD3 00000003
+EQU DDD4 00000004
+EQU DDD5 00000005
+EQU DDD6 00000006
+EQU DDD7 00000007
+EQU PIND0 00000000
+EQU PIND1 00000001
+EQU PIND2 00000002
+EQU PIND3 00000003
+EQU PIND4 00000004
+EQU PIND5 00000005
+EQU PIND6 00000006
+EQU PIND7 00000007
+EQU TOIE0 00000000
+EQU OCIE0A 00000001
+EQU OCIE0B 00000002
+EQU TOV0 00000000
+EQU OCF0A 00000001
+EQU OCF0B 00000002
+EQU WGM00 00000000
+EQU WGM01 00000001
+EQU COM0B0 00000004
+EQU COM0B1 00000005
+EQU COM0A0 00000006
+EQU COM0A1 00000007
+EQU CS00 00000000
+EQU CS01 00000001
+EQU CS02 00000002
+EQU WGM02 00000003
+EQU FOC0B 00000006
+EQU FOC0A 00000007
+EQU TCNT0_0 00000000
+EQU TCNT0_1 00000001
+EQU TCNT0_2 00000002
+EQU TCNT0_3 00000003
+EQU TCNT0_4 00000004
+EQU TCNT0_5 00000005
+EQU TCNT0_6 00000006
+EQU TCNT0_7 00000007
+EQU OCR0A_0 00000000
+EQU OCR0A_1 00000001
+EQU OCR0A_2 00000002
+EQU OCR0A_3 00000003
+EQU OCR0A_4 00000004
+EQU OCR0A_5 00000005
+EQU OCR0A_6 00000006
+EQU OCR0A_7 00000007
+EQU OCR0B_0 00000000
+EQU OCR0B_1 00000001
+EQU OCR0B_2 00000002
+EQU OCR0B_3 00000003
+EQU OCR0B_4 00000004
+EQU OCR0B_5 00000005
+EQU OCR0B_6 00000006
+EQU OCR0B_7 00000007
+EQU PSR10 00000000
+EQU ISC00 00000000
+EQU ISC01 00000001
+EQU ISC10 00000002
+EQU ISC11 00000003
+EQU INT0 00000000
+EQU INT1 00000001
+EQU INTF0 00000000
+EQU INTF1 00000001
+EQU PCIE0 00000000
+EQU PCIE1 00000001
+EQU PCIE2 00000002
+EQU PCINT16 00000000
+EQU PCINT17 00000001
+EQU PCINT18 00000002
+EQU PCINT19 00000003
+EQU PCINT20 00000004
+EQU PCINT21 00000005
+EQU PCINT22 00000006
+EQU PCINT23 00000007
+EQU PCINT8 00000000
+EQU PCINT9 00000001
+EQU PCINT10 00000002
+EQU PCINT11 00000003
+EQU PCINT12 00000004
+EQU PCINT13 00000005
+EQU PCINT14 00000006
+EQU PCINT0 00000000
+EQU PCINT1 00000001
+EQU PCINT2 00000002
+EQU PCINT3 00000003
+EQU PCINT4 00000004
+EQU PCINT5 00000005
+EQU PCINT6 00000006
+EQU PCINT7 00000007
+EQU PCIF0 00000000
+EQU PCIF1 00000001
+EQU PCIF2 00000002
+EQU SPDR0 00000000
+EQU SPDR1 00000001
+EQU SPDR2 00000002
+EQU SPDR3 00000003
+EQU SPDR4 00000004
+EQU SPDR5 00000005
+EQU SPDR6 00000006
+EQU SPDR7 00000007
+EQU SPI2X 00000000
+EQU WCOL 00000006
+EQU SPIF 00000007
+EQU SPR0 00000000
+EQU SPR1 00000001
+EQU CPHA 00000002
+EQU CPOL 00000003
+EQU MSTR 00000004
+EQU DORD 00000005
+EQU SPE 00000006
+EQU SPIE 00000007
+EQU WDP0 00000000
+EQU WDP1 00000001
+EQU WDP2 00000002
+EQU WDE 00000003
+EQU WDCE 00000004
+EQU WDP3 00000005
+EQU WDIE 00000006
+EQU WDIF 00000007
+EQU SREG_C 00000000
+EQU SREG_Z 00000001
+EQU SREG_N 00000002
+EQU SREG_V 00000003
+EQU SREG_S 00000004
+EQU SREG_H 00000005
+EQU SREG_T 00000006
+EQU SREG_I 00000007
+EQU CAL0 00000000
+EQU CAL1 00000001
+EQU CAL2 00000002
+EQU CAL3 00000003
+EQU CAL4 00000004
+EQU CAL5 00000005
+EQU CAL6 00000006
+EQU CAL7 00000007
+EQU CLKPS0 00000000
+EQU CLKPS1 00000001
+EQU CLKPS2 00000002
+EQU CLKPS3 00000003
+EQU CLKPCE 00000007
+EQU SELFPRGEN 00000000
+EQU SPMEN 00000000
+EQU PGERS 00000001
+EQU PGWRT 00000002
+EQU BLBSET 00000003
+EQU RWWSRE 00000004
+EQU SIGRD 00000005
+EQU RWWSB 00000006
+EQU SPMIE 00000007
+EQU IVCE 00000000
+EQU IVSEL 00000001
+EQU PUD 00000004
+EQU BODSE 00000005
+EQU BODS 00000006
+EQU PORF 00000000
+EQU EXTRF 00000001
+EQU EXTREF 00000001
+EQU BORF 00000002
+EQU WDRF 00000003
+EQU SE 00000000
+EQU SM0 00000001
+EQU SM1 00000002
+EQU SM2 00000003
+EQU GPIOR20 00000000
+EQU GPIOR21 00000001
+EQU GPIOR22 00000002
+EQU GPIOR23 00000003
+EQU GPIOR24 00000004
+EQU GPIOR25 00000005
+EQU GPIOR26 00000006
+EQU GPIOR27 00000007
+EQU GPIOR10 00000000
+EQU GPIOR11 00000001
+EQU GPIOR12 00000002
+EQU GPIOR13 00000003
+EQU GPIOR14 00000004
+EQU GPIOR15 00000005
+EQU GPIOR16 00000006
+EQU GPIOR17 00000007
+EQU GPIOR00 00000000
+EQU GPIOR01 00000001
+EQU GPIOR02 00000002
+EQU GPIOR03 00000003
+EQU GPIOR04 00000004
+EQU GPIOR05 00000005
+EQU GPIOR06 00000006
+EQU GPIOR07 00000007
+EQU PRADC 00000000
+EQU PRUSART0 00000001
+EQU PRSPI 00000002
+EQU PRTIM1 00000003
+EQU PRTIM0 00000005
+EQU PRTIM2 00000006
+EQU PRTWI 00000007
+EQU EEAR0 00000000
+EQU EEAR1 00000001
+EQU EEAR2 00000002
+EQU EEAR3 00000003
+EQU EEAR4 00000004
+EQU EEAR5 00000005
+EQU EEAR6 00000006
+EQU EEAR7 00000007
+EQU EEAR8 00000000
+EQU EEAR9 00000001
+EQU EEDR0 00000000
+EQU EEDR1 00000001
+EQU EEDR2 00000002
+EQU EEDR3 00000003
+EQU EEDR4 00000004
+EQU EEDR5 00000005
+EQU EEDR6 00000006
+EQU EEDR7 00000007
+EQU EERE 00000000
+EQU EEPE 00000001
+EQU EEMPE 00000002
+EQU EERIE 00000003
+EQU EEPM0 00000004
+EQU EEPM1 00000005
+EQU LB1 00000000
+EQU LB2 00000001
+EQU BLB01 00000002
+EQU BLB02 00000003
+EQU BLB11 00000004
+EQU BLB12 00000005
+EQU CKSEL0 00000000
+EQU CKSEL1 00000001
+EQU CKSEL2 00000002
+EQU CKSEL3 00000003
+EQU SUT0 00000004
+EQU SUT1 00000005
+EQU CKOUT 00000006
+EQU CKDIV8 00000007
+EQU BOOTRST 00000000
+EQU BOOTSZ0 00000001
+EQU BOOTSZ1 00000002
+EQU EESAVE 00000003
+EQU WDTON 00000004
+EQU SPIEN 00000005
+EQU DWEN 00000006
+EQU RSTDISBL 00000007
+EQU BODLEVEL0 00000000
+EQU BODLEVEL1 00000001
+EQU BODLEVEL2 00000002
+DEF XH r27
+DEF XL r26
+DEF YH r29
+DEF YL r28
+DEF ZH r31
+DEF ZL r30
+EQU FLASHEND 00003fff
+EQU IOEND 000000ff
+EQU SRAM_START 00000100
+EQU SRAM_SIZE 00000800
+EQU RAMEND 000008ff
+EQU XRAMEND 00000000
+EQU E2END 000003ff
+EQU EEPROMEND 000003ff
+EQU EEADRBITS 0000000a
+EQU NRWW_START_ADDR 00003800
+EQU NRWW_STOP_ADDR 00003fff
+EQU RWW_START_ADDR 00000000
+EQU RWW_STOP_ADDR 000037ff
+EQU PAGESIZE 00000040
+EQU FIRSTBOOTSTART 00003f00
+EQU SECONDBOOTSTART 00003e00
+EQU THIRDBOOTSTART 00003c00
+EQU FOURTHBOOTSTART 00003800
+EQU SMALLBOOTSTART 00003f00
+EQU LARGEBOOTSTART 00003800
+EQU INT0addr 00000002
+EQU INT1addr 00000004
+EQU PCI0addr 00000006
+EQU PCI1addr 00000008
+EQU PCI2addr 0000000a
+EQU WDTaddr 0000000c
+EQU OC2Aaddr 0000000e
+EQU OC2Baddr 00000010
+EQU OVF2addr 00000012
+EQU ICP1addr 00000014
+EQU OC1Aaddr 00000016
+EQU OC1Baddr 00000018
+EQU OVF1addr 0000001a
+EQU OC0Aaddr 0000001c
+EQU OC0Baddr 0000001e
+EQU OVF0addr 00000020
+EQU SPIaddr 00000022
+EQU URXCaddr 00000024
+EQU UDREaddr 00000026
+EQU UTXCaddr 00000028
+EQU ADCCaddr 0000002a
+EQU ERDYaddr 0000002c
+EQU ACIaddr 0000002e
+EQU TWIaddr 00000030
+EQU SPMRaddr 00000032
+EQU INT_VECTORS_SIZE 00000034
+EQU b0 00000000
+EQU b1 00000001
+EQU b2 00000002
+EQU b3 00000003
+EQU b4 00000004
+EQU b5 00000005
+EQU b6 00000006
+EQU b7 00000007
+EQU CHIP_SELECTED 0000001e
+DEF OutA0 r0
+DEF OutC0 r1
+DEF OutA1 r2
+DEF CntN r3
+DEF OutB r4
+DEF BusOut1 r5
+DEF NoiseAddon r6
+DEF C00 r7
+DEF CC0 r8
+DEF TabE_AY0 r9
+DEF OutC1 r10
+DEF EVal_AY1 r11
+DEF EVal_AY0 r12
+DEF C21 r13
+DEF RNGL r14
+DEF RNGH r15
+DEF TNLevel_AY1 r16
+DEF BusOut2 r17
+DEF TabP_AY0 r18
+DEF TNLevel_AY0 r19
+DEF BusData r20
+DEF TMP r21
+DEF TabE_AY1 r22
+DEF TabP_AY1 r23
+DEF CntEL_AY0 r24
+DEF CntEH_AY0 r25
+DEF CntEL_AY1 r26
+DEF CntEH_AY1 r27
+DEF ADDR r30
+EQU CCP 00000034
+EQU CLKMSR 00000105
+EQU BCR 00000107
+EQU BOOTEND 00000108
+EQU BODCR 00000104
+EQU PMCR 000000f2
+EQU PMCE 00000007
+EQU CLKFS 00000006
+EQU CLKSS 00000005
+EQU WCLKS 00000004
+EQU WCES 00000004
+EQU OSCKEN 00000003
+EQU OSCMEN 00000002
+EQU RCKEN 00000001
+EQU RCMEN 00000000
+EQU PMX2 000000f0
+EQU IOCR 000000f0
+EQU IOCE 00000007
+EQU STSC1 00000006
+EQU STSC0 00000005
+EQU XIEN 00000002
+EQU E6EN 00000001
+EQU REFIOEN 00000001
+EQU C6EN 00000000
+EQU RSTIOEN 00000000
+EQU C0SR 00000050
+EQU C0D 00000007
+EQU C0BG 00000006
+EQU C0O 00000005
+EQU C0I 00000004
+EQU C0IE 00000003
+EQU C0IC 00000002
+EQU C0IS1 00000001
+EQU C0IS0 00000000
+EQU C0XR 00000051
+EQU C0OE 00000006
+EQU C0HSYE 00000005
+EQU C0PS0 00000004
+EQU C0WKE 00000003
+EQU C0FEN 00000002
+EQU C0FS1 00000001
+EQU C0FS0 00000000
+EQU C0TR 00000052
+EQU C1SR 0000002f
+EQU C1D 00000007
+EQU C1BG 00000006
+EQU C1O 00000005
+EQU C1I 00000004
+EQU C1IE 00000003
+EQU C1IC 00000002
+EQU C1IS1 00000001
+EQU C1IS0 00000000
+EQU C1XR 0000003a
+EQU C1OE 00000006
+EQU C1HSYE 00000005
+EQU C1PS0 00000004
+EQU C1WKE 00000003
+EQU C1FEN 00000002
+EQU C1FS1 00000001
+EQU C1FS0 00000000
+EQU C1TR 0000005b
+EQU DSCR 00000020
+EQU DSUEN 00000007
+EQU DSMM 00000006
+EQU DSD1 00000005
+EQU DSD0 00000004
+EQU DSZ 00000002
+EQU DSN 00000001
+EQU DSC 00000000
+EQU DSIR 00000021
+EQU DSSD 00000022
+EQU DSDX 00000030
+EQU DSDY 00000031
+EQU DSAL 00000058
+EQU DSAH 00000059
+CSEG _LGT_INIT 00000085
+CSEG _INT0_Handler 0000002d
+CSEG _INT1_Handler 00000050
+CSEG Volumes 00000005
+CSEG EVolumes 0000000d
+CSEG Envelopes 0000001d
+CSEG RegsMask 00000025
+CSEG LATCH_REG_ADDR0 00000039
+CSEG LOOP_NOT_INACTIVE 00000031
+CSEG exit_int0 00000035
+CSEG SELECT_CHIP_ADDR0 00000047
+CSEG READ_CHIP0 00000043
+DSEG AY1_REG00 00000310
+CSEG SELECT_CHIP0_ADDR0 0000004c
+CSEG SELECT_CHIP1_ADDR0 0000004e
+CSEG LATCH_REG_ADDR1 0000006f
+CSEG NO_ENVELOPE_CHANGED_P 0000006a
+CSEG exit_int1 0000006c
+CSEG SELECT_CHIP_ADDR1 0000007c
+CSEG READ_CHIP1 00000078
+CSEG SELECT_CHIP0_ADDR1 00000081
+CSEG SELECT_CHIP1_ADDR1 00000083
+CSEG wait 0000009f
+CSEG _RESET 000000ab
+CSEG LOOP0 000000c6
+CSEG _COPY 0000027f
+CSEG LOOP1 000000e4
+DSEG AY0_CntAL 00000260
+CSEG LOOP2 000000ec
+CSEG CALIB_WAIT 00000112
+CSEG CALIB_DO 0000012b
+CSEG CALIB_END 00000149
+CSEG CALIB_DIV_LOOP 00000137
+CSEG CALIB_DIV_SUB 0000013c
+CSEG CALIB_DIV_DONE 00000143
+CSEG NO_CALIBRATION 00000153
+DSEG ConstL 0000026c
+CSEG _MAIN_LOOP 0000017b
+CSEG NOISE_GENERATOR_END 00000196
+DSEG AY0_REG06 00000116
+DSEG AY1_REG06 00000316
+CSEG LESS 00000188
+CSEG NO_ENVELOPE_CHANGED_AY0 0000019e
+DSEG AY0_REG13 0000011d
+CSEG E_NEXT_STEP_AY0 000001aa
+CSEG ENVELOPE_GENERATOR_END_AY0 000001b3
+CSEG E_NEXT_PERIOD_AY0 000001a3
+DSEG AY0_REG11 0000011b
+DSEG AY0_REG12 0000011c
+CSEG NO_ENVELOPE_CHANGED_AY1 000001bb
+DSEG AY1_REG13 0000031d
+CSEG E_NEXT_STEP_AY1 000001c7
+CSEG ENVELOPE_GENERATOR_END_AY1 000001d0
+CSEG E_NEXT_PERIOD_AY1 000001c0
+DSEG AY1_REG11 0000031b
+DSEG AY1_REG12 0000031c
+CSEG GENERATORS_AY1 000001fe
+CSEG CH_A_NO_CHANGE_AY0 000001de
+DSEG AY0_REG00 00000110
+DSEG AY0_CntBL 00000262
+CSEG CH_B_NO_CHANGE_AY0 000001ec
+DSEG AY0_REG02 00000112
+DSEG AY0_CntCL 00000264
+CSEG CH_C_NO_CHANGE_AY0 000001fa
+DSEG AY0_REG04 00000114
+CSEG GENERATORS_END 0000022f
+DSEG AY1_CntAL 00000266
+CSEG CH_A_NO_CHANGE_AY1 0000020c
+DSEG AY1_CntBL 00000268
+CSEG CH_B_NO_CHANGE_AY1 0000021c
+DSEG AY1_REG02 00000312
+DSEG AY1_CntCL 0000026a
+CSEG CH_C_NO_CHANGE_AY1 0000022c
+DSEG AY1_REG04 00000314
+DSEG AY0_REG07 00000117
+DSEG AY0_REG08 00000118
+DSEG AY0_REG09 00000119
+DSEG AY0_REG10 0000011a
+DSEG AY1_REG07 00000317
+DSEG AY1_REG08 00000318
+DSEG AY1_REG09 00000319
+DSEG AY1_REG10 0000031a
+DSEG AY0_REG01 00000111
+DSEG AY0_REG03 00000113
+DSEG AY0_REG05 00000115
+DSEG AY0_REG14 0000011e
+DSEG AY0_REG15 0000011f
+DSEG AY0_CntAH 00000261
+DSEG AY0_CntBH 00000263
+DSEG AY0_CntCH 00000265
+DSEG AY1_CntAH 00000267
+DSEG AY1_CntBH 00000269
+DSEG AY1_CntCH 0000026b
+DSEG ConstH 0000026d
+DSEG AY1_REG01 00000311
+DSEG AY1_REG03 00000313
+DSEG AY1_REG05 00000315
+DSEG AY1_REG14 0000031e
+DSEG AY1_REG15 0000031f
diff --git a/Sources/AY_Emu/AY_Emu/Release/AY_Emu.obj b/Sources/AY_Emu/AY_Emu/Release/AY_Emu.obj
new file mode 100644
index 0000000..2077aaa
Binary files /dev/null and b/Sources/AY_Emu/AY_Emu/Release/AY_Emu.obj differ
diff --git a/Sources/AY_Emu/AY_Emu/Release/AY_Emu.tmp b/Sources/AY_Emu/AY_Emu/Release/AY_Emu.tmp
new file mode 100644
index 0000000..047a7a4
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/AY_Emu.tmp
@@ -0,0 +1,125 @@
+
+ 2.2.7
+ "ATmega328P"
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\Release
+
+ C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.3.300\avrasm\inc
+ C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avrassembler\Include
+
+
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm
+
+ C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.3.300\avrasm\inc\m328pdef.inc
+
+
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\Release\AY_Emu.obj
+
+
+ AY_Emu.hex
+
+
+ AY_Emu.map
+ AY_Emu.lss
+
+
+ <_LGT_INIT>D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm334
+ <_INT0_Handler>D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm197
+ <_INT1_Handler>D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm252
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm172
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm174
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm189
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm193
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm216
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm204
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm210
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm236
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm229
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1071
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm243
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm247
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm297
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm289
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm292
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm316
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm309
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm323
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm327
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm383
+ <_RESET>D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm402
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm437
+ <_COPY>D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1003
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm478
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1051
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm489
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm537
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm562
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm610
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm584
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm591
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm600
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm632
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1066
+ <_MAIN_LOOP>D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm680
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm709
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1028
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1083
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm694
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm724
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1042
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm740
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm749
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm731
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1038
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1040
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm764
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1097
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm780
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm789
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm771
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1093
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1095
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm844
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm808
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1016
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1053
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm823
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1020
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1055
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm838
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1024
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm902
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1059
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm863
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1061
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm880
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1075
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1063
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm897
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1079
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1030
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1032
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1034
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1036
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1085
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1087
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1089
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1091
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1018
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1022
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1026
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1044
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1046
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1052
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1054
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1056
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1060
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1062
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1064
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1067
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1073
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1077
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1081
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1099
+ D:\ST\AY_Emul_Version26_0\AY_Emu_Prj\AY_Emu\AY_Emu\main.asm1101
+
+
diff --git a/Sources/AY_Emu/AY_Emu/Release/AY_Emu_40MHz.hex b/Sources/AY_Emu/AY_Emu/Release/AY_Emu_40MHz.hex
new file mode 100644
index 0000000..e3fc209
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/AY_Emu_40MHz.hex
@@ -0,0 +1,80 @@
+:020000020000FC
+:0200000084C0BA
+:020004002AC010
+:100008004BC0000101010202030506090D11161D6E
+:10001800242D000001010101010102020202030373
+:100028000505060607090B0D0F111316191D2024C7
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B990AC01AB957B84A99FECF77B82B
+:100068007AB8F1E042E04CBB1895E6B1EF734F99CE
+:100078000AC0F09904C0F1E050A010A9F2CFF3E053
+:1000880050A010A9EECFEF3319F0EE3319F0E9CFF5
+:10009800F098E7CFF09AE5CF46B14F734A991BC065
+:1000A80059B07FB658204529542E5094F1E010815C
+:1000B800F099F3E050A24123152D182110AB408B85
+:1000C800ED3021F4F09B3068F09900687FBE77240A
+:1000D800F1E0FCBB1895E42F4E990AC0F09904C0D2
+:1000E800F1E050A010A9F4CFF3E050A010A9F0CF90
+:1000F800EF3319F0EE3319F0EBCFF098E9CFF09A1F
+:10010800E7CFF89400E00093600000E80093F20065
+:1001180004E20093F20000E10093F00004E0009391
+:10012800F00000E80093610000E200936100000025
+:1001380000000000000000000000000003E0009341
+:1001480007010FE70093080100E80093200000C0B2
+:1001580005B7046005BF0FEF0DBF08E00EBF00E054
+:1001680007B908B90AB90BB900E80093500000E8CC
+:100178000FBDF098F198772400EC802E04E0A02EB3
+:1001880001E2D02E0FEF502E182DFF247727DFEF36
+:1001980020E1E0E1F1E080A2008B71922A95D9F785
+:1001A800B2E0A0E1EAE3F0E020E17FD1A0E2EAE0FA
+:1001B800F0E020E17AD1A0E3EAE1F0E020E275D1B5
+:1001C800AA27B1E0EAE4F0E020E16FD120E1E0E124
+:1001D800F3E080A2008B71922A95D9F720E1E0E63E
+:1001E800F2E071922A95E9F7E1E5F2E000E81127DB
+:1001F8002227019311932193E4E5F2E001931193EF
+:100208002193F1E0EE276F2EBF2E70928900709235
+:10021800880070928B0070928A00219A229A02EAD2
+:100228000093800009E10093810026EB709287001B
+:10023800209386000FE00093690003E00CBB03E005
+:100248000DBBE0E133270027002444241124282D86
+:10025800992433242224AA27BB2788279927CC242A
+:10026800D4E0CCE601E0088300E00983D4E21880FA
+:10027800D2E07894C6B3C0FFFDCFC6BBC1E5988075
+:100288002981CA8037FF06C0C0911D0198882FE1D7
+:100298003F770CC097FC13C0019708F081F42A95AA
+:1002A8002AF42FE191FC9F2692FC982880911B014B
+:1002B80090911C01C22F5FE190FEC527C8A83A940F
+:1002C8006AF4309016013A9466946E2CF794E79489
+:1002D8003863E0FE377C660C6E246694D1E2C0E693
+:1002E8000880D0922100019B05C0C0E10880D0920F
+:1002F80021003F27C0E62882C2E60880D09221006C
+:10030800019B06C0C2E10880D092210052E0352747
+:10031800C2E62882C4E60880D0922100019B05C06D
+:10032800C4E10880D09221003A25C4E62882509181
+:100338001701532BC52FCC0FC2955C23D2E0C09177
+:1003480018010C2CC4FF08A050FF0024C09119010B
+:100358004C2CC4FF48A051FF4424C0911A011C2C06
+:10036800C4FF18A052FF1124C42D46944694C41902
+:100378004694C4190C0E1C0EC1E598822983CA82C2
+:1003880008861986C4E598802981CA8007FF06C0B7
+:10039800C0911D0398882FE10F770CC097FC13C0FC
+:1003A800119708F081F42A952AF42FE191FC9F26F1
+:1003B80092FC9828A0911B03B0911C03C22F5FE107
+:1003C80090FEC527C8A82A946AF4209016032A9498
+:1003D800B694B62E77956795086360FF077CBB0CCB
+:1003E800B626B694D1E2C6E60880D0922100019BD9
+:1003F80007C0D3E2C0E10880D09221000F27D1E2E4
+:10040800C6E62882C8E60880D0922100019B08C071
+:10041800D3E2C2E10880D092210052E00527D1E260
+:10042800C8E62882CAE60880D0922100019B07C04E
+:10043800D3E2C4E10880D09221000A25D1E2CAE6BD
+:10044800288250911703502BC52FCC0FC2955C23DF
+:10045800D2E0C09118030C2CC4FF08A050FF002460
+:10046800C09119034C2CC4FF48A051FF4424C091EB
+:100478001A031C2CC4FF18A052FF1124C42D469443
+:100488004694C4194694C4190C0E1C0EC4E59882EF
+:100498002983CA8250915902050E50915A02150EAD
+:1004A8000092880010928A00E5CE05910D932A9556
+:0404B800E1F70895CB
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/Release/AY_Emu_INT_37MHz_Auto.hex b/Sources/AY_Emu/AY_Emu/Release/AY_Emu_INT_37MHz_Auto.hex
new file mode 100644
index 0000000..38c0aa8
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/AY_Emu_INT_37MHz_Auto.hex
@@ -0,0 +1,84 @@
+:020000020000FC
+:0200000084C0BA
+:020004002AC010
+:100008004BC0000101010202030405070A0D121882
+:10001800222D000001010101010102020202020376
+:10002800030404050607080A0B0D0F1215181D22F4
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B990AC01AB957B84A99FECF77B82B
+:100068007AB8F1E042E04CBB1895E6B1EF734F99CE
+:100078000AC0F09904C0F1E050A010A9F2CFF3E053
+:1000880050A010A9EECFEF3319F0EE3319F0E9CFF5
+:10009800F098E7CFF09AE5CF46B14F734A991BC065
+:1000A80059B07FB658204529542E5094F1E010815C
+:1000B800F099F3E050A24123152D182110AB408B85
+:1000C800ED3021F4F09B3068F09900687FBE77240A
+:1000D800F1E0FCBB1895E42F4E990AC0F09904C0D2
+:1000E800F1E050A010A9F4CFF3E050A010A9F0CF90
+:1000F800EF3319F0EE3319F0EBCFF098E9CFF09A1F
+:10010800E7CFF89400E00093600008ED0093340016
+:1001180000E80093610008ED0093340000E00093CC
+:10012800610008ED0093340004E00093050100EE3F
+:10013800009366000FEF0A95F1F703E000930701BB
+:100148000FE70093080100E80093200000C005B7FE
+:10015800046005BF0FEF0DBF08E00EBF00E8009375
+:10016800500000E80FBDF098F198772400EC802E3D
+:1001780001E2D02E0FEF502E182DFF24DFEF20E1E3
+:10018800E0E1F1E080A2008B71922A95D9F7B2E004
+:10019800A0E1EAE3F0E020E1A7D1A0E2EAE0F0E0A4
+:1001A80020E1A2D1A0E3EAE1F0E020E29DD1AA2774
+:1001B800B1E0EAE4F0E020E197D120E1E0E1F3E00A
+:1001C80080A2008B71922A95D9F720E1E0E6F2E04F
+:1001D80071922A95E9F7F1E0EE276F2E7092890067
+:1001E8007092880070928B0070928A00219A229AED
+:1001F80000240027009380000027009385000093C7
+:10020800840007E000938100002704BD002706BD95
+:1002180001E005BB01E005BDA0EDB7E005B300FFB7
+:10022800FDCF01E005BB1197C9F700270093250012
+:10023800009381004091840050918500002700932D
+:10024800850000938400442311F45523B9F060E03D
+:1002580070E82EE388279927222319F46417750775
+:1002680038F0641B750B27098395B1F79395F4CF84
+:1002780081509040992311F4C82F009402EA00930A
+:10028800800009E1009381002DEA002009F02C2F5D
+:1002980070928700209386000FE00093690003E0C6
+:1002A8000CBB03E00DBBE0E1332700270024442406
+:1002B80011242224AA24282D782D99246627332452
+:1002C800AA27BB2788279927CC24BB24D4E0CCE6CF
+:1002D80002E0088300E00983D4E21880D2E0789431
+:1002E800C6B3C0FFFDCFC6BB3A94AAF4309016013E
+:1002F8005091160335160CF4352E3A9466946E2CEC
+:10030800F794E79438630863E0FE377CE0FE077CE7
+:10031800660C6E24669437FF06C0C0911D0198884C
+:100328002FE13F770CC097FC13C001970CF081F4C4
+:100338002A952AF42FE191FC9F2692FC9828809117
+:100348001B0190911C01C22F5FE190FEC527C8A830
+:1003580007FF06C0C0911D0368897FE10F770CC0B5
+:1003680067FD13C011970CF081F47A952AF47FE1A8
+:1003780061FD6F2762FD6829A0911B03B0911C03E2
+:10038800C72F5FE160FFC527B8A8F19B2CC0D1E259
+:10039800C0E60880D0922100019B05C0C0E108801A
+:1003A800D09221003F27C0E62882C2E60880D0927A
+:1003B8002100019B06C0C2E10880D092210052E0D2
+:1003C8003527C2E62882C4E60880D0922100019B26
+:1003D80006C0C4E10880D092210054E03527C4E665
+:1003E8002882F19831C0D1E2C6E60880D092210077
+:1003F800019B07C0D3E2C0E10880D09221000F27FB
+:10040800D1E2C6E62882C8E60880D0922100019B86
+:1004180008C0D3E2C2E10880D092210052E005274B
+:10042800D1E2C8E62882CAE60880D0922100019B62
+:1004380008C0D3E2C4E10880D092210054E0052727
+:10044800D1E2CAE62882F19A50911701532BC52FA1
+:10045800CC0FC2955C23D2E0C09118010C2CC4FFCC
+:1004680008A050FF0024C09119014C2CC4FF48A0DB
+:1004780051FF4424C0911A011C2CC4FF18A052FF3C
+:100488001124C42D46944694C4194694C4190C0EDC
+:100498001C0E50911703502BC52FCC0FC2955C230F
+:1004A800C09118032B2CC4FF28A050FF2224C09110
+:1004B80019034B2CC4FF48A051FF4424C0911A03D0
+:1004C800AB2CC4FFA8A052FFAA24C42D469446947E
+:1004D800C4194694C4192C0EAC0E020C1A0C0092C6
+:1004E800880010928A00FCCE05910D932A95E1F7B9
+:0204F800089565
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/Release/AY_Emu_INT_37MHz_Auto_Calib.hex b/Sources/AY_Emu/AY_Emu/Release/AY_Emu_INT_37MHz_Auto_Calib.hex
new file mode 100644
index 0000000..ed6787e
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/AY_Emu_INT_37MHz_Auto_Calib.hex
@@ -0,0 +1,84 @@
+:020000020000FC
+:0200000084C0BA
+:020004002AC010
+:100008004BC0000101010202030506090D11161D6E
+:10001800242D000001010101010102020202030373
+:100028000505060607090B0D0F111316191D2024C7
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B990AC01AB957B84A99FECF77B82B
+:100068007AB8F1E042E04CBB1895E6B1EF734F99CE
+:100078000AC0F09904C0F1E050A010A9F2CFF3E053
+:1000880050A010A9EECFEF3319F0EE3319F0E9CFF5
+:10009800F098E7CFF09AE5CF46B14F734A991BC065
+:1000A80059B07FB658204529542E5094F1E010815C
+:1000B800F099F3E050A24123152D182110AB408B85
+:1000C800ED3021F4F09B3068F09900687FBE77240A
+:1000D800F1E0FCBB1895E42F4E990AC0F09904C0D2
+:1000E800F1E050A010A9F4CFF3E050A010A9F0CF90
+:1000F800EF3319F0EE3319F0EBCFF098E9CFF09A1F
+:10010800E7CFF89400E00093600008ED0093340016
+:1001180000E80093610008ED0093340000E00093CC
+:10012800610008ED0093340004E00093050100EE3F
+:10013800009366000FEF0A95F1F703E000930701BB
+:100148000FE70093080100E80093200000C005B7FE
+:10015800046005BF0FEF0DBF08E00EBF00E8009375
+:10016800500000E80FBDF098F198772400EC802E3D
+:1001780001E2D02E0FEF502E182DFF24DFEF20E1E3
+:10018800E0E1F1E080A2008B71922A95D9F7B2E004
+:10019800A0E1EAE3F0E020E1AED1A0E2EAE0F0E09D
+:1001A80020E1A9D1A0E3EAE1F0E020E2A4D1AA2766
+:1001B800B1E0EAE4F0E020E19ED120E1E0E1F3E003
+:1001C80080A2008B71922A95D9F720E1E0E6F2E04F
+:1001D80071922A95E9F7F1E0EE276F2E7092890067
+:1001E8007092880070928B0070928A00219A229AED
+:1001F80000240027009380000027009385000093C7
+:10020800840007E000938100002704BD002706BD95
+:1002180001E005BB01E005BDA0EDB7E005B300FFB7
+:10022800FDCF01E005BB1197C9F700270093250012
+:10023800009381004091840050918500002700932D
+:10024800850000938400442311F45523F1F060E005
+:1002580070E82EE3A42FB52FB695A7956A0F7B1FDC
+:10026800271D88279927222319F46417750738F062
+:10027800641B750B27098395B1F79395F4CF8150CB
+:100288009040992311F4C82F009402EA009380004B
+:1002980009E1009381002DEA002009F02C2F7092CB
+:1002A8008700209386000FE00093690003E00CBBF1
+:1002B80003E00DBBE0E13327002700244424112488
+:1002C8002224AA24282D782D992466273324AA27A6
+:1002D800BB2788279927CC24BB24D4E0CCE602E0AE
+:1002E800088300E00983D4E21880D2E07894C6B38A
+:1002F800C0FFFDCFC6BB3A94AAF4309016015091C6
+:10030800160335160CF4352E3A9466946E2CF79431
+:10031800E79438630863E0FE377CE0FE077C660CF0
+:100328006E24669437FF06C0C0911D0198882FE19E
+:100338003F770CC097FC13C001970CF081F42A9505
+:100348002AF42FE191FC9F2692FC982880911B01AA
+:1003580090911C01C22F5FE190FEC527C8A807FF36
+:1003680006C0C0911D0368897FE10F770CC067FD47
+:1003780013C011970CF081F47A952AF47FE161FD9E
+:100388006F2762FD6829A0911B03B0911C03C72F3A
+:100398005FE160FFC527B8A8F19B2CC0D1E2C0E699
+:1003A8000880D0922100019B05C0C0E10880D0924E
+:1003B80021003F27C0E62882C2E60880D0922100AB
+:1003C800019B06C0C2E10880D092210052E0352787
+:1003D800C2E62882C4E60880D0922100019B06C0AC
+:1003E800C4E10880D092210054E03527C4E6288271
+:1003F800F19831C0D1E2C6E60880D0922100019B75
+:1004080007C0D3E2C0E10880D09221000F27D1E2D3
+:10041800C6E62882C8E60880D0922100019B08C061
+:10042800D3E2C2E10880D092210052E00527D1E250
+:10043800C8E62882CAE60880D0922100019B08C03D
+:10044800D3E2C4E10880D092210054E00527D1E22C
+:10045800CAE62882F19A50911701532BC52FCC0F69
+:10046800C2955C23D2E0C09118010C2CC4FF08A0EF
+:1004780050FF0024C09119014C2CC4FF48A051FF23
+:100488004424C0911A011C2CC4FF18A052FF112447
+:10049800C42D46944694C4194694C4190C0E1C0ED7
+:1004A80050911703502BC52FCC0FC2955C23C091D8
+:1004B80018032B2CC4FF28A050FF2224C091190335
+:1004C8004B2CC4FF48A051FF4424C0911A03AB2C05
+:1004D800C4FFA8A052FFAA24C42D46944694C41968
+:1004E8004694C4192C0EAC0E020C1A0C009288000B
+:1004F80010928A00FCCE05910D932A95E1F7089594
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/Release/Flashing.bat b/Sources/AY_Emu/AY_Emu/Release/Flashing.bat
new file mode 100644
index 0000000..1d8970f
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/Flashing.bat
@@ -0,0 +1,9 @@
+@echo off
+cd /d "%~dp0"
+
+set Path=%Path%;D:\ST\Spectrum\AVRDUDESS-2.20-portable
+
+avrdude -c arduino_as_isp -P COM20 -b 19200 -p lgt328p -U lfuse:w:0xE2:m -U hfuse:w:0xDF:m -U efuse:w:0xFD:m -U flash:w:AY_Emu.hex:a
+pause
+
+REM avrdude.exe -c arduino_as_isp -p lgt328p -P COM20 -b 19200 -U lfuse:w:0xFF:m -U hfuse:w:0xFF:m -U efuse:w:0xFF:m
diff --git a/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_40MHz_AY.hex b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_40MHz_AY.hex
new file mode 100644
index 0000000..4178627
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_40MHz_AY.hex
@@ -0,0 +1,74 @@
+:020000020000FC
+:0200000084C0BA
+:020004002AC010
+:100008004BC0000101010202030506090D11161D6E
+:10001800242D000001010101010102020202030373
+:100028000505060607090B0D0F111316191D2024C7
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B990AC01AB957B84A99FECF77B82B
+:100068007AB8F1E042E04CBB1895E6B1EF734F99CE
+:100078000AC0F09904C0F1E050A010A9F2CFF3E053
+:1000880050A010A9EECFEF3319F0EE3319F0E9CFF5
+:10009800F098E7CFF09AE5CF46B14F734A991BC065
+:1000A80059B07FB658204529542E5094F1E010815C
+:1000B800F099F3E050A24123152D182110AB408B85
+:1000C800ED3021F4F09B3068F09900687FBE77240A
+:1000D800F1E0FCBB1895E42F4E990AC0F09904C0D2
+:1000E800F1E050A010A9F4CFF3E050A010A9F0CF90
+:1000F800EF3319F0EE3319F0EBCFF098E9CFF09A1F
+:10010800E7CFF89400E00093600000E80093F20065
+:1001180004E20093F20000E10093F00004E0009391
+:10012800F00000E80093610000E2009361000FEF27
+:100138000A95F1F703E0009307010FE70093080120
+:1001480000E80093200000C005B7046005BF0FEF6A
+:100158000DBF08E00EBF00E80093500000E80FBD97
+:10016800F098F198772400EC802E01E2D02E0FEF62
+:10017800502E182DFF24DFEF20E1E0E1F1E080A20E
+:10018800008B71922A95D9F7B2E0A0E1EAE3F0E09A
+:1001980020E15ED1A0E2EAE0F0E020E159D1A0E35D
+:1001A800EAE1F0E020E254D1AA27B1E0EAE4F0E085
+:1001B80020E14ED120E1E0E1F3E080A2008B7192D2
+:1001C8002A95D9F720E1E0E6F2E071922A95E9F75D
+:1001D800F1E0EE276F2E709289007092880070927D
+:1001E8008B0070928A00219A229A02EA009380007A
+:1001F80009E10093810026EB709287002093860026
+:100208000FE00093690003E00CBB03E00DBBE0E1E5
+:10021800332700270024442411242224AA24282D2B
+:10022800782D992466273324AA27BB27882799275E
+:10023800CC24BB24D4E0CCE602E0088300E00983A8
+:10024800D4E21880D2E07894C6B3C0FFFDCFC6BB15
+:100258003A94AAF4309016015091160335160CF40E
+:10026800352E3A9466946E2CF794E79438630863B5
+:10027800E0FE377CE0FE077C660C6E24669437FF50
+:1002880006C0C0911D0198882FE13F770CC097FCEC
+:1002980013C001970CF081F42A952AF42FE191FC00
+:1002A8009F2692FC982880911B0190911C01C22FD7
+:1002B8005FE190FEC527C8A807FF06C0C0911D03CF
+:1002C80068897FE10F770CC067FD13C011970CF0A8
+:1002D80081F47A952AF47FE161FD6F2762FD682930
+:1002E800A0911B03B0911C03C72F5FE160FFC527D6
+:1002F800B8A8F19B2CC0D1E2C0E60880D0922100BA
+:10030800019B05C0C0E10880D09221003F27C0E6CC
+:100318002882C2E60880D0922100019B06C0C2E173
+:100328000880D092210052E03527C2E62882C4E630
+:100338000880D0922100019B06C0C4E10880D092B9
+:10034800210054E03527C4E62882F19831C0D1E273
+:10035800C6E60880D0922100019B07C0D3E2C0E125
+:100368000880D09221000F27D1E2C6E62882C8E68D
+:100378000880D0922100019B08C0D3E2C2E1088026
+:10038800D092210052E00527D1E2C8E62882CAE6C9
+:100398000880D0922100019B08C0D3E2C4E1088004
+:1003A800D092210054E00527D1E2CAE62882F19ACA
+:1003B80050911701532BC52FCC0FC2955C23D2E067
+:1003C800C09118010C2CC4FF08A050FF0024C09154
+:1003D80019014C2CC4FF48A051FF4424C0911A01B4
+:1003E8001C2CC4FF18A052FF1124C42D4694469417
+:1003F800C4194694C4190C0E1C0E50911703502BA7
+:10040800C52FCC0FC2955C23C09118032B2CC4FFB9
+:1004180028A050FF2224C09119034B2CC4FF48A0E8
+:1004280051FF4424C0911A03AB2CC4FFA8A052FF6B
+:10043800AA24C42D46944694C4194694C4192C0E73
+:10044800AC0E020C1A0C0092880010928A00FCCEA6
+:0A04580005910D932A95E1F7089530
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_40MHz_YM.hex b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_40MHz_YM.hex
new file mode 100644
index 0000000..fa9f352
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_40MHz_YM.hex
@@ -0,0 +1,74 @@
+:020000020000FC
+:0200000084C0BA
+:020004002AC010
+:100008004BC0000101010202030405070A0D121882
+:10001800222D000001010101010102020202020376
+:10002800030404050607080A0B0D0F1215181D22F4
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B990AC01AB957B84A99FECF77B82B
+:100068007AB8F1E042E04CBB1895E6B1EF734F99CE
+:100078000AC0F09904C0F1E050A010A9F2CFF3E053
+:1000880050A010A9EECFEF3319F0EE3319F0E9CFF5
+:10009800F098E7CFF09AE5CF46B14F734A991BC065
+:1000A80059B07FB658204529542E5094F1E010815C
+:1000B800F099F3E050A24123152D182110AB408B85
+:1000C800ED3021F4F09B3068F09900687FBE77240A
+:1000D800F1E0FCBB1895E42F4E990AC0F09904C0D2
+:1000E800F1E050A010A9F4CFF3E050A010A9F0CF90
+:1000F800EF3319F0EE3319F0EBCFF098E9CFF09A1F
+:10010800E7CFF89400E00093600000E80093F20065
+:1001180004E20093F20000E10093F00004E0009391
+:10012800F00000E80093610000E2009361000FEF27
+:100138000A95F1F703E0009307010FE70093080120
+:1001480000E80093200000C005B7046005BF0FEF6A
+:100158000DBF08E00EBF00E80093500000E80FBD97
+:10016800F098F198772400EC802E01E2D02E0FEF62
+:10017800502E182DFF24DFEF20E1E0E1F1E080A20E
+:10018800008B71922A95D9F7B2E0A0E1EAE3F0E09A
+:1001980020E15ED1A0E2EAE0F0E020E159D1A0E35D
+:1001A800EAE1F0E020E254D1AA27B1E0EAE4F0E085
+:1001B80020E14ED120E1E0E1F3E080A2008B7192D2
+:1001C8002A95D9F720E1E0E6F2E071922A95E9F75D
+:1001D800F1E0EE276F2E709289007092880070927D
+:1001E8008B0070928A00219A229A02EA009380007A
+:1001F80009E10093810026EB709287002093860026
+:100208000FE00093690003E00CBB03E00DBBE0E1E5
+:10021800332700270024442411242224AA24282D2B
+:10022800782D992466273324AA27BB27882799275E
+:10023800CC24BB24D4E0CCE602E0088300E00983A8
+:10024800D4E21880D2E07894C6B3C0FFFDCFC6BB15
+:100258003A94AAF4309016015091160335160CF40E
+:10026800352E3A9466946E2CF794E79438630863B5
+:10027800E0FE377CE0FE077C660C6E24669437FF50
+:1002880006C0C0911D0198882FE13F770CC097FCEC
+:1002980013C001970CF081F42A952AF42FE191FC00
+:1002A8009F2692FC982880911B0190911C01C22FD7
+:1002B8005FE190FEC527C8A807FF06C0C0911D03CF
+:1002C80068897FE10F770CC067FD13C011970CF0A8
+:1002D80081F47A952AF47FE161FD6F2762FD682930
+:1002E800A0911B03B0911C03C72F5FE160FFC527D6
+:1002F800B8A8F19B2CC0D1E2C0E60880D0922100BA
+:10030800019B05C0C0E10880D09221003F27C0E6CC
+:100318002882C2E60880D0922100019B06C0C2E173
+:100328000880D092210052E03527C2E62882C4E630
+:100338000880D0922100019B06C0C4E10880D092B9
+:10034800210054E03527C4E62882F19831C0D1E273
+:10035800C6E60880D0922100019B07C0D3E2C0E125
+:100368000880D09221000F27D1E2C6E62882C8E68D
+:100378000880D0922100019B08C0D3E2C2E1088026
+:10038800D092210052E00527D1E2C8E62882CAE6C9
+:100398000880D0922100019B08C0D3E2C4E1088004
+:1003A800D092210054E00527D1E2CAE62882F19ACA
+:1003B80050911701532BC52FCC0FC2955C23D2E067
+:1003C800C09118010C2CC4FF08A050FF0024C09154
+:1003D80019014C2CC4FF48A051FF4424C0911A01B4
+:1003E8001C2CC4FF18A052FF1124C42D4694469417
+:1003F800C4194694C4190C0E1C0E50911703502BA7
+:10040800C52FCC0FC2955C23C09118032B2CC4FFB9
+:1004180028A050FF2224C09119034B2CC4FF48A0E8
+:1004280051FF4424C0911A03AB2CC4FFA8A052FF6B
+:10043800AA24C42D46944694C4194694C4192C0E73
+:10044800AC0E020C1A0C0092880010928A00FCCEA6
+:0A04580005910D932A95E1F7089530
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_48MHz_AY.hex b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_48MHz_AY.hex
new file mode 100644
index 0000000..529527c
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_48MHz_AY.hex
@@ -0,0 +1,74 @@
+:020000020000FC
+:0200000084C0BA
+:020004002AC010
+:100008004BC0000101010202030506090D11161D6E
+:10001800242D000001010101010102020202030373
+:100028000505060607090B0D0F111316191D2024C7
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B990AC01AB957B84A99FECF77B82B
+:100068007AB8F1E042E04CBB1895E6B1EF734F99CE
+:100078000AC0F09904C0F1E050A010A9F2CFF3E053
+:1000880050A010A9EECFEF3319F0EE3319F0E9CFF5
+:10009800F098E7CFF09AE5CF46B14F734A991BC065
+:1000A80059B07FB658204529542E5094F1E010815C
+:1000B800F099F3E050A24123152D182110AB408B85
+:1000C800ED3021F4F09B3068F09900687FBE77240A
+:1000D800F1E0FCBB1895E42F4E990AC0F09904C0D2
+:1000E800F1E050A010A9F4CFF3E050A010A9F0CF90
+:1000F800EF3319F0EE3319F0EBCFF098E9CFF09A1F
+:10010800E7CFF89400E00093600000E80093F20065
+:1001180004E20093F20000E10093F00004E0009391
+:10012800F00000E80093610000E2009361000FEF27
+:100138000A95F1F703E0009307010FE70093080120
+:1001480000E80093200000C005B7046005BF0FEF6A
+:100158000DBF08E00EBF00E80093500000E80FBD97
+:10016800F098F198772400EC802E01E2D02E0FEF62
+:10017800502E182DFF24DFEF20E1E0E1F1E080A20E
+:10018800008B71922A95D9F7B2E0A0E1EAE3F0E09A
+:1001980020E15ED1A0E2EAE0F0E020E159D1A0E35D
+:1001A800EAE1F0E020E254D1AA27B1E0EAE4F0E085
+:1001B80020E14ED120E1E0E1F3E080A2008B7192D2
+:1001C8002A95D9F720E1E0E6F2E071922A95E9F75D
+:1001D800F1E0EE276F2E709289007092880070927D
+:1001E8008B0070928A00219A229A02EA009380007A
+:1001F80009E1009381002AED709287002093860020
+:100208000FE00093690003E00CBB03E00DBBE0E1E5
+:10021800332700270024442411242224AA24282D2B
+:10022800782D992466273324AA27BB27882799275E
+:10023800CC24BB24D4E0CCE602E0088300E00983A8
+:10024800D4E21880D2E07894C6B3C0FFFDCFC6BB15
+:100258003A94AAF4309016015091160335160CF40E
+:10026800352E3A9466946E2CF794E79438630863B5
+:10027800E0FE377CE0FE077C660C6E24669437FF50
+:1002880006C0C0911D0198882FE13F770CC097FCEC
+:1002980013C001970CF081F42A952AF42FE191FC00
+:1002A8009F2692FC982880911B0190911C01C22FD7
+:1002B8005FE190FEC527C8A807FF06C0C0911D03CF
+:1002C80068897FE10F770CC067FD13C011970CF0A8
+:1002D80081F47A952AF47FE161FD6F2762FD682930
+:1002E800A0911B03B0911C03C72F5FE160FFC527D6
+:1002F800B8A8F19B2CC0D1E2C0E60880D0922100BA
+:10030800019B05C0C0E10880D09221003F27C0E6CC
+:100318002882C2E60880D0922100019B06C0C2E173
+:100328000880D092210052E03527C2E62882C4E630
+:100338000880D0922100019B06C0C4E10880D092B9
+:10034800210054E03527C4E62882F19831C0D1E273
+:10035800C6E60880D0922100019B07C0D3E2C0E125
+:100368000880D09221000F27D1E2C6E62882C8E68D
+:100378000880D0922100019B08C0D3E2C2E1088026
+:10038800D092210052E00527D1E2C8E62882CAE6C9
+:100398000880D0922100019B08C0D3E2C4E1088004
+:1003A800D092210054E00527D1E2CAE62882F19ACA
+:1003B80050911701532BC52FCC0FC2955C23D2E067
+:1003C800C09118010C2CC4FF08A050FF0024C09154
+:1003D80019014C2CC4FF48A051FF4424C0911A01B4
+:1003E8001C2CC4FF18A052FF1124C42D4694469417
+:1003F800C4194694C4190C0E1C0E50911703502BA7
+:10040800C52FCC0FC2955C23C09118032B2CC4FFB9
+:1004180028A050FF2224C09119034B2CC4FF48A0E8
+:1004280051FF4424C0911A03AB2CC4FFA8A052FF6B
+:10043800AA24C42D46944694C4194694C4192C0E73
+:10044800AC0E020C1A0C0092880010928A00FCCEA6
+:0A04580005910D932A95E1F7089530
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_48MHz_YM.hex b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_48MHz_YM.hex
new file mode 100644
index 0000000..fcf2e48
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_48MHz_YM.hex
@@ -0,0 +1,74 @@
+:020000020000FC
+:0200000084C0BA
+:020004002AC010
+:100008004BC0000101010202030405070A0D121882
+:10001800222D000001010101010102020202020376
+:10002800030404050607080A0B0D0F1215181D22F4
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B990AC01AB957B84A99FECF77B82B
+:100068007AB8F1E042E04CBB1895E6B1EF734F99CE
+:100078000AC0F09904C0F1E050A010A9F2CFF3E053
+:1000880050A010A9EECFEF3319F0EE3319F0E9CFF5
+:10009800F098E7CFF09AE5CF46B14F734A991BC065
+:1000A80059B07FB658204529542E5094F1E010815C
+:1000B800F099F3E050A24123152D182110AB408B85
+:1000C800ED3021F4F09B3068F09900687FBE77240A
+:1000D800F1E0FCBB1895E42F4E990AC0F09904C0D2
+:1000E800F1E050A010A9F4CFF3E050A010A9F0CF90
+:1000F800EF3319F0EE3319F0EBCFF098E9CFF09A1F
+:10010800E7CFF89400E00093600000E80093F20065
+:1001180004E20093F20000E10093F00004E0009391
+:10012800F00000E80093610000E2009361000FEF27
+:100138000A95F1F703E0009307010FE70093080120
+:1001480000E80093200000C005B7046005BF0FEF6A
+:100158000DBF08E00EBF00E80093500000E80FBD97
+:10016800F098F198772400EC802E01E2D02E0FEF62
+:10017800502E182DFF24DFEF20E1E0E1F1E080A20E
+:10018800008B71922A95D9F7B2E0A0E1EAE3F0E09A
+:1001980020E15ED1A0E2EAE0F0E020E159D1A0E35D
+:1001A800EAE1F0E020E254D1AA27B1E0EAE4F0E085
+:1001B80020E14ED120E1E0E1F3E080A2008B7192D2
+:1001C8002A95D9F720E1E0E6F2E071922A95E9F75D
+:1001D800F1E0EE276F2E709289007092880070927D
+:1001E8008B0070928A00219A229A02EA009380007A
+:1001F80009E1009381002AED709287002093860020
+:100208000FE00093690003E00CBB03E00DBBE0E1E5
+:10021800332700270024442411242224AA24282D2B
+:10022800782D992466273324AA27BB27882799275E
+:10023800CC24BB24D4E0CCE602E0088300E00983A8
+:10024800D4E21880D2E07894C6B3C0FFFDCFC6BB15
+:100258003A94AAF4309016015091160335160CF40E
+:10026800352E3A9466946E2CF794E79438630863B5
+:10027800E0FE377CE0FE077C660C6E24669437FF50
+:1002880006C0C0911D0198882FE13F770CC097FCEC
+:1002980013C001970CF081F42A952AF42FE191FC00
+:1002A8009F2692FC982880911B0190911C01C22FD7
+:1002B8005FE190FEC527C8A807FF06C0C0911D03CF
+:1002C80068897FE10F770CC067FD13C011970CF0A8
+:1002D80081F47A952AF47FE161FD6F2762FD682930
+:1002E800A0911B03B0911C03C72F5FE160FFC527D6
+:1002F800B8A8F19B2CC0D1E2C0E60880D0922100BA
+:10030800019B05C0C0E10880D09221003F27C0E6CC
+:100318002882C2E60880D0922100019B06C0C2E173
+:100328000880D092210052E03527C2E62882C4E630
+:100338000880D0922100019B06C0C4E10880D092B9
+:10034800210054E03527C4E62882F19831C0D1E273
+:10035800C6E60880D0922100019B07C0D3E2C0E125
+:100368000880D09221000F27D1E2C6E62882C8E68D
+:100378000880D0922100019B08C0D3E2C2E1088026
+:10038800D092210052E00527D1E2C8E62882CAE6C9
+:100398000880D0922100019B08C0D3E2C4E1088004
+:1003A800D092210054E00527D1E2CAE62882F19ACA
+:1003B80050911701532BC52FCC0FC2955C23D2E067
+:1003C800C09118010C2CC4FF08A050FF0024C09154
+:1003D80019014C2CC4FF48A051FF4424C0911A01B4
+:1003E8001C2CC4FF18A052FF1124C42D4694469417
+:1003F800C4194694C4190C0E1C0E50911703502BA7
+:10040800C52FCC0FC2955C23C09118032B2CC4FFB9
+:1004180028A050FF2224C09119034B2CC4FF48A0E8
+:1004280051FF4424C0911A03AB2CC4FFA8A052FF6B
+:10043800AA24C42D46944694C4194694C4192C0E73
+:10044800AC0E020C1A0C0092880010928A00FCCEA6
+:0A04580005910D932A95E1F7089530
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_50MHz_AY.hex b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_50MHz_AY.hex
new file mode 100644
index 0000000..626d407
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_50MHz_AY.hex
@@ -0,0 +1,74 @@
+:020000020000FC
+:0200000084C0BA
+:020004002AC010
+:100008004BC0000101010202030506090D11161D6E
+:10001800242D000001010101010102020202030373
+:100028000505060607090B0D0F111316191D2024C7
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B990AC01AB957B84A99FECF77B82B
+:100068007AB8F1E042E04CBB1895E6B1EF734F99CE
+:100078000AC0F09904C0F1E050A010A9F2CFF3E053
+:1000880050A010A9EECFEF3319F0EE3319F0E9CFF5
+:10009800F098E7CFF09AE5CF46B14F734A991BC065
+:1000A80059B07FB658204529542E5094F1E010815C
+:1000B800F099F3E050A24123152D182110AB408B85
+:1000C800ED3021F4F09B3068F09900687FBE77240A
+:1000D800F1E0FCBB1895E42F4E990AC0F09904C0D2
+:1000E800F1E050A010A9F4CFF3E050A010A9F0CF90
+:1000F800EF3319F0EE3319F0EBCFF098E9CFF09A1F
+:10010800E7CFF89400E00093600000E80093F20065
+:1001180004E20093F20000E10093F00004E0009391
+:10012800F00000E80093610000E2009361000FEF27
+:100138000A95F1F703E0009307010FE70093080120
+:1001480000E80093200000C005B7046005BF0FEF6A
+:100158000DBF08E00EBF00E80093500000E80FBD97
+:10016800F098F198772400EC802E01E2D02E0FEF62
+:10017800502E182DFF24DFEF20E1E0E1F1E080A20E
+:10018800008B71922A95D9F7B2E0A0E1EAE3F0E09A
+:1001980020E15ED1A0E2EAE0F0E020E159D1A0E35D
+:1001A800EAE1F0E020E254D1AA27B1E0EAE4F0E085
+:1001B80020E14ED120E1E0E1F3E080A2008B7192D2
+:1001C8002A95D9F720E1E0E6F2E071922A95E9F75D
+:1001D800F1E0EE276F2E709289007092880070927D
+:1001E8008B0070928A00219A229A02EA009380007A
+:1001F80009E10093810025EE709287002093860024
+:100208000FE00093690003E00CBB03E00DBBE0E1E5
+:10021800332700270024442411242224AA24282D2B
+:10022800782D992466273324AA27BB27882799275E
+:10023800CC24BB24D4E0CCE602E0088300E00983A8
+:10024800D4E21880D2E07894C6B3C0FFFDCFC6BB15
+:100258003A94AAF4309016015091160335160CF40E
+:10026800352E3A9466946E2CF794E79438630863B5
+:10027800E0FE377CE0FE077C660C6E24669437FF50
+:1002880006C0C0911D0198882FE13F770CC097FCEC
+:1002980013C001970CF081F42A952AF42FE191FC00
+:1002A8009F2692FC982880911B0190911C01C22FD7
+:1002B8005FE190FEC527C8A807FF06C0C0911D03CF
+:1002C80068897FE10F770CC067FD13C011970CF0A8
+:1002D80081F47A952AF47FE161FD6F2762FD682930
+:1002E800A0911B03B0911C03C72F5FE160FFC527D6
+:1002F800B8A8F19B2CC0D1E2C0E60880D0922100BA
+:10030800019B05C0C0E10880D09221003F27C0E6CC
+:100318002882C2E60880D0922100019B06C0C2E173
+:100328000880D092210052E03527C2E62882C4E630
+:100338000880D0922100019B06C0C4E10880D092B9
+:10034800210054E03527C4E62882F19831C0D1E273
+:10035800C6E60880D0922100019B07C0D3E2C0E125
+:100368000880D09221000F27D1E2C6E62882C8E68D
+:100378000880D0922100019B08C0D3E2C2E1088026
+:10038800D092210052E00527D1E2C8E62882CAE6C9
+:100398000880D0922100019B08C0D3E2C4E1088004
+:1003A800D092210054E00527D1E2CAE62882F19ACA
+:1003B80050911701532BC52FCC0FC2955C23D2E067
+:1003C800C09118010C2CC4FF08A050FF0024C09154
+:1003D80019014C2CC4FF48A051FF4424C0911A01B4
+:1003E8001C2CC4FF18A052FF1124C42D4694469417
+:1003F800C4194694C4190C0E1C0E50911703502BA7
+:10040800C52FCC0FC2955C23C09118032B2CC4FFB9
+:1004180028A050FF2224C09119034B2CC4FF48A0E8
+:1004280051FF4424C0911A03AB2CC4FFA8A052FF6B
+:10043800AA24C42D46944694C4194694C4192C0E73
+:10044800AC0E020C1A0C0092880010928A00FCCEA6
+:0A04580005910D932A95E1F7089530
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_50MHz_YM.hex b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_50MHz_YM.hex
new file mode 100644
index 0000000..761efec
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_EXT_50MHz_YM.hex
@@ -0,0 +1,74 @@
+:020000020000FC
+:0200000084C0BA
+:020004002AC010
+:100008004BC0000101010202030405070A0D121882
+:10001800222D000001010101010102020202020376
+:10002800030404050607080A0B0D0F1215181D22F4
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B990AC01AB957B84A99FECF77B82B
+:100068007AB8F1E042E04CBB1895E6B1EF734F99CE
+:100078000AC0F09904C0F1E050A010A9F2CFF3E053
+:1000880050A010A9EECFEF3319F0EE3319F0E9CFF5
+:10009800F098E7CFF09AE5CF46B14F734A991BC065
+:1000A80059B07FB658204529542E5094F1E010815C
+:1000B800F099F3E050A24123152D182110AB408B85
+:1000C800ED3021F4F09B3068F09900687FBE77240A
+:1000D800F1E0FCBB1895E42F4E990AC0F09904C0D2
+:1000E800F1E050A010A9F4CFF3E050A010A9F0CF90
+:1000F800EF3319F0EE3319F0EBCFF098E9CFF09A1F
+:10010800E7CFF89400E00093600000E80093F20065
+:1001180004E20093F20000E10093F00004E0009391
+:10012800F00000E80093610000E2009361000FEF27
+:100138000A95F1F703E0009307010FE70093080120
+:1001480000E80093200000C005B7046005BF0FEF6A
+:100158000DBF08E00EBF00E80093500000E80FBD97
+:10016800F098F198772400EC802E01E2D02E0FEF62
+:10017800502E182DFF24DFEF20E1E0E1F1E080A20E
+:10018800008B71922A95D9F7B2E0A0E1EAE3F0E09A
+:1001980020E15ED1A0E2EAE0F0E020E159D1A0E35D
+:1001A800EAE1F0E020E254D1AA27B1E0EAE4F0E085
+:1001B80020E14ED120E1E0E1F3E080A2008B7192D2
+:1001C8002A95D9F720E1E0E6F2E071922A95E9F75D
+:1001D800F1E0EE276F2E709289007092880070927D
+:1001E8008B0070928A00219A229A02EA009380007A
+:1001F80009E10093810025EE709287002093860024
+:100208000FE00093690003E00CBB03E00DBBE0E1E5
+:10021800332700270024442411242224AA24282D2B
+:10022800782D992466273324AA27BB27882799275E
+:10023800CC24BB24D4E0CCE602E0088300E00983A8
+:10024800D4E21880D2E07894C6B3C0FFFDCFC6BB15
+:100258003A94AAF4309016015091160335160CF40E
+:10026800352E3A9466946E2CF794E79438630863B5
+:10027800E0FE377CE0FE077C660C6E24669437FF50
+:1002880006C0C0911D0198882FE13F770CC097FCEC
+:1002980013C001970CF081F42A952AF42FE191FC00
+:1002A8009F2692FC982880911B0190911C01C22FD7
+:1002B8005FE190FEC527C8A807FF06C0C0911D03CF
+:1002C80068897FE10F770CC067FD13C011970CF0A8
+:1002D80081F47A952AF47FE161FD6F2762FD682930
+:1002E800A0911B03B0911C03C72F5FE160FFC527D6
+:1002F800B8A8F19B2CC0D1E2C0E60880D0922100BA
+:10030800019B05C0C0E10880D09221003F27C0E6CC
+:100318002882C2E60880D0922100019B06C0C2E173
+:100328000880D092210052E03527C2E62882C4E630
+:100338000880D0922100019B06C0C4E10880D092B9
+:10034800210054E03527C4E62882F19831C0D1E273
+:10035800C6E60880D0922100019B07C0D3E2C0E125
+:100368000880D09221000F27D1E2C6E62882C8E68D
+:100378000880D0922100019B08C0D3E2C2E1088026
+:10038800D092210052E00527D1E2C8E62882CAE6C9
+:100398000880D0922100019B08C0D3E2C4E1088004
+:1003A800D092210054E00527D1E2CAE62882F19ACA
+:1003B80050911701532BC52FCC0FC2955C23D2E067
+:1003C800C09118010C2CC4FF08A050FF0024C09154
+:1003D80019014C2CC4FF48A051FF4424C0911A01B4
+:1003E8001C2CC4FF18A052FF1124C42D4694469417
+:1003F800C4194694C4190C0E1C0E50911703502BA7
+:10040800C52FCC0FC2955C23C09118032B2CC4FFB9
+:1004180028A050FF2224C09119034B2CC4FF48A0E8
+:1004280051FF4424C0911A03AB2CC4FFA8A052FF6B
+:10043800AA24C42D46944694C4194694C4192C0E73
+:10044800AC0E020C1A0C0092880010928A00FCCEA6
+:0A04580005910D932A95E1F7089530
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/Release/TS_Emu_INT_32MHz_AY.hex b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_INT_32MHz_AY.hex
new file mode 100644
index 0000000..748a2b1
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_INT_32MHz_AY.hex
@@ -0,0 +1,74 @@
+:020000020000FC
+:0200000084C0BA
+:020004002AC010
+:100008004BC0000101010202030506090D11161D6E
+:10001800242D000001010101010102020202030373
+:100028000505060607090B0D0F111316191D2024C7
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B990AC01AB957B84A99FECF77B82B
+:100068007AB8F1E042E04CBB1895E6B1EF734F99CE
+:100078000AC0F09904C0F1E050A010A9F2CFF3E053
+:1000880050A010A9EECFEF3319F0EE3319F0E9CFF5
+:10009800F098E7CFF09AE5CF46B14F734A991BC065
+:1000A80059B07FB658204529542E5094F1E010815C
+:1000B800F099F3E050A24123152D182110AB408B85
+:1000C800ED3021F4F09B3068F09900687FBE77240A
+:1000D800F1E0FCBB1895E42F4E990AC0F09904C0D2
+:1000E800F1E050A010A9F4CFF3E050A010A9F0CF90
+:1000F800EF3319F0EE3319F0EBCFF098E9CFF09A1F
+:10010800E7CFF89400E00093600008ED0093340016
+:1001180000E80093610008ED0093340000E00093CC
+:10012800610008ED0093340004E0009305010FEF2F
+:100138000A95F1F703E0009307010FE70093080120
+:1001480000E80093200000C005B7046005BF0FEF6A
+:100158000DBF08E00EBF00E80093500000E80FBD97
+:10016800F098F198772400EC802E01E2D02E0FEF62
+:10017800502E182DFF24DFEF20E1E0E1F1E080A20E
+:10018800008B71922A95D9F7B2E0A0E1EAE3F0E09A
+:1001980020E15ED1A0E2EAE0F0E020E159D1A0E35D
+:1001A800EAE1F0E020E254D1AA27B1E0EAE4F0E085
+:1001B80020E14ED120E1E0E1F3E080A2008B7192D2
+:1001C8002A95D9F720E1E0E6F2E071922A95E9F75D
+:1001D800F1E0EE276F2E709289007092880070927D
+:1001E8008B0070928A00219A229A02EA009380007A
+:1001F80009E10093810021E970928700209386002D
+:100208000FE00093690003E00CBB03E00DBBE0E1E5
+:10021800332700270024442411242224AA24282D2B
+:10022800782D992466273324AA27BB27882799275E
+:10023800CC24BB24D4E0CCE602E0088300E00983A8
+:10024800D4E21880D2E07894C6B3C0FFFDCFC6BB15
+:100258003A94AAF4309016015091160335160CF40E
+:10026800352E3A9466946E2CF794E79438630863B5
+:10027800E0FE377CE0FE077C660C6E24669437FF50
+:1002880006C0C0911D0198882FE13F770CC097FCEC
+:1002980013C001970CF081F42A952AF42FE191FC00
+:1002A8009F2692FC982880911B0190911C01C22FD7
+:1002B8005FE190FEC527C8A807FF06C0C0911D03CF
+:1002C80068897FE10F770CC067FD13C011970CF0A8
+:1002D80081F47A952AF47FE161FD6F2762FD682930
+:1002E800A0911B03B0911C03C72F5FE160FFC527D6
+:1002F800B8A8F19B2CC0D1E2C0E60880D0922100BA
+:10030800019B05C0C0E10880D09221003F27C0E6CC
+:100318002882C2E60880D0922100019B06C0C2E173
+:100328000880D092210052E03527C2E62882C4E630
+:100338000880D0922100019B06C0C4E10880D092B9
+:10034800210054E03527C4E62882F19831C0D1E273
+:10035800C6E60880D0922100019B07C0D3E2C0E125
+:100368000880D09221000F27D1E2C6E62882C8E68D
+:100378000880D0922100019B08C0D3E2C2E1088026
+:10038800D092210052E00527D1E2C8E62882CAE6C9
+:100398000880D0922100019B08C0D3E2C4E1088004
+:1003A800D092210054E00527D1E2CAE62882F19ACA
+:1003B80050911701532BC52FCC0FC2955C23D2E067
+:1003C800C09118010C2CC4FF08A050FF0024C09154
+:1003D80019014C2CC4FF48A051FF4424C0911A01B4
+:1003E8001C2CC4FF18A052FF1124C42D4694469417
+:1003F800C4194694C4190C0E1C0E50911703502BA7
+:10040800C52FCC0FC2955C23C09118032B2CC4FFB9
+:1004180028A050FF2224C09119034B2CC4FF48A0E8
+:1004280051FF4424C0911A03AB2CC4FFA8A052FF6B
+:10043800AA24C42D46944694C4194694C4192C0E73
+:10044800AC0E020C1A0C0092880010928A00FCCEA6
+:0A04580005910D932A95E1F7089530
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/Release/TS_Emu_INT_32MHz_YM.hex b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_INT_32MHz_YM.hex
new file mode 100644
index 0000000..832c55d
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_INT_32MHz_YM.hex
@@ -0,0 +1,74 @@
+:020000020000FC
+:0200000084C0BA
+:020004002AC010
+:100008004BC0000101010202030405070A0D121882
+:10001800222D000001010101010102020202020376
+:10002800030404050607080A0B0D0F1215181D22F4
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B990AC01AB957B84A99FECF77B82B
+:100068007AB8F1E042E04CBB1895E6B1EF734F99CE
+:100078000AC0F09904C0F1E050A010A9F2CFF3E053
+:1000880050A010A9EECFEF3319F0EE3319F0E9CFF5
+:10009800F098E7CFF09AE5CF46B14F734A991BC065
+:1000A80059B07FB658204529542E5094F1E010815C
+:1000B800F099F3E050A24123152D182110AB408B85
+:1000C800ED3021F4F09B3068F09900687FBE77240A
+:1000D800F1E0FCBB1895E42F4E990AC0F09904C0D2
+:1000E800F1E050A010A9F4CFF3E050A010A9F0CF90
+:1000F800EF3319F0EE3319F0EBCFF098E9CFF09A1F
+:10010800E7CFF89400E00093600008ED0093340016
+:1001180000E80093610008ED0093340000E00093CC
+:10012800610008ED0093340004E0009305010FEF2F
+:100138000A95F1F703E0009307010FE70093080120
+:1001480000E80093200000C005B7046005BF0FEF6A
+:100158000DBF08E00EBF00E80093500000E80FBD97
+:10016800F098F198772400EC802E01E2D02E0FEF62
+:10017800502E182DFF24DFEF20E1E0E1F1E080A20E
+:10018800008B71922A95D9F7B2E0A0E1EAE3F0E09A
+:1001980020E15ED1A0E2EAE0F0E020E159D1A0E35D
+:1001A800EAE1F0E020E254D1AA27B1E0EAE4F0E085
+:1001B80020E14ED120E1E0E1F3E080A2008B7192D2
+:1001C8002A95D9F720E1E0E6F2E071922A95E9F75D
+:1001D800F1E0EE276F2E709289007092880070927D
+:1001E8008B0070928A00219A229A02EA009380007A
+:1001F80009E10093810021E970928700209386002D
+:100208000FE00093690003E00CBB03E00DBBE0E1E5
+:10021800332700270024442411242224AA24282D2B
+:10022800782D992466273324AA27BB27882799275E
+:10023800CC24BB24D4E0CCE602E0088300E00983A8
+:10024800D4E21880D2E07894C6B3C0FFFDCFC6BB15
+:100258003A94AAF4309016015091160335160CF40E
+:10026800352E3A9466946E2CF794E79438630863B5
+:10027800E0FE377CE0FE077C660C6E24669437FF50
+:1002880006C0C0911D0198882FE13F770CC097FCEC
+:1002980013C001970CF081F42A952AF42FE191FC00
+:1002A8009F2692FC982880911B0190911C01C22FD7
+:1002B8005FE190FEC527C8A807FF06C0C0911D03CF
+:1002C80068897FE10F770CC067FD13C011970CF0A8
+:1002D80081F47A952AF47FE161FD6F2762FD682930
+:1002E800A0911B03B0911C03C72F5FE160FFC527D6
+:1002F800B8A8F19B2CC0D1E2C0E60880D0922100BA
+:10030800019B05C0C0E10880D09221003F27C0E6CC
+:100318002882C2E60880D0922100019B06C0C2E173
+:100328000880D092210052E03527C2E62882C4E630
+:100338000880D0922100019B06C0C4E10880D092B9
+:10034800210054E03527C4E62882F19831C0D1E273
+:10035800C6E60880D0922100019B07C0D3E2C0E125
+:100368000880D09221000F27D1E2C6E62882C8E68D
+:100378000880D0922100019B08C0D3E2C2E1088026
+:10038800D092210052E00527D1E2C8E62882CAE6C9
+:100398000880D0922100019B08C0D3E2C4E1088004
+:1003A800D092210054E00527D1E2CAE62882F19ACA
+:1003B80050911701532BC52FCC0FC2955C23D2E067
+:1003C800C09118010C2CC4FF08A050FF0024C09154
+:1003D80019014C2CC4FF48A051FF4424C0911A01B4
+:1003E8001C2CC4FF18A052FF1124C42D4694469417
+:1003F800C4194694C4190C0E1C0E50911703502BA7
+:10040800C52FCC0FC2955C23C09118032B2CC4FFB9
+:1004180028A050FF2224C09119034B2CC4FF48A0E8
+:1004280051FF4424C0911A03AB2CC4FFA8A052FF6B
+:10043800AA24C42D46944694C4194694C4192C0E73
+:10044800AC0E020C1A0C0092880010928A00FCCEA6
+:0A04580005910D932A95E1F7089530
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/Release/TS_Emu_INT_37MHz_AY.hex b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_INT_37MHz_AY.hex
new file mode 100644
index 0000000..708db06
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_INT_37MHz_AY.hex
@@ -0,0 +1,74 @@
+:020000020000FC
+:0200000084C0BA
+:020004002AC010
+:100008004BC0000101010202030506090D11161D6E
+:10001800242D000001010101010102020202030373
+:100028000505060607090B0D0F111316191D2024C7
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B990AC01AB957B84A99FECF77B82B
+:100068007AB8F1E042E04CBB1895E6B1EF734F99CE
+:100078000AC0F09904C0F1E050A010A9F2CFF3E053
+:1000880050A010A9EECFEF3319F0EE3319F0E9CFF5
+:10009800F098E7CFF09AE5CF46B14F734A991BC065
+:1000A80059B07FB658204529542E5094F1E010815C
+:1000B800F099F3E050A24123152D182110AB408B85
+:1000C800ED3021F4F09B3068F09900687FBE77240A
+:1000D800F1E0FCBB1895E42F4E990AC0F09904C0D2
+:1000E800F1E050A010A9F4CFF3E050A010A9F0CF90
+:1000F800EF3319F0EE3319F0EBCFF098E9CFF09A1F
+:10010800E7CFF89400E00093600008ED0093340016
+:1001180000E80093610008ED0093340000E00093CC
+:10012800610008ED0093340004E00093050100EE3F
+:10013800009366000FEF0A95F1F703E000930701BB
+:100148000FE70093080100E80093200000C005B7FE
+:10015800046005BF0FEF0DBF08E00EBF00E8009375
+:10016800500000E80FBDF098F198772400EC802E3D
+:1001780001E2D02E0FEF502E182DFF24DFEF20E1E3
+:10018800E0E1F1E080A2008B71922A95D9F7B2E004
+:10019800A0E1EAE3F0E020E15ED1A0E2EAE0F0E0ED
+:1001A80020E159D1A0E3EAE1F0E020E254D1AA2706
+:1001B800B1E0EAE4F0E020E14ED120E1E0E1F3E053
+:1001C80080A2008B71922A95D9F720E1E0E6F2E04F
+:1001D80071922A95E9F7F1E0EE276F2E7092890067
+:1001E8007092880070928B0070928A00219A229AED
+:1001F80002EA0093800009E1009381002DEA7092E1
+:100208008700209386000FE00093690003E00CBB91
+:1002180003E00DBBE0E13327002700244424112428
+:100228002224AA24282D782D992466273324AA2746
+:10023800BB2788279927CC24BB24D4E0CCE602E04E
+:10024800088300E00983D4E21880D2E07894C6B32A
+:10025800C0FFFDCFC6BB3A94AAF430901601509166
+:10026800160335160CF4352E3A9466946E2CF794D2
+:10027800E79438630863E0FE377CE0FE077C660C91
+:100288006E24669437FF06C0C0911D0198882FE13F
+:100298003F770CC097FC13C001970CF081F42A95A6
+:1002A8002AF42FE191FC9F2692FC982880911B014B
+:1002B80090911C01C22F5FE190FEC527C8A807FFD7
+:1002C80006C0C0911D0368897FE10F770CC067FDE8
+:1002D80013C011970CF081F47A952AF47FE161FD3F
+:1002E8006F2762FD6829A0911B03B0911C03C72FDB
+:1002F8005FE160FFC527B8A8F19B2CC0D1E2C0E63A
+:100308000880D0922100019B05C0C0E10880D092EE
+:1003180021003F27C0E62882C2E60880D09221004B
+:10032800019B06C0C2E10880D092210052E0352727
+:10033800C2E62882C4E60880D0922100019B06C04C
+:10034800C4E10880D092210054E03527C4E6288211
+:10035800F19831C0D1E2C6E60880D0922100019B15
+:1003680007C0D3E2C0E10880D09221000F27D1E274
+:10037800C6E62882C8E60880D0922100019B08C002
+:10038800D3E2C2E10880D092210052E00527D1E2F1
+:10039800C8E62882CAE60880D0922100019B08C0DE
+:1003A800D3E2C4E10880D092210054E00527D1E2CD
+:1003B800CAE62882F19A50911701532BC52FCC0F0A
+:1003C800C2955C23D2E0C09118010C2CC4FF08A090
+:1003D80050FF0024C09119014C2CC4FF48A051FFC4
+:1003E8004424C0911A011C2CC4FF18A052FF1124E8
+:1003F800C42D46944694C4194694C4190C0E1C0E78
+:1004080050911703502BC52FCC0FC2955C23C09178
+:1004180018032B2CC4FF28A050FF2224C0911903D5
+:100428004B2CC4FF48A051FF4424C0911A03AB2CA5
+:10043800C4FFA8A052FFAA24C42D46944694C41908
+:100448004694C4192C0EAC0E020C1A0C00928800AB
+:1004580010928A00FCCE05910D932A95E1F7089534
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/Release/TS_Emu_INT_37MHz_YM.hex b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_INT_37MHz_YM.hex
new file mode 100644
index 0000000..904029f
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/TS_Emu_INT_37MHz_YM.hex
@@ -0,0 +1,74 @@
+:020000020000FC
+:0200000084C0BA
+:020004002AC010
+:100008004BC0000101010202030405070A0D121882
+:10001800222D000001010101010102020202020376
+:10002800030404050607080A0B0D0F1215181D22F4
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B990AC01AB957B84A99FECF77B82B
+:100068007AB8F1E042E04CBB1895E6B1EF734F99CE
+:100078000AC0F09904C0F1E050A010A9F2CFF3E053
+:1000880050A010A9EECFEF3319F0EE3319F0E9CFF5
+:10009800F098E7CFF09AE5CF46B14F734A991BC065
+:1000A80059B07FB658204529542E5094F1E010815C
+:1000B800F099F3E050A24123152D182110AB408B85
+:1000C800ED3021F4F09B3068F09900687FBE77240A
+:1000D800F1E0FCBB1895E42F4E990AC0F09904C0D2
+:1000E800F1E050A010A9F4CFF3E050A010A9F0CF90
+:1000F800EF3319F0EE3319F0EBCFF098E9CFF09A1F
+:10010800E7CFF89400E00093600008ED0093340016
+:1001180000E80093610008ED0093340000E00093CC
+:10012800610008ED0093340004E00093050100EE3F
+:10013800009366000FEF0A95F1F703E000930701BB
+:100148000FE70093080100E80093200000C005B7FE
+:10015800046005BF0FEF0DBF08E00EBF00E8009375
+:10016800500000E80FBDF098F198772400EC802E3D
+:1001780001E2D02E0FEF502E182DFF24DFEF20E1E3
+:10018800E0E1F1E080A2008B71922A95D9F7B2E004
+:10019800A0E1EAE3F0E020E15ED1A0E2EAE0F0E0ED
+:1001A80020E159D1A0E3EAE1F0E020E254D1AA2706
+:1001B800B1E0EAE4F0E020E14ED120E1E0E1F3E053
+:1001C80080A2008B71922A95D9F720E1E0E6F2E04F
+:1001D80071922A95E9F7F1E0EE276F2E7092890067
+:1001E8007092880070928B0070928A00219A229AED
+:1001F80002EA0093800009E1009381002DEA7092E1
+:100208008700209386000FE00093690003E00CBB91
+:1002180003E00DBBE0E13327002700244424112428
+:100228002224AA24282D782D992466273324AA2746
+:10023800BB2788279927CC24BB24D4E0CCE602E04E
+:10024800088300E00983D4E21880D2E07894C6B32A
+:10025800C0FFFDCFC6BB3A94AAF430901601509166
+:10026800160335160CF4352E3A9466946E2CF794D2
+:10027800E79438630863E0FE377CE0FE077C660C91
+:100288006E24669437FF06C0C0911D0198882FE13F
+:100298003F770CC097FC13C001970CF081F42A95A6
+:1002A8002AF42FE191FC9F2692FC982880911B014B
+:1002B80090911C01C22F5FE190FEC527C8A807FFD7
+:1002C80006C0C0911D0368897FE10F770CC067FDE8
+:1002D80013C011970CF081F47A952AF47FE161FD3F
+:1002E8006F2762FD6829A0911B03B0911C03C72FDB
+:1002F8005FE160FFC527B8A8F19B2CC0D1E2C0E63A
+:100308000880D0922100019B05C0C0E10880D092EE
+:1003180021003F27C0E62882C2E60880D09221004B
+:10032800019B06C0C2E10880D092210052E0352727
+:10033800C2E62882C4E60880D0922100019B06C04C
+:10034800C4E10880D092210054E03527C4E6288211
+:10035800F19831C0D1E2C6E60880D0922100019B15
+:1003680007C0D3E2C0E10880D09221000F27D1E274
+:10037800C6E62882C8E60880D0922100019B08C002
+:10038800D3E2C2E10880D092210052E00527D1E2F1
+:10039800C8E62882CAE60880D0922100019B08C0DE
+:1003A800D3E2C4E10880D092210054E00527D1E2CD
+:1003B800CAE62882F19A50911701532BC52FCC0F0A
+:1003C800C2955C23D2E0C09118010C2CC4FF08A090
+:1003D80050FF0024C09119014C2CC4FF48A051FFC4
+:1003E8004424C0911A011C2CC4FF18A052FF1124E8
+:1003F800C42D46944694C4194694C4190C0E1C0E78
+:1004080050911703502BC52FCC0FC2955C23C09178
+:1004180018032B2CC4FF28A050FF2224C0911903D5
+:100428004B2CC4FF48A051FF4424C0911A03AB2CA5
+:10043800C4FFA8A052FFAA24C42D46944694C41908
+:100448004694C4192C0EAC0E020C1A0C00928800AB
+:1004580010928A00FCCE05910D932A95E1F7089534
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/Release/YM_Emu_INT_37MHz_Auto_Calib.hex b/Sources/AY_Emu/AY_Emu/Release/YM_Emu_INT_37MHz_Auto_Calib.hex
new file mode 100644
index 0000000..a2d12f5
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/Release/YM_Emu_INT_37MHz_Auto_Calib.hex
@@ -0,0 +1,84 @@
+:020000020000FC
+:0200000084C0BA
+:020004002AC010
+:100008004BC0000101010202030405070A0D121882
+:10001800222D000001010101010102020202020376
+:10002800030404050607080A0B0D0F1215181D22F4
+:10003800282D070707070404040401070305000621
+:100048000204FF0FFF0FFF0F1FFF1F1F1FFFFF0FF0
+:10005800FFFF4B990AC01AB957B84A99FECF77B82B
+:100068007AB8F1E042E04CBB1895E6B1EF734F99CE
+:100078000AC0F09904C0F1E050A010A9F2CFF3E053
+:1000880050A010A9EECFEF3319F0EE3319F0E9CFF5
+:10009800F098E7CFF09AE5CF46B14F734A991BC065
+:1000A80059B07FB658204529542E5094F1E010815C
+:1000B800F099F3E050A24123152D182110AB408B85
+:1000C800ED3021F4F09B3068F09900687FBE77240A
+:1000D800F1E0FCBB1895E42F4E990AC0F09904C0D2
+:1000E800F1E050A010A9F4CFF3E050A010A9F0CF90
+:1000F800EF3319F0EE3319F0EBCFF098E9CFF09A1F
+:10010800E7CFF89400E00093600008ED0093340016
+:1001180000E80093610008ED0093340000E00093CC
+:10012800610008ED0093340004E00093050100EE3F
+:10013800009366000FEF0A95F1F703E000930701BB
+:100148000FE70093080100E80093200000C005B7FE
+:10015800046005BF0FEF0DBF08E00EBF00E8009375
+:10016800500000E80FBDF098F198772400EC802E3D
+:1001780001E2D02E0FEF502E182DFF24DFEF20E1E3
+:10018800E0E1F1E080A2008B71922A95D9F7B2E004
+:10019800A0E1EAE3F0E020E1AED1A0E2EAE0F0E09D
+:1001A80020E1A9D1A0E3EAE1F0E020E2A4D1AA2766
+:1001B800B1E0EAE4F0E020E19ED120E1E0E1F3E003
+:1001C80080A2008B71922A95D9F720E1E0E6F2E04F
+:1001D80071922A95E9F7F1E0EE276F2E7092890067
+:1001E8007092880070928B0070928A00219A229AED
+:1001F80000240027009380000027009385000093C7
+:10020800840007E000938100002704BD002706BD95
+:1002180001E005BB01E005BDA0EDB7E005B300FFB7
+:10022800FDCF01E005BB1197C9F700270093250012
+:10023800009381004091840050918500002700932D
+:10024800850000938400442311F45523F1F060E005
+:1002580070E82EE3A42FB52FB695A7956A0F7B1FDC
+:10026800271D88279927222319F46417750738F062
+:10027800641B750B27098395B1F79395F4CF8150CB
+:100288009040992311F4C82F009402EA009380004B
+:1002980009E1009381002DEA002009F02C2F7092CB
+:1002A8008700209386000FE00093690003E00CBBF1
+:1002B80003E00DBBE0E13327002700244424112488
+:1002C8002224AA24282D782D992466273324AA27A6
+:1002D800BB2788279927CC24BB24D4E0CCE602E0AE
+:1002E800088300E00983D4E21880D2E07894C6B38A
+:1002F800C0FFFDCFC6BB3A94AAF4309016015091C6
+:10030800160335160CF4352E3A9466946E2CF79431
+:10031800E79438630863E0FE377CE0FE077C660CF0
+:100328006E24669437FF06C0C0911D0198882FE19E
+:100338003F770CC097FC13C001970CF081F42A9505
+:100348002AF42FE191FC9F2692FC982880911B01AA
+:1003580090911C01C22F5FE190FEC527C8A807FF36
+:1003680006C0C0911D0368897FE10F770CC067FD47
+:1003780013C011970CF081F47A952AF47FE161FD9E
+:100388006F2762FD6829A0911B03B0911C03C72F3A
+:100398005FE160FFC527B8A8F19B2CC0D1E2C0E699
+:1003A8000880D0922100019B05C0C0E10880D0924E
+:1003B80021003F27C0E62882C2E60880D0922100AB
+:1003C800019B06C0C2E10880D092210052E0352787
+:1003D800C2E62882C4E60880D0922100019B06C0AC
+:1003E800C4E10880D092210054E03527C4E6288271
+:1003F800F19831C0D1E2C6E60880D0922100019B75
+:1004080007C0D3E2C0E10880D09221000F27D1E2D3
+:10041800C6E62882C8E60880D0922100019B08C061
+:10042800D3E2C2E10880D092210052E00527D1E250
+:10043800C8E62882CAE60880D0922100019B08C03D
+:10044800D3E2C4E10880D092210054E00527D1E22C
+:10045800CAE62882F19A50911701532BC52FCC0F69
+:10046800C2955C23D2E0C09118010C2CC4FF08A0EF
+:1004780050FF0024C09119014C2CC4FF48A051FF23
+:100488004424C0911A011C2CC4FF18A052FF112447
+:10049800C42D46944694C4194694C4190C0E1C0ED7
+:1004A80050911703502BC52FCC0FC2955C23C091D8
+:1004B80018032B2CC4FF28A050FF2224C091190335
+:1004C8004B2CC4FF48A051FF4424C0911A03AB2C05
+:1004D800C4FFA8A052FFAA24C42D46944694C41968
+:1004E8004694C4192C0EAC0E020C1A0C009288000B
+:1004F80010928A00FCCE05910D932A95E1F7089594
+:00000001FF
diff --git a/Sources/AY_Emu/AY_Emu/deepseek_assembly_20260201_497cab.txt b/Sources/AY_Emu/AY_Emu/deepseek_assembly_20260201_497cab.txt
new file mode 100644
index 0000000..199b82c
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/deepseek_assembly_20260201_497cab.txt
@@ -0,0 +1,1065 @@
+; AY-3-8912 IC emulator version 26.0 for LGT8F328P
+; Эмулятор микросхемы AY-3-8912 версии 26.0 для LGT8F328P
+;
+; Sources for Atmel AVRStudio 7
+; Исходный код для Atmel AVRStudio 7
+;
+; visit our site for more information
+; посетите наш сайт для получения дополнительной информации
+; These source codes are distributed under the GPL v3 license
+; Эти исходные коды распространяются под лицензией GPL v3
+; If you share these sources you should put the link to web site www.avray.ru
+; Если вы делитесь этими исходниками, вы должны указать ссылку на сайт www.avray.ru
+;
+; ORIGIN: http://www.avray.ru
+; ИСТОЧНИК: http://www.avray.ru
+
+; CONFIGURATION VALUES ===================================================
+; КОНФИГУРАЦИОННЫЕ ЗНАЧЕНИЯ ==============================================
+#define CHANNELS 2 ; choose 2 or 3 channel version
+ ; выбрать версию с 2 или 3 каналами
+#define SPEAKER 0 ; use SPEAKER port input on PD1 (0 - no, 1 - yes)
+ ; использовать вход SPEAKER на PD1 (0 - нет, 1 - да)
+#define VOLUME_TABLE 0 ; 0 - AY, 1 - YM, 2 - ALTERNATE volume table
+ ; 0 - таблица громкости AY, 1 - YM, 2 - АЛЬТЕРНАТИВНАЯ
+#define USART_ENABLE 0 ; 0 - OFF, 1 - ON
+ ; 0 - выключено, 1 - включено
+#define INT_ENABLE 1 ; 0 - OFF, 1 - ON
+ ; 0 - выключено, 1 - включено
+#define Enable2MHz 0 ; 0 - 1,75 MHz, 1 - 2MHz
+ ; 0 - 1,75 МГц, 1 - 2МГц
+#define TS_Chip_0 1 ; 0 - OFF, 1 - On Если выключены оба TS_Chip, то будет работать как один стандартный AY
+ ; 0 - выкл, 1 - вкл Если оба TS_Chip выключены, работает как один стандартный AY
+#define TS_Chip_1 0 ; 0 - OFF, 1 - On Для TS версии нельзя выбирать сразу 2 чипа!!!!
+ ; 0 - выкл, 1 - вкл Для TS версии нельзя выбирать сразу 2 чипа!!!!
+; ========================================================================
+; bit numbers:
+; определения битов:
+.equ b0 = 0x00
+.equ b1 = 0x01
+.equ b2 = 0x02
+.equ b3 = 0x03
+.equ b4 = 0x04
+.equ b5 = 0x05
+.equ b6 = 0x06
+.equ b7 = 0x07
+.equ CHIP_SELECTED = GPIOR0 ; регистр выбора чипа
+
+; ===== РАСПРЕДЕЛЕНИЕ РЕГИСТРОВ =====
+; r0 - OutA (выход канала A)
+; r1 - OutC (выход канала C)
+; r2 - C1F (константа 0x1F для инверсии конверта)
+; r3 - CntN (счетчик шума)
+; r4 - OutB (выход канала B)
+; r5 - BusOut1 (маска портов C/D для записи)
+; r6 - NoiseAddon (LFSR шума)
+; r7 - C00 (константа 0x00)
+; r8 - CC0 (константа 0xC0)
+; r9 - TabE (код конверта)
+; r10 - C04 (константа 0x04)
+; r11 - TMP (временный регистр)
+; r12 - EVal (значение конверта)
+; r13 - SREGSave (сохраненный SREG)
+; r14 - RNGL (LFSR шума LOW)
+; r15 - RNGH (LFSR шума HIGH)
+; r16 - BusData (данные шины)
+; r17 - BusOut2 (маска портов для чтения)
+; r18 - TabP (счетчик периода конверта)
+; r19 - TNLevel (уровни тонов и шума)
+; r20 - CntAL (счетчик канала A LOW)
+; r21 - CntAH (счетчик канала A HIGH)
+; r22 - CntBL (счетчик канала B LOW)
+; r23 - CntBH (счетчик канала B HIGH)
+; r24 - CntCL (счетчик канала C LOW)
+; r25 - CntCH (счетчик канала C HIGH)
+; r26 - CntEL (счетчик конверта LOW)
+; r27 - CntEH (счетчик конверта HIGH)
+; r30 - ADDR (адрес регистра, используется как Z)
+
+.def OutA = r0 ; определение псевдонимов для регистров
+.def OutC = r1
+.def C1F = r2
+.def CntN = r3
+.def OutB = r4
+.def BusOut1 = r5
+.def NoiseAddon = r6
+.def C00 = r7
+.def CC0 = r8
+.def TabE = r9
+.def C04 = r10
+.def TMP = r11
+.def EVal = r12
+.def SREGSave = r13
+.def RNGL = r14
+.def RNGH = r15
+.def BusData = r16
+.def BusOut2 = r17
+.def TabP = r18
+.def TNLevel = r19
+.def CntAL = r20
+.def CntAH = r21
+.def CntBL = r22
+.def CntBH = r23
+.def CntCL = r24
+.def CntCH = r25
+.def CntEL = r26
+.def CntEH = r27
+.def ADDR = r30
+
+; ==============================================
+; LGT8F328P REGISTER DEFINITIONS
+; ОПРЕДЕЛЕНИЯ РЕГИСТРОВ LGT8F328P
+; ==============================================
+; Memory-mapped I/O addresses for LGT8F328P
+; Адреса ввода/вывода для LGT8F328P
+.equ CCP = 0x34 ; Configuration Change Protection
+ ; Защита изменения конфигурации
+.equ CLKMSR = 0x105 ; Clock Main Settings Register
+ ; Регистр основных настроек тактирования
+.equ BCR = 0x107 ; Boot Control Register
+ ; Регистр управления загрузчиком
+.equ BOOTEND = 0x108 ; Boot End Address
+ ; Конечный адрес загрузчика
+.equ BODCR = 0x104 ; BOD Control Register
+ ; Регистр управления BOD
+
+; AC0 (Analog Comparator 0) Register Definition
+; Определение регистров AC0 (аналоговый компаратор 0)
+.equ C0SR = 0x50 ; статусный регистр компаратора 0
+.equ C0D = 7 ; бит отключения компаратора
+.equ C0BG = 6 ; бит выбора опорного напряжения
+.equ C0O = 5 ; выход компаратора
+.equ C0I = 4 ; инвертирование выхода
+.equ C0IE = 3 ; разрешение прерывания
+.equ C0IC = 2 ; флаг прерывания
+.equ C0IS1 = 1 ; выбор источника прерывания
+.equ C0IS0 = 0 ; выбор источника прерывания
+
+.equ C0XR = 0x51 ; регистр управления компаратором 0
+.equ C0OE = 6 ; выходной драйвер
+.equ C0HSYE = 5 ; высокоскоростной режим
+.equ C0PS0 = 4 ; положительный вход
+.equ C0WKE = 3 ; пробуждение
+.equ C0FEN = 2 ; фильтр
+.equ C0FS1 = 1 ; выбор фильтра
+.equ C0FS0 = 0 ; выбор фильтра
+
+.equ C0TR = 0x52 ; регистр триггера компаратора 0
+
+; AC1 (Analog Comparator 1) Register Definition
+; Определение регистров AC1 (аналоговый компаратор 1)
+.equ C1SR = 0x2F ; статусный регистр компаратора 1
+.equ C1D = 7 ; бит отключения компаратора
+.equ C1BG = 6 ; бит выбора опорного напряжения
+.equ C1O = 5 ; выход компаратора
+.equ C1I = 4 ; инвертирование выхода
+.equ C1IE = 3 ; разрешение прерывания
+.equ C1IC = 2 ; флаг прерывания
+.equ C1IS1 = 1 ; выбор источника прерывания
+.equ C1IS0 = 0 ; выбор источника прерывания
+
+.equ C1XR = 0x3A ; регистр управления компаратором 1
+.equ C1OE = 6 ; выходной драйвер
+.equ C1HSYE = 5 ; высокоскоростной режим
+.equ C1PS0 = 4 ; положительный вход
+.equ C1WKE = 3 ; пробуждение
+.equ C1FEN = 2 ; фильтр
+.equ C1FS1 = 1 ; выбор фильтра
+.equ C1FS0 = 0 ; выбор фильтра
+
+.equ C1TR = 0x5B ; регистр триггера компаратора 1
+
+; LGT8F328P FAST GPIO REGISTERS
+; РЕГИСТРЫ БЫСТРОГО GPIO LGT8F328P
+.equ FGPIOE = 0x10A ; Fast GPIO Enable Register
+ ; Регистр разрешения быстрого GPIO
+.equ FGPIO = 0x10B ; Fast GPIO Control Register
+ ; Регистр управления быстрым GPIO
+
+ .cseg ; начало сегмента кода
+;------------------------------------------------------
+; INTERRUPT VECTORS TABLE
+; ТАБЛИЦА ВЕКТОРОВ ПРЕРЫВАНИЙ
+;------------------------------------------------------
+ .org 0x0000 ; адрес вектора сброса
+ rjmp _LGT_INIT ; переход к инициализации LGT
+
+ .org INT0addr ; адрес вектора прерывания INT0
+ rjmp _INT0_Handler ; обработчик прерывания INT0
+
+ .org INT1addr ; адрес вектора прерывания INT1
+ rjmp _INT1_Handler ; обработчик прерывания INT1
+
+ .org URXCaddr ; адрес вектора прерывания USART RX
+ rjmp _USART_RX_COMPLETE ; обработчик завершения приема USART
+
+;------------------------------------------------------
+
+#if VOLUME_TABLE == 0 ; если выбрана таблица AY
+ Volumes: ; volume table for amplitude
+ ; таблица громкости для амплитуды
+ .db 0,1,1,1,2,2,3,5,6,9,13,17,22,29,36,45 // AY_TABLE
+ EVolumes: ; volume table for envelopes
+ ; таблица громкости для огибающих
+ .db 0,0,1,1,1,1,1,1,2,2,2,2,3,3,5,5,6,6,7,9,11,13,15,17,19,22,25,29,32,36,40,45 // AY_TABLE
+#elif VOLUME_TABLE == 1 ; если выбрана таблица YM
+ Volumes: ; volume table for amplitude
+ ; таблица громкости для амплитуды
+ .db 0,1,1,1,2,2,3,4,5,7,10,13,18,24,34,45 // YM_TABLE
+ EVolumes: ; volume table for envelopes
+ ; таблица громкости для огибающих
+ .db 0,0,1,1,1,1,1,1,2,2,2,2,2,3,3,4,4,5,6,7,8,10,11,13,15,18,21,24,29,34,40,45 // YM_TABLE
+#elif VOLUME_TABLE == 2 ; если выбрана альтернативная таблица
+ Volumes: ; volume table for amplitude
+ ; таблица громкости для амплитуды
+ .db 0,1,2,3,4,5,6,7,9,11,13,16,22,31,42,58 // ALT_TABLE
+ EVolumes: ; volume table for envelopes
+ ; таблица громкости для огибающих
+ .db 0,1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,24,26,28,30,33,36,40,45,51,58 // ALT_TABLE
+#endif
+
+; envelope codes, bit0 - attack, bit1 - invert on next cycle, bit2 - stop generator on next cycle
+; коды огибающей, бит0 - атака, бит1 - инвертировать в следующем цикле, бит2 - остановить генератор в следующем цикле
+Envelopes: ; таблица кодов огибающей
+ .db 7,7,7,7,4,4,4,4,1,7,3,5,0,6,2,4
+
+; mask applied to registers values after receiving
+; маска, применяемая к значениям регистров после получения
+RegsMask: ; таблица масок регистров
+ .db 0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0x1F,0xFF,0x1F,0x1F,0x1F,0xFF,0xFF,0x0F,0xFF,0xFF
+
+;==========================================================
+_INT0_Handler: ; 4 cycles to enter
+ ; обработчик INT0, 4 цикла на вход
+ sbic PinD,b3 ; check BDIR (1)
+ ; проверить BDIR (1)
+ rjmp LATCH_REG_ADDR0 ; (2) if BDIR=1
+ ; (2) если BDIR=1
+
+#if TS_Chip_0 > 0 || TS_Chip_1 > 0
+ ; если активен хотя бы один TS-чип
+ sbic CHIP_SELECTED,0 ; (1) check chip select
+ ; (1) проверить выбор чипа
+ rjmp exit_int0 ; (2) skip if not selected
+ ; (2) пропустить если не выбран
+#endif
+
+ ; READ MODE - минимальное время
+ ; РЕЖИМ ЧТЕНИЯ - минимальное время
+ out DDRD,BusOut2 ; 1 - set data bus
+ ; 1 - установить шину данных
+ out DDRC,BusOut1 ; 1
+ ; 1
+
+LOOP_NOT_INACTIVE: ; цикл ожидания неактивного состояния
+ sbic PinD,b2 ; 1 - wait for BC1=0
+ ; 1 - ждать BC1=0
+ rjmp LOOP_NOT_INACTIVE ; 2
+ ; 2
+
+ ; Быстрый сброс портов (4 цикла вместо 6)
+ out DDRC, C00 ; 1
+ ; 1
+ out DDRD, C00 ; 1
+ ; 1
+ ; Убрал выключение подтяжек - они не критичны для работы
+exit_int0: ; выход из обработчика
+ out EIFR, YH ; 1 - clear flags
+ ; 1 - очистить флаги
+ reti ; 4
+ ; 4
+
+LATCH_REG_ADDR0: ; защелкнуть адрес регистра
+ in ADDR, PinC ; 1
+ ; 1
+ andi ADDR, 0x3F ; 1
+ ; 1
+
+#if TS_Chip_0 > 0 || TS_Chip_1 > 0
+ ; если активен TS-чип
+ sbic PinD,b7 ; проверить CS
+ rjmp SELECT_CHIP_ADDR0 ; перейти к выбору чипа
+#endif
+ ldd BusOut1, Z+0x20 ; 2
+ ; 2
+ ldd BusOut2, Z+0x30 ; 2
+ ; 2
+ rjmp exit_int0 ; 2
+ ; 2
+
+
+SELECT_CHIP_ADDR0: ; выбор чипа по адресу
+#if TS_Chip_0 > 0 ; если активен TS_Chip_0
+ cpi ADDR, 0x3F ; 1
+ ; 1
+ breq LATCH_SELECT_CHIP0 ; 1/2
+ ; 1/2
+ cpi ADDR, 0x3E ; сравнить с 0x3E
+ breq RESET_LATCH0 ; 2
+ ; 2
+#elif TS_Chip_1 > 0 ; если активен TS_Chip_1
+ cpi ADDR, 0x3E ; 1
+ ; 1
+ breq LATCH_SELECT_CHIP0 ; 1/2
+ ; 1/2
+ cpi ADDR, 0x3F ; сравнить с 0x3F
+ breq RESET_LATCH0 ; 2
+ ; 2
+#endif
+
+LATCH_SELECT_CHIP0: ; защелкнуть выбор чипа
+ sbi CHIP_SELECTED, b0 ; 2
+ ; 2
+ rjmp exit_int0 ; 2
+ ; 2
+
+RESET_LATCH0: ; сбросить выбор чипа
+ cbi CHIP_SELECTED, b0 ; 2
+ ; 2
+ rjmp exit_int0 ; 2
+ ; 2
+
+;==========================================================
+_INT1_Handler: ; 4 cycles to enter
+ ; обработчик INT1, 4 цикла на вход
+ in BusData, PinC ; 1
+ ; 1
+ andi BusData, 0x3F ; 1
+ ; 1
+
+ sbic PinD, b2 ; 1
+ ; 1
+ rjmp LATCH_REG_ADDR1 ; 2
+ ; 2
+
+#if TS_Chip_0 > 0 || TS_Chip_1 > 0
+ ; если активен TS-чип
+ sbic CHIP_SELECTED, 0 ; 1
+ ; 1
+ rjmp exit_int1 ; 2
+ ; 2
+#endif
+
+ ; WRITE MODE - оптимизированная версия
+ ; РЕЖИМ ЗАПИСИ - оптимизированная версия
+ in BusOut1, PinD ; 1
+ ; 1
+ in SREGSave, SREG ; 1
+ ; 1
+ and BusOut1, CC0 ; AND с константой 0xC0
+ or BusData, BusOut1 ; 1
+ ; 1
+ mov BusOut1, BusData ; 1
+ ; 1
+ com BusOut1 ; 1
+ ; 1
+
+ ; Загружаем маску одновременно с другими операциями
+ ld BusOut2, Z ; 2 - load mask
+ ; 2 - загрузить маску
+ std Z+0x20, BusOut1 ; 2 - save inverted
+ ; 2 - сохранить инвертированное значение
+
+ and BusData, BusOut2 ; 1 - apply mask
+ ; 1 - применить маску
+ mov BusOut2, BusOut1 ; 1
+ ; 1
+ andi BusOut2, 0xC0 ; 1 - extract bits 6-7
+ ; 1 - извлечь биты 6-7
+
+ std Z+0x30, BusOut2 ; 2 - save high bits
+ ; 2 - сохранить старшие биты
+ std Z+0x10, BusData ; 2 - save value
+ ; 2 - сохранить значение
+
+ ; Проверка регистра 13 через прямое сравнение
+ cpi ADDR, 0x0D ; 1
+ ; 1
+ brne NO_ENVELOPE_CHANGED_P; 1/2
+ ; 1/2
+ ori TNLevel, 0x80 ; 1
+ ; 1
+NO_ENVELOPE_CHANGED_P: ; огибающая не изменилась
+ out SREG, SREGSave ; 1
+ ; 1
+ rjmp exit_int1 ; 2
+ ; 2
+
+LATCH_REG_ADDR1: ; защелкнуть адрес регистра
+ mov ADDR, BusData ; 1
+ ; 1
+
+#if TS_Chip_0 > 0 || TS_Chip_1 > 0
+ ; если активен TS-чип
+ sbic PinD,b6 ; проверить CS
+ rjmp SELECT_CHIP_ADDR1 ; перейти к выбору чипа
+#endif
+
+ ldd BusOut1, Z+0x20 ; 2
+ ; 2
+ ldd BusOut2, Z+0x30 ; 2
+ ; 2
+ rjmp exit_int1 ; 2
+ ; 2
+
+SELECT_CHIP_ADDR1: ; выбор чипа по адресу
+#if TS_Chip_0 > 0 ; если активен TS_Chip_0
+ cpi ADDR, 0x3F ; 1
+ ; 1
+ breq LATCH_SELECT_CHIP1 ; 1/2
+ ; 1/2
+ cpi ADDR, 0x3E ; сравнить с 0x3E
+ breq RESET_LATCH1 ; 2
+ ; 2
+#elif TS_Chip_1 > 0 ; если активен TS_Chip_1
+ cpi ADDR, 0x3E ; 1
+ ; 1
+ breq LATCH_SELECT_CHIP1 ; 1/2
+ ; 1/2
+ cpi ADDR, 0x3F ; сравнить с 0x3F
+ breq RESET_LATCH1 ; 2
+ ; 2
+#endif
+
+
+LATCH_SELECT_CHIP1: ; защелкнуть выбор чипа
+ sbi CHIP_SELECTED, b0 ; 2
+ ; 2
+exit_int1: ; выход из обработчика
+ out EIFR, ZH ; 1
+ ; 1
+ reti ; завершить прерывание
+
+RESET_LATCH1: ; сбросить выбор чипа
+ cbi CHIP_SELECTED, b0 ; 2
+ ; 2
+ rjmp exit_int1 ; 2
+ ; 2
+
+;==========================================================
+_USART_RX_COMPLETE: ; завершение приема USART
+ lds BusData,UDR0 ; get byte from USART
+ ; получить байт из USART
+ sbrs ADDR,b4 ; check for address/data mode
+ ; проверить режим адрес/данные
+ rjmp RECV_REG_VALUE ; перейти к приему значения регистра
+ sbrc BusData,b7 ; проверить старший бит
+ rjmp USART_SYNC ; перейти к синхронизации
+ mov ADDR,BusData ; ------ receive register number ------------
+ ; ------ принять номер регистра ------------
+ reti ; вернуться из прерывания
+USART_SYNC: ; ------ synchronization mode ---------------
+ ; ------ режим синхронизации ---------------
+ ldi ADDR,0x10 ; установить адрес 0x10
+ reti ; вернуться из прерывания
+
+RECV_REG_VALUE: ; ------ receive register value -------------
+ ; ------ принять значение регистра ------------
+ in SREGSave,SREG ; сохранить SREG
+ ld BusOut1,Z ; load register mask
+ ; загрузить маску регистра
+ and BusData,BusOut1 ; apply register mask
+ ; применить маску регистра
+ std Z+0x10,BusData ; put register value to SRAM
+ ; поместить значение регистра в SRAM
+ cpi ADDR,0x0D ; check for envelope shape register
+ ; проверить регистр формы огибающей
+ brne NO_ENVELOPE_CHANGED_S ; если не регистр 13
+ ori TNLevel,0x80 ; set envelope change flag (bit 7)
+ ; установить флаг изменения огибающей (бит 7)
+NO_ENVELOPE_CHANGED_S: ; огибающая не изменилась
+ ldi ADDR,0x10 ; set bit 4 to jump to receive register number on next byte received
+ ; установить бит 4 для перехода к приему номера регистра при следующем байте
+ out SREG,SREGSave ; восстановить SREG
+ reti ; вернуться из прерывания
+
+
+; ==============================================
+; LGT8F328P INITIALIZATION - NO BOOTLOADER
+; ИНИЦИАЛИЗАЦИЯ LGT8F328P - БЕЗ ЗАГРУЗЧИКА
+; ==============================================
+_LGT_INIT: ; инициализация LGT
+ ; 1. Disable watchdog immediately
+ ; 1. Немедленно отключить watchdog
+ ldi r16, 0x00 ; загрузить 0x00
+ sts WDTCSR, r16 ; записать в регистр WDTCSR
+
+ ; 2. Unlock protected registers (LGT specific)
+ ; 2. Разблокировать защищенные регистры (специфично для LGT)
+ ldi r16, 0xD8 ; загрузить магическое число
+ sts CCP, r16 ; Enable configuration changes
+ ; разрешить изменения конфигурации
+
+ ; 3. Configure clock: 32MHz internal, divisor = 1
+ ; 3. Настроить тактирование: внутренний 32МГц, делитель = 1
+ ldi r16, 0x80 ; загрузить значение для CLKPR
+ sts CLKPR, r16 ; Enable CLKPR changes
+ ; разрешить изменения CLKPR
+
+ ldi r16, 0xD8 ; загрузить магическое число
+ sts CCP, r16 ; разрешить изменения
+ ldi r16, 0x00 ; делитель = 1
+ sts CLKPR, r16 ; Divisor = 1 (32MHz)
+ ; делитель = 1 (32МГц)
+
+ ; 4. Select internal 32MHz oscillator
+ ; 4. Выбрать внутренний 32МГц осциллятор
+ ldi r16, 0xD8 ; загрузить магическое число
+ sts CCP, r16 ; разрешить изменения
+ ldi r16, 0x04 ; выбрать внутренний 32МГц
+ sts CLKMSR, r16 ; Internal 32MHz oscillator
+ ; внутренний 32МГц осциллятор
+
+ ; 5. ENABLE FAST GPIO FOR PORTS B, C, D
+ ; 5. ВКЛЮЧИТЬ БЫСТРЫЙ GPIO ДЛЯ ПОРТОВ B, C, D
+ ldi r16, 0xD8 ; загрузить магическое число
+ sts CCP, r16 ; разрешить изменения
+ ldi r16, (1<<2) | (1<<1) | (1<<0) ; включить для портов B, C, D
+ sts FGPIOE, r16 ; записать в регистр FGPIOE
+ ldi r16, 0xD8 ; загрузить магическое число
+ sts CCP, r16 ; разрешить изменения
+ ldi r16, (0<<4) | (0<<2) | (0<<0) ; No delay for all ports
+ ; без задержки для всех портов
+ sts FGPIO, r16 ; записать в регистр FGPIO
+
+ ; 6. Configure Fast GPIO timing (optional, default is usually OK)
+ ; 6. Настроить тайминг быстрого GPIO (опционально, обычно подходит по умолчанию)
+ ldi r16, 0xD8 ; загрузить магическое число
+ sts CCP, r16 ; разрешить изменения
+ ldi r16, 0x00 ; тайминг по умолчанию (без задержки)
+ sts FGPIO, r16 ; Set Fast GPIO Control register
+ ; установить регистр управления быстрым GPIO
+
+ ; 7. DISABLE BOOTLOADER - BOOTRST=0, start from 0x0000
+ ; 7. ОТКЛЮЧИТЬ ЗАГРУЗЧИК - BOOTRST=0, старт с 0x0000
+ ldi r16, 0x03 ; BOOTSZ=11, BOOTRST=0
+ sts BCR, r16 ; записать в регистр BCR
+
+ ; 8. Set BOOTEND (optional, defines flash boundary)
+ ; 8. Установить BOOTEND (опционально, определяет границу flash)
+ ldi r16, 0x7F ; 0x7F00 для 32КБ flash
+ sts BOOTEND, r16 ; записать в регистр BOOTEND
+
+ ; 9. Continue to original reset code
+ ; 9. Продолжить выполнение оригинального кода сброса
+ rjmp _RESET ; перейти к сбросу
+
+;==========================================================
+_RESET: // Emulator start
+ // Начало эмулятора
+ in r16,MCUCR ; 1-> PUD for
+ ; загрузить MCUCR
+ sbr r16,PUD ; установить бит PUD
+ out MCUCR,r16 ; выключить подтяжки
+
+ // init stack pointer at end of RAM
+ // инициализировать указатель стека в конце RAM
+ ldi r16,low(RAMEND) ; загрузить младший байт конца RAM
+ out SPL,r16 ; записать в SPL
+ ldi r16,high(RAMEND) ; загрузить старший байт конца RAM
+ out SPH,r16 ; записать в SPH
+
+ ; ИНИЦИАЛИЗАЦИЯ ПОРТОВ C и D В HI-Z ===================
+ ; Порт C: PC0-PC5 - данные, должны быть в HI-Z
+ ; Порт D: PD6,PD7 - данные, должны быть в HI-Z
+ ldi r16,0x00 ; загрузить 0x00
+ out DDRC,r16 ; все пины порта C как входы
+ ; установить все пины порта C как входы
+ out PORTC,r16 ; отключить подтяжки
+ ; отключить подтяжки порта C
+ out DDRD,r16 ; все пины порта D как входы
+ ; установить все пины порта D как входы
+ out PORTD,r16 ; отключить подтяжки
+ ; отключить подтяжки порта D
+ ; =====================================================
+
+ ; disable Analog Comparator ==============================
+ ; отключить аналоговый компаратор =========================
+ ldi r16, (1< 0 ; если активен TS_Chip_0
+ sbi CHIP_SELECTED, b0 ; установить бит выбора чипа
+#elif TS_Chip_1 > 0 ; если активен TS_Chip_1
+ cbi CHIP_SELECTED, b0 ; сбросить бит выбора чипа
+#endif
+
+ clr C00 ; очистить регистр C00 (0x00)
+ ldi r16,0xC0 ; загрузить 0xC0
+ mov CC0,r16 ; переместить в CC0
+ ldi r16,0x04 ; загрузить 0x04
+ mov C04,r16 ; переместить в C04
+ ldi r16,0x1F ; загрузить 0x1F
+ mov C1F,r16 ; переместить в C1F
+ ldi r16,0xFF ; загрузить 0xFF
+ mov BusOut1,r16 ; переместить в BusOut1
+ mov BusOut2,CC0 ; переместить CC0 в BusOut2
+ clr RNGH ; очистить RNGH
+ ldi YH,0xFF ; загрузить 0xFF в YH
+ // clear register values in SRAM 0x110-0x13F
+ // очистить значения регистров в SRAM 0x110-0x13F
+ ldi r18,0x10 ; загрузить счетчик (16)
+ ldi ZL,0x10 ; начальный адрес
+ ldi ZH,0x01 ; старший байт адреса
+LOOP0: ; цикл очистки
+ std Z+0x20,CC0 ; сохранить CC0 по смещению 0x20
+ std Z+0x10,r16 ; сохранить 0xFF по смещению 0x10
+ st Z+,C00 ; сохранить 0x00 и увеличить указатель
+ dec r18 ; уменьшить счетчик
+ brne LOOP0 ; повторять пока не 0
+
+ ; load envelope codes to SRAM 0x210, 16 bytes
+ ; загрузить коды огибающей в SRAM 0x210, 16 байт
+ ldi xh,0x02 ; старший байт адреса X
+ ldi xl,0x10 ; младший байт адреса X
+ ldi zl, low(2*Envelopes) ; младший байт адреса таблицы
+ ldi zh, high(2*Envelopes); старший байт адреса таблицы
+ ldi r18,0x10 ; счетчик (16 байт)
+ rcall _COPY ; вызвать подпрограмму копирования
+
+ ; load volume table for amplitude to SRAM 0x220, 16 bytes
+ ; загрузить таблицу громкости для амплитуды в SRAM 0x220, 16 байт
+ ldi xl,0x20 ; младший байт адреса X
+ ldi zl, low(2*Volumes) ; младший байт адреса таблицы
+ ldi zh, high(2*Volumes) ; старший байт адреса таблицы
+ ldi r18,0x10 ; счетчик (16 байт)
+ rcall _COPY ; вызвать подпрограмму копирования
+
+ ; load volume table for envelopes to SRAM 0x230, 32 bytes
+ ; загрузить таблицу громкости для огибающих в SRAM 0x230, 32 байта
+ ldi xl,0x30 ; младший байт адреса X
+ ldi zl, low(2*EVolumes) ; младший байт адреса таблицы
+ ldi zh, high(2*EVolumes) ; старший байт адреса таблицы
+ ldi r18,0x20 ; счетчик (32 байта)
+ rcall _COPY ; вызвать подпрограмму копирования
+
+ ; load register masks to SRAM 0x100, 16 bytes
+ ; загрузить маски регистров в SRAM 0x100, 16 байт
+ clr xl ; очистить XL
+ ldi xh,0x01 ; старший байт адреса X
+ ldi zl, low(2*RegsMask) ; младший байт адреса таблицы
+ ldi zh, high(2*RegsMask) ; старший байт адреса таблицы
+ ldi r18,0x10 ; счетчик (16 байт)
+ rcall _COPY ; вызвать подпрограмму копирования
+
+ ldi ZH,0x01 ; set high byte of register Z for fast acces to register values
+ ; установить старший байт регистра Z для быстрого доступа к значениям регистров
+ clr ZL ; очистить младший байт Z
+ ldi YH,0x02 ; set high byte of register Y for fast acces to volume table
+ ; установить старший байт регистра Y для быстрого доступа к таблице громкости
+ mov NoiseAddon,ZH ; load default value = 1 to high bit of noise generator
+ ; загрузить значение по умолчанию = 1 в старший бит генератора шума
+
+#if USART_ENABLE > 0 ; если USART включен
+ // init USART
+ // инициализация USART
+ clr r16 ; очистить r16
+ sts UBRR0H,r16 ; установить старший байт скорости
+ ldi r16,0x06 ; загрузить значение для UCSR0C
+ sts UCSR0C,r16 ; установить формат 8N1
+ ldi r16,0x02 ; загрузить значение для UCSR0A
+ sts UCSR0A,r16 ; установить флаг
+ ldi r16,0x90 ; загрузить значение для UCSR0B
+ sts UCSR0B,r16 ; включить приемник и прерывание
+ ldi r18,0x44 ; загрузить значение скорости
+ sts UBRR0L,r18 ; установить младший байт скорости
+#endif
+
+ // init Timer1
+ // инициализация Timer1
+ sts OCR1AH,C00 ; очистить старший байт OCR1A
+ sts OCR1AL,C00 ; очистить младший байт OCR1A
+ sts OCR1BH,C00 ; очистить старший байт OCR1B
+ sts OCR1BL,C00 ; очистить младший байт OCR1B
+ sbi DDRB,b1 ; set port B pin 1 to output for PWM (AY channel A)
+ ; установить вывод B1 как выход для ШИМ (канал A AY)
+ sbi DDRB,b2 ; set port B pin 2 to output for PWM (AY channel B)
+ ; установить вывод B2 как выход для ШИМ (канал B AY)
+ ldi r16,0xA2 ; загрузить значение для TCCR1A
+ sts TCCR1A,r16 ; настроить режим ШИМ
+ ldi r16,0x19 ; загрузить значение для TCCR1B
+ sts TCCR1B,r16 ; настроить предделитель и режим
+ ldi r16,0x19 ; загрузить значение для TCCR1B
+ sts TCCR1B,r16 ; настроить предделитель и режим
+#if Enable2MHz == 0 ; если 1,75 МГц версия
+ ldi r18, 0x91 ; загрузить значение для ICR1
+#else ; иначе 2 МГц версия
+ ldi r18, 0x7F ; загрузить значение для ICR1
+#endif
+ sts ICR1H,C00 ; очистить старший байт ICR1
+ sts ICR1L,r18 ; set PWM speed
+ ; установить скорость ШИМ
+ ; ICR1L value formula (32000000/109375/2 - 1) where 32000000 = 32MHz - AVR oscillator frequency
+ ; формула для ICR1L (32000000/109375/2 - 1), где 32000000 = 32МГц - частота осциллятора AVR
+ ; 109375 is for 1.75 MHz version, formula is (PSG frequency / 16) e.g. for 2MHz it is 2000000/16 = 125000
+ ; 109375 для версии 1.75 МГц, формула (частота PSG / 16), например для 2МГц это 2000000/16 = 125000
+
+#if CHANNELS == 3 ; если 3-канальная версия
+ // init Timer2
+ // инициализация Timer2
+ sbi DDRB,DDB3 ; set port B pin 3 to output for PWM (AY channel C)
+ ; установить вывод B3 как выход для ШИМ (канал C AY)
+ ldi r16,0x83 ; загрузить значение для TCCR2A
+ sts TCCR2A,r16 ; настроить режим ШИМ
+ ldi r16,0x01 ; загрузить значение для TCCR2B
+ sts TCCR2B,r16 ; настроить предделитель
+#endif
+
+#if INT_ENABLE > 0 ; если прерывания включены
+ ; set INT0,INT1 ============================================
+ ; настройка INT0,INT1 ======================================
+ ldi r16, (1<= 0
+ ; перейти к следующему шагу если период >= 0
+ ;init new envelope period
+ ;инициализировать новый период огибающей
+ ldi TabP,0x1F ; установить счетчик периода
+ sbrc TabE,b1 ; если бит инверсии установлен
+ eor TabE,ZH ; invert envelope ATTACK bit
+ ; инвертировать бит атаки огибающей
+ sbrc TabE,b2 ; если бит остановки установлен
+ or TabE,CC0 ; disable envelope generator until new envelope shape register recived
+ ; отключить генератор огибающей до получения нового регистра формы
+E_NEXT_STEP: ; следующий шаг
+ lds CntEL,AY_REG11 ; загрузить младший байт периода огибающей
+ lds CntEH,AY_REG12 ; загрузить старший байт периода огибающей
+ mov YL,TabP ; скопировать счетчик периода
+ sbrs TabE,b0 ; если бит атаки не установлен
+ eor YL,C1F ; invert envelope value if ATTACK bit is not set
+ ; инвертировать значение огибающей
+ ldd EVal,Y+0x30 ; translate envelope value to volume, read volume value from SRAM 0x230+YL
+ ; преобразовать значение огибающей в громкость, прочитать из SRAM
+ENVELOPE_GENERATOR_END: ; конец генератора огибающей
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// NOISE GENERATOR
+ /// ГЕНЕРАТОР ШУМА
+ /////////////////////////////////////////////////////////////////////////////////////
+ dec CntN ; decrease noise period counter
+ ; уменьшить счетчик периода шума
+ brpl NOISE_GENERATOR_END ; skip if noise period is not finished (CntN>=0)
+ ; пропустить если период шума не закончился
+ //init new cycle
+ //инициализировать новый цикл
+ lds CntN,AY_REG06 ; init noise period counter with value in AY register 6
+ ; инициализировать счетчик периода шума значением из регистра 6 AY
+ dec CntN ; уменьшить счетчик
+
+ lsr NoiseAddon ; сдвинуть NoiseAddon вправо
+ mov NoiseAddon,RNGL ; скопировать RNGL в NoiseAddon
+ ror RNGH ; циклический сдвиг вправо RNGH
+ ror RNGL ; циклический сдвиг вправо RNGL
+
+ ori TNLevel,0x38 ; set noise bits
+ ; установить биты шума
+ sbrs RNGL,b0 ; если младший бит RNGL не установлен
+ andi TNLevel,0xC7 ; reset noise bits
+ ; сбросить биты шума
+ // make input bit
+ // сформировать входной бит
+ lsl NoiseAddon ; сдвинуть NoiseAddon влево
+ eor NoiseAddon,RNGL ; XOR с RNGL
+ lsr NoiseAddon ; сдвинуть NoiseAddon вправо
+NOISE_GENERATOR_END: ; конец генератора шума
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// TONE GENERATOR
+ /// ГЕНЕРАТОР ТОНА
+ /////////////////////////////////////////////////////////////////////////////////////
+ ; all counters are Int16 values (signed)
+ ; все счетчики 16-битные (знаковые)
+ // Channel A -------------
+ // Канал A -------------
+ subi CntAL,0x01 ; CntA - 1
+ ; CntA - 1
+ sbci CntAH,0x00 ; вычесть с переносом
+ brpl CH_A_NO_CHANGE ; CntA >= 0
+ ; CntA >= 0
+ lds CntAL,AY_REG00 ; update channel A tone period counter
+ ; обновить счетчик периода тона канала A
+ lds CntAH,AY_REG01 ; загрузить старший байт
+ subi CntAL,0x01 ; CntA - 1
+ ; CntA - 1
+ sbci CntAH,0x00 ; вычесть с переносом
+ eor TNLevel,ZH ; TNLevel xor 1 (change logical level of channel A)
+ ; TNLevel XOR 1 (изменить логический уровень канала A)
+CH_A_NO_CHANGE: ; канал A не изменился
+
+ // Channel B -------------
+ // Канал B -------------
+ subi CntBL,0x01 ; CntB - 1
+ ; CntB - 1
+ sbci CntBH,0x00 ; вычесть с переносом
+ brpl CH_B_NO_CHANGE ; CntB >= 0
+ ; CntB >= 0
+ lds CntBL,AY_REG02 ; update channel B tone period counter
+ ; обновить счетчик периода тона канала B
+ lds CntBH,AY_REG03 ; загрузить старший байт
+ subi CntBL,0x01 ; CntB - 1
+ ; CntB - 1
+ sbci CntBH,0x00 ; вычесть с переносом
+ eor TNLevel,YH ; TNLevel xor 2 (change logical level of channel B)
+ ; TNLevel XOR 2 (изменить логический уровень канала B)
+CH_B_NO_CHANGE: ; канал B не изменился
+
+ // Channel C -------------
+ // Канал C -------------
+ sbiw CntCL,0x01 ; CntC - 1
+ ; CntC - 1
+ brpl CH_C_NO_CHANGE ; CntC >= 0
+ ; CntC >= 0
+ lds CntCL,AY_REG04 ; update channel C tone period counter
+ ; обновить счетчик периода тона канала C
+ lds CntCH,AY_REG05 ; загрузить старший байт
+ sbiw CntCL,0x01 ; CntC - 1
+ ; CntC - 1
+ eor TNLevel,C04 ; TNLevel xor 4 (change logical level of channel C)
+ ; TNLevel XOR 4 (изменить логический уровень канала C)
+CH_C_NO_CHANGE: ; канал C не изменился
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// MIXER
+ /// МИКШЕР
+ /////////////////////////////////////////////////////////////////////////////////////
+ lds TMP,AY_REG07 ; Load Mixer AY Register from SRAM
+ ; Загрузить регистр микшера AY из SRAM
+ or TMP,TNLevel ; Mixer formula = (Mixer Register Tone | TNLevel Tone) & (Mixer Register Noise | TNLevel Noise)
+ ; Формула микшера = (Тон регистра микшера | Тон TNLevel) & (Шум регистра микшера | Шум TNLevel)
+ mov YL,TMP ; скопировать TMP в YL
+ lsl YL ; сдвинуть YL влево
+ swap YL ; поменять местами тетрады
+ and TMP,YL ; логическое И с YL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// AMPLITUDE CONTROL
+ /// УПРАВЛЕНИЕ АМПЛИТУДОЙ
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ // Channel A
+ // Канал A
+ lds YL,AY_REG08 ; Load Channel A Amplitude register
+ ; Загрузить регистр амплитуды канала A
+ mov OutA,EVal ; set envelope volume as default value
+ ; установить громкость огибающей как значение по умолчанию
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ; если бит 4 не установлен, преобразовать в громкость
+ ldd OutA,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ ; загрузить значение громкости из SRAM 0x220 + YL
+ sbrs TMP,b0 ; if channel is disabled in mixer - set volume to zero
+ ; если канал отключен в микшере - установить громкость в 0
+ clr OutA ; очистить OutA
+
+ // Channel B
+ // Канал B
+ lds YL,AY_REG09 ; Load Channel B Amplitude register
+ ; Загрузить регистр амплитуды канала B
+ mov OutB,EVal ; set envelope volume as default value
+ ; установить громкость огибающей как значение по умолчанию
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ; если бит 4 не установлен, преобразовать в громкость
+ ldd OutB,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ ; загрузить значение громкости из SRAM 0x220 + YL
+ sbrs TMP,b1 ; if channel is disabled in mixer - set volume to zero
+ ; если канал отключен в микшере - установить громкость в 0
+ clr OutB ; очистить OutB
+
+ // Channel C
+ // Канал C
+ lds YL,AY_REG10 ; Load Channel C Amplitude register
+ ; Загрузить регистр амплитуды канала C
+ mov OutC,EVal ; set envelope volume as default value
+ ; установить громкость огибающей как значение по умолчанию
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ; если бит 4 не установлен, преобразовать в громкость
+ ldd OutC,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ ; загрузить значение громкости из SRAM 0x220 + YL
+ sbrs TMP,b2 ; if channel is disabled in mixer - set volume to zero
+ ; если канал отключен в микшере - установить громкость в 0
+ clr OutC ; очистить OutC
+
+ // Channel B
+ // Канал B
+#if CHANNELS == 2 ; если 2-канальная версия
+// two channel version ----------------------------------------
+// двухканальная версия ----------------------------------------
+ mov YL,OutB ; скопировать OutB в YL
+ lsr OutB ; TMP = TMP - (TMP/4 + TMP/8);
+ ; сдвиг вправо OutB
+ lsr OutB ; сдвиг вправо OutB
+ sub YL,OutB ; вычесть OutB из YL
+ lsr OutB ; сдвиг вправо OutB
+ sub YL,OutB ; вычесть OutB из YL
+ add OutA,YL ; add channel B volume to channels A and C
+ ; добавить громкость канала B к каналам A и C
+ add OutC,YL ; добавить к OutC
+// --------------------------------------------------------------
+#elif CHANNELS == 3 ; если 3-канальная версия
+// three channel version ----------------------------------------
+// трехканальная версия ----------------------------------------
+ sts OCR2A,OutB ; установить значение ШИМ для канала C
+// --------------------------------------------------------------
+#endif
+
+// --------------------------------------------------------------
+#if SPEAKER == 1 ; если включен вход динамика
+// speaker port enabled -----------------------------------------
+// вход динамика включен ----------------------------------------
+ sbic PinD,b1 ; check PD1 (SPEAKER PORT INPUT) skip if bit is not set
+ ; проверить PD1 (вход динамика), пропустить если бит не установлен
+ add OutA,C1F ; add some volume to channel A
+ ; добавить громкость к каналу A
+ sbic PinD,b1 ; check PD1 (SPEAKER PORT INPUT) skip if bit is not set
+ ; проверить PD1 (вход динамика), пропустить если бит не установлен
+ add OutC,C1F ; add some volume to channel A
+ ; добавить громкость к каналу A
+// --------------------------------------------------------------
+#endif
+
+ sts OCR1AL,OutA ; update PWM counters
+ ; обновить счетчики ШИМ
+ sts OCR1BL,OutC ; обновить OCR1B
+ rjmp _MAIN_LOOP ; вернуться в главный цикл
+// MAIN LOOP END ====================================================================
+// КОНЕЦ ГЛАВНОГО ЦИКЛА =============================================================
+
+
+// copy routine from flash to SRAM
+// подпрограмма копирования из flash в SRAM
+_COPY: ; подпрограмма копирования
+ lpm r16,Z+ ; загрузить из flash с пост-инкрементом
+ st X+,r16 ; сохранить в SRAM с пост-инкрементом
+ dec r18 ; уменьшить счетчик
+ brne _COPY ; повторять пока не 0
+ ret ; вернуться из подпрограммы
+
+/////////////////////////////////////////////////////////////////
+/// AY REGISTERS IN SRAM
+/// РЕГИСТРЫ AY В SRAM
+/////////////////////////////////////////////////////////////////
+ .dseg ; начало сегмента данных
+ .org 0x0110 ; адрес в SRAM
+AY_REG00: ; регистр 0 AY (тон канала A, младший байт)
+ .byte 1
+AY_REG01: ; регистр 1 AY (тон канала A, старший байт)
+ .byte 1
+AY_REG02: ; регистр 2 AY (тон канала B, младший байт)
+ .byte 1
+AY_REG03: ; регистр 3 AY (тон канала B, старший байт)
+ .byte 1
+AY_REG04: ; регистр 4 AY (тон канала C, младший байт)
+ .byte 1
+AY_REG05: ; регистр 5 AY (тон канала C, старший байт)
+ .byte 1
+AY_REG06: ; регистр 6 AY (период шума)
+ .byte 1
+AY_REG07: ; регистр 7 AY (управление микшером)
+ .byte 1
+AY_REG08: ; регистр 8 AY (амплитуда канала A)
+ .byte 1
+AY_REG09: ; регистр 9 AY (амплитуда канала B)
+ .byte 1
+AY_REG10: ; регистр 10 AY (амплитуда канала C)
+ .byte 1
+AY_REG11: ; регистр 11 AY (период огибающей, младший байт)
+ .byte 1
+AY_REG12: ; регистр 12 AY (период огибающей, старший байт)
+ .byte 1
+AY_REG13: ; регистр 13 AY (форма огибающей)
+ .byte 1
+AY_REG14: ; регистр 14 AY (порт A ввода/вывода)
+ .byte 1
+AY_REG15: ; регистр 15 AY (порт B ввода/вывода)
+ .byte 1
\ No newline at end of file
diff --git a/Sources/AY_Emu/AY_Emu/main — копия.asm b/Sources/AY_Emu/AY_Emu/main — копия.asm
new file mode 100644
index 0000000..3ce7483
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/main — копия.asm
@@ -0,0 +1,1053 @@
+; AY-3-8912 IC emulator version 26.0 for LGT8F328P
+;
+; Sources for Atmel AVRStudio 7
+;
+; visit our site for more information
+; These source codes are distributed under the GPL v3 license
+; If you share these sources you should put the link to web site www.avray.ru
+;
+; ORIGIN: http://www.avray.ru
+
+; CONFIGURATION VALUES ===================================================
+#define VOLUME_TABLE 0 ; 0 - AY, 1 - YM, 2 - ALTERNATE volume table
+; ========================================================================
+; bit numbers:
+.equ b0 = 0x00
+.equ b1 = 0x01
+.equ b2 = 0x02
+.equ b3 = 0x03
+.equ b4 = 0x04
+.equ b5 = 0x05
+.equ b6 = 0x06
+.equ b7 = 0x07
+.equ CHIP_SELECTED = GPIOR0
+
+.def OutA = r0
+.def OutC = r1
+.def CntN_AY1 = r2
+.def CntN_AY0 = r3
+.def OutB = r4
+.def BusOut1 = r5
+.def NoiseAddon_AY0 = r6
+.def C00 = r7
+.def CC0 = r8
+.def TabE = r9
+.def C04 = r10
+.def NoiseAddon_AY1 = r11
+.def EVal = r12
+.def C21 = r13
+.def RNGL_AY0 = r14
+.def RNGH_AY0 = r15
+.def TNLevel_AY1 = r16
+.def BusOut2 = r17
+.def TabP = r18
+.def TNLevel_AY0 = r19
+.def BusData = r20
+.def TMP = r21
+.def RNGL_AY1 = r22
+.def RNGH_AY1 = r23
+.def CntEL_AY0 = r24
+.def CntEH_AY0 = r25
+.def CntEL_AY1 = r26
+.def CntEH_AY1 = r27
+.def ADDR = r30
+
+; ==============================================
+; LGT8F328P REGISTER DEFINITIONS
+; ==============================================
+; Memory-mapped I/O addresses for LGT8F328P
+.equ CCP = 0x34 ; Configuration Change Protection
+.equ CLKMSR = 0x105 ; Clock Main Settings Register
+.equ BCR = 0x107 ; Boot Control Register
+.equ BOOTEND = 0x108 ; Boot End Address
+.equ BODCR = 0x104 ; BOD Control Register
+
+.equ PMCR = 0xF2
+.equ PMCE = 7
+.equ CLKFS = 6
+.equ CLKSS = 5
+.equ WCLKS = 4
+.equ WCES = 4
+.equ OSCKEN = 3
+.equ OSCMEN = 2
+.equ RCKEN = 1
+.equ RCMEN = 0
+
+.equ PMX2 = 0xF0
+.equ IOCR = 0xF0
+.equ IOCE = 7
+.equ STSC1 = 6
+.equ STSC0 = 5
+.equ XIEN = 2
+.equ E6EN = 1
+.equ REFIOEN = 1
+.equ C6EN = 0
+.equ RSTIOEN = 0
+
+; AC0 (Analog Comparator 0) Register Definition
+.equ C0SR = 0x50
+.equ C0D = 7
+.equ C0BG = 6
+.equ C0O = 5
+.equ C0I = 4
+.equ C0IE = 3
+.equ C0IC = 2
+.equ C0IS1 = 1
+.equ C0IS0 = 0
+
+.equ C0XR = 0x51
+.equ C0OE = 6
+.equ C0HSYE = 5
+.equ C0PS0 = 4
+.equ C0WKE = 3
+.equ C0FEN = 2
+.equ C0FS1 = 1
+.equ C0FS0 = 0
+
+.equ C0TR = 0x52
+
+; AC1 (Analog Comparator 1) Register Definition
+.equ C1SR = 0x2F
+.equ C1D = 7
+.equ C1BG = 6
+.equ C1O = 5
+.equ C1I = 4
+.equ C1IE = 3
+.equ C1IC = 2
+.equ C1IS1 = 1
+.equ C1IS0 = 0
+
+.equ C1XR = 0x3A
+.equ C1OE = 6
+.equ C1HSYE = 5
+.equ C1PS0 = 4
+.equ C1WKE = 3
+.equ C1FEN = 2
+.equ C1FS1 = 1
+.equ C1FS0 = 0
+
+.equ C1TR = 0x5B
+
+;----------------------------------------------------------------
+; DSU (Digital Signal Co-processor) Register Definition
+;----------------------------------------------------------------
+.equ DSCR = 0x20
+.equ DSUEN = 7
+.equ DSMM = 6
+.equ DSD1 = 5
+.equ DSD0 = 4
+.equ DSZ = 2 ; .
+.equ DSN = 1
+.equ DSC = 0
+
+.equ DSIR = 0x21
+
+.equ DSSD = 0x22
+.equ DSDX = 0x30
+.equ DSDY = 0x31
+.equ DSAL = 0x58
+.equ DSAH = 0x59
+
+ .cseg
+;------------------------------------------------------
+; INTERRUPT VECTORS TABLE
+;------------------------------------------------------
+ .org 0x0000
+ rjmp _LGT_INIT
+
+ .org INT0addr
+ rjmp _INT0_Handler
+
+ .org INT1addr
+ rjmp _INT1_Handler
+
+;------------------------------------------------------
+
+#if VOLUME_TABLE == 0
+ Volumes: ; volume table for amplitude
+ .db 0,1,1,1,2,2,3,5,6,9,13,17,22,29,36,45 // AY_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,0,1,1,1,1,1,1,2,2,2,2,3,3,5,5,6,6,7,9,11,13,15,17,19,22,25,29,32,36,40,45 // AY_TABLE
+#elif VOLUME_TABLE == 1
+ Volumes: ; volume table for amplitude
+ .db 0,1,1,1,2,2,3,4,5,7,10,13,18,24,34,45 // YM_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,0,1,1,1,1,1,1,2,2,2,2,2,3,3,4,4,5,6,7,8,10,11,13,15,18,21,24,29,34,40,45 // YM_TABLE
+#elif VOLUME_TABLE == 2
+ Volumes: ; volume table for amplitude
+ .db 0,1,2,3,4,5,6,7,9,11,13,16,22,31,42,58 // ALT_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,24,26,28,30,33,36,40,45,51,58 // ALT_TABLE
+#endif
+
+; envelope codes, bit0 - attack, bit1 - invert on next cycle, bit2 - stop generator on next cycle
+Envelopes:
+ .db 7,7,7,7,4,4,4,4,1,7,3,5,0,6,2,4
+
+; mask applied to registers values after receiving
+RegsMask:
+ .db 0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0x1F,0xFF,0x1F,0x1F,0x1F,0xFF,0xFF,0x0F,0xFF,0xFF
+
+;==========================================================
+_INT0_Handler: ; 4 cycles to enter
+ sbic PinD,b3 ; check BDIR (1)
+ rjmp LATCH_REG_ADDR0 ; (2) if BDIR=1
+
+ out DDRD,BusOut2 ; 1 - set data bus
+ out DDRC,BusOut1 ; 1
+
+LOOP_NOT_INACTIVE:
+ sbic PinD,b2 ; 1 - wait for BC1=0
+ rjmp LOOP_NOT_INACTIVE ; 2
+ out DDRC, C00 ; 1
+ out DDRD, C00 ; 1
+
+exit_int0:
+ ldi ZH, 0x01
+ ldi r20, 0x02
+ out EIFR, r20 ; 1 - clear flags
+ reti ; 4
+
+LATCH_REG_ADDR0:
+ in ADDR, PinC ; 1
+ andi ADDR, 0x3F ; 1
+ sbic PinD,b7
+ rjmp SELECT_CHIP_ADDR0
+ sbic CHIP_SELECTED,b0
+ rjmp READ_CHIP0
+ ; 0
+ ldi ZH,0x01
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int0
+
+READ_CHIP0:
+ ; 1
+ ldi ZH,high(AY1_REG00)
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int0
+
+SELECT_CHIP_ADDR0:
+ cpi ADDR, 0x3F ; 1
+ breq SELECT_CHIP0_ADDR0 ; 1/2
+ cpi ADDR, 0x3E
+ breq SELECT_CHIP1_ADDR0 ; 2
+ rjmp exit_int0
+
+SELECT_CHIP0_ADDR0:
+ cbi CHIP_SELECTED, b0
+ rjmp exit_int0
+
+SELECT_CHIP1_ADDR0:
+ sbi CHIP_SELECTED, b0
+ rjmp exit_int0
+
+;==========================================================
+_INT1_Handler: ; 4 cycles to enter
+ in BusData, PinC ; 1
+ andi BusData, 0x3F ; 1
+
+ sbic PinD, b2 ; 1
+ rjmp LATCH_REG_ADDR1 ; 2
+
+ in BusOut1, PinD ; 1
+ in C00, SREG ; 1
+
+ and BusOut1, CC0
+ or BusData, BusOut1 ; 1
+ mov BusOut1, BusData ; 1
+ com BusOut1 ; 1
+ ldi ZH, 0x01
+ ld BusOut2, Z ; 2 - load mask
+
+ sbic CHIP_SELECTED, b0
+ ldi ZH, high(AY1_REG00)
+
+ std Z+0x20, BusOut1 ; 2 - save inverted
+ and BusData, BusOut2 ; 1 - apply mask
+ mov BusOut2, BusOut1 ; 1
+ and BusOut2, CC0 ; 1 - extract bits 6-7
+
+ std Z+0x30, BusOut2 ; 2 - save high bits
+ std Z+0x10, BusData ; 2 - save value
+
+ ; 13
+ cpi ADDR, 0x0D ; 1
+ brne NO_ENVELOPE_CHANGED_P; 1/2
+
+ sbis CHIP_SELECTED, b0
+ ori TNLevel_AY0, 0x80
+ sbic CHIP_SELECTED, b0
+ ori TNLevel_AY1, 0x80
+
+NO_ENVELOPE_CHANGED_P:
+ out SREG, C00 ; 1
+ clr C00
+exit_int1:
+ ldi ZH, 0x01
+ out EIFR, ZH ; 1
+ reti
+
+LATCH_REG_ADDR1:
+ mov ADDR, BusData ; 1
+ sbic PinD,b6
+ rjmp SELECT_CHIP_ADDR1
+ sbic CHIP_SELECTED,b0
+ rjmp READ_CHIP1
+ ; 0
+ ldi ZH,0x01
+ ldd BusOut1, Z+0x20 ; 2
+ ldd BusOut2, Z+0x30 ; 2
+ rjmp exit_int1
+
+READ_CHIP1:
+ ; 1
+ ldi ZH,high(AY1_REG00)
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int1 ; 2
+
+SELECT_CHIP_ADDR1:
+ cpi ADDR, 0x3F ; 1
+ breq SELECT_CHIP0_ADDR1 ; 1/2
+ cpi ADDR, 0x3E
+ breq SELECT_CHIP1_ADDR1 ; 2
+ rjmp exit_int1
+
+SELECT_CHIP0_ADDR1:
+ cbi CHIP_SELECTED, b0
+ rjmp exit_int1
+
+SELECT_CHIP1_ADDR1:
+ sbi CHIP_SELECTED, b0
+ rjmp exit_int1
+
+; ==============================================
+; LGT8F328P INITIALIZATION - NO BOOTLOADER
+; ==============================================
+_LGT_INIT:
+ cli
+ ; watchdog
+ ldi r16, 0x00
+ sts WDTCSR, r16
+
+ ;
+; ldi r16, (1< PUD for
+ sbr r16,PUD
+ out MCUCR,r16
+
+ // init stack pointer at end of RAM
+ ldi r16,low(RAMEND)
+ out SPL,r16
+ ldi r16,high(RAMEND)
+ out SPH,r16
+
+ ; disable Analog Comparator ==============================
+ ldi r16, (1<= 0
+ ;init new envelope period
+ ldi TabP,0x1F
+ sbrc TabE,b1
+ eor TabE,ZH ; invert envelope ATTACK bit
+ sbrc TabE,b2
+ or TabE,CC0 ; disable envelope generator until new envelope shape register recived
+E_NEXT_STEP_AY0:
+ lds CntEL_AY0,AY0_REG11
+ lds CntEH_AY0,AY0_REG12
+ mov YL,TabP
+ ldi TMP, 0x1F
+ sbrs TabE,b0
+ eor YL,TMP ; invert envelope value if ATTACK bit is not set
+ ldd EVal,Y+0x30 ; translate envelope value to volume, read volume value from SRAM 0x230+YL
+ENVELOPE_GENERATOR_END_AY0:
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// NOISE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+; dec CntN_AY0 ; decrease noise period counter
+; brpl NOISE_GENERATOR_END_AY0 ; skip if noise period is not finished (CntN>=0)
+ //init new cycle
+; lds CntN_AY0,AY0_REG06 ; init noise period counter with value in AY register 6
+; dec CntN_AY0
+; lsr NoiseAddon_AY0
+; mov NoiseAddon_AY0,RNGL_AY0
+; ror RNGH_AY0
+; ror RNGL_AY0
+; ori TNLevel_AY0,0x38 ; set noise bitsP
+; sbrs RNGL_AY0,b0
+; andi TNLevel_AY0,0xC7 ; reset noise bits
+; lsl NoiseAddon_AY0
+; eor NoiseAddon_AY0,RNGL_AY0
+; lsr NoiseAddon_AY0
+;NOISE_GENERATOR_END_AY0:
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// TONE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ ; all counters are Int16 values (signed)
+ ; Channel A -------------
+ ldi YH, 0x21
+ ldi YL, low(AY0_CntAL)
+
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_A_NO_CHANGE_AY0
+ ldi YL, low(AY0_REG00)
+ ld r0, Y
+ sts 0x21, C21
+ eor TNLevel_AY0, ZH
+CH_A_NO_CHANGE_AY0:
+ ldi YL, low(AY0_CntAL)
+ st Y, r2
+
+ ; Channel B -------------
+ ldi YL, low(AY0_CntBL)
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_B_NO_CHANGE_AY0
+ ldi YL, low(AY0_REG02)
+ ld r0, Y
+ sts 0x21, C21
+ ldi TMP, 0x02
+ eor TNLevel_AY0, TMP
+CH_B_NO_CHANGE_AY0:
+ ldi YL, low(AY0_CntBL)
+ st Y, r2
+
+ ; Channel C -------------
+ ldi YL, low(AY0_CntCL)
+ ld r0, Y
+ sts 0x21, C21
+
+ sbis 0x00, 1
+ rjmp CH_C_NO_CHANGE_AY0
+ ldi YL, low(AY0_REG04)
+ ld r0, Y
+ sts 0x21, C21
+ eor TNLevel_AY0, C04
+CH_C_NO_CHANGE_AY0:
+ ldi YL, low(AY0_CntCL)
+ st Y, r2
+
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// MIXER
+ /////////////////////////////////////////////////////////////////////////////////////
+ lds TMP,AY0_REG07 ; Load Mixer AY Register from SRAM
+ or TMP,TNLevel_AY0 ; Mixer formula = (Mixer Register Tone | TNLevel Tone) & (Mixer Register Noise | TNLevel Noise)
+ mov YL,TMP
+ lsl YL
+ swap YL
+ and TMP,YL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// AMPLITUDE CONTROL
+ /////////////////////////////////////////////////////////////////////////////////////
+ ldi YH, 0x02
+ // Channel A
+ lds YL,AY0_REG08 ; Load Channel A Amplitude register
+ mov OutA,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutA,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b0 ; if channel is disabled in mixer - set volume to zero
+ clr OutA
+
+ // Channel B
+ lds YL,AY0_REG09 ; Load Channel B Amplitude register
+ mov OutB,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutB,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b1 ; if channel is disabled in mixer - set volume to zero
+ clr OutB
+
+ // Channel C
+ lds YL,AY0_REG10 ; Load Channel C Amplitude register
+ mov OutC,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutC,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b2 ; if channel is disabled in mixer - set volume to zero
+ clr OutC
+
+ mov YL,OutB
+ lsr OutB ; TMP = TMP - (TMP/4 + TMP/8);
+ lsr OutB
+ sub YL,OutB
+ lsr OutB
+ sub YL,OutB
+ add OutA,YL ; add channel B volume to channels A and C
+ add OutC,YL
+
+ ; === AY0 ===
+ ldi YL, low(EnvState_AY0)
+ st Y, TabE
+ std Y+1, TabP
+ std Y+2, EVal
+ std Y+8, OutA
+ std Y+9, OutC
+
+AY1_PROCESSING:
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// ENVELOPE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ ; === AY1 ===
+ ldi YL, low(EnvState_AY1)
+ ld TabE, Y
+ ldd TabP, Y+1
+ ldd EVal, Y+2
+
+ sbrs TNLevel_AY1,b7
+ rjmp NO_ENVELOPE_CHANGED_AY1
+
+ // initialize envelope generator after change envelope shape register, only first 1/32 part of the first period!
+ lds YL,AY1_REG13 ; load envelope shape register value to TabE
+ ldd TabE,Y+0x10 ; get envelope code from SRAM
+ ldi TabP,0x1F ; set counter for envelope period
+ andi TNLevel_AY1,0x7F ; clear envelope shape change flag
+ rjmp E_NEXT_STEP_AY1
+
+NO_ENVELOPE_CHANGED_AY1:
+ sbrc TabE,b7 ; alternate: cpi TabE,0x80 ; check if envelope generator is disabled
+ rjmp ENVELOPE_GENERATOR_END_AY1 ; alternate: brcc ENVELOPE_GENERATOR_END
+ sbiw CntEL_AY1,0x01
+ brcs E_NEXT_PERIOD_AY1 ; jump to init next envelope value if counter overflow (if initial value was 0)
+ brne ENVELOPE_GENERATOR_END_AY1 ; go to the next step if zero value is not reached
+E_NEXT_PERIOD_AY1:
+ dec TabP
+ brpl E_NEXT_STEP_AY1 ; jump to next step if envelope period >= 0
+ ;init new envelope period
+ ldi TabP,0x1F
+ sbrc TabE,b1
+ eor TabE,ZH ; invert envelope ATTACK bit
+ sbrc TabE,b2
+ or TabE,CC0 ; disable envelope generator until new envelope shape register recived
+E_NEXT_STEP_AY1:
+ lds CntEL_AY1,AY1_REG11
+ lds CntEH_AY1,AY1_REG12
+ mov YL,TabP
+ ldi TMP, 0x1F
+ sbrs TabE,b0
+ eor YL,TMP ; invert envelope value if ATTACK bit is not set
+ ldd EVal,Y+0x30 ; translate envelope value to volume, read volume value from SRAM 0x230+YL
+ENVELOPE_GENERATOR_END_AY1:
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// NOISE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ dec CntN_AY1 ; decrease noise period counter
+ brpl NOISE_GENERATOR_END_AY1 ; skip if noise period is not finished (CntN>=0)
+ //init new cycle
+ lds CntN_AY1,AY1_REG06 ; init noise period counter with value in AY register 6
+ dec CntN_AY1
+ lsr NoiseAddon_AY1
+ mov NoiseAddon_AY1,RNGL_AY1
+ ror RNGH_AY1
+ ror RNGL_AY1
+ ori TNLevel_AY1,0x38 ; set noise bitsP
+ sbrs RNGL_AY1,b0
+ andi TNLevel_AY1,0xC7 ; reset noise bits
+
+ lsl NoiseAddon_AY1
+ eor NoiseAddon_AY1,RNGL_AY1
+ lsr NoiseAddon_AY1
+NOISE_GENERATOR_END_AY1:
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// TONE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ ; all counters are Int16 values (signed)
+ ; Channel A -------------
+ ldi YH, 0x21
+ ldi YL, low(AY1_CntAL)
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_A_NO_CHANGE_AY1
+ ldi YH, 0x23
+ ldi YL, low(AY1_REG00)
+ ld r0, Y
+ sts 0x21, C21
+ eor TNLevel_AY1, ZH
+ ldi YH, 0x21
+CH_A_NO_CHANGE_AY1:
+ ldi YL, low(AY1_CntAL)
+ st Y, r2
+
+ ; Channel B -------------
+ ldi YL, low(AY1_CntBL)
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_B_NO_CHANGE_AY1
+ ldi YH, 0x23
+ ldi YL, low(AY1_REG02)
+ ld r0, Y
+ sts 0x21, C21
+ ldi TMP, 0x02
+ eor TNLevel_AY1, TMP
+ ldi YH, 0x21
+CH_B_NO_CHANGE_AY1:
+ ldi YL, low(AY1_CntBL)
+ st Y, r2
+
+ ; Channel C -------------
+ ldi YL, low(AY1_CntCL)
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_C_NO_CHANGE_AY1
+ ldi YH, 0x23
+ ldi YL, low(AY1_REG04)
+ ld r0, Y
+ sts 0x21, C21
+ eor TNLevel_AY1, C04
+ ldi YH, 0x21
+CH_C_NO_CHANGE_AY1:
+ ldi YL, low(AY1_CntCL)
+ st Y, r2
+
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// MIXER
+ /////////////////////////////////////////////////////////////////////////////////////
+ lds TMP,AY1_REG07 ; Load Mixer AY Register from SRAM
+ or TMP,TNLevel_AY1 ; Mixer formula = (Mixer Register Tone | TNLevel Tone) & (Mixer Register Noise | TNLevel Noise)
+ mov YL,TMP
+ lsl YL
+ swap YL
+ and TMP,YL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// AMPLITUDE CONTROL
+ /////////////////////////////////////////////////////////////////////////////////////
+ ldi YH, 0x02
+ // Channel A
+ lds YL,AY1_REG08 ; Load Channel A Amplitude register
+ mov OutA,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutA,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b0 ; if channel is disabled in mixer - set volume to zero
+ clr OutA
+
+ // Channel B
+ lds YL,AY1_REG09 ; Load Channel B Amplitude register
+ mov OutB,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutB,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b1 ; if channel is disabled in mixer - set volume to zero
+ clr OutB
+
+ // Channel C
+ lds YL,AY1_REG10 ; Load Channel C Amplitude register
+ mov OutC,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutC,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b2 ; if channel is disabled in mixer - set volume to zero
+ clr OutC
+
+ mov YL,OutB
+ lsr OutB ; TMP = TMP - (TMP/4 + TMP/8);
+ lsr OutB
+ sub YL,OutB
+ lsr OutB
+ sub YL,OutB
+ add OutA,YL ; add channel B volume to channels A and C
+ add OutC,YL
+
+ ; === AY1 ===
+ ldi YL, low(EnvState_AY1)
+ st Y, TabE
+ std Y+1, TabP
+ std Y+2, EVal
+
+ ; === AY0 AY1 ===
+ ldd TMP, Y+5
+ add OutA, TMP
+ ldd TMP, Y+6
+ add OutC, TMP
+
+ sts OCR1AL,OutA ; update PWM counters
+ sts OCR1BL,OutC
+ rjmp _MAIN_LOOP
+// MAIN LOOP END ====================================================================
+
+// copy routine from flash to SRAM
+_COPY:
+ lpm r16,Z+
+ st X+,r16
+ dec r18
+ brne _COPY
+ ret
+
+/////////////////////////////////////////////////////////////////
+/// AY REGISTERS IN SRAM
+/////////////////////////////////////////////////////////////////
+ .dseg
+ .org 0x0110
+; AY
+AY0_REG00:
+ .byte 1
+AY0_REG01:
+ .byte 1
+AY0_REG02:
+ .byte 1
+AY0_REG03:
+ .byte 1
+AY0_REG04:
+ .byte 1
+AY0_REG05:
+ .byte 1
+AY0_REG06:
+ .byte 1
+AY0_REG07:
+ .byte 1
+AY0_REG08:
+ .byte 1
+AY0_REG09:
+ .byte 1
+AY0_REG10:
+ .byte 1
+AY0_REG11:
+ .byte 1
+AY0_REG12:
+ .byte 1
+AY0_REG13:
+ .byte 1
+AY0_REG14:
+ .byte 1
+AY0_REG15:
+ .byte 1
+
+.org 0x0251
+EnvState_AY0: .byte 3 ; [TabE, TabP, EVal] AY0
+EnvState_AY1: .byte 3 ; [TabE, TabP, EVal] AY1
+
+.org 0x0259
+OutA0: .byte 1
+OutC0: .byte 1
+
+.org 0x0260
+; AY0
+AY0_CntAL: .byte 1
+AY0_CntAH: .byte 1
+AY0_CntBL: .byte 1
+AY0_CntBH: .byte 1
+AY0_CntCL: .byte 1
+AY0_CntCH: .byte 1
+
+; AY1
+AY1_CntAL: .byte 1
+AY1_CntAH: .byte 1
+AY1_CntBL: .byte 1
+AY1_CntBH: .byte 1
+AY1_CntCL: .byte 1
+AY1_CntCH: .byte 1
+
+ConstL: .byte 1
+ConstH: .byte 1
+
+; AY
+ .org 0x0310
+AY1_REG00:
+ .byte 1
+AY1_REG01:
+ .byte 1
+AY1_REG02:
+ .byte 1
+AY1_REG03:
+ .byte 1
+AY1_REG04:
+ .byte 1
+AY1_REG05:
+ .byte 1
+AY1_REG06:
+ .byte 1
+AY1_REG07:
+ .byte 1
+AY1_REG08:
+ .byte 1
+AY1_REG09:
+ .byte 1
+AY1_REG10:
+ .byte 1
+AY1_REG11:
+ .byte 1
+AY1_REG12:
+ .byte 1
+AY1_REG13:
+ .byte 1
+AY1_REG14:
+ .byte 1
+AY1_REG15:
+ .byte 1
diff --git a/Sources/AY_Emu/AY_Emu/main.asm b/Sources/AY_Emu/AY_Emu/main.asm
new file mode 100644
index 0000000..60d0fe3
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/main.asm
@@ -0,0 +1,1103 @@
+; AY-3-8912 IC emulator version 26.0 for LGT8F328P
+;
+; Sources for Atmel AVRStudio 7
+;
+; visit our site for more information
+; These source codes are distributed under the GPL v3 license
+; If you share these sources you should put the link to web site www.avray.ru
+;
+; ORIGIN: http://www.avray.ru
+
+; CONFIGURATION VALUES ===================================================
+#define VOLUME_TABLE 0 ; 1 - AY, 1 - YM, 2 - ALTERNATE volume table
+#define INT_32MHz 0
+#define INT_37MHz 1
+#define EXT_40MHz 0
+#define EXT_48MHz 0
+#define EXT_50MHz 0
+; ========================================================================
+; bit numbers:
+.equ b0 = 0x00
+.equ b1 = 0x01
+.equ b2 = 0x02
+.equ b3 = 0x03
+.equ b4 = 0x04
+.equ b5 = 0x05
+.equ b6 = 0x06
+.equ b7 = 0x07
+.equ CHIP_SELECTED = GPIOR0
+
+.def OutA0 = r0
+.def OutC0 = r1
+.def OutA1 = r2
+.def CntN = r3
+.def OutB = r4
+.def BusOut1 = r5
+.def NoiseAddon = r6
+.def C00 = r7
+.def CC0 = r8
+.def TabE_AY0 = r9
+.def OutC1 = r10
+.def EVal_AY1 = r11
+.def EVal_AY0 = r12
+.def C21 = r13
+.def RNGL = r14
+.def RNGH = r15
+.def TNLevel_AY1 = r16
+.def BusOut2 = r17
+.def TabP_AY0 = r18
+.def TNLevel_AY0 = r19
+.def BusData = r20
+.def TMP = r21
+.def TabE_AY1 = r22
+.def TabP_AY1 = r23
+.def CntEL_AY0 = r24
+.def CntEH_AY0 = r25
+.def CntEL_AY1 = r26
+.def CntEH_AY1 = r27
+.def ADDR = r30
+
+; ==============================================
+; LGT8F328P REGISTER DEFINITIONS
+; ==============================================
+; Memory-mapped I/O addresses for LGT8F328P
+.equ CCP = 0x34 ; Configuration Change Protection
+.equ CLKMSR = 0x105 ; Clock Main Settings Register
+.equ BCR = 0x107 ; Boot Control Register
+.equ BOOTEND = 0x108 ; Boot End Address
+.equ BODCR = 0x104 ; BOD Control Register
+
+.equ PMCR = 0xF2
+.equ PMCE = 7
+.equ CLKFS = 6
+.equ CLKSS = 5
+.equ WCLKS = 4
+.equ WCES = 4
+.equ OSCKEN = 3
+.equ OSCMEN = 2
+.equ RCKEN = 1
+.equ RCMEN = 0
+
+.equ PMX2 = 0xF0
+.equ IOCR = 0xF0
+.equ IOCE = 7
+.equ STSC1 = 6
+.equ STSC0 = 5
+.equ XIEN = 2
+.equ E6EN = 1
+.equ REFIOEN = 1
+.equ C6EN = 0
+.equ RSTIOEN = 0
+
+; AC0 (Analog Comparator 0) Register Definition
+.equ C0SR = 0x50
+.equ C0D = 7
+.equ C0BG = 6
+.equ C0O = 5
+.equ C0I = 4
+.equ C0IE = 3
+.equ C0IC = 2
+.equ C0IS1 = 1
+.equ C0IS0 = 0
+
+.equ C0XR = 0x51
+.equ C0OE = 6
+.equ C0HSYE = 5
+.equ C0PS0 = 4
+.equ C0WKE = 3
+.equ C0FEN = 2
+.equ C0FS1 = 1
+.equ C0FS0 = 0
+
+.equ C0TR = 0x52
+
+; AC1 (Analog Comparator 1) Register Definition
+.equ C1SR = 0x2F
+.equ C1D = 7
+.equ C1BG = 6
+.equ C1O = 5
+.equ C1I = 4
+.equ C1IE = 3
+.equ C1IC = 2
+.equ C1IS1 = 1
+.equ C1IS0 = 0
+
+.equ C1XR = 0x3A
+.equ C1OE = 6
+.equ C1HSYE = 5
+.equ C1PS0 = 4
+.equ C1WKE = 3
+.equ C1FEN = 2
+.equ C1FS1 = 1
+.equ C1FS0 = 0
+
+.equ C1TR = 0x5B
+
+;----------------------------------------------------------------
+; DSU (Digital Signal Co-processor) Register Definition
+;----------------------------------------------------------------
+.equ DSCR = 0x20
+.equ DSUEN = 7
+.equ DSMM = 6
+.equ DSD1 = 5
+.equ DSD0 = 4
+.equ DSZ = 2 ; .
+.equ DSN = 1
+.equ DSC = 0
+
+.equ DSIR = 0x21
+
+.equ DSSD = 0x22
+.equ DSDX = 0x30
+.equ DSDY = 0x31
+.equ DSAL = 0x58
+.equ DSAH = 0x59
+
+ .cseg
+;------------------------------------------------------
+; INTERRUPT VECTORS TABLE
+;------------------------------------------------------
+ .org 0x0000
+ rjmp _LGT_INIT
+
+ .org INT0addr
+ rjmp _INT0_Handler
+
+ .org INT1addr
+ rjmp _INT1_Handler
+
+;------------------------------------------------------
+
+#if VOLUME_TABLE == 0
+ Volumes: ; volume table for amplitude
+ .db 0,1,1,1,2,2,3,5,6,9,13,17,22,29,36,45 // AY_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,0,1,1,1,1,1,1,2,2,2,2,3,3,5,5,6,6,7,9,11,13,15,17,19,22,25,29,32,36,40,45 // AY_TABLE
+#elif VOLUME_TABLE == 1
+ Volumes: ; volume table for amplitude
+ .db 0,1,1,1,2,2,3,4,5,7,10,13,18,24,34,45 // YM_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,0,1,1,1,1,1,1,2,2,2,2,2,3,3,4,4,5,6,7,8,10,11,13,15,18,21,24,29,34,40,45 // YM_TABLE
+#elif VOLUME_TABLE == 2
+ Volumes: ; volume table for amplitude
+ .db 0,1,2,3,4,5,6,7,9,11,13,16,22,31,42,58 // ALT_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,24,26,28,30,33,36,40,45,51,58 // ALT_TABLE
+#endif
+
+; envelope codes, bit0 - attack, bit1 - invert on next cycle, bit2 - stop generator on next cycle
+Envelopes:
+ .db 7,7,7,7,4,4,4,4,1,7,3,5,0,6,2,4
+
+; mask applied to registers values after receiving
+RegsMask:
+ .db 0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0x1F,0xFF,0x1F,0x1F,0x1F,0xFF,0xFF,0x0F,0xFF,0xFF
+
+;==========================================================
+_INT0_Handler: ; 4 cycles to enter
+ sbic PinD,b3 ; check BDIR (1)
+ rjmp LATCH_REG_ADDR0 ; (2) if BDIR=1
+
+ out DDRD,BusOut2 ; 1 - set data bus
+ out DDRC,BusOut1 ; 1
+
+LOOP_NOT_INACTIVE:
+ sbic PinD,b2 ; 1 - wait for BC1=0
+ rjmp LOOP_NOT_INACTIVE ; 2
+ out DDRC, C00 ; 1
+ out DDRD, C00 ; 1
+
+exit_int0:
+ ldi ZH, 0x01
+ ldi r20, 0x02
+ out EIFR, r20 ; 1 - clear flags
+ reti ; 4
+
+LATCH_REG_ADDR0:
+ in ADDR, PinC ; 1
+ andi ADDR, 0x3F ; 1
+ sbic PinD,b7
+ rjmp SELECT_CHIP_ADDR0
+ sbic CHIP_SELECTED,b0
+ rjmp READ_CHIP0
+ ; 0
+ ldi ZH,0x01
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int0
+
+READ_CHIP0:
+ ; 1
+ ldi ZH,high(AY1_REG00)
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int0
+
+SELECT_CHIP_ADDR0:
+ cpi ADDR, 0x3F ; 1
+ breq SELECT_CHIP0_ADDR0 ; 1/2
+ cpi ADDR, 0x3E
+ breq SELECT_CHIP1_ADDR0 ; 2
+ rjmp exit_int0
+
+SELECT_CHIP0_ADDR0:
+ cbi CHIP_SELECTED, b0
+ rjmp exit_int0
+
+SELECT_CHIP1_ADDR0:
+ sbi CHIP_SELECTED, b0
+ rjmp exit_int0
+
+;==========================================================
+_INT1_Handler: ; 4 cycles to enter
+ in BusData, PinC ; 1
+ andi BusData, 0x3F ; 1
+
+ sbic PinD, b2 ; 1
+ rjmp LATCH_REG_ADDR1 ; 2
+
+ in BusOut1, PinD ; 1
+ in C00, SREG ; 1
+
+ and BusOut1, CC0
+ or BusData, BusOut1 ; 1
+ mov BusOut1, BusData ; 1
+ com BusOut1 ; 1
+ ldi ZH, 0x01
+ ld BusOut2, Z ; 2 - load mask
+
+ sbic CHIP_SELECTED, b0
+ ldi ZH, high(AY1_REG00)
+
+ std Z+0x20, BusOut1 ; 2 - save inverted
+ and BusData, BusOut2 ; 1 - apply mask
+ mov BusOut2, BusOut1 ; 1
+ and BusOut2, CC0 ; 1 - extract bits 6-7
+
+ std Z+0x30, BusOut2 ; 2 - save high bits
+ std Z+0x10, BusData ; 2 - save value
+
+ ; 13
+ cpi ADDR, 0x0D ; 1
+ brne NO_ENVELOPE_CHANGED_P; 1/2
+
+ sbis CHIP_SELECTED, b0
+ ori TNLevel_AY0, 0x80
+ sbic CHIP_SELECTED, b0
+ ori TNLevel_AY1, 0x80
+
+NO_ENVELOPE_CHANGED_P:
+ out SREG, C00 ; 1
+ clr C00
+exit_int1:
+ ldi ZH, 0x01
+ out EIFR, ZH ; 1
+ reti
+
+LATCH_REG_ADDR1:
+ mov ADDR, BusData ; 1
+ sbic PinD,b6
+ rjmp SELECT_CHIP_ADDR1
+ sbic CHIP_SELECTED,b0
+ rjmp READ_CHIP1
+ ; 0
+ ldi ZH,0x01
+ ldd BusOut1, Z+0x20 ; 2
+ ldd BusOut2, Z+0x30 ; 2
+ rjmp exit_int1
+
+READ_CHIP1:
+ ; 1
+ ldi ZH,high(AY1_REG00)
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int1 ; 2
+
+SELECT_CHIP_ADDR1:
+ cpi ADDR, 0x3F ; 1
+ breq SELECT_CHIP0_ADDR1 ; 1/2
+ cpi ADDR, 0x3E
+ breq SELECT_CHIP1_ADDR1 ; 2
+ rjmp exit_int1
+
+SELECT_CHIP0_ADDR1:
+ cbi CHIP_SELECTED, b0
+ rjmp exit_int1
+
+SELECT_CHIP1_ADDR1:
+ sbi CHIP_SELECTED, b0
+ rjmp exit_int1
+
+; ==============================================
+; LGT8F328P INITIALIZATION - NO BOOTLOADER
+; ==============================================
+_LGT_INIT:
+ cli
+ ; watchdog
+ ldi r16, 0x00
+ sts WDTCSR, r16
+
+
+#if INT_32MHz == 1 || INT_37MHz == 1
+ ;Unlock protected registers (LGT specific)
+ ldi r16, 0xD8
+ sts CCP, r16 ; Enable configuration changes
+ ;Configure clock: 32MHz internal, divisor = 1
+ ldi r16, 0x80
+ sts CLKPR, r16 ; Enable CLKPR changes
+
+ ldi r16, 0xD8
+ sts CCP, r16
+ ldi r16, 0x00
+ sts CLKPR, r16 ; Divisor = 1 (32MHz)
+
+ ;Select internal 32MHz oscillator
+ ldi r16, 0xD8
+ sts CCP, r16
+ ldi r16, 0x04
+ sts CLKMSR, r16 ; Internal 32MHz oscillator
+
+ #if INT_37MHz == 1
+ ;
+ ldi r16, 0xE0
+ sts OSCCAL, r16
+ #endif
+
+#elif EXT_40MHz == 1 || EXT_48MHz == 1 || EXT_50MHz == 1
+ ;
+ ldi r16, (1< PUD for
+ sbr r16,PUD
+ out MCUCR,r16
+
+ // init stack pointer at end of RAM
+ ldi r16,low(RAMEND)
+ out SPL,r16
+ ldi r16,high(RAMEND)
+ out SPH,r16
+
+ ; disable Analog Comparator ==============================
+ ldi r16, (1< 2000*256 = 512000
+ ldi r26, low(2000)
+ ldi r27, high(2000)
+CALIB_WAIT:
+ in r16, TIFR0
+ sbrs r16, TOV0
+ rjmp CALIB_WAIT
+ ldi r16, (1< ,
+ tst r20
+ brne CALIB_DO
+ tst r21
+ breq CALIB_END
+
+CALIB_DO:
+ ; 4096000 / N_ref ,
+ ; ( ) -
+ ; ICR1 ~0.5% ( ICR1~200
+ ; - )
+ ldi r22, 0x00 ; numL
+ ldi r23, 0x80 ; numM
+ ldi r18, 0x3E ; numH (numH:numM:numL = 4096000)
+
+ ; N_ref/2 -
+ ;
+ mov r26, r20
+ mov r27, r21
+ lsr r27
+ ror r26
+ add r22, r26
+ adc r23, r27
+ adc r18, C00
+
+ clr r24 ; quotL
+ clr r25 ; quotH
+
+CALIB_DIV_LOOP:
+ tst r18 ; numH == 0 ?
+ brne CALIB_DIV_SUB ; num >= 65536 > N_ref -
+ cp r22, r20 ; (numM:numL) (denH:denL)
+ cpc r23, r21
+ brlo CALIB_DIV_DONE
+
+CALIB_DIV_SUB:
+ sub r22, r20
+ sbc r23, r21
+ sbc r18, C00
+ inc r24
+ brne CALIB_DIV_LOOP
+ inc r25
+ rjmp CALIB_DIV_LOOP
+
+CALIB_DIV_DONE:
+ subi r24, 1 ; ICR1 = quotient - 1
+ sbci r25, 0
+
+ tst r25 ; 1
+ brne CALIB_END ; - ,
+
+ mov r28, r24 ; ICR1
+ com r0 ; (r0 0 -> 0xFF)
+
+CALIB_END:
+ ; ===== =====
+
+ ldi r16,0xA2
+ sts TCCR1A,r16
+ ldi r16,0x19
+ sts TCCR1B,r16
+
+#if INT_32MHz == 1
+ ldi r18, 0x91
+#elif INT_37MHz == 1
+ ldi r18, 0xAD
+#elif EXT_40MHz == 1
+ ldi r18, 0xB6
+#elif EXT_48MHz == 1
+ ldi r18, 0xDA
+#elif EXT_50MHz == 1
+ ldi r18, 0xE5
+#endif
+ tst r0 ; -
+ breq NO_CALIBRATION
+ mov r18, r28
+NO_CALIBRATION:
+ sts ICR1H,C00
+ sts ICR1L,r18 ; set PWM speed
+ ; ICR1L value formula (32000000/109375/2 - 1) where 32000000 = 32MHz - AVR oscillator frequency
+ ; 109375 is for 1.75 MHz version, formula is (PSG frequency / 16) e.g. for 2MHz it is 2000000/16 = 125000
+
+ ; set INT0,INT1 ============================================
+ ldi r16, (1<=0)
+ lds CntN,AY0_REG06 ; init noise period counter with value in AY register 6
+ lds TMP,AY1_REG06
+ cp CntN, TMP
+ brge LESS
+ mov CntN, TMP
+LESS:
+ dec CntN
+ lsr NoiseAddon
+ mov NoiseAddon,RNGL
+ ror RNGH
+ ror RNGL
+ ori TNLevel_AY0,0x38 ; set noise bitsP
+ ori TNLevel_AY1,0x38 ; set noise bitsP
+ sbrs RNGL,b0
+ andi TNLevel_AY0,0xC7 ; reset noise bits
+ sbrs RNGL,b0
+ andi TNLevel_AY1,0xC7 ; reset noise bits
+ lsl NoiseAddon
+ eor NoiseAddon,RNGL
+ lsr NoiseAddon
+NOISE_GENERATOR_END:
+
+;============================================
+;=======ENVELOPE_GENERATOR_AY0===============
+;============================================
+ sbrs TNLevel_AY0, b7
+ rjmp NO_ENVELOPE_CHANGED_AY0
+
+ ; initialize envelope generator
+ lds YL, AY0_REG13
+ ldd TabE_AY0, Y+0x10
+ ldi TabP_AY0, 0x1F
+ andi TNLevel_AY0, 0x7F
+ rjmp E_NEXT_STEP_AY0
+
+NO_ENVELOPE_CHANGED_AY0:
+ sbrc TabE_AY0, b7
+ rjmp ENVELOPE_GENERATOR_END_AY0
+ sbiw CntEL_AY0, 0x01
+ brlt E_NEXT_PERIOD_AY0
+ brne ENVELOPE_GENERATOR_END_AY0
+
+E_NEXT_PERIOD_AY0:
+ dec TabP_AY0
+ brpl E_NEXT_STEP_AY0
+ ldi TabP_AY0, 0x1F
+ sbrc TabE_AY0, b1
+ eor TabE_AY0, ZH
+ sbrc TabE_AY0, b2
+ or TabE_AY0, CC0
+
+E_NEXT_STEP_AY0:
+ lds CntEL_AY0, AY0_REG11
+ lds CntEH_AY0, AY0_REG12
+ mov YL, TabP_AY0
+ ldi TMP, 0x1F
+ sbrs TabE_AY0, b0
+ eor YL, TMP
+ ldd EVal_AY0, Y+0x30
+
+ENVELOPE_GENERATOR_END_AY0:
+
+;============================================
+;=======ENVELOPE_GENERATOR_AY1===============
+;============================================
+ sbrs TNLevel_AY1, b7
+ rjmp NO_ENVELOPE_CHANGED_AY1
+
+ ;initialize_envelope_generator_AY1:
+ lds YL, AY1_REG13
+ ldd TabE_AY1, Y+0x10
+ ldi TabP_AY1, 0x1F
+ andi TNLevel_AY1, 0x7F
+ rjmp E_NEXT_STEP_AY1
+
+NO_ENVELOPE_CHANGED_AY1:
+ sbrc TabE_AY1, b7
+ rjmp ENVELOPE_GENERATOR_END_AY1
+ sbiw CntEL_AY1, 0x01
+ brlt E_NEXT_PERIOD_AY1
+ brne ENVELOPE_GENERATOR_END_AY1
+
+E_NEXT_PERIOD_AY1:
+ dec TabP_AY1
+ brpl E_NEXT_STEP_AY1
+ ldi TabP_AY1, 0x1F
+ sbrc TabE_AY1, b1
+ eor TabE_AY1, ZH
+ sbrc TabE_AY1, b2
+ or TabE_AY1, CC0
+
+E_NEXT_STEP_AY1:
+ lds CntEL_AY1, AY1_REG11
+ lds CntEH_AY1, AY1_REG12
+ mov YL, TabP_AY1
+ ldi TMP, 0x1F
+ sbrs TabE_AY1, b0
+ eor YL, TMP
+ ldd EVal_AY1, Y+0x30
+
+ENVELOPE_GENERATOR_END_AY1:
+
+ sbis CHIP_SELECTED, b1
+ rjmp GENERATORS_AY1
+
+;============================================
+;=======TONE_GENERATOR_AY0===============
+;============================================
+ ; Channel A
+ ldi YH, 0x21
+ ldi YL, low(AY0_CntAL)
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_A_NO_CHANGE_AY0
+ ldi YL, low(AY0_REG00)
+ ld r0, Y
+ sts 0x21, C21
+ eor TNLevel_AY0, ZH
+CH_A_NO_CHANGE_AY0:
+ ldi YL, low(AY0_CntAL)
+ st Y, r2
+
+ ; Channel B
+ ldi YL, low(AY0_CntBL)
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_B_NO_CHANGE_AY0
+ ldi YL, low(AY0_REG02)
+ ld r0, Y
+ sts 0x21, C21
+ ldi TMP, 0x02
+ eor TNLevel_AY0, TMP
+CH_B_NO_CHANGE_AY0:
+ ldi YL, low(AY0_CntBL)
+ st Y, r2
+
+ ; Channel C
+ ldi YL, low(AY0_CntCL)
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_C_NO_CHANGE_AY0
+ ldi YL, low(AY0_REG04)
+ ld r0, Y
+ sts 0x21, C21
+ ldi TMP, 0x04
+ eor TNLevel_AY0, TMP
+CH_C_NO_CHANGE_AY0:
+ ldi YL, low(AY0_CntCL)
+ st Y, r2
+ cbi CHIP_SELECTED, b1
+ rjmp GENERATORS_END
+
+GENERATORS_AY1:
+
+;============================================
+;=======TONE_GENERATOR_AY1===============
+;============================================
+ ldi YH, 0x21
+
+ ; Channel A
+ ldi YL, low(AY1_CntAL)
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_A_NO_CHANGE_AY1
+ ldi YH, 0x23
+ ldi YL, low(AY1_REG00)
+ ld r0, Y
+ sts 0x21, C21
+ eor TNLevel_AY1, ZH
+ ldi YH, 0x21
+CH_A_NO_CHANGE_AY1:
+ ldi YL, low(AY1_CntAL)
+ st Y, r2
+
+ ; Channel B
+ ldi YL, low(AY1_CntBL)
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_B_NO_CHANGE_AY1
+ ldi YH, 0x23
+ ldi YL, low(AY1_REG02)
+ ld r0, Y
+ sts 0x21, C21
+ ldi TMP, 0x02
+ eor TNLevel_AY1, TMP
+ ldi YH, 0x21
+CH_B_NO_CHANGE_AY1:
+ ldi YL, low(AY1_CntBL)
+ st Y, r2
+
+ ; Channel C
+ ldi YL, low(AY1_CntCL)
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_C_NO_CHANGE_AY1
+ ldi YH, 0x23
+ ldi YL, low(AY1_REG04)
+ ld r0, Y
+ sts 0x21, C21
+ ldi TMP, 0x04
+ eor TNLevel_AY1,TMP
+ ldi YH, 0x21
+CH_C_NO_CHANGE_AY1:
+ ldi YL, low(AY1_CntCL)
+ st Y, r2
+ sbi CHIP_SELECTED, b1
+
+GENERATORS_END:
+
+ ; === MIXER AY 0===
+ lds TMP, AY0_REG07
+ or TMP, TNLevel_AY0
+ mov YL, TMP
+ lsl YL
+ swap YL
+ and TMP, YL
+
+ ; === AMPLITUDE CONTROL AY0===
+ ldi YH, 0x02
+
+ ; Channel A
+ lds YL, AY0_REG08
+ mov OutA0, EVal_AY0
+ sbrs YL, b4
+ ldd OutA0, Y+0x20
+ sbrs TMP, b0
+ clr OutA0
+
+ ; Channel B
+ lds YL, AY0_REG09
+ mov OutB, EVal_AY0
+ sbrs YL, b4
+ ldd OutB, Y+0x20
+ sbrs TMP, b1
+ clr OutB
+
+ ; Channel C
+ lds YL, AY0_REG10
+ mov OutC0, EVal_AY0
+ sbrs YL, b4
+ ldd OutC0, Y+0x20
+ sbrs TMP, b2
+ clr OutC0
+
+ ; Mix channels
+ mov YL, OutB
+ lsr OutB
+ lsr OutB
+ sub YL, OutB
+ lsr OutB
+ sub YL, OutB
+ add OutA0, YL
+ add OutC0, YL
+
+ ; === MIXER AY 1===
+ lds TMP, AY1_REG07
+ or TMP, TNLevel_AY1
+ mov YL, TMP
+ lsl YL
+ swap YL
+ and TMP, YL
+
+ ; === AMPLITUDE CONTROL AY1===
+
+ ; Channel A
+ lds YL, AY1_REG08
+ mov OutA1, EVal_AY1
+ sbrs YL, b4
+ ldd OutA1, Y+0x20
+ sbrs TMP, b0
+ clr OutA1
+
+ ; Channel B
+ lds YL, AY1_REG09
+ mov OutB, EVal_AY1
+ sbrs YL, b4
+ ldd OutB, Y+0x20
+ sbrs TMP, b1
+ clr OutB
+
+ ; Channel C
+ lds YL, AY1_REG10
+ mov OutC1, EVal_AY1
+ sbrs YL, b4
+ ldd OutC1, Y+0x20
+ sbrs TMP, b2
+ clr OutC1
+
+ ; Mix channels
+ mov YL, OutB
+ lsr OutB
+ lsr OutB
+ sub YL, OutB
+ lsr OutB
+ sub YL, OutB
+ add OutA1, YL
+ add OutC1, YL
+
+ ; === AY0 AY1 ===
+ add OutA0, OutA1
+ add OutC0, OutC1
+
+ sts OCR1AL, OutA0
+ sts OCR1BL, OutC0
+ rjmp _MAIN_LOOP
+// MAIN LOOP END ====================================================================
+
+// copy routine from flash to SRAM
+_COPY:
+ lpm r16,Z+
+ st X+,r16
+ dec r18
+ brne _COPY
+ ret
+
+/////////////////////////////////////////////////////////////////
+/// AY REGISTERS IN SRAM
+/////////////////////////////////////////////////////////////////
+ .dseg
+ .org 0x0110
+; AY
+AY0_REG00:
+ .byte 1
+AY0_REG01:
+ .byte 1
+AY0_REG02:
+ .byte 1
+AY0_REG03:
+ .byte 1
+AY0_REG04:
+ .byte 1
+AY0_REG05:
+ .byte 1
+AY0_REG06:
+ .byte 1
+AY0_REG07:
+ .byte 1
+AY0_REG08:
+ .byte 1
+AY0_REG09:
+ .byte 1
+AY0_REG10:
+ .byte 1
+AY0_REG11:
+ .byte 1
+AY0_REG12:
+ .byte 1
+AY0_REG13:
+ .byte 1
+AY0_REG14:
+ .byte 1
+AY0_REG15:
+ .byte 1
+
+.org 0x0260
+; AY0
+AY0_CntAL: .byte 1
+AY0_CntAH: .byte 1
+AY0_CntBL: .byte 1
+AY0_CntBH: .byte 1
+AY0_CntCL: .byte 1
+AY0_CntCH: .byte 1
+
+; AY1
+AY1_CntAL: .byte 1
+AY1_CntAH: .byte 1
+AY1_CntBL: .byte 1
+AY1_CntBH: .byte 1
+AY1_CntCL: .byte 1
+AY1_CntCH: .byte 1
+
+ConstL: .byte 1
+ConstH: .byte 1
+
+; AY
+ .org 0x0310
+AY1_REG00:
+ .byte 1
+AY1_REG01:
+ .byte 1
+AY1_REG02:
+ .byte 1
+AY1_REG03:
+ .byte 1
+AY1_REG04:
+ .byte 1
+AY1_REG05:
+ .byte 1
+AY1_REG06:
+ .byte 1
+AY1_REG07:
+ .byte 1
+AY1_REG08:
+ .byte 1
+AY1_REG09:
+ .byte 1
+AY1_REG10:
+ .byte 1
+AY1_REG11:
+ .byte 1
+AY1_REG12:
+ .byte 1
+AY1_REG13:
+ .byte 1
+AY1_REG14:
+ .byte 1
+AY1_REG15:
+ .byte 1
diff --git a/Sources/AY_Emu/AY_Emu/main_50MHz.asm b/Sources/AY_Emu/AY_Emu/main_50MHz.asm
new file mode 100644
index 0000000..066ee21
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/main_50MHz.asm
@@ -0,0 +1,1037 @@
+; AY-3-8912 IC emulator version 26.0 for LGT8F328P
+;
+; Sources for Atmel AVRStudio 7
+;
+; visit our site for more information
+; These source codes are distributed under the GPL v3 license
+; If you share these sources you should put the link to web site www.avray.ru
+;
+; ORIGIN: http://www.avray.ru
+
+; CONFIGURATION VALUES ===================================================
+#define VOLUME_TABLE 0 ; 0 - AY, 1 - YM, 2 - ALTERNATE volume table
+; ========================================================================
+; bit numbers:
+.equ b0 = 0x00
+.equ b1 = 0x01
+.equ b2 = 0x02
+.equ b3 = 0x03
+.equ b4 = 0x04
+.equ b5 = 0x05
+.equ b6 = 0x06
+.equ b7 = 0x07
+.equ CHIP_SELECTED = GPIOR0
+
+.def OutA = r0
+.def OutC = r1
+.def CntN_AY1 = r2
+.def CntN_AY0 = r3
+.def OutB = r4
+.def BusOut1 = r5
+.def NoiseAddon_AY0 = r6
+.def C00 = r7
+.def CC0 = r8
+.def TabE = r9
+.def C04 = r10
+.def NoiseAddon_AY1 = r11
+.def EVal = r12
+.def C21 = r13
+.def RNGL_AY0 = r14
+.def RNGH_AY0 = r15
+.def TNLevel_AY1 = r16
+.def BusOut2 = r17
+.def TabP = r18
+.def TNLevel_AY0 = r19
+.def BusData = r20
+.def TMP = r21
+.def RNGL_AY1 = r22
+.def RNGH_AY1 = r23
+.def CntEL_AY0 = r24
+.def CntEH_AY0 = r25
+.def CntEL_AY1 = r26
+.def CntEH_AY1 = r27
+.def ADDR = r30
+
+; ==============================================
+; LGT8F328P REGISTER DEFINITIONS
+; ==============================================
+; Memory-mapped I/O addresses for LGT8F328P
+.equ CCP = 0x34 ; Configuration Change Protection
+.equ CLKMSR = 0x105 ; Clock Main Settings Register
+.equ BCR = 0x107 ; Boot Control Register
+.equ BOOTEND = 0x108 ; Boot End Address
+.equ BODCR = 0x104 ; BOD Control Register
+
+.equ PMCR = 0xF2
+.equ PMCE = 7
+.equ CLKFS = 6
+.equ CLKSS = 5
+.equ WCLKS = 4
+.equ WCES = 4
+.equ OSCKEN = 3
+.equ OSCMEN = 2
+.equ RCKEN = 1
+.equ RCMEN = 0
+
+.equ PMX2 = 0xF0
+.equ IOCR = 0xF0
+.equ IOCE = 7
+.equ STSC1 = 6
+.equ STSC0 = 5
+.equ XIEN = 2
+.equ E6EN = 1
+.equ REFIOEN = 1
+.equ C6EN = 0
+.equ RSTIOEN = 0
+
+; AC0 (Analog Comparator 0) Register Definition
+.equ C0SR = 0x50
+.equ C0D = 7
+.equ C0BG = 6
+.equ C0O = 5
+.equ C0I = 4
+.equ C0IE = 3
+.equ C0IC = 2
+.equ C0IS1 = 1
+.equ C0IS0 = 0
+
+.equ C0XR = 0x51
+.equ C0OE = 6
+.equ C0HSYE = 5
+.equ C0PS0 = 4
+.equ C0WKE = 3
+.equ C0FEN = 2
+.equ C0FS1 = 1
+.equ C0FS0 = 0
+
+.equ C0TR = 0x52
+
+; AC1 (Analog Comparator 1) Register Definition
+.equ C1SR = 0x2F
+.equ C1D = 7
+.equ C1BG = 6
+.equ C1O = 5
+.equ C1I = 4
+.equ C1IE = 3
+.equ C1IC = 2
+.equ C1IS1 = 1
+.equ C1IS0 = 0
+
+.equ C1XR = 0x3A
+.equ C1OE = 6
+.equ C1HSYE = 5
+.equ C1PS0 = 4
+.equ C1WKE = 3
+.equ C1FEN = 2
+.equ C1FS1 = 1
+.equ C1FS0 = 0
+
+.equ C1TR = 0x5B
+
+;----------------------------------------------------------------
+; DSU (Digital Signal Co-processor) Register Definition
+;----------------------------------------------------------------
+.equ DSCR = 0x20
+.equ DSUEN = 7
+.equ DSMM = 6
+.equ DSD1 = 5
+.equ DSD0 = 4
+.equ DSZ = 2 ; .
+.equ DSN = 1
+.equ DSC = 0
+
+.equ DSIR = 0x21
+
+.equ DSSD = 0x22
+.equ DSDX = 0x30
+.equ DSDY = 0x31
+.equ DSAL = 0x58
+.equ DSAH = 0x59
+
+ .cseg
+;------------------------------------------------------
+; INTERRUPT VECTORS TABLE
+;------------------------------------------------------
+ .org 0x0000
+ rjmp _LGT_INIT
+
+ .org INT0addr
+ rjmp _INT0_Handler
+
+ .org INT1addr
+ rjmp _INT1_Handler
+
+;------------------------------------------------------
+
+#if VOLUME_TABLE == 0
+ Volumes: ; volume table for amplitude
+ .db 0,1,1,1,2,2,3,5,6,9,13,17,22,29,36,45 // AY_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,0,1,1,1,1,1,1,2,2,2,2,3,3,5,5,6,6,7,9,11,13,15,17,19,22,25,29,32,36,40,45 // AY_TABLE
+#elif VOLUME_TABLE == 1
+ Volumes: ; volume table for amplitude
+ .db 0,1,1,1,2,2,3,4,5,7,10,13,18,24,34,45 // YM_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,0,1,1,1,1,1,1,2,2,2,2,2,3,3,4,4,5,6,7,8,10,11,13,15,18,21,24,29,34,40,45 // YM_TABLE
+#elif VOLUME_TABLE == 2
+ Volumes: ; volume table for amplitude
+ .db 0,1,2,3,4,5,6,7,9,11,13,16,22,31,42,58 // ALT_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,24,26,28,30,33,36,40,45,51,58 // ALT_TABLE
+#endif
+
+; envelope codes, bit0 - attack, bit1 - invert on next cycle, bit2 - stop generator on next cycle
+Envelopes:
+ .db 7,7,7,7,4,4,4,4,1,7,3,5,0,6,2,4
+
+; mask applied to registers values after receiving
+RegsMask:
+ .db 0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0x1F,0xFF,0x1F,0x1F,0x1F,0xFF,0xFF,0x0F,0xFF,0xFF
+
+;==========================================================
+_INT0_Handler: ; 4 cycles to enter
+ sbic PinD,b3 ; check BDIR (1)
+ rjmp LATCH_REG_ADDR0 ; (2) if BDIR=1
+
+ out DDRD,BusOut2 ; 1 - set data bus
+ out DDRC,BusOut1 ; 1
+
+LOOP_NOT_INACTIVE:
+ sbic PinD,b2 ; 1 - wait for BC1=0
+ rjmp LOOP_NOT_INACTIVE ; 2
+ out DDRC, C00 ; 1
+ out DDRD, C00 ; 1
+
+exit_int0:
+ ldi ZH, 0x01
+ ldi r20, 0x02
+ out EIFR, r20 ; 1 - clear flags
+ reti ; 4
+
+LATCH_REG_ADDR0:
+ in ADDR, PinC ; 1
+ andi ADDR, 0x3F ; 1
+ sbic PinD,b7
+ rjmp SELECT_CHIP_ADDR0
+ sbic CHIP_SELECTED,b0
+ rjmp READ_CHIP0
+ ; 0
+ ldi ZH,0x01
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int0
+
+READ_CHIP0:
+ ; 1
+ ldi ZH,high(AY1_REG00)
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int0
+
+SELECT_CHIP_ADDR0:
+ cpi ADDR, 0x3F ; 1
+ breq SELECT_CHIP0_ADDR0 ; 1/2
+ cpi ADDR, 0x3E
+ breq SELECT_CHIP1_ADDR0 ; 2
+ rjmp exit_int0
+
+SELECT_CHIP0_ADDR0:
+ cbi CHIP_SELECTED, b0
+ rjmp exit_int0
+
+SELECT_CHIP1_ADDR0:
+ sbi CHIP_SELECTED, b0
+ rjmp exit_int0
+
+;==========================================================
+_INT1_Handler: ; 4 cycles to enter
+ in BusData, PinC ; 1
+ andi BusData, 0x3F ; 1
+
+ sbic PinD, b2 ; 1
+ rjmp LATCH_REG_ADDR1 ; 2
+
+ in BusOut1, PinD ; 1
+ in C00, SREG ; 1
+
+ and BusOut1, CC0
+ or BusData, BusOut1 ; 1
+ mov BusOut1, BusData ; 1
+ com BusOut1 ; 1
+ ldi ZH, 0x01
+ ld BusOut2, Z ; 2 - load mask
+
+ sbic CHIP_SELECTED, b0
+ ldi ZH, high(AY1_REG00)
+
+ std Z+0x20, BusOut1 ; 2 - save inverted
+ and BusData, BusOut2 ; 1 - apply mask
+ mov BusOut2, BusOut1 ; 1
+ and BusOut2, CC0 ; 1 - extract bits 6-7
+
+ std Z+0x30, BusOut2 ; 2 - save high bits
+ std Z+0x10, BusData ; 2 - save value
+
+ ; 13
+ cpi ADDR, 0x0D ; 1
+ brne NO_ENVELOPE_CHANGED_P; 1/2
+
+ sbis CHIP_SELECTED, b0
+ ori TNLevel_AY0, 0x80
+ sbic CHIP_SELECTED, b0
+ ori TNLevel_AY1, 0x80
+
+NO_ENVELOPE_CHANGED_P:
+ out SREG, C00 ; 1
+ clr C00
+exit_int1:
+ ldi ZH, 0x01
+ out EIFR, ZH ; 1
+ reti
+
+LATCH_REG_ADDR1:
+ mov ADDR, BusData ; 1
+ sbic PinD,b6
+ rjmp SELECT_CHIP_ADDR1
+ sbic CHIP_SELECTED,b0
+ rjmp READ_CHIP1
+ ; 0
+ ldi ZH,0x01
+ ldd BusOut1, Z+0x20 ; 2
+ ldd BusOut2, Z+0x30 ; 2
+ rjmp exit_int1
+
+READ_CHIP1:
+ ; 1
+ ldi ZH,high(AY1_REG00)
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int1 ; 2
+
+SELECT_CHIP_ADDR1:
+ cpi ADDR, 0x3F ; 1
+ breq SELECT_CHIP0_ADDR1 ; 1/2
+ cpi ADDR, 0x3E
+ breq SELECT_CHIP1_ADDR1 ; 2
+ rjmp exit_int1
+
+SELECT_CHIP0_ADDR1:
+ cbi CHIP_SELECTED, b0
+ rjmp exit_int1
+
+SELECT_CHIP1_ADDR1:
+ sbi CHIP_SELECTED, b0
+ rjmp exit_int1
+
+; ==============================================
+; LGT8F328P INITIALIZATION - NO BOOTLOADER
+; ==============================================
+_LGT_INIT:
+ cli
+ ; watchdog
+ ldi r16, 0x00
+ sts WDTCSR, r16
+
+ ;
+ ldi r16, (1< PUD for
+ sbr r16,PUD
+ out MCUCR,r16
+
+ // init stack pointer at end of RAM
+ ldi r16,low(RAMEND)
+ out SPL,r16
+ ldi r16,high(RAMEND)
+ out SPH,r16
+
+ ; C D HI-Z ===================
+ ; C: PC0-PC5 - , HI-Z
+ ; D: PD6,PD7 - , HI-Z
+ ldi r16,0x00
+ out DDRC,r16 ; C
+ out PORTC,r16 ;
+ out DDRD,r16 ; D
+ out PORTD,r16 ;
+ ; =====================================================
+
+ ; disable Analog Comparator ==============================
+ ldi r16, (1<= 0
+ ;init new envelope period
+ ldi TabP,0x1F
+ sbrc TabE,b1
+ eor TabE,ZH ; invert envelope ATTACK bit
+ sbrc TabE,b2
+ or TabE,CC0 ; disable envelope generator until new envelope shape register recived
+E_NEXT_STEP_AY0:
+ lds CntEL_AY0,AY0_REG11
+ lds CntEH_AY0,AY0_REG12
+ mov YL,TabP
+ ldi TMP, 0x1F
+ sbrs TabE,b0
+ eor YL,TMP ; invert envelope value if ATTACK bit is not set
+ ldd EVal,Y+0x30 ; translate envelope value to volume, read volume value from SRAM 0x230+YL
+ENVELOPE_GENERATOR_END_AY0:
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// NOISE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ dec CntN_AY0 ; decrease noise period counter
+ brpl NOISE_GENERATOR_END_AY0 ; skip if noise period is not finished (CntN>=0)
+ //init new cycle
+ lds CntN_AY0,AY0_REG06 ; init noise period counter with value in AY register 6
+ dec CntN_AY0
+ lsr NoiseAddon_AY0
+ mov NoiseAddon_AY0,RNGL_AY0
+ ror RNGH_AY0
+ ror RNGL_AY0
+ ori TNLevel_AY0,0x38 ; set noise bitsP
+ sbrs RNGL_AY0,b0
+ andi TNLevel_AY0,0xC7 ; reset noise bits
+ lsl NoiseAddon_AY0
+ eor NoiseAddon_AY0,RNGL_AY0
+ lsr NoiseAddon_AY0
+NOISE_GENERATOR_END_AY0:
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// TONE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ ; all counters are Int16 values (signed)
+ ; Channel A -------------
+ ldi YH, 0x21
+ ldi YL, low(AY0_CntAL)
+
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_A_NO_CHANGE_AY0
+ ldi YL, low(AY0_REG00)
+ ld r0, Y
+ sts 0x21, C21
+ eor TNLevel_AY0, ZH
+CH_A_NO_CHANGE_AY0:
+ ldi YL, low(AY0_CntAL)
+ st Y, r2
+
+ ; Channel B -------------
+ ldi YL, low(AY0_CntBL)
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_B_NO_CHANGE_AY0
+ ldi YL, low(AY0_REG02)
+ ld r0, Y
+ sts 0x21, C21
+ ldi TMP, 0x02
+ eor TNLevel_AY0, TMP
+CH_B_NO_CHANGE_AY0:
+ ldi YL, low(AY0_CntBL)
+ st Y, r2
+
+ ; Channel C -------------
+ ldi YL, low(AY0_CntCL)
+ ld r0, Y
+ sts 0x21, C21
+
+ sbis 0x00, 1
+ rjmp CH_C_NO_CHANGE_AY0
+ ldi YL, low(AY0_REG04)
+ ld r0, Y
+ sts 0x21, C21
+ eor TNLevel_AY0, C04
+CH_C_NO_CHANGE_AY0:
+ ldi YL, low(AY0_CntCL)
+ st Y, r2
+
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// MIXER
+ /////////////////////////////////////////////////////////////////////////////////////
+ lds TMP,AY0_REG07 ; Load Mixer AY Register from SRAM
+ or TMP,TNLevel_AY0 ; Mixer formula = (Mixer Register Tone | TNLevel Tone) & (Mixer Register Noise | TNLevel Noise)
+ mov YL,TMP
+ lsl YL
+ swap YL
+ and TMP,YL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// AMPLITUDE CONTROL
+ /////////////////////////////////////////////////////////////////////////////////////
+ ldi YH, 0x02
+ // Channel A
+ lds YL,AY0_REG08 ; Load Channel A Amplitude register
+ mov OutA,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutA,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b0 ; if channel is disabled in mixer - set volume to zero
+ clr OutA
+
+ // Channel B
+ lds YL,AY0_REG09 ; Load Channel B Amplitude register
+ mov OutB,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutB,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b1 ; if channel is disabled in mixer - set volume to zero
+ clr OutB
+
+ // Channel C
+ lds YL,AY0_REG10 ; Load Channel C Amplitude register
+ mov OutC,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutC,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b2 ; if channel is disabled in mixer - set volume to zero
+ clr OutC
+
+ mov YL,OutB
+ lsr OutB ; TMP = TMP - (TMP/4 + TMP/8);
+ lsr OutB
+ sub YL,OutB
+ lsr OutB
+ sub YL,OutB
+ add OutA,YL ; add channel B volume to channels A and C
+ add OutC,YL
+
+ ; === AY0 ===
+ ldi YL, low(EnvState_AY0)
+ st Y, TabE
+ std Y+1, TabP
+ std Y+2, EVal
+ std Y+8, OutA
+ std Y+9, OutC
+
+AY1_PROCESSING:
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// ENVELOPE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ ; === AY1 ===
+ ldi YL, low(EnvState_AY1)
+ ld TabE, Y
+ ldd TabP, Y+1
+ ldd EVal, Y+2
+
+ sbrs TNLevel_AY1,b7
+ rjmp NO_ENVELOPE_CHANGED_AY1
+
+ // initialize envelope generator after change envelope shape register, only first 1/32 part of the first period!
+ lds YL,AY1_REG13 ; load envelope shape register value to TabE
+ ldd TabE,Y+0x10 ; get envelope code from SRAM
+ ldi TabP,0x1F ; set counter for envelope period
+ andi TNLevel_AY1,0x7F ; clear envelope shape change flag
+ rjmp E_NEXT_STEP_AY1
+
+NO_ENVELOPE_CHANGED_AY1:
+ sbrc TabE,b7 ; alternate: cpi TabE,0x80 ; check if envelope generator is disabled
+ rjmp ENVELOPE_GENERATOR_END_AY1 ; alternate: brcc ENVELOPE_GENERATOR_END
+ sbiw CntEL_AY1,0x01
+ brcs E_NEXT_PERIOD_AY1 ; jump to init next envelope value if counter overflow (if initial value was 0)
+ brne ENVELOPE_GENERATOR_END_AY1 ; go to the next step if zero value is not reached
+E_NEXT_PERIOD_AY1:
+ dec TabP
+ brpl E_NEXT_STEP_AY1 ; jump to next step if envelope period >= 0
+ ;init new envelope period
+ ldi TabP,0x1F
+ sbrc TabE,b1
+ eor TabE,ZH ; invert envelope ATTACK bit
+ sbrc TabE,b2
+ or TabE,CC0 ; disable envelope generator until new envelope shape register recived
+E_NEXT_STEP_AY1:
+ lds CntEL_AY1,AY1_REG11
+ lds CntEH_AY1,AY1_REG12
+ mov YL,TabP
+ ldi TMP, 0x1F
+ sbrs TabE,b0
+ eor YL,TMP ; invert envelope value if ATTACK bit is not set
+ ldd EVal,Y+0x30 ; translate envelope value to volume, read volume value from SRAM 0x230+YL
+ENVELOPE_GENERATOR_END_AY1:
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// NOISE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ dec CntN_AY1 ; decrease noise period counter
+ brpl NOISE_GENERATOR_END_AY1 ; skip if noise period is not finished (CntN>=0)
+ //init new cycle
+ lds CntN_AY1,AY1_REG06 ; init noise period counter with value in AY register 6
+ dec CntN_AY1
+ lsr NoiseAddon_AY1
+ mov NoiseAddon_AY1,RNGL_AY1
+ ror RNGH_AY1
+ ror RNGL_AY1
+ ori TNLevel_AY1,0x38 ; set noise bitsP
+ sbrs RNGL_AY1,b0
+ andi TNLevel_AY1,0xC7 ; reset noise bits
+
+ lsl NoiseAddon_AY1
+ eor NoiseAddon_AY1,RNGL_AY1
+ lsr NoiseAddon_AY1
+NOISE_GENERATOR_END_AY1:
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// TONE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ ; all counters are Int16 values (signed)
+ ; Channel A -------------
+ ldi YH, 0x21
+ ldi YL, low(AY1_CntAL)
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_A_NO_CHANGE_AY1
+ ldi YH, 0x23
+ ldi YL, low(AY1_REG00)
+ ld r0, Y
+ sts 0x21, C21
+ eor TNLevel_AY1, ZH
+ ldi YH, 0x21
+CH_A_NO_CHANGE_AY1:
+ ldi YL, low(AY1_CntAL)
+ st Y, r2
+
+ ; Channel B -------------
+ ldi YL, low(AY1_CntBL)
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_B_NO_CHANGE_AY1
+ ldi YH, 0x23
+ ldi YL, low(AY1_REG02)
+ ld r0, Y
+ sts 0x21, C21
+ ldi TMP, 0x02
+ eor TNLevel_AY1, TMP
+ ldi YH, 0x21
+CH_B_NO_CHANGE_AY1:
+ ldi YL, low(AY1_CntBL)
+ st Y, r2
+
+ ; Channel C -------------
+ ldi YL, low(AY1_CntCL)
+ ld r0, Y
+ sts 0x21, C21
+ sbis 0x00, 1
+ rjmp CH_C_NO_CHANGE_AY1
+ ldi YH, 0x23
+ ldi YL, low(AY1_REG04)
+ ld r0, Y
+ sts 0x21, C21
+ eor TNLevel_AY1, C04
+ ldi YH, 0x21
+CH_C_NO_CHANGE_AY1:
+ ldi YL, low(AY1_CntCL)
+ st Y, r2
+
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// MIXER
+ /////////////////////////////////////////////////////////////////////////////////////
+ lds TMP,AY1_REG07 ; Load Mixer AY Register from SRAM
+ or TMP,TNLevel_AY1 ; Mixer formula = (Mixer Register Tone | TNLevel Tone) & (Mixer Register Noise | TNLevel Noise)
+ mov YL,TMP
+ lsl YL
+ swap YL
+ and TMP,YL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// AMPLITUDE CONTROL
+ /////////////////////////////////////////////////////////////////////////////////////
+ ldi YH, 0x02
+ // Channel A
+ lds YL,AY1_REG08 ; Load Channel A Amplitude register
+ mov OutA,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutA,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b0 ; if channel is disabled in mixer - set volume to zero
+ clr OutA
+
+ // Channel B
+ lds YL,AY1_REG09 ; Load Channel B Amplitude register
+ mov OutB,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutB,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b1 ; if channel is disabled in mixer - set volume to zero
+ clr OutB
+
+ // Channel C
+ lds YL,AY1_REG10 ; Load Channel C Amplitude register
+ mov OutC,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutC,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b2 ; if channel is disabled in mixer - set volume to zero
+ clr OutC
+
+ mov YL,OutB
+ lsr OutB ; TMP = TMP - (TMP/4 + TMP/8);
+ lsr OutB
+ sub YL,OutB
+ lsr OutB
+ sub YL,OutB
+ add OutA,YL ; add channel B volume to channels A and C
+ add OutC,YL
+
+ ; === AY1 ===
+ ldi YL, low(EnvState_AY1)
+ st Y, TabE
+ std Y+1, TabP
+ std Y+2, EVal
+
+ ; === AY0 AY1 ===
+ lds TMP, OutA0
+ add OutA, TMP
+ lds TMP, OutC0
+ add OutC, TMP
+
+ sts OCR1AL,OutA ; update PWM counters
+ sts OCR1BL,OutC
+ rjmp _MAIN_LOOP
+// MAIN LOOP END ====================================================================
+
+// copy routine from flash to SRAM
+_COPY:
+ lpm r16,Z+
+ st X+,r16
+ dec r18
+ brne _COPY
+ ret
+
+/////////////////////////////////////////////////////////////////
+/// AY REGISTERS IN SRAM
+/////////////////////////////////////////////////////////////////
+ .dseg
+ .org 0x0110
+; AY
+AY0_REG00:
+ .byte 1
+AY0_REG01:
+ .byte 1
+AY0_REG02:
+ .byte 1
+AY0_REG03:
+ .byte 1
+AY0_REG04:
+ .byte 1
+AY0_REG05:
+ .byte 1
+AY0_REG06:
+ .byte 1
+AY0_REG07:
+ .byte 1
+AY0_REG08:
+ .byte 1
+AY0_REG09:
+ .byte 1
+AY0_REG10:
+ .byte 1
+AY0_REG11:
+ .byte 1
+AY0_REG12:
+ .byte 1
+AY0_REG13:
+ .byte 1
+AY0_REG14:
+ .byte 1
+AY0_REG15:
+ .byte 1
+
+.org 0x0251
+EnvState_AY0: .byte 3 ; [TabE, TabP, EVal] AY0
+EnvState_AY1: .byte 3 ; [TabE, TabP, EVal] AY1
+
+.org 0x0259
+OutA0: .byte 1
+OutC0: .byte 1
+
+.org 0x0260
+; AY0
+AY0_CntAL: .byte 1
+AY0_CntAH: .byte 1
+AY0_CntBL: .byte 1
+AY0_CntBH: .byte 1
+AY0_CntCL: .byte 1
+AY0_CntCH: .byte 1
+
+; AY1
+AY1_CntAL: .byte 1
+AY1_CntAH: .byte 1
+AY1_CntBL: .byte 1
+AY1_CntBH: .byte 1
+AY1_CntCL: .byte 1
+AY1_CntCH: .byte 1
+
+ConstL: .byte 1
+ConstH: .byte 1
+
+; AY
+ .org 0x0310
+AY1_REG00:
+ .byte 1
+AY1_REG01:
+ .byte 1
+AY1_REG02:
+ .byte 1
+AY1_REG03:
+ .byte 1
+AY1_REG04:
+ .byte 1
+AY1_REG05:
+ .byte 1
+AY1_REG06:
+ .byte 1
+AY1_REG07:
+ .byte 1
+AY1_REG08:
+ .byte 1
+AY1_REG09:
+ .byte 1
+AY1_REG10:
+ .byte 1
+AY1_REG11:
+ .byte 1
+AY1_REG12:
+ .byte 1
+AY1_REG13:
+ .byte 1
+AY1_REG14:
+ .byte 1
+AY1_REG15:
+ .byte 1
diff --git a/Sources/AY_Emu/AY_Emu/main_TS.asm b/Sources/AY_Emu/AY_Emu/main_TS.asm
new file mode 100644
index 0000000..ab79cb6
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/main_TS.asm
@@ -0,0 +1,810 @@
+; AY-3-8912 IC emulator version 26.0 for LGT8F328P
+;
+; Sources for Atmel AVRStudio 7
+;
+; visit our site for more information
+; These source codes are distributed under the GPL v3 license
+; If you share these sources you should put the link to web site www.avray.ru
+;
+; ORIGIN: http://www.avray.ru
+
+; CONFIGURATION VALUES ===================================================
+#define CHANNELS 2 ; choose 2 or 3 channel version
+#define SPEAKER 0 ; use SPEAKER port input on PD1 (0 - no, 1 - yes)
+#define VOLUME_TABLE 0 ; 0 - AY, 1 - YM, 2 - ALTERNATE volume table
+#define USART_ENABLE 0 ; 0 - OFF, 1 - ON
+#define INT_ENABLE 1 ; 0 - OFF, 1 - ON
+#define Enable2MHz 0 ; 0 - 1,75 MHz, 1 - 2MHz
+#define TS_Chip_0 0 ; 0 - OFF, 1 - On TS_Chip, AY
+#define TS_Chip_1 0 ; 0 - OFF, 1 - On TS 2 !!!!
+; ========================================================================
+; bit numbers:
+.equ b0 = 0x00
+.equ b1 = 0x01
+.equ b2 = 0x02
+.equ b3 = 0x03
+.equ b4 = 0x04
+.equ b5 = 0x05
+.equ b6 = 0x06
+.equ b7 = 0x07
+.equ CHIP_SELECTED = GPIOR0
+
+; ===== =====
+; r0 - OutA ( A)
+; r1 - OutC ( C)
+; r2 - C1F ( 0x1F )
+; r3 - CntN ( )
+; r4 - OutB ( B)
+; r5 - BusOut1 ( C/D )
+; r6 - NoiseAddon (LFSR )
+; r7 - C00 ( 0x00)
+; r8 - CC0 ( 0xC0)
+; r9 - TabE ( )
+; r10 - C04 ( 0x04)
+; r11 - TMP ( )
+; r12 - EVal ( )
+; r13 - SREGSave ( SREG)
+; r14 - RNGL (LFSR LOW)
+; r15 - RNGH (LFSR HIGH)
+; r16 - BusData ( )
+; r17 - BusOut2 ( )
+; r18 - TabP ( )
+; r19 - TNLevel ( )
+; r20 - CntAL ( A LOW)
+; r21 - CntAH ( A HIGH)
+; r22 - CntBL ( B LOW)
+; r23 - CntBH ( B HIGH)
+; r24 - CntCL ( C LOW)
+; r25 - CntCH ( C HIGH)
+; r26 - CntEL ( LOW)
+; r27 - CntEH ( HIGH)
+; r30 - ADDR ( , Z)
+
+.def OutA = r0
+.def OutC = r1
+.def C1F = r2
+.def CntN = r3
+.def OutB = r4
+.def BusOut1 = r5
+.def NoiseAddon = r6
+.def C00 = r7
+.def CC0 = r8
+.def TabE = r9
+.def C04 = r10
+.def TMP = r11
+.def EVal = r12
+.def SREGSave = r13
+.def RNGL = r14
+.def RNGH = r15
+.def BusData = r16
+.def BusOut2 = r17
+.def TabP = r18
+.def TNLevel = r19
+.def CntAL = r20
+.def CntAH = r21
+.def CntBL = r22
+.def CntBH = r23
+.def CntCL = r24
+.def CntCH = r25
+.def CntEL = r26
+.def CntEH = r27
+.def ADDR = r30
+
+; ==============================================
+; LGT8F328P REGISTER DEFINITIONS
+; ==============================================
+; Memory-mapped I/O addresses for LGT8F328P
+.equ CCP = 0x34 ; Configuration Change Protection
+.equ CLKMSR = 0x105 ; Clock Main Settings Register
+.equ BCR = 0x107 ; Boot Control Register
+.equ BOOTEND = 0x108 ; Boot End Address
+.equ BODCR = 0x104 ; BOD Control Register
+
+; AC0 (Analog Comparator 0) Register Definition
+.equ C0SR = 0x50
+.equ C0D = 7
+.equ C0BG = 6
+.equ C0O = 5
+.equ C0I = 4
+.equ C0IE = 3
+.equ C0IC = 2
+.equ C0IS1 = 1
+.equ C0IS0 = 0
+
+.equ C0XR = 0x51
+.equ C0OE = 6
+.equ C0HSYE = 5
+.equ C0PS0 = 4
+.equ C0WKE = 3
+.equ C0FEN = 2
+.equ C0FS1 = 1
+.equ C0FS0 = 0
+
+.equ C0TR = 0x52
+
+; AC1 (Analog Comparator 1) Register Definition
+.equ C1SR = 0x2F
+.equ C1D = 7
+.equ C1BG = 6
+.equ C1O = 5
+.equ C1I = 4
+.equ C1IE = 3
+.equ C1IC = 2
+.equ C1IS1 = 1
+.equ C1IS0 = 0
+
+.equ C1XR = 0x3A
+.equ C1OE = 6
+.equ C1HSYE = 5
+.equ C1PS0 = 4
+.equ C1WKE = 3
+.equ C1FEN = 2
+.equ C1FS1 = 1
+.equ C1FS0 = 0
+
+.equ C1TR = 0x5B
+
+; LGT8F328P FAST GPIO REGISTERS
+.equ FGPIOE = 0x10A ; Fast GPIO Enable Register
+.equ FGPIO = 0x10B ; Fast GPIO Control Register
+
+ .cseg
+;------------------------------------------------------
+; INTERRUPT VECTORS TABLE
+;------------------------------------------------------
+ .org 0x0000
+ rjmp _LGT_INIT
+
+ .org INT0addr
+ rjmp _INT0_Handler
+
+ .org INT1addr
+ rjmp _INT1_Handler
+
+ .org URXCaddr
+ rjmp _USART_RX_COMPLETE
+
+;------------------------------------------------------
+
+#if VOLUME_TABLE == 0
+ Volumes: ; volume table for amplitude
+ .db 0,1,1,1,2,2,3,5,6,9,13,17,22,29,36,45 // AY_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,0,1,1,1,1,1,1,2,2,2,2,3,3,5,5,6,6,7,9,11,13,15,17,19,22,25,29,32,36,40,45 // AY_TABLE
+#elif VOLUME_TABLE == 1
+ Volumes: ; volume table for amplitude
+ .db 0,1,1,1,2,2,3,4,5,7,10,13,18,24,34,45 // YM_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,0,1,1,1,1,1,1,2,2,2,2,2,3,3,4,4,5,6,7,8,10,11,13,15,18,21,24,29,34,40,45 // YM_TABLE
+#elif VOLUME_TABLE == 2
+ Volumes: ; volume table for amplitude
+ .db 0,1,2,3,4,5,6,7,9,11,13,16,22,31,42,58 // ALT_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,24,26,28,30,33,36,40,45,51,58 // ALT_TABLE
+#endif
+
+; envelope codes, bit0 - attack, bit1 - invert on next cycle, bit2 - stop generator on next cycle
+Envelopes:
+ .db 7,7,7,7,4,4,4,4,1,7,3,5,0,6,2,4
+
+; mask applied to registers values after receiving
+RegsMask:
+ .db 0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0x1F,0xFF,0x1F,0x1F,0x1F,0xFF,0xFF,0x0F,0xFF,0xFF
+
+;==========================================================
+_INT0_Handler: ; 4 cycles to enter
+ sbic PinD,b3 ; check BDIR (1)
+ rjmp LATCH_REG_ADDR0 ; (2) if BDIR=1
+
+#if TS_Chip_0 > 0 || TS_Chip_1 > 0
+ sbic CHIP_SELECTED,0 ; (1) check chip select
+ rjmp exit_int0 ; (2) skip if not selected
+#endif
+
+ ; READ MODE -
+ out DDRD,BusOut2 ; 1 - set data bus
+ out DDRC,BusOut1 ; 1
+
+LOOP_NOT_INACTIVE:
+ sbic PinD,b2 ; 1 - wait for BC1=0
+ rjmp LOOP_NOT_INACTIVE ; 2
+
+ ; (4 6)
+ out DDRC, C00 ; 1
+ out DDRD, C00 ; 1
+ ; -
+exit_int0:
+ out EIFR, YH ; 1 - clear flags
+ reti ; 4
+
+LATCH_REG_ADDR0:
+ in ADDR, PinC ; 1
+ andi ADDR, 0x3F ; 1
+
+#if TS_Chip_0 > 0 || TS_Chip_1 > 0
+ sbic PinD,b7
+ rjmp SELECT_CHIP_ADDR0
+#endif
+ ldd BusOut1, Z+0x20 ; 2
+ ldd BusOut2, Z+0x30 ; 2
+ rjmp exit_int0 ; 2
+
+
+SELECT_CHIP_ADDR0:
+#if TS_Chip_0 > 0
+ cpi ADDR, 0x3F ; 1
+ breq LATCH_SELECT_CHIP0 ; 1/2
+ cpi ADDR, 0x3E
+ breq RESET_LATCH0 ; 2
+#elif TS_Chip_1 > 0
+ cpi ADDR, 0x3E ; 1
+ breq LATCH_SELECT_CHIP0 ; 1/2
+ cpi ADDR, 0x3F
+ breq RESET_LATCH0 ; 2
+#endif
+
+LATCH_SELECT_CHIP0:
+ sbi CHIP_SELECTED, b0 ; 2
+ rjmp exit_int0 ; 2
+
+RESET_LATCH0:
+ cbi CHIP_SELECTED, b0 ; 2
+ rjmp exit_int0 ; 2
+
+;==========================================================
+_INT1_Handler: ; 4 cycles to enter
+ in BusData, PinC ; 1
+ andi BusData, 0x3F ; 1
+
+ sbic PinD, b2 ; 1
+ rjmp LATCH_REG_ADDR1 ; 2
+
+#if TS_Chip_0 > 0 || TS_Chip_1 > 0
+ sbic CHIP_SELECTED, 0 ; 1
+ rjmp exit_int1 ; 2
+#endif
+
+ ; WRITE MODE -
+ in BusOut1, PinD ; 1
+ in SREGSave, SREG ; 1
+ and BusOut1, CC0
+ or BusData, BusOut1 ; 1
+ mov BusOut1, BusData ; 1
+ com BusOut1 ; 1
+
+ ;
+ ld BusOut2, Z ; 2 - load mask
+ std Z+0x20, BusOut1 ; 2 - save inverted
+
+ and BusData, BusOut2 ; 1 - apply mask
+ mov BusOut2, BusOut1 ; 1
+ andi BusOut2, 0xC0 ; 1 - extract bits 6-7
+
+ std Z+0x30, BusOut2 ; 2 - save high bits
+ std Z+0x10, BusData ; 2 - save value
+
+ ; 13
+ cpi ADDR, 0x0D ; 1
+ brne NO_ENVELOPE_CHANGED_P; 1/2
+ ori TNLevel, 0x80 ; 1
+NO_ENVELOPE_CHANGED_P:
+ out SREG, SREGSave ; 1
+ rjmp exit_int1 ; 2
+
+LATCH_REG_ADDR1:
+ mov ADDR, BusData ; 1
+
+#if TS_Chip_0 > 0 || TS_Chip_1 > 0
+ sbic PinD,b6
+ rjmp SELECT_CHIP_ADDR1
+#endif
+
+ ldd BusOut1, Z+0x20 ; 2
+ ldd BusOut2, Z+0x30 ; 2
+ rjmp exit_int1 ; 2
+
+SELECT_CHIP_ADDR1:
+#if TS_Chip_0 > 0
+ cpi ADDR, 0x3F ; 1
+ breq LATCH_SELECT_CHIP1 ; 1/2
+ cpi ADDR, 0x3E
+ breq RESET_LATCH1 ; 2
+#elif TS_Chip_1 > 0
+ cpi ADDR, 0x3E ; 1
+ breq LATCH_SELECT_CHIP1 ; 1/2
+ cpi ADDR, 0x3F
+ breq RESET_LATCH1 ; 2
+#endif
+
+
+LATCH_SELECT_CHIP1:
+ sbi CHIP_SELECTED, b0 ; 2
+exit_int1:
+ out EIFR, ZH ; 1
+ reti ;
+
+RESET_LATCH1:
+ cbi CHIP_SELECTED, b0 ; 2
+ rjmp exit_int1 ; 2
+
+;==========================================================
+_USART_RX_COMPLETE:
+ lds BusData,UDR0 ; get byte from USART
+ sbrs ADDR,b4 ; check for address/data mode
+ rjmp RECV_REG_VALUE
+ sbrc BusData,b7
+ rjmp USART_SYNC
+ mov ADDR,BusData ; ------ receive register number ------------
+ reti
+USART_SYNC: ; ------ synchronization mode ---------------
+ ldi ADDR,0x10
+ reti
+
+RECV_REG_VALUE: ; ------ receive register value -------------
+ in SREGSave,SREG
+ ld BusOut1,Z ; load register mask
+ and BusData,BusOut1 ; apply register mask
+ std Z+0x10,BusData ; put register value to SRAM
+ cpi ADDR,0x0D ; check for envelope shape register
+ brne NO_ENVELOPE_CHANGED_S
+ ori TNLevel,0x80 ; set envelope change flag (bit 7)
+NO_ENVELOPE_CHANGED_S:
+ ldi ADDR,0x10 ; set bit 4 to jump to receive register number on next byte received
+ out SREG,SREGSave
+ reti
+
+
+; ==============================================
+; LGT8F328P INITIALIZATION - NO BOOTLOADER
+; ==============================================
+_LGT_INIT:
+ ; 1. Disable watchdog immediately
+ ldi r16, 0x00
+ sts WDTCSR, r16
+
+ ; 2. Unlock protected registers (LGT specific)
+ ldi r16, 0xD8
+ sts CCP, r16 ; Enable configuration changes
+
+ ; 3. Configure clock: 32MHz internal, divisor = 1
+ ldi r16, 0x80
+ sts CLKPR, r16 ; Enable CLKPR changes
+
+ ldi r16, 0xD8
+ sts CCP, r16
+ ldi r16, 0x00
+ sts CLKPR, r16 ; Divisor = 1 (32MHz)
+
+ ; 4. Select internal 32MHz oscillator
+ ldi r16, 0xD8
+ sts CCP, r16
+ ldi r16, 0x04
+ sts CLKMSR, r16 ; Internal 32MHz oscillator
+
+ ; 5. ENABLE FAST GPIO FOR PORTS B, C, D
+ ldi r16, 0xD8
+ sts CCP, r16
+ ldi r16, (1<<2) | (1<<1) | (1<<0)
+ sts FGPIOE, r16
+ ldi r16, 0xD8
+ sts CCP, r16
+ ldi r16, (0<<4) | (0<<2) | (0<<0) ; No delay for all ports
+ sts FGPIO, r16
+
+ ; 6. Configure Fast GPIO timing (optional, default is usually OK)
+ ldi r16, 0xD8
+ sts CCP, r16
+ ldi r16, 0x00 ; Default timing (no delay)
+ sts FGPIO, r16 ; Set Fast GPIO Control register
+
+ ; 7. DISABLE BOOTLOADER - BOOTRST=0, start from 0x0000
+ ldi r16, 0x03 ; BOOTSZ=11, BOOTRST=0
+ sts BCR, r16
+
+ ; 8. Set BOOTEND (optional, defines flash boundary)
+ ldi r16, 0x7F ; 0x7F00 for 32KB flash
+ sts BOOTEND, r16
+
+ ; 9. Continue to original reset code
+ rjmp _RESET
+
+;==========================================================
+_RESET: // Emulator start
+ in r16,MCUCR ; 1-> PUD for
+ sbr r16,PUD
+ out MCUCR,r16
+
+ // init stack pointer at end of RAM
+ ldi r16,low(RAMEND)
+ out SPL,r16
+ ldi r16,high(RAMEND)
+ out SPH,r16
+
+ ; C D HI-Z ===================
+ ; C: PC0-PC5 - , HI-Z
+ ; D: PD6,PD7 - , HI-Z
+ ldi r16,0x00
+ out DDRC,r16 ; C
+ out PORTC,r16 ;
+ out DDRD,r16 ; D
+ out PORTD,r16 ;
+ ; =====================================================
+
+ ; disable Analog Comparator ==============================
+ ldi r16, (1< 0
+ sbi CHIP_SELECTED, b0
+#elif TS_Chip_1 > 0
+ cbi CHIP_SELECTED, b0
+#endif
+
+ clr C00
+ ldi r16,0xC0
+ mov CC0,r16
+ ldi r16,0x04
+ mov C04,r16
+ ldi r16,0x1F
+ mov C1F,r16
+ ldi r16,0xFF
+ mov BusOut1,r16
+ mov BusOut2,CC0
+ clr RNGH
+ ldi YH,0xFF
+ // clear register values in SRAM 0x110-0x13F
+ ldi r18,0x10
+ ldi ZL,0x10
+ ldi ZH,0x01
+LOOP0:
+ std Z+0x20,CC0
+ std Z+0x10,r16
+ st Z+,C00
+ dec r18
+ brne LOOP0
+
+ ; load envelope codes to SRAM 0x210, 16 bytes
+ ldi xh,0x02
+ ldi xl,0x10
+ ldi zl, low(2*Envelopes)
+ ldi zh, high(2*Envelopes)
+ ldi r18,0x10
+ rcall _COPY
+
+ ; load volume table for amplitude to SRAM 0x220, 16 bytes
+ ldi xl,0x20
+ ldi zl, low(2*Volumes)
+ ldi zh, high(2*Volumes)
+ ldi r18,0x10
+ rcall _COPY
+
+ ; load volume table for envelopes to SRAM 0x230, 32 bytes
+ ldi xl,0x30
+ ldi zl, low(2*EVolumes)
+ ldi zh, high(2*EVolumes)
+ ldi r18,0x20
+ rcall _COPY
+
+ ; load register masks to SRAM 0x100, 16 bytes
+ clr xl
+ ldi xh,0x01
+ ldi zl, low(2*RegsMask)
+ ldi zh, high(2*RegsMask)
+ ldi r18,0x10
+ rcall _COPY
+
+ ldi ZH,0x01 ; set high byte of register Z for fast acces to register values
+ clr ZL
+ ldi YH,0x02 ; set high byte of register Y for fast acces to volume table
+ mov NoiseAddon,ZH ; load default value = 1 to high bit of noise generator
+
+#if USART_ENABLE > 0
+ // init USART
+ clr r16
+ sts UBRR0H,r16
+ ldi r16,0x06
+ sts UCSR0C,r16
+ ldi r16,0x02
+ sts UCSR0A,r16
+ ldi r16,0x90
+ sts UCSR0B,r16
+ ldi r18,0x44
+ sts UBRR0L,r18
+#endif
+
+ // init Timer1
+ sts OCR1AH,C00 ; clear OCR values
+ sts OCR1AL,C00
+ sts OCR1BH,C00
+ sts OCR1BL,C00
+ sbi DDRB,b1 ; set port B pin 1 to output for PWM (AY channel A)
+ sbi DDRB,b2 ; set port B pin 2 to output for PWM (AY channel B)
+ ldi r16,0xA2
+ sts TCCR1A,r16
+ ldi r16,0x19
+ sts TCCR1B,r16
+ ldi r16,0x19
+ sts TCCR1B,r16
+#if Enable2MHz == 0
+ ldi r18, 0x91
+#else
+ ldi r18, 0x7F
+#endif
+ sts ICR1H,C00
+ sts ICR1L,r18 ; set PWM speed
+ ; ICR1L value formula (32000000/109375/2 - 1) where 32000000 = 32MHz - AVR oscillator frequency
+ ; 109375 is for 1.75 MHz version, formula is (PSG frequency / 16) e.g. for 2MHz it is 2000000/16 = 125000
+
+#if CHANNELS == 3
+ // init Timer2
+ sbi DDRB,DDB3 ; set port B pin 3 to output for PWM (AY channel C)
+ ldi r16,0x83
+ sts TCCR2A,r16
+ ldi r16,0x01
+ sts TCCR2B,r16
+#endif
+
+#if INT_ENABLE > 0
+ ; set INT0,INT1 ============================================
+ ldi r16, (1<= 0
+ ;init new envelope period
+ ldi TabP,0x1F
+ sbrc TabE,b1
+ eor TabE,ZH ; invert envelope ATTACK bit
+ sbrc TabE,b2
+ or TabE,CC0 ; disable envelope generator until new envelope shape register recived
+E_NEXT_STEP:
+ lds CntEL,AY_REG11
+ lds CntEH,AY_REG12
+ mov YL,TabP
+ sbrs TabE,b0
+ eor YL,C1F ; invert envelope value if ATTACK bit is not set
+ ldd EVal,Y+0x30 ; translate envelope value to volume, read volume value from SRAM 0x230+YL
+ENVELOPE_GENERATOR_END:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// NOISE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ dec CntN ; decrease noise period counter
+ brpl NOISE_GENERATOR_END ; skip if noise period is not finished (CntN>=0)
+ //init new cycle
+ lds CntN,AY_REG06 ; init noise period counter with value in AY register 6
+ dec CntN
+
+ lsr NoiseAddon
+ mov NoiseAddon,RNGL
+ ror RNGH
+ ror RNGL
+
+ ori TNLevel,0x38 ; set noise bits
+ sbrs RNGL,b0
+ andi TNLevel,0xC7 ; reset noise bits
+ // make input bit
+ lsl NoiseAddon
+ eor NoiseAddon,RNGL
+ lsr NoiseAddon
+NOISE_GENERATOR_END:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// TONE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ ; all counters are Int16 values (signed)
+ // Channel A -------------
+ subi CntAL,0x01 ; CntA - 1
+ sbci CntAH,0x00
+ brpl CH_A_NO_CHANGE ; CntA >= 0
+ lds CntAL,AY_REG00 ; update channel A tone period counter
+ lds CntAH,AY_REG01
+ subi CntAL,0x01 ; CntA - 1
+ sbci CntAH,0x00
+ eor TNLevel,ZH ; TNLevel xor 1 (change logical level of channel A)
+CH_A_NO_CHANGE:
+
+ // Channel B -------------
+ subi CntBL,0x01 ; CntB - 1
+ sbci CntBH,0x00
+ brpl CH_B_NO_CHANGE ; CntB >= 0
+ lds CntBL,AY_REG02 ; update channel B tone period counter
+ lds CntBH,AY_REG03
+ subi CntBL,0x01 ; CntB - 1
+ sbci CntBH,0x00
+ eor TNLevel,YH ; TNLevel xor 2 (change logical level of channel B)
+CH_B_NO_CHANGE:
+
+ // Channel C -------------
+ sbiw CntCL,0x01 ; CntC - 1
+ brpl CH_C_NO_CHANGE ; CntC >= 0
+ lds CntCL,AY_REG04 ; update channel C tone period counter
+ lds CntCH,AY_REG05
+ sbiw CntCL,0x01 ; CntC - 1
+ eor TNLevel,C04 ; TNLevel xor 4 (change logical level of channel C)
+CH_C_NO_CHANGE:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// MIXER
+ /////////////////////////////////////////////////////////////////////////////////////
+ lds TMP,AY_REG07 ; Load Mixer AY Register from SRAM
+ or TMP,TNLevel ; Mixer formula = (Mixer Register Tone | TNLevel Tone) & (Mixer Register Noise | TNLevel Noise)
+ mov YL,TMP
+ lsl YL
+ swap YL
+ and TMP,YL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// AMPLITUDE CONTROL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ // Channel A
+ lds YL,AY_REG08 ; Load Channel A Amplitude register
+ mov OutA,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutA,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b0 ; if channel is disabled in mixer - set volume to zero
+ clr OutA
+
+ // Channel B
+ lds YL,AY_REG09 ; Load Channel B Amplitude register
+ mov OutB,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutB,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b1 ; if channel is disabled in mixer - set volume to zero
+ clr OutB
+
+ // Channel C
+ lds YL,AY_REG10 ; Load Channel C Amplitude register
+ mov OutC,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutC,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b2 ; if channel is disabled in mixer - set volume to zero
+ clr OutC
+
+ // Channel B
+#if CHANNELS == 2
+// two channel version ----------------------------------------
+ mov YL,OutB
+ lsr OutB ; TMP = TMP - (TMP/4 + TMP/8);
+ lsr OutB
+ sub YL,OutB
+ lsr OutB
+ sub YL,OutB
+ add OutA,YL ; add channel B volume to channels A and C
+ add OutC,YL
+// --------------------------------------------------------------
+#elif CHANNELS == 3
+// three channel version ----------------------------------------
+ sts OCR2A,OutB
+// --------------------------------------------------------------
+#endif
+
+// --------------------------------------------------------------
+#if SPEAKER == 1
+// speaker port enabled -----------------------------------------
+ sbic PinD,b1 ; check PD1 (SPEAKER PORT INPUT) skip if bit is not set
+ add OutA,C1F ; add some volume to channel A
+ sbic PinD,b1 ; check PD1 (SPEAKER PORT INPUT) skip if bit is not set
+ add OutC,C1F ; add some volume to channel A
+// --------------------------------------------------------------
+#endif
+
+ sts OCR1AL,OutA ; update PWM counters
+ sts OCR1BL,OutC
+ rjmp _MAIN_LOOP
+// MAIN LOOP END ====================================================================
+
+
+// copy routine from flash to SRAM
+_COPY:
+ lpm r16,Z+
+ st X+,r16
+ dec r18
+ brne _COPY
+ ret
+
+/////////////////////////////////////////////////////////////////
+/// AY REGISTERS IN SRAM
+/////////////////////////////////////////////////////////////////
+ .dseg
+ .org 0x0110
+AY_REG00:
+ .byte 1
+AY_REG01:
+ .byte 1
+AY_REG02:
+ .byte 1
+AY_REG03:
+ .byte 1
+AY_REG04:
+ .byte 1
+AY_REG05:
+ .byte 1
+AY_REG06:
+ .byte 1
+AY_REG07:
+ .byte 1
+AY_REG08:
+ .byte 1
+AY_REG09:
+ .byte 1
+AY_REG10:
+ .byte 1
+AY_REG11:
+ .byte 1
+AY_REG12:
+ .byte 1
+AY_REG13:
+ .byte 1
+AY_REG14:
+ .byte 1
+AY_REG15:
+ .byte 1
diff --git a/Sources/AY_Emu/AY_Emu/main_TS_1Chip.asm b/Sources/AY_Emu/AY_Emu/main_TS_1Chip.asm
new file mode 100644
index 0000000..3ad1853
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/main_TS_1Chip.asm
@@ -0,0 +1,774 @@
+; AY-3-8912 IC emulator version 26.0 for LGT8F328P
+;
+; Sources for Atmel AVRStudio 7
+;
+; visit our site for more information
+; These source codes are distributed under the GPL v3 license
+; If you share these sources you should put the link to web site www.avray.ru
+;
+; ORIGIN: http://www.avray.ru
+
+; CONFIGURATION VALUES ===================================================
+#define CHANNELS 2 ; choose 2 or 3 channel version
+#define VOLUME_TABLE 0 ; 0 - AY, 1 - YM, 2 - ALTERNATE volume table
+; ========================================================================
+; bit numbers:
+.equ b0 = 0x00
+.equ b1 = 0x01
+.equ b2 = 0x02
+.equ b3 = 0x03
+.equ b4 = 0x04
+.equ b5 = 0x05
+.equ b6 = 0x06
+.equ b7 = 0x07
+.equ CHIP_SELECTED = GPIOR0
+
+
+.def OutA = r0
+.def OutC = r1
+.def C1F = r2
+.def CntN = r3
+.def OutB = r4
+.def BusOut1 = r5
+.def NoiseAddon = r6
+.def C00 = r7
+.def CC0 = r8
+.def TabE = r9
+.def C04 = r10
+.def TMP = r11
+.def EVal = r12
+.def SREGSave = r13
+.def RNGL = r14
+.def RNGH = r15
+.def BusData = r16
+.def BusOut2 = r17
+.def TabP = r18
+.def TNLevel = r19
+.def CntAL = r20
+.def CntAH = r21
+.def CntBL = r22
+.def CntBH = r23
+.def CntCL = r24
+.def CntCH = r25
+.def CntEL = r26
+.def CntEH = r27
+.def ADDR = r30
+
+; ==============================================
+; LGT8F328P REGISTER DEFINITIONS
+; ==============================================
+; Memory-mapped I/O addresses for LGT8F328P
+.equ CCP = 0x34 ; Configuration Change Protection
+.equ CLKMSR = 0x105 ; Clock Main Settings Register
+.equ BCR = 0x107 ; Boot Control Register
+.equ BOOTEND = 0x108 ; Boot End Address
+.equ BODCR = 0x104 ; BOD Control Register
+
+; AC0 (Analog Comparator 0) Register Definition
+.equ C0SR = 0x50
+.equ C0D = 7
+.equ C0BG = 6
+.equ C0O = 5
+.equ C0I = 4
+.equ C0IE = 3
+.equ C0IC = 2
+.equ C0IS1 = 1
+.equ C0IS0 = 0
+
+.equ C0XR = 0x51
+.equ C0OE = 6
+.equ C0HSYE = 5
+.equ C0PS0 = 4
+.equ C0WKE = 3
+.equ C0FEN = 2
+.equ C0FS1 = 1
+.equ C0FS0 = 0
+
+.equ C0TR = 0x52
+
+; AC1 (Analog Comparator 1) Register Definition
+.equ C1SR = 0x2F
+.equ C1D = 7
+.equ C1BG = 6
+.equ C1O = 5
+.equ C1I = 4
+.equ C1IE = 3
+.equ C1IC = 2
+.equ C1IS1 = 1
+.equ C1IS0 = 0
+
+.equ C1XR = 0x3A
+.equ C1OE = 6
+.equ C1HSYE = 5
+.equ C1PS0 = 4
+.equ C1WKE = 3
+.equ C1FEN = 2
+.equ C1FS1 = 1
+.equ C1FS0 = 0
+
+.equ C1TR = 0x5B
+
+; LGT8F328P FAST GPIO REGISTERS
+.equ FGPIOE = 0x10A ; Fast GPIO Enable Register
+.equ FGPIO = 0x10B ; Fast GPIO Control Register
+
+ .cseg
+;------------------------------------------------------
+; INTERRUPT VECTORS TABLE
+;------------------------------------------------------
+ .org 0x0000
+ rjmp _LGT_INIT
+
+ .org INT0addr
+ rjmp _INT0_Handler
+
+ .org INT1addr
+ rjmp _INT1_Handler
+
+;------------------------------------------------------
+
+#if VOLUME_TABLE == 0
+ Volumes: ; volume table for amplitude
+ .db 0,1,1,1,2,2,3,5,6,9,13,17,22,29,36,45 // AY_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,0,1,1,1,1,1,1,2,2,2,2,3,3,5,5,6,6,7,9,11,13,15,17,19,22,25,29,32,36,40,45 // AY_TABLE
+#elif VOLUME_TABLE == 1
+ Volumes: ; volume table for amplitude
+ .db 0,1,1,1,2,2,3,4,5,7,10,13,18,24,34,45 // YM_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,0,1,1,1,1,1,1,2,2,2,2,2,3,3,4,4,5,6,7,8,10,11,13,15,18,21,24,29,34,40,45 // YM_TABLE
+#elif VOLUME_TABLE == 2
+ Volumes: ; volume table for amplitude
+ .db 0,1,2,3,4,5,6,7,9,11,13,16,22,31,42,58 // ALT_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,24,26,28,30,33,36,40,45,51,58 // ALT_TABLE
+#endif
+
+; envelope codes, bit0 - attack, bit1 - invert on next cycle, bit2 - stop generator on next cycle
+Envelopes:
+ .db 7,7,7,7,4,4,4,4,1,7,3,5,0,6,2,4
+
+; mask applied to registers values after receiving
+RegsMask:
+ .db 0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0x1F,0xFF,0x1F,0x1F,0x1F,0xFF,0xFF,0x0F,0xFF,0xFF
+
+;==========================================================
+_INT0_Handler: ; 4 cycles to enter
+ sbic PinD,b3 ; check BDIR (1)
+ rjmp LATCH_REG_ADDR0 ; (2) if BDIR=1
+
+ out DDRD,BusOut2 ; 1 - set data bus
+ out DDRC,BusOut1 ; 1
+
+LOOP_NOT_INACTIVE:
+ sbic PinD,b2 ; 1 - wait for BC1=0
+ rjmp LOOP_NOT_INACTIVE ; 2
+ out DDRC, C00 ; 1
+ out DDRD, C00 ; 1
+
+exit_int0:
+ out EIFR, YH ; 1 - clear flags
+ reti ; 4
+
+LATCH_REG_ADDR0:
+ in ADDR, PinC ; 1
+ andi ADDR, 0x3F ; 1
+ sbic PinD,b7
+ rjmp SELECT_CHIP_ADDR0
+ sbic CHIP_SELECTED,b0
+ rjmp READ_CHIP0
+ ; 0
+ ldi ZH,0x01
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int0
+
+READ_CHIP0:
+ ; 1
+ ldi ZH,0x08
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int0
+
+SELECT_CHIP_ADDR0:
+ cpi ADDR, 0x3F ; 1
+ breq SELECT_CHIP0_ADDR0 ; 1/2
+ cpi ADDR, 0x3E
+ breq SELECT_CHIP1_ADDR0 ; 2
+ rjmp exit_int0
+
+SELECT_CHIP0_ADDR0:
+ cbi CHIP_SELECTED, b0
+ rjmp exit_int0
+
+SELECT_CHIP1_ADDR0:
+ sbi CHIP_SELECTED, b0
+ rjmp exit_int0
+
+;==========================================================
+_INT1_Handler: ; 4 cycles to enter
+ in BusData, PinC ; 1
+ andi BusData, 0x3F ; 1
+
+ sbic PinD, b2 ; 1
+ rjmp LATCH_REG_ADDR1 ; 2
+
+ in BusOut1, PinD ; 1
+ in SREGSave, SREG ; 1
+ and BusOut1, CC0
+ or BusData, BusOut1 ; 1
+ mov BusOut1, BusData ; 1
+ com BusOut1 ; 1
+ sbic CHIP_SELECTED, b0
+ rjmp WRITE_TO_CHIP1
+
+ ; Z AY0
+ ldi ZH, 0x01
+ rjmp WRITE_COMMON
+
+WRITE_TO_CHIP1:
+ ; Z AY1
+ ldi ZH, 0x08
+
+WRITE_COMMON:
+ ld BusOut2, Z ; 2 - load mask
+ std Z+0x20, BusOut1 ; 2 - save inverted
+ and BusData, BusOut2 ; 1 - apply mask
+ mov BusOut2, BusOut1 ; 1
+ andi BusOut2, 0xC0 ; 1 - extract bits 6-7
+
+ std Z+0x30, BusOut2 ; 2 - save high bits
+ std Z+0x10, BusData ; 2 - save value
+
+ ; 13
+ cpi ADDR, 0x0D ; 1
+ brne NO_ENVELOPE_CHANGED_P; 1/2
+ ori TNLevel, 0x80 ; 1
+NO_ENVELOPE_CHANGED_P:
+ out SREG, SREGSave ; 1
+exit_int1:
+ ldi ZH, 0x01
+ out EIFR, ZH ; 1
+ reti
+
+LATCH_REG_ADDR1:
+ mov ADDR, BusData ; 1
+ sbic PinD,b6
+ rjmp SELECT_CHIP_ADDR1
+ sbic CHIP_SELECTED,b0
+ rjmp READ_CHIP1
+ ; 0
+ ldi ZH,0x01
+ ldd BusOut1, Z+0x20 ; 2
+ ldd BusOut2, Z+0x30 ; 2
+ rjmp exit_int1
+
+READ_CHIP1:
+ ; 1
+ ldi ZH,0x08
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int1 ; 2
+
+SELECT_CHIP_ADDR1:
+ cpi ADDR, 0x3F ; 1
+ breq SELECT_CHIP0_ADDR1 ; 1/2
+ cpi ADDR, 0x3E
+ breq SELECT_CHIP1_ADDR1 ; 2
+ rjmp exit_int1
+
+SELECT_CHIP0_ADDR1:
+ cbi CHIP_SELECTED, b0
+ rjmp exit_int1
+
+SELECT_CHIP1_ADDR1:
+ sbi CHIP_SELECTED, b0
+ rjmp exit_int1
+
+; ==============================================
+; LGT8F328P INITIALIZATION - NO BOOTLOADER
+; ==============================================
+_LGT_INIT:
+ ; 1. Disable watchdog immediately
+ ldi r16, 0x00
+ sts WDTCSR, r16
+
+ ; 2. Unlock protected registers (LGT specific)
+ ldi r16, 0xD8
+ sts CCP, r16 ; Enable configuration changes
+
+ ; 3. Configure clock: 32MHz internal, divisor = 1
+ ldi r16, 0x80
+ sts CLKPR, r16 ; Enable CLKPR changes
+
+ ldi r16, 0xD8
+ sts CCP, r16
+ ldi r16, 0x00
+ sts CLKPR, r16 ; Divisor = 1 (32MHz)
+
+ ; 4. Select internal 32MHz oscillator
+ ldi r16, 0xD8
+ sts CCP, r16
+ ldi r16, 0x04
+ sts CLKMSR, r16 ; Internal 32MHz oscillator
+
+ ; 5. ENABLE FAST GPIO FOR PORTS B, C, D
+ ldi r16, 0xD8
+ sts CCP, r16
+ ldi r16, (1<<2) | (1<<1) | (1<<0)
+ sts FGPIOE, r16
+ ldi r16, 0xD8
+ sts CCP, r16
+ ldi r16, (0<<4) | (0<<2) | (0<<0) ; No delay for all ports
+ sts FGPIO, r16
+
+ ; 6. Configure Fast GPIO timing (optional, default is usually OK)
+ ldi r16, 0xD8
+ sts CCP, r16
+ ldi r16, 0x00 ; Default timing (no delay)
+ sts FGPIO, r16 ; Set Fast GPIO Control register
+
+ ; 7. DISABLE BOOTLOADER - BOOTRST=0, start from 0x0000
+ ldi r16, 0x03 ; BOOTSZ=11, BOOTRST=0
+ sts BCR, r16
+
+ ; 8. Set BOOTEND (optional, defines flash boundary)
+ ldi r16, 0x7F ; 0x7F00 for 32KB flash
+ sts BOOTEND, r16
+
+ ; 9. Continue to original reset code
+ rjmp _RESET
+
+;==========================================================
+_RESET: // Emulator start
+ in r16,MCUCR ; 1-> PUD for
+ sbr r16,PUD
+ out MCUCR,r16
+
+ // init stack pointer at end of RAM
+ ldi r16,low(RAMEND)
+ out SPL,r16
+ ldi r16,high(RAMEND)
+ out SPH,r16
+
+ ; C D HI-Z ===================
+ ; C: PC0-PC5 - , HI-Z
+ ; D: PD6,PD7 - , HI-Z
+ ldi r16,0x00
+ out DDRC,r16 ; C
+ out PORTC,r16 ;
+ out DDRD,r16 ; D
+ out PORTD,r16 ;
+ ; =====================================================
+
+ ; disable Analog Comparator ==============================
+ ldi r16, (1<= 0
+ ;init new envelope period
+ ldi TabP,0x1F
+ sbrc TabE,b1
+ eor TabE,ZH ; invert envelope ATTACK bit
+ sbrc TabE,b2
+ or TabE,CC0 ; disable envelope generator until new envelope shape register recived
+E_NEXT_STEP:
+ lds CntEL,AY_REG11
+ lds CntEH,AY_REG12
+ mov YL,TabP
+ sbrs TabE,b0
+ eor YL,C1F ; invert envelope value if ATTACK bit is not set
+ ldd EVal,Y+0x30 ; translate envelope value to volume, read volume value from SRAM 0x230+YL
+ENVELOPE_GENERATOR_END:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// NOISE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ dec CntN ; decrease noise period counter
+ brpl NOISE_GENERATOR_END ; skip if noise period is not finished (CntN>=0)
+ //init new cycle
+ lds CntN,AY_REG06 ; init noise period counter with value in AY register 6
+ dec CntN
+
+ lsr NoiseAddon
+ mov NoiseAddon,RNGL
+ ror RNGH
+ ror RNGL
+
+ ori TNLevel,0x38 ; set noise bits
+ sbrs RNGL,b0
+ andi TNLevel,0xC7 ; reset noise bits
+ // make input bit
+ lsl NoiseAddon
+ eor NoiseAddon,RNGL
+ lsr NoiseAddon
+NOISE_GENERATOR_END:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// TONE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ ; all counters are Int16 values (signed)
+ // Channel A -------------
+ subi CntAL,0x01 ; CntA - 1
+ sbci CntAH,0x00
+ brpl CH_A_NO_CHANGE ; CntA >= 0
+ lds CntAL,AY_REG00 ; update channel A tone period counter
+ lds CntAH,AY_REG01
+ subi CntAL,0x01 ; CntA - 1
+ sbci CntAH,0x00
+ eor TNLevel,ZH ; TNLevel xor 1 (change logical level of channel A)
+CH_A_NO_CHANGE:
+
+ // Channel B -------------
+ subi CntBL,0x01 ; CntB - 1
+ sbci CntBH,0x00
+ brpl CH_B_NO_CHANGE ; CntB >= 0
+ lds CntBL,AY_REG02 ; update channel B tone period counter
+ lds CntBH,AY_REG03
+ subi CntBL,0x01 ; CntB - 1
+ sbci CntBH,0x00
+ eor TNLevel,YH ; TNLevel xor 2 (change logical level of channel B)
+CH_B_NO_CHANGE:
+
+ // Channel C -------------
+ sbiw CntCL,0x01 ; CntC - 1
+ brpl CH_C_NO_CHANGE ; CntC >= 0
+ lds CntCL,AY_REG04 ; update channel C tone period counter
+ lds CntCH,AY_REG05
+ sbiw CntCL,0x01 ; CntC - 1
+ eor TNLevel,C04 ; TNLevel xor 4 (change logical level of channel C)
+CH_C_NO_CHANGE:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// MIXER
+ /////////////////////////////////////////////////////////////////////////////////////
+ lds TMP,AY_REG07 ; Load Mixer AY Register from SRAM
+ or TMP,TNLevel ; Mixer formula = (Mixer Register Tone | TNLevel Tone) & (Mixer Register Noise | TNLevel Noise)
+ mov YL,TMP
+ lsl YL
+ swap YL
+ and TMP,YL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// AMPLITUDE CONTROL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ // Channel A
+ lds YL,AY_REG08 ; Load Channel A Amplitude register
+ mov OutA,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutA,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b0 ; if channel is disabled in mixer - set volume to zero
+ clr OutA
+
+ // Channel B
+ lds YL,AY_REG09 ; Load Channel B Amplitude register
+ mov OutB,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutB,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b1 ; if channel is disabled in mixer - set volume to zero
+ clr OutB
+
+ // Channel C
+ lds YL,AY_REG10 ; Load Channel C Amplitude register
+ mov OutC,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutC,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b2 ; if channel is disabled in mixer - set volume to zero
+ clr OutC
+ rjmp ENDING_MAIN_LOOP
+
+PROCESS_CHIP1_TICK:
+ cbi CHIP_SELECTED, b1
+
+
+
+
+ENDING_MAIN_LOOP:
+ // Channel B
+#if CHANNELS == 2
+// two channel version ----------------------------------------
+ mov YL,OutB
+ lsr OutB ; TMP = TMP - (TMP/4 + TMP/8);
+ lsr OutB
+ sub YL,OutB
+ lsr OutB
+ sub YL,OutB
+ add OutA,YL ; add channel B volume to channels A and C
+ add OutC,YL
+// --------------------------------------------------------------
+#elif CHANNELS == 3
+// three channel version ----------------------------------------
+ sts OCR2A,OutB
+// --------------------------------------------------------------
+#endif
+
+// --------------------------------------------------------------
+
+ sts OCR1AL,OutA ; update PWM counters
+ sts OCR1BL,OutC
+ rjmp _MAIN_LOOP
+// MAIN LOOP END ====================================================================
+
+
+// copy routine from flash to SRAM
+_COPY:
+ lpm r16,Z+
+ st X+,r16
+ dec r18
+ brne _COPY
+ ret
+
+/////////////////////////////////////////////////////////////////
+/// AY REGISTERS IN SRAM
+/////////////////////////////////////////////////////////////////
+ .dseg
+ .org 0x0110
+; AY
+AY_REG00:
+ .byte 1
+AY_REG01:
+ .byte 1
+AY_REG02:
+ .byte 1
+AY_REG03:
+ .byte 1
+AY_REG04:
+ .byte 1
+AY_REG05:
+ .byte 1
+AY_REG06:
+ .byte 1
+AY_REG07:
+ .byte 1
+AY_REG08:
+ .byte 1
+AY_REG09:
+ .byte 1
+AY_REG10:
+ .byte 1
+AY_REG11:
+ .byte 1
+AY_REG12:
+ .byte 1
+AY_REG13:
+ .byte 1
+AY_REG14:
+ .byte 1
+AY_REG15:
+ .byte 1
+
+; AY
+.org 0x0810
+AY1_REG00:
+ .byte 1
+AY1_REG01:
+ .byte 1
+AY1_REG02:
+ .byte 1
+AY1_REG03:
+ .byte 1
+AY1_REG04:
+ .byte 1
+AY1_REG05:
+ .byte 1
+AY1_REG06:
+ .byte 1
+AY1_REG07:
+ .byte 1
+AY1_REG08:
+ .byte 1
+AY1_REG09:
+ .byte 1
+AY1_REG10:
+ .byte 1
+AY1_REG11:
+ .byte 1
+AY1_REG12:
+ .byte 1
+AY1_REG13:
+ .byte 1
+AY1_REG14:
+ .byte 1
+AY1_REG15:
+ .byte 1
\ No newline at end of file
diff --git a/Sources/AY_Emu/AY_Emu/main_v1.asm b/Sources/AY_Emu/AY_Emu/main_v1.asm
new file mode 100644
index 0000000..f270f79
--- /dev/null
+++ b/Sources/AY_Emu/AY_Emu/main_v1.asm
@@ -0,0 +1,1098 @@
+; AY-3-8912 IC emulator version 26.0 for LGT8F328P
+;
+; Sources for Atmel AVRStudio 7
+;
+; visit our site for more information
+; These source codes are distributed under the GPL v3 license
+; If you share these sources you should put the link to web site www.avray.ru
+;
+; ORIGIN: http://www.avray.ru
+
+; CONFIGURATION VALUES ===================================================
+#define VOLUME_TABLE 0 ; 0 - AY, 1 - YM, 2 - ALTERNATE volume table
+; ========================================================================
+; bit numbers:
+.equ b0 = 0x00
+.equ b1 = 0x01
+.equ b2 = 0x02
+.equ b3 = 0x03
+.equ b4 = 0x04
+.equ b5 = 0x05
+.equ b6 = 0x06
+.equ b7 = 0x07
+.equ CHIP_SELECTED = GPIOR0
+
+.def OutA = r0
+.def OutC = r1
+.def C1F = r2
+.def CntN = r3
+.def OutB = r4
+.def BusOut1 = r5
+.def NoiseAddon = r6
+.def C00 = r7
+.def CC0 = r8
+.def TabE = r9
+.def C04 = r10
+.def TMP = r11
+.def EVal = r12
+.def SREGSave = r13
+.def RNGL = r14
+.def RNGH = r15
+.def BusData = r16
+.def BusOut2 = r17
+.def TabP = r18
+.def TNLevel = r19
+.def CntAL = r20
+.def CntAH = r21
+.def CntBL = r22
+.def CntBH = r23
+.def CntCL = r24
+.def CntCH = r25
+.def CntEL = r26
+.def CntEH = r27
+.def ADDR = r30
+
+; ==============================================
+; LGT8F328P REGISTER DEFINITIONS
+; ==============================================
+; Memory-mapped I/O addresses for LGT8F328P
+.equ BCR = 0x107 ; Boot Control Register
+.equ BOOTEND = 0x108 ; Boot End Address
+.equ BODCR = 0x104 ; BOD Control Register
+
+.equ PMCR = 0xF2
+.equ PMCE = 7
+.equ CLKFS = 6
+.equ CLKSS = 5
+.equ WCLKS = 4
+.equ WCES = 4
+.equ OSCKEN = 3
+.equ OSCMEN = 2
+.equ RCKEN = 1
+.equ RCMEN = 0
+
+.equ PMX2 = 0xF0
+.equ IOCR = 0xF0
+.equ IOCE = 7
+.equ STSC1 = 6
+.equ STSC0 = 5
+.equ XIEN = 2
+.equ E6EN = 1
+.equ REFIOEN = 1
+.equ C6EN = 0
+.equ RSTIOEN = 0
+; AC0 (Analog Comparator 0) Register Definition
+.equ C0SR = 0x50
+.equ C0D = 7
+.equ C0BG = 6
+.equ C0O = 5
+.equ C0I = 4
+.equ C0IE = 3
+.equ C0IC = 2
+.equ C0IS1 = 1
+.equ C0IS0 = 0
+
+.equ C0XR = 0x51
+.equ C0OE = 6
+.equ C0HSYE = 5
+.equ C0PS0 = 4
+.equ C0WKE = 3
+.equ C0FEN = 2
+.equ C0FS1 = 1
+.equ C0FS0 = 0
+
+.equ C0TR = 0x52
+
+; AC1 (Analog Comparator 1) Register Definition
+.equ C1SR = 0x2F
+.equ C1D = 7
+.equ C1BG = 6
+.equ C1O = 5
+.equ C1I = 4
+.equ C1IE = 3
+.equ C1IC = 2
+.equ C1IS1 = 1
+.equ C1IS0 = 0
+
+.equ C1XR = 0x3A
+.equ C1OE = 6
+.equ C1HSYE = 5
+.equ C1PS0 = 4
+.equ C1WKE = 3
+.equ C1FEN = 2
+.equ C1FS1 = 1
+.equ C1FS0 = 0
+
+.equ C1TR = 0x5B
+
+//----------------------------------------------------------------
+// TC3 (Timer Counter 3) Register Definition
+//----------------------------------------------------------------
+.equ TIFR3 = 0x38
+.equ OC3A = 7
+.equ OC3B = 6
+.equ ICF3 = 5
+.equ OCF3C = 3
+.equ OCF3B = 2
+.equ OCF3A = 1
+.equ TOV3 = 0
+
+.equ TIMSK3 = 0x71
+.equ ICIE3 = 5
+.equ OCIE3C = 3
+.equ OCIE3B = 2
+.equ OCIE3A = 1
+.equ TOIE3 = 0
+
+.equ TCCR3A = 0x90
+.equ COM3A1 = 7
+.equ COM3A0 = 6
+.equ COM3B1 = 5
+.equ COM3B0 = 4
+.equ COM3C1 = 3
+.equ COM3C0 = 2
+.equ WGM31 = 1
+.equ WGM30 = 0
+
+.equ TCCR3B = 0x91
+.equ ICNC3 = 7
+.equ ICES3 = 6
+.equ WGM33 = 4
+.equ WGM32 = 3
+.equ CS32 = 2
+.equ CS31 = 1
+.equ CS30 = 0
+
+.equ TCCR3C = 0x92
+.equ FOC3A = 7
+.equ FOC3B = 6
+.equ DOC31 = 5
+.equ DOC30 = 4
+.equ DTEN3 = 3
+.equ DOC32 = 1
+.equ FOC3C = 0
+
+.equ TCCR3D = 0x93
+.equ DSX37 = 7
+.equ DSX36 = 6
+.equ DSX35 = 5
+.equ DSX34 = 4
+.equ DSX31 = 1
+.equ DSX30 = 0
+
+.equ TCNT3 = 0x94
+.equ TCNT3L = 0x94
+.equ TCNT3H = 0x95
+
+.equ ICR3 = 0x96
+.equ ICR3L = 0x96
+.equ ICR3H = 0x97
+
+.equ OCR3A = 0x98
+.equ OCR3AL = 0x98
+.equ OCR3AH = 0x99
+
+.equ OCR3B = 0x9A
+.equ OCR3BL = 0x9A
+.equ OCR3BH = 0x9B
+
+.equ DTR3 = 0x9C
+.equ DTR3L = 0x9C
+.equ DTR3H = 0x9D
+
+.equ OCR3C = 0x9E
+.equ OCR3CL = 0x9E
+.equ OCR3CH = 0x9F
+
+// Bits of PSSR
+.equ PSS3 = 6
+.equ PSR3 = 1
+
+; LGT8F328P FAST GPIO REGISTERS
+.equ FGPIOE = 0x10A ; Fast GPIO Enable Register
+.equ FGPIO = 0x10B ; Fast GPIO Control Register
+
+ .cseg
+;------------------------------------------------------
+; INTERRUPT VECTORS TABLE
+;------------------------------------------------------
+ .org 0x0000
+ rjmp _LGT_INIT
+
+ .org INT0addr
+ rjmp _INT0_Handler
+
+ .org INT1addr
+ rjmp _INT1_Handler
+
+;------------------------------------------------------
+
+#if VOLUME_TABLE == 0
+ Volumes: ; volume table for amplitude
+ .db 0,1,1,1,2,2,3,5,6,9,13,17,22,29,36,45 // AY_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,0,1,1,1,1,1,1,2,2,2,2,3,3,5,5,6,6,7,9,11,13,15,17,19,22,25,29,32,36,40,45 // AY_TABLE
+#elif VOLUME_TABLE == 1
+ Volumes: ; volume table for amplitude
+ .db 0,1,1,1,2,2,3,4,5,7,10,13,18,24,34,45 // YM_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,0,1,1,1,1,1,1,2,2,2,2,2,3,3,4,4,5,6,7,8,10,11,13,15,18,21,24,29,34,40,45 // YM_TABLE
+#elif VOLUME_TABLE == 2
+ Volumes: ; volume table for amplitude
+ .db 0,1,2,3,4,5,6,7,9,11,13,16,22,31,42,58 // ALT_TABLE
+ EVolumes: ; volume table for envelopes
+ .db 0,1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,24,26,28,30,33,36,40,45,51,58 // ALT_TABLE
+#endif
+
+; envelope codes, bit0 - attack, bit1 - invert on next cycle, bit2 - stop generator on next cycle
+Envelopes:
+ .db 7,7,7,7,4,4,4,4,1,7,3,5,0,6,2,4
+
+; mask applied to registers values after receiving
+RegsMask:
+ .db 0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0x1F,0xFF,0x1F,0x1F,0x1F,0xFF,0xFF,0x0F,0xFF,0xFF
+
+;==========================================================
+_INT0_Handler: ; 4 cycles to enter
+ sbic PinD,b3 ; check BDIR (1)
+ rjmp LATCH_REG_ADDR0 ; (2) if BDIR=1
+
+ out DDRD,BusOut2 ; 1 - set data bus
+ out DDRC,BusOut1 ; 1
+
+LOOP_NOT_INACTIVE:
+ sbic PinD,b2 ; 1 - wait for BC1=0
+ rjmp LOOP_NOT_INACTIVE ; 2
+ out DDRC, C00 ; 1
+ out DDRD, C00 ; 1
+
+exit_int0:
+ ldi ZH, 0x01
+ out EIFR, YH ; 1 - clear flags
+ reti ; 4
+
+LATCH_REG_ADDR0:
+ in ADDR, PinC ; 1
+ andi ADDR, 0x3F ; 1
+ sbic PinD,b7
+ rjmp SELECT_CHIP_ADDR0
+ sbic CHIP_SELECTED,b0
+ rjmp READ_CHIP0
+ ; 0
+ ldi ZH,0x01
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int0
+
+READ_CHIP0:
+ ; 1
+ ldi ZH,high(AY1_REG00)
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int0
+
+SELECT_CHIP_ADDR0:
+ cpi ADDR, 0x3F ; 1
+ breq SELECT_CHIP0_ADDR0 ; 1/2
+ cpi ADDR, 0x3E
+ breq SELECT_CHIP1_ADDR0 ; 2
+ rjmp exit_int0
+
+SELECT_CHIP0_ADDR0:
+ cbi CHIP_SELECTED, b0
+ rjmp exit_int0
+
+SELECT_CHIP1_ADDR0:
+ sbi CHIP_SELECTED, b0
+ rjmp exit_int0
+
+;==========================================================
+_INT1_Handler: ; 4 cycles to enter
+ in BusData, PinC ; 1
+ andi BusData, 0x3F ; 1
+
+ sbic PinD, b2 ; 1
+ rjmp LATCH_REG_ADDR1 ; 2
+
+ in BusOut1, PinD ; 1
+ in SREGSave, SREG ; 1
+ and BusOut1, CC0
+ or BusData, BusOut1 ; 1
+ mov BusOut1, BusData ; 1
+ com BusOut1 ; 1
+ ldi ZH, 0x01
+ ld BusOut2, Z ; 2 - load mask
+
+ sbic CHIP_SELECTED, b0
+ ldi ZH, high(AY1_REG00)
+
+ std Z+0x20, BusOut1 ; 2 - save inverted
+ and BusData, BusOut2 ; 1 - apply mask
+ mov BusOut2, BusOut1 ; 1
+ andi BusOut2, 0xC0 ; 1 - extract bits 6-7
+
+ std Z+0x30, BusOut2 ; 2 - save high bits
+ std Z+0x10, BusData ; 2 - save value
+
+ ; 13
+ cpi ADDR, 0x0D ; 1
+ brne NO_ENVELOPE_CHANGED_P; 1/2
+ ori TNLevel, 0x80 ; 1
+NO_ENVELOPE_CHANGED_P:
+ out SREG, SREGSave ; 1
+exit_int1:
+ ldi ZH, 0x01
+ out EIFR, ZH ; 1
+ reti
+
+LATCH_REG_ADDR1:
+ mov ADDR, BusData ; 1
+ sbic PinD,b6
+ rjmp SELECT_CHIP_ADDR1
+ sbic CHIP_SELECTED,b0
+ rjmp READ_CHIP1
+ ; 0
+ ldi ZH,0x01
+ ldd BusOut1, Z+0x20 ; 2
+ ldd BusOut2, Z+0x30 ; 2
+ rjmp exit_int1
+
+READ_CHIP1:
+ ; 1
+ ldi ZH,high(AY1_REG00)
+ ldd BusOut1, Z+0x20
+ ldd BusOut2, Z+0x30
+ rjmp exit_int1 ; 2
+
+SELECT_CHIP_ADDR1:
+ cpi ADDR, 0x3F ; 1
+ breq SELECT_CHIP0_ADDR1 ; 1/2
+ cpi ADDR, 0x3E
+ breq SELECT_CHIP1_ADDR1 ; 2
+ rjmp exit_int1
+
+SELECT_CHIP0_ADDR1:
+ cbi CHIP_SELECTED, b0
+ rjmp exit_int1
+
+SELECT_CHIP1_ADDR1:
+ sbi CHIP_SELECTED, b0
+ rjmp exit_int1
+
+; ==============================================
+; LGT8F328P INITIALIZATION - NO BOOTLOADER
+; ==============================================
+_LGT_INIT:
+ ; watchdog
+ ldi r16, 0x00
+ sts WDTCSR, r16
+
+ ;
+ ldi r16, (1< PUD for
+ sbr r16,PUD
+ out MCUCR,r16
+
+ // init stack pointer at end of RAM
+ ldi r16,low(RAMEND)
+ out SPL,r16
+ ldi r16,high(RAMEND)
+ out SPH,r16
+
+ ; C D HI-Z ===================
+ ; C: PC0-PC5 - , HI-Z
+ ; D: PD6,PD7 - , HI-Z
+ ldi r16,0x00
+ out DDRC,r16 ; C
+ out PORTC,r16 ;
+ out DDRD,r16 ; D
+ out PORTD,r16 ;
+ ; =====================================================
+
+ ; disable Analog Comparator ==============================
+ ldi r16, (1<= 0
+ ;init new envelope period
+ ldi TabP,0x1F
+ sbrc TabE,b1
+ eor TabE,ZH ; invert envelope ATTACK bit
+ sbrc TabE,b2
+ or TabE,CC0 ; disable envelope generator until new envelope shape register recived
+E_NEXT_STEP_AY0:
+ lds CntEL,AY_REG11
+ lds CntEH,AY_REG12
+ mov YL,TabP
+ sbrs TabE,b0
+ eor YL,C1F ; invert envelope value if ATTACK bit is not set
+ ldd EVal,Y+0x30 ; translate envelope value to volume, read volume value from SRAM 0x230+YL
+ENVELOPE_GENERATOR_END_AY0:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// NOISE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ dec CntN ; decrease noise period counter
+ brpl NOISE_GENERATOR_END_AY0 ; skip if noise period is not finished (CntN>=0)
+ //init new cycle
+ lds CntN,AY_REG06 ; init noise period counter with value in AY register 6
+ dec CntN
+
+ lsr NoiseAddon
+ mov NoiseAddon,RNGL
+ ror RNGH
+ ror RNGL
+ ori TNLevel,0x38 ; set noise bits
+ sbrs RNGL,b0
+ andi TNLevel,0xC7 ; reset noise bits
+
+ lsl NoiseAddon
+ eor NoiseAddon,RNGL
+ lsr NoiseAddon
+NOISE_GENERATOR_END_AY0:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// TONE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ ; all counters are Int16 values (signed)
+ // Channel A -------------
+ subi CntAL,0x01 ; CntA - 1
+ sbci CntAH,0x00
+ brpl CH_A_NO_CHANGE_AY0 ; CntA >= 0
+ lds CntAL,AY_REG00 ; update channel A tone period counter
+ lds CntAH,AY_REG01
+ subi CntAL,0x01 ; CntA - 1
+ sbci CntAH,0x00
+ eor TNLevel,ZH ; TNLevel xor 1 (change logical level of channel A)
+CH_A_NO_CHANGE_AY0:
+
+ // Channel B -------------
+ subi CntBL,0x01 ; CntB - 1
+ sbci CntBH,0x00
+ brpl CH_B_NO_CHANGE_AY0 ; CntB >= 0
+ lds CntBL,AY_REG02 ; update channel B tone period counter
+ lds CntBH,AY_REG03
+ subi CntBL,0x01 ; CntB - 1
+ sbci CntBH,0x00
+ eor TNLevel,YH ; TNLevel xor 2 (change logical level of channel B)
+CH_B_NO_CHANGE_AY0:
+
+ // Channel C -------------
+ sbiw CntCL,0x01 ; CntC - 1
+ brpl CH_C_NO_CHANGE_AY0 ; CntC >= 0
+ lds CntCL,AY_REG04 ; update channel C tone period counter
+ lds CntCH,AY_REG05
+ sbiw CntCL,0x01 ; CntC - 1
+ eor TNLevel,C04 ; TNLevel xor 4 (change logical level of channel C)
+CH_C_NO_CHANGE_AY0:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// MIXER
+ /////////////////////////////////////////////////////////////////////////////////////
+ lds TMP,AY_REG07 ; Load Mixer AY Register from SRAM
+ or TMP,TNLevel ; Mixer formula = (Mixer Register Tone | TNLevel Tone) & (Mixer Register Noise | TNLevel Noise)
+ mov YL,TMP
+ lsl YL
+ swap YL
+ and TMP,YL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// AMPLITUDE CONTROL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ // Channel A
+ lds YL,AY_REG08 ; Load Channel A Amplitude register
+ mov OutA,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutA,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b0 ; if channel is disabled in mixer - set volume to zero
+ clr OutA
+
+ // Channel B
+ lds YL,AY_REG09 ; Load Channel B Amplitude register
+ mov OutB,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutB,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b1 ; if channel is disabled in mixer - set volume to zero
+ clr OutB
+
+ // Channel C
+ lds YL,AY_REG10 ; Load Channel C Amplitude register
+ mov OutC,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutC,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b2 ; if channel is disabled in mixer - set volume to zero
+ clr OutC
+ mov YL,OutB
+ lsr OutB ; TMP = TMP - (TMP/4 + TMP/8);
+ lsr OutB
+ sub YL,OutB
+ lsr OutB
+ sub YL,OutB
+ add OutA,YL ; add channel B volume to channels A and C
+ add OutC,YL
+ rcall SAVE_AY0_STATE
+
+AY1_PROCESSING:
+
+ rcall RESTORE_AY1_STATE
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// ENVELOPE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ sbrs TNLevel,b7
+ rjmp NO_ENVELOPE_CHANGED_AY1
+
+ // initialize envelope generator after change envelope shape register, only first 1/32 part of the first period!
+ lds YL,AY1_REG13 ; load envelope shape register value to TabE
+ ldd TabE,Y+0x10 ; get envelope code from SRAM
+ ldi TabP,0x1F ; set counter for envelope period
+ andi TNLevel,0x7F ; clear envelope shape change flag
+ rjmp E_NEXT_STEP_AY1
+
+NO_ENVELOPE_CHANGED_AY1:
+ sbrc TabE,b7 ; alternate: cpi TabE,0x80 ; check if envelope generator is disabled
+ rjmp ENVELOPE_GENERATOR_END_AY1 ; alternate: brcc ENVELOPE_GENERATOR_END
+ sbiw CntEL,0x01
+ brcs E_NEXT_PERIOD_AY1 ; jump to init next envelope value if counter overflow (if initial value was 0)
+ brne ENVELOPE_GENERATOR_END_AY1 ; go to the next step if zero value is not reached
+E_NEXT_PERIOD_AY1:
+ dec TabP
+ brpl E_NEXT_STEP_AY1 ; jump to next step if envelope period >= 0
+ ;init new envelope period
+ ldi TabP,0x1F
+ sbrc TabE,b1
+ eor TabE,ZH ; invert envelope ATTACK bit
+ sbrc TabE,b2
+ or TabE,CC0 ; disable envelope generator until new envelope shape register recived
+E_NEXT_STEP_AY1:
+ lds CntEL,AY1_REG11
+ lds CntEH,AY1_REG12
+ mov YL,TabP
+ sbrs TabE,b0
+ eor YL,C1F ; invert envelope value if ATTACK bit is not set
+ ldd EVal,Y+0x30 ; translate envelope value to volume, read volume value from SRAM 0x230+YL
+ENVELOPE_GENERATOR_END_AY1:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// NOISE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ dec CntN ; decrease noise period counter
+ brpl NOISE_GENERATOR_END_AY1 ; skip if noise period is not finished (CntN>=0)
+ //init new cycle
+ lds CntN,AY1_REG06 ; init noise period counter with value in AY register 6
+ dec CntN
+
+ lsr NoiseAddon
+ mov NoiseAddon,RNGL
+ ror RNGH
+ ror RNGL
+ ori TNLevel,0x38 ; set noise bitsP
+ sbrs RNGL,b0
+ andi TNLevel,0xC7 ; reset noise bits
+
+ ;MAKE_INPUT_BIT_AY1
+ lsl NoiseAddon
+ eor NoiseAddon,RNGL
+ lsr NoiseAddon
+NOISE_GENERATOR_END_AY1:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// TONE GENERATOR
+ /////////////////////////////////////////////////////////////////////////////////////
+ ; all counters are Int16 values (signed)
+ // Channel A -------------
+ subi CntAL,0x01 ; CntA - 1
+ sbci CntAH,0x00
+ brpl CH_A_NO_CHANGE_AY1 ; CntA >= 0
+ lds CntAL,AY1_REG00 ; update channel A tone period counter
+ lds CntAH,AY1_REG01
+ subi CntAL,0x01 ; CntA - 1
+ sbci CntAH,0x00
+ eor TNLevel,ZH ; TNLevel xor 1 (change logical level of channel A)
+CH_A_NO_CHANGE_AY1:
+
+ // Channel B -------------
+ subi CntBL,0x01 ; CntB - 1
+ sbci CntBH,0x00
+ brpl CH_B_NO_CHANGE_AY1 ; CntB >= 0
+ lds CntBL,AY1_REG02 ; update channel B tone period counter
+ lds CntBH,AY1_REG03
+ subi CntBL,0x01 ; CntB - 1
+ sbci CntBH,0x00
+ eor TNLevel,YH ; TNLevel xor 2 (change logical level of channel B)
+CH_B_NO_CHANGE_AY1:
+
+ // Channel C -------------
+ sbiw CntCL,0x01 ; CntC - 1
+ brpl CH_C_NO_CHANGE_AY1 ; CntC >= 0
+ lds CntCL,AY1_REG04 ; update channel C tone period counter
+ lds CntCH,AY1_REG05
+ sbiw CntCL,0x01 ; CntC - 1
+ eor TNLevel,C04 ; TNLevel xor 4 (change logical level of channel C)
+CH_C_NO_CHANGE_AY1:
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// MIXER
+ /////////////////////////////////////////////////////////////////////////////////////
+ lds TMP,AY1_REG07 ; Load Mixer AY Register from SRAM
+ or TMP,TNLevel ; Mixer formula = (Mixer Register Tone | TNLevel Tone) & (Mixer Register Noise | TNLevel Noise)
+ mov YL,TMP
+ lsl YL
+ swap YL
+ and TMP,YL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ /// AMPLITUDE CONTROL
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ // Channel A
+ lds YL,AY1_REG08 ; Load Channel A Amplitude register
+ mov OutA,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutA,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b0 ; if channel is disabled in mixer - set volume to zero
+ clr OutA
+
+ // Channel B
+ lds YL,AY1_REG09 ; Load Channel B Amplitude register
+ mov OutB,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutB,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b1 ; if channel is disabled in mixer - set volume to zero
+ clr OutB
+
+ // Channel C
+ lds YL,AY1_REG10 ; Load Channel C Amplitude register
+ mov OutC,EVal ; set envelope volume as default value
+ sbrs YL,b4 ; if bit 4 is not set in amplitude register then translate it to volume
+ ldd OutC,Y+0x20 ; load volume value from SRAM 0x220 + YL
+ sbrs TMP,b2 ; if channel is disabled in mixer - set volume to zero
+ clr OutC
+
+ mov YL,OutB
+ lsr OutB ; TMP = TMP - (TMP/4 + TMP/8);
+ lsr OutB
+ sub YL,OutB
+ lsr OutB
+ sub YL,OutB
+ add OutA,YL ; add channel B volume to channels A and C
+ add OutC,YL
+
+ rcall SAVE_AY1_STATE
+
+ lds TMP, OutA0
+ lds YL, OutA1
+ add YL, TMP
+ mov OutA, YL
+ lds TMP, OutC0
+ lds YL, OutC1
+ add YL, TMP
+ mov OutC, YL
+
+ sts OCR1AL,OutA ; update PWM counters
+ sts OCR1BL,OutC
+ rjmp _MAIN_LOOP
+// MAIN LOOP END ====================================================================
+
+;
+SAVE_AY0_STATE:
+ sts AY0_CntN, CntN
+ sts AY0_CntAL, CntAL
+ sts AY0_CntAH, CntAH
+ sts AY0_CntBL, CntBL
+ sts AY0_CntBH, CntBH
+ sts AY0_CntCL, CntCL
+ sts AY0_CntCH, CntCH
+ sts AY0_CntEL, CntEL
+ sts AY0_CntEH, CntEH
+ sts AY0_NoiseAddon, NoiseAddon
+ sts AY0_RNGH, RNGH
+ sts AY0_RNGL, RNGL
+ sts AY0_TabE, TabE
+ sts AY0_TabP, TabP
+ sts AY0_EVal, EVal
+
+ sts OutA0, OutA ; AY0
+ sts OutC0, OutC
+ ret
+
+RESTORE_AY0_STATE:
+ lds CntN, AY0_CntN
+ lds CntAL, AY0_CntAL
+ lds CntAH, AY0_CntAH
+ lds CntBL, AY0_CntBL
+ lds CntBH, AY0_CntBH
+ lds CntCL, AY0_CntCL
+ lds CntCH, AY0_CntCH
+ lds CntEL, AY0_CntEL
+ lds CntEH, AY0_CntEH
+ lds NoiseAddon, AY0_NoiseAddon
+ lds RNGH, AY0_RNGH
+ lds RNGL, AY0_RNGL
+ lds TabE, AY0_TabE
+ lds TabP, AY0_TabP
+ lds EVal, AY0_EVal
+ ret
+
+SAVE_AY1_STATE:
+ sts AY1_CntN, CntN
+ sts AY1_CntAL, CntAL
+ sts AY1_CntAH, CntAH
+ sts AY1_CntBL, CntBL
+ sts AY1_CntBH, CntBH
+ sts AY1_CntCL, CntCL
+ sts AY1_CntCH, CntCH
+ sts AY1_CntEL, CntEL
+ sts AY1_CntEH, CntEH
+ sts AY1_NoiseAddon, NoiseAddon
+ sts AY1_RNGH, RNGH
+ sts AY1_RNGL, RNGL
+ sts AY1_TabE, TabE
+ sts AY1_TabP, TabP
+ sts AY1_EVal, EVal
+
+ sts OutA1, OutA ; AY1
+ sts OutC1, OutC
+ ret
+
+RESTORE_AY1_STATE:
+ lds CntN, AY1_CntN
+ lds CntAL, AY1_CntAL
+ lds CntAH, AY1_CntAH
+ lds CntBL, AY1_CntBL
+ lds CntBH, AY1_CntBH
+ lds CntCL, AY1_CntCL
+ lds CntCH, AY1_CntCH
+ lds CntEL, AY1_CntEL
+ lds CntEH, AY1_CntEH
+ lds NoiseAddon, AY1_NoiseAddon
+ lds RNGH, AY1_RNGH
+ lds RNGL, AY1_RNGL
+ lds TabE, AY1_TabE
+ lds TabP, AY1_TabP
+ lds EVal, AY1_EVal
+ ret
+
+// copy routine from flash to SRAM
+_COPY:
+ lpm r16,Z+
+ st X+,r16
+ dec r18
+ brne _COPY
+ ret
+
+/////////////////////////////////////////////////////////////////
+/// AY REGISTERS IN SRAM
+/////////////////////////////////////////////////////////////////
+ .dseg
+ .org 0x0110
+; AY
+AY_REG00:
+ .byte 1
+AY_REG01:
+ .byte 1
+AY_REG02:
+ .byte 1
+AY_REG03:
+ .byte 1
+AY_REG04:
+ .byte 1
+AY_REG05:
+ .byte 1
+AY_REG06:
+ .byte 1
+AY_REG07:
+ .byte 1
+AY_REG08:
+ .byte 1
+AY_REG09:
+ .byte 1
+AY_REG10:
+ .byte 1
+AY_REG11:
+ .byte 1
+AY_REG12:
+ .byte 1
+AY_REG13:
+ .byte 1
+AY_REG14:
+ .byte 1
+AY_REG15:
+ .byte 1
+
+; AY
+ .org 0x0310
+AY1_REG00:
+ .byte 1
+AY1_REG01:
+ .byte 1
+AY1_REG02:
+ .byte 1
+AY1_REG03:
+ .byte 1
+AY1_REG04:
+ .byte 1
+AY1_REG05:
+ .byte 1
+AY1_REG06:
+ .byte 1
+AY1_REG07:
+ .byte 1
+AY1_REG08:
+ .byte 1
+AY1_REG09:
+ .byte 1
+AY1_REG10:
+ .byte 1
+AY1_REG11:
+ .byte 1
+AY1_REG12:
+ .byte 1
+AY1_REG13:
+ .byte 1
+AY1_REG14:
+ .byte 1
+AY1_REG15:
+ .byte 1
+
+; AY0
+ .org 0x0400
+AY0_CntN: .byte 1
+AY0_CntAL: .byte 1
+AY0_CntAH: .byte 1
+AY0_CntBL: .byte 1
+AY0_CntBH: .byte 1
+AY0_CntCL: .byte 1
+AY0_CntCH: .byte 1
+AY0_CntEL: .byte 1
+AY0_CntEH: .byte 1
+AY0_NoiseAddon: .byte 1
+AY0_RNGH: .byte 1
+AY0_RNGL: .byte 1
+AY0_TabE: .byte 1
+AY0_TabP: .byte 1
+AY0_EVal: .byte 1
+
+; AY1
+AY1_CntN: .byte 1
+AY1_CntAL: .byte 1
+AY1_CntAH: .byte 1
+AY1_CntBL: .byte 1
+AY1_CntBH: .byte 1
+AY1_CntCL: .byte 1
+AY1_CntCH: .byte 1
+AY1_CntEL: .byte 1
+AY1_CntEH: .byte 1
+AY1_NoiseAddon: .byte 1
+AY1_RNGH: .byte 1
+AY1_RNGL: .byte 1
+AY1_TabE: .byte 1
+AY1_TabP: .byte 1
+AY1_EVal: .byte 1
+
+OutA0: .byte 1
+OutC0: .byte 1
+OutA1: .byte 1
+OutC1: .byte 1