Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- org 0000h
- ; Инициализация
- 0000 F3 di ; Запрет прерываний
- 0001 31 FF FF ld sp,0FFFFh ; Установка стека
- 0004 21 00 02 ld hl,0200h ; HL = исходные данные
- 0007 11 4C F8 ld de,0F84Ch ; DE = куда копировать
- 000A 01 5C 04 ld bc,045Ch ; BC = длина блока
- 000D ED B0 ldir ; Копирование памяти
- ; Основной цикл обработки звука
- 000F 21 91 01 ld hl,0191h ; HL = таблица тонов
- 0012 06 FF ld b,0FFh ; Инициализация счетчика
- ; Чтение таблицы тонов
- 0014 7E ld a,(hl) ; Загрузка значения тона
- 0015 23 inc hl ; Следующий байт
- 0016 4E ld c,(hl) ; Загрузка длительности
- 0017 23 inc hl
- 0018 04 inc b ; Увеличить счетчик тонов
- 0019 A1 and c ; Проверка конца маркера
- 001A 3C inc a
- 001B 20 F7 jr nz,0014h ; Цикл если не конец
- 001D 3A 01 F8 ld a,(0F801h) ; Проверка текущей позиции
- 0020 B8 cp b
- 0021 38 04 jr c,0027h ; Если не достигли конца
- 0023 AF xor a ; Сброс позиции
- 0024 32 01 F8 ld (0F801h),a
- 0027 CD 3A 01 call 013Ah ; Настройка AY
- 002A CD C7 00 call 00C7h ; Обновление звука
- 002D CD 1F 01 call 011Fh ; Проверка ввода
- 0030 3A 00 F8 ld a,(0F800h) ; Проверка статуса
- 0033 CB 47 bit 0,a
- 0035 20 07 jr nz,003Eh ; Если бит 0 не установлен
- 0037 AF xor a
- 0038 32 04 F8 ld (0F804h),a ; Отключить канал A
- 003B 32 05 F8 ld (0F805h),a ; Отключить канал B
- 003E 3A 00 F8 ld a,(0F800h)
- 0041 CB 4F bit 1,a
- 0043 CC AC 00 call z,00ACh ; Обработка тона если бит 1=0
- 0046 CD 87 00 call 0087h ; Дополнительная обработка звука
- 0049 3A 04 F8 ld a,(0F804h) ; Проверка состояния каналов
- 004C 6F ld l,a
- 004D 3A 05 F8 ld a,(0F805h)
- 0050 B5 or l
- 0051 CC 54 01 call z,0154h ; Следующий тон если оба канала выключены
- 0054 18 D4 jr 002Ah ; Главный цикл
- ; Подпрограмма настройки AY (013Ah)
- 00C7 3E 07 ld a,07h ; Выбор регистра 7 (микширование)
- 00C9 06 FF ld b,0FFh
- 00CB ED 79 out (c),a
- 00CD ED 78 in a,(c) ; Чтение текущего значения
- 00CF CB BF res 7,a ; Сброс битов
- 00D1 CB B7 res 6,a
- 00D3 06 BF ld b,0BFh
- 00D5 ED 79 out (c),a ; - - - Запись нового значения
- 00D7 3E 0E ld a,0Eh ; Настройка регистра огибающей
- 00D9 06 FF ld b,0FFh
- 00DB ED 79 out (c),a
- 00DD ED 78 in a,(c)
- 00DF 32 00 F8 ld (0F800h),a ; Сохранение статуса
- 00E2 C9 ret
- ; Таблица тонов (начиная с 0191h)
- 0191 01 50 C4 10 10 10 38 00
- 0199 00 50 00 01 00 30 7F BF
- 01A1 DF EF 00 5C 06 89 0D 16
- ... (и т.д.)
- //////////////////////////////
- #include <stdint.h>
- #include <stdbool.h>
- #define AY_REG_SELECT 0x07
- #define AY_REG_WRITE 0xFF
- uint8_t memory[0x1000]; // Z80 memory space
- void ay_write(uint8_t reg, uint8_t val) // Select AY register
- {
- out(AY_REG_SELECT, reg);
- out(AY_REG_WRITE , val); // Write value to selected register
- }
- void main()
- {
- asm("di"); // Initialize stack and copy data
- uint16_t sp = 0xFFFF;
- memcpy(&memory[0xF84C], &memory[0x0200], 0x045C);
- while (1) // Process tone table
- {
- uint8_t* tone_ptr = &memory[0x0191];
- uint8_t tone_count = 0;
- while (1)
- {
- uint8_t tone = *tone_ptr++;
- uint8_t duration = *tone_ptr++;
- tone_count++;
- if ((tone & duration) + 1 == 0) break;
- }
- // Check if tone sequence needs reset
- if (memory[0xF801] >= tone_count) {
- memory[0xF801] = 0;
- }
- // Update AY registers
- ay_update(); // Equivalent to call 013Ah
- // Update sound output
- update_sound(); // Equivalent to call 00C7h
- // Check input status
- check_input(); // Equivalent to call 011Fh
- // Handle mute condition
- if (!(memory[0xF800] & 0x01)) {
- memory[0xF804] = 0; // Channel A off
- memory[0xF805] = 0; // Channel B off
- }
- // Process tone if needed
- if (!(memory[0xF800] & 0x02)) {
- handle_tone(); // Equivalent to call 00ACh
- }
- // Continue sound generation
- update_sound_again(); // Equivalent to call 0087h
- // Check if sound should advance
- if ((memory[0xF804] | memory[0xF805]) == 0) {
- next_tone(); // Equivalent to call 0154h
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement