не должен.
из исходников Vinxru:
Код:CLC_PORT = 0F001h
DATA_PORT = 0F002h
CTL_PORT = 0F003h
Вид для печати
У Сергея при реализации AY в FPGA встал вопрос, который тут пока не обсуждался. А как, собственно, раскидывать ABC по правому и левому каналам?
Не все должно быть оптимизированно под 10 растровых строк. Такие плееры уже есть. Они полезны для демок и игр, но в них удобство использования не на первом месте. А кому-то может быть хотелось бы просто запустить плеер и послушать коллекцию pt2/pt3. Такого под Вектор по-моему нет даже на минималках, не говоря уже о том, чтобы красиво.
У меня есть Галаксия. Так вот в нёй есть AY и проигрыватель то же. Посмотрите информацию - может что полезное найдёте.
https://xn----7sbombne2agmgm0c.xn--p...s/SoundGen.png
В общем вот. Это очень грубая адаптация под i8080 проигрывателя PT2/PT3-модулей Сергея Бульбы. Требует серьёзнейшей оптимизации! Гарантировать, что там нет ошибок, я не могу, хотя несколько модулей, которые я тестировал, на мой немузыкальный слух играли как положено.
В комплекте исходный код проигрывателя + файл с макросами + мелодия + готовый к запуску RKS. Макросы сильно упрощённые, подготовленные для конкретной программы. Использовать их для какого-либо другого переноса кода с Z80 на i8080 я не рекомендую.
На Специалисте без прерываний на прилагаемой мелодии слышна неравномерность воспроизведения, которая отсутствует при использовании прерываний.
Будет здорово, если кто-то поищет баги и займётся оптимизацией кода.
Развернул все макросы и, как и ожидал, увидел полный ужас. Кропотливо прошёл по всей программе, каждый раз проверяя свои изменения. Убеждался в каждом конкретном месте, какие регистры нужно сохранять, а какие можно игнорировать. В итоге универсальные конструкции типа таких:
Превратились в такое:Код:; LD E,(IX+CHP.TnAcc)
ld (t_084 + 1), a
ld a, h
ld (TMP1 + 1), a
ld a, l
ld (TMP1), a
ld hl, (rIX)
ld a, b
ld (TMP2 + 1), a
ld a, c
ld (TMP2), a
ld bc, CHP.TnAcc
add hl, bc
ld a, (TMP2 + 1)
ld b, a
ld a, (TMP2)
ld c, a
ld e, (hl)
ld a, (TMP1 + 1)
ld h, a
ld a, (TMP1)
ld l, a
t_084 ld a, 0
; LD D,(IX+CHP.TnAcc+1)
ld (t_085 + 1), a
ld a, h
ld (TMP1 + 1), a
ld a, l
ld (TMP1), a
ld hl, (rIX)
ld a, b
ld (TMP2 + 1), a
ld a, c
ld (TMP2), a
ld bc, CHP.TnAcc+1
add hl, bc
ld a, (TMP2 + 1)
ld b, a
ld a, (TMP2)
ld c, a
ld d, (hl)
ld a, (TMP1 + 1)
ld h, a
ld a, (TMP1)
ld l, a
t_085 ld a, 0
Не везде можно пользоваться стеком, но, где можно, я использовал PUSH/POP.Код:; LD E,(IX+CHP.TnAcc)
; LD D,(IX+CHP.TnAcc+1)
ld (TMP1+1), hl
ld hl, (rIX)
ld de, CHP.TnAcc
add hl, de
ld e, (hl)
inc hl
ld d, (hl)
TMP1: ld hl, 0
В аттаче текущая версия. Сделал всё, что мог. Думаю, что этим уже можно пользоваться. Но хотелось бы, чтобы всё-таки кто-нибудь сделал code review и потестировал на своих компах/эмуляторах с i8080.
Также выложил на GitHub.
Pyk внедрил в Emu80 TurboSound и кадровые прерывания в эмуляцию Специалиста. Пока что в тестовой версии. Вот как оно работает:
https://plvideo.ru/watch?v=iMkMn3qB6Flz
Пока для теста использую проигрыватель, который я сам адаптировал. По совету ivagor воспроизвожу двумя проигрывателями, скомпилированными по разным адресам. Вроде бы играет, но есть уверенность, что так неправильно. Нужно вначале вывести данные на оба AY, а уже потом подготавливать данные для обеих AY для следующего кадра. Буду ждать правильной реализацию от ivagor ;)
Столкнулся с неожиданной проблемой. Не могу определить начало второй половины модуля, кроме как по поиску сигнатуры. Неужели в заголовке первого модуля нигде не указана его длина, чтобы автоматически вычислить смещение для второй половины? Даже у ИИ спросил. Но он то ли не знает, то ли ещё чего, но говорит, что именно по сигнатуре и нужно искать, и что якобы длина модуля нигде явно не указана. Странно это...
В "двухчастных" модулях в любом случае по сигнатуре искать. Не знаю, как положено, а для себя я сформулировал два варианта:
1. Ищем первую сигнатуру PT3! - после нее указано смещение второй части. Как вариант - ищем сигнатуру 02TS и потом по отрицательному смещению находим смещение второй части.
2. Вторую часть можно искать по совпадению начальных сигнатур модулей.
Собственно, именно этот вариант я у себя и реализовал в итоге.
Проверки не длину нет, то есть считается, что повтор обязательно встретится. Вот так я придумал, но, как обычно, я делаю всё "в лоб". А как можно улучшить?Код:string_length equ 10 ; По какому количеству байт искать
; Ищем второе вхождение начальной сигнатуры
; На выходе в HL адрес второй части
find_second_half:
ld bс, 0xff00
ld de, melody
ld hl, melody + string_length
find_second_half_01:
ld a, (de)
cp (hl)
jp z, find_second_half_02
ld c, 0
ld de, melody
jp find_second_half_03
find_second_half_02:
dec c
inc de
find_second_half_03:
inc hl
ld a, c
cp -string_length
jp nz, find_second_half_01
add hl, bc
ret