NeoGS – шаг в будущее — Abzac


PeriodicalsAbzac2009 No. 32 → NeoGS – шаг в будущее

NeoGS – шаг в будущее

Группа NedoPC запустила в произ­водство качественно новое звуковое устройство для вашего Спектрума – NeoGS. Данная карта программно со­вместима со старой картой General Sound (в дальнейшем oldGS), однако предлагает значительно улучшенные и практически неограниченные (при соответственном программировании) возможности. В данной статье крат­ко описывается потенциал NeoGS.


Итак, что же такое NeoGS? Это звуковая карта, основанная (как и oldGS) на процессоре Z80. Од­нако, на этом вся схожесть заканчивается. Истин­ным сердцем NeoGS является ПЛИС (программи­руемая логическая интегральная схема - она же FPGA – field programmable gate array), содержащая в себе 1728 логических ячеек (одна такая ячейка выполняет произвольную четырёхвходовую ло­гическую функцию и может содержать на выходе триггер) и 3 килобайта синхронного ОЗУ, выпол­ненного блоками по 4 килобита (512 байт). Конеч­но, по современным меркам ёмкость FPGA весь­ма скромна, однако и такая ёмкость ограничивает потенциальные возможности NeoGS лишь прин­ципиальной схемой и фантазией разработчика.

Помимо ПЛИС, NeoGS также содержит:

- процессор Z80, работающий на частотах до 24 Мгц

- 512 килобайт flash-ПЗУ

- 2 мегабайта статического ОЗУ

- 16-битный стереоаудио ЦАП типа TDA1543

- слот SD-карты

- аппаратный (в виде отдельной м/сх) MP3-де­кодер - аналог VS1001 или VS1011.

Прошивка в FPGA (загружаемая при каждом включении или холодном сбросе) превращает сбо­рище микросхем в звуковую карту NeoGS, выпол­няющую на данный момент следующие функции:

- полная программная совместимость с oldGS;

- адресация памяти вплоть до 2 мегабайт ОЗУ и 512 килобайт ПЗУ страничным методом: страни­цами по 32 килобайта в одном окне (как в oldGS) или двумя страницами по 16 килобайт одновре­менно в двух окнах;

- эмуляция ПЗУ oldGS при помощи аппаратной защиты от записи нулевой страницы.

- поддержка 4 каналов семплированного звука (как в oldGS), а также новых режимов: 8 каналов звука и 4 каналов звука с двумя громкостями;

- управление частотой процессора Z80 (10, 12, 20 и 24 Мгц);

- дополнительные возможности контроля NeoGS со стороны Спектрума: тёплый сброс, вы­дача NMI и управление светодиодом на плате (по­лезно при отладке программ);

- аппаратные SPI-интерфейсы с SD-картой и MP3-декодером.

Кроме того, предусмотрены штатные про­граммные средства перезагрузки прошивки ПЛИС.

В настоящее время ведутся работы над DMA (к моменту сборки номера стало известно, что тестовая прошивка NeoGS с поддержкой DMA соз­дана и проходит тестирование - прим. ред.), ко­торый позволит:

- быстрое копирование данных со Спектрума или на Спектрум (Спектрум пишет или читает дан­ные для NeoGS в область ПЗУ, обмен с памятью NeoGS происходит средствами DMA независимо от процессора NeoGS);

- обмен данными с SD-картой и MP3-декоде­ром независимо от процессора NeoGS;

- вывод семплированного звука через DMA.

Кроме того, разрабатывается контроллер пре­рываний для NeoGS, который позволит:

- иметь прерывания от программируемых тай­меров;

- иметь прерывания от командного интерфей­са со Спектрумом (нет необходимости в «поллин­ге» портов обмена со стороны NeoGS);

- иметь прерывания по окончании чтения или записи сектора на SD-карту.

Данная статья нисколько не пытается предос­тавить техническую информацию по программи­рованию NeoGS. В настоящее время готовится ру­ководство программиста, которое будет доступно на сайте http://www.nedopc.com.

Однако исключительно для иллюстрации неко­торых возможностей NeoGS здесь приводится ис­ходный код простейшего MP3-плеера на NeoGS, иг­рающего MP3-поток с SD-карты. Предполагается, что MP3-файл записан на SD-карту без файловой системы с нулевого сектора. Запись можно осуще­ствить утилитой dd в линуксе или же программой WinHEX в Windows (ими же можно сделать резерв­ную копию всей SD-карты). В исходном коде пред­полагается использование файла «ports.inc», со­держащего символические обозначения для всех внутренних портов NeoGS и битовых полей этих портов, а также обозначения портов NeoGS, дос­тупных со стороны Спектрума. Данный файл так­же будет доступен на сайте http://www.nedopc.com вместе с руководством программиста.

Примечание: политика NedoPC в отношении руководства программиста и исходных кодов для NeoGS состоит в использовании исключи­тельно символических имён портов и битовых полей, в противовес документации на oldGS.

Плеер состоит из двух частей: кода, работаю­щего на NeoGS (как загрузить и запустить этот код в NeoGS, следует читать в руководстве к стандартной прошивке gs105a.rom, которая ис­пользовалась в oldGS и под управлением кото­рой работает процессор NeoGS по умолчанию), и кода, работающего на Спектруме, который и осу­ществляет все функции плеера, кроме непосред­ственно копирования данных с SD-карты в MP3-декодер.

Исходник кода в NeoGS:


    ORG #5B00
    DI
;устанавливаем частоту процессора 12 МГц
    IN A,(GSCFG0)
    AND #FF-M_CKSEL1-M_CKSEL0
    OR C_12MHZ
    OUT (GSCFG0),A
MAINLOOP    IN A,(CLRCBIT)    ;очищаем COMMAND BIT
WAITCOMMAND    IN A,(ZXSTAT)    ;ждем, когда Спектрум запишет команду
    AND M_CBIT
    JR Z,WAITCOMMAND
    IN A,(ZXCMD)    ;читаем команду
    CP #FF
    JR Z,MOVMP3    ;копирование 512 байт из SD-карты в MP3-декодер
    RLCA
    SRL A
    JR C,PREAD    ;старший бит=1 - чтение порта для Cпектрума
        ;старший бит=0 - запись в порт
PWRITE    LD C,A    ;биты 6-0 - адрес порта
    IN A,(ZXDATRD)    ;данные для записи
    OUT (C),A
    JR MAINLOOP
PREAD    LD C,A
    IN A,(C)    ;читаем указанный порт
    OUT (ZXDATWR),A    ;отправляем спеку байт
    JR MAINLOOP
MOVMP3    LD D,16
SECLOOP    IN A,(SSTAT)    ;ждем готовности MP3-декодера
    AND M_MDDRQ    ;принять данные
    JR Z,SECLOOP    
    LD B,32    ;шлем по 32 байта
    LD C,MD_SEND
BYTELOOP    LD A,#FF    ;инициируем обмен по SPI с SD-картой
    OUT (SD_SEND),A    ;(в карту уходит холостой байт #FF)
    NOP    ;пауза - >=16 тактов для обмена по SPI
    NOP
    IN A,(SD_READ)    ;читаем принятые данные
    OUT (MD_SEND),A    ;отсылаем в MP3-декодер
    DJNZ BYTELOOP
    DEC D
    JR NZ,SECLOOP
    JR MAINLOOP
Исходник кода для Спектрума (для понимания рекомендуется изучения datasheet’ов на VS1001 и SD-карты):
    ORG #8000
    CALL I_MP3    ;инициализация MP3-декодера
    CALL I_SDC    ;инициализациз SD-карты
    CALL PLAYMP3    ;проигрывание
    CALL DEI_SDC    ;деинициализация SD-карты
    EI
    RET
RDSECBEG    LD HL,CMD17
    CALL SENDCMD
CMDOK2    LD A,#FF
    LD C,SD_SEND
    CALL WRPORT
    LD C,SD_READ
    CALL RDPORT
    CP #FE
    JR NZ,CMDOK2
    RET
RDSECEND    LD A,#FF
    LD C,SD_SEND
    CALL WRPORT
    CALL WRPORT
    CALL WFF
    LD HL,CMD17+3
    INC (HL)
    INC (HL)
    RET NZ
    DEC HL
    INC (HL)
    RET NZ
    DEC HL
    INC (HL)
    RET
WRPORT    OUT (GSDAT),A    ;write GS port: OUT (C),A
    PUSH AF
    LD A,C
    AND #7F
    OUT (GSCOM),A
    IN A,(GSSTAT)
    RRA
    JR C,$-3
    POP AF
    RET
RDPORT    ;read GS port: IN A,(C)
    LD A,C
    OR #80
    OUT (GSCOM),A
    IN A,(GSSTAT)
    RRA
    JR C,$-3
    IN A,(GSDAT)
    RET
SENDCMD    LD B,6
SCMDL    LD A,(HL)
    LD C,SD_SEND
    CALL WRPORT
    CALL RDPORT
    INC HL
    DJNZ SCMDL
    RET
CMD0    DB #40,0,0,0,0,#95
CMD1    DB #41,0,0,0,0,#FF
CMD17    DB #51,0,0,000,0,#FF
I_MP3    LD C,GSCFG0
    LD A,C_10MHZ
    CALL WRPORT    ;частота процессора в NeoGS 10 MHz
    LD C,SCTRL
    LD A,M_MPXRS    ;вкл. сигнал сброса на MP3-декодер
    CALL WRPORT
    LD C,SCTRL    ;выкл. сброс
    LD A,M_SETNCLR+M_MPXRS
    CALL WRPORT
    HALT
    HALT
WDRQ1    LD C,SSTAT
    CALL RDPORT
    AND M_MDDRQ
    JR Z,WDRQ1    ;ждем готожности MP3-декодера
;информируем декодер о частоте кварца и включаем умножитель
    ;9B58 for 14MHz
    LD C,SCTRL
    LD A,M_MCNCS
    CALL WRPORT    ;CS=0 на SPI-интерфейс декодера
    LD C,MC_SEND    ;шлем 4 байта
    LD A,2
    CALL WRPORT
    LD A,3
    CALL WRPORT
    LD A,#9B
    CALL WRPORT
    LD A,#58
    CALL WRPORT
    LD C,SCTRL
    LD A,M_SETNCLR+M_MCNCS    ;CS=1
    CALL WRPORT
    HALT
    LD C,SCTRL
    LD A,M_MCNCS
    CALL WRPORT    ;CS=0
    LD C,MC_SEND
    LD A,2
    CALL WRPORT
    LD A,2
    CALL WRPORT
    LD A,#80    ;включаем умножитель
    CALL WRPORT    ;(см. аппноты на VS1001)
    LD A,#08
    CALL WRPORT
    LD C,SCTRL
    LD A,M_SETNCLR+M_MCNCS
    CALL WRPORT
    HALT
    LD C,GSCFG0
    LD A,C_12MHZ    ;проц. Обратно на 12 МГц
    CALL WRPORT
    RET
I_SDC    LD HL,CMD17+1
    LD (HL),0
    INC HL
    LD (HL),0
    INC HL
    LD (HL),0
    LD C,SCTRL
    LD A,M_SETNCLR+M_SDNCS    ;SD CS=1
    CALL WRPORT
    LD B,74
FFLO    LD C,SD_SEND    ;шлем много FF’ов в карту при
    LD A,#FF    ;снятом CS’е
    CALL WRPORT
    DJNZ FFLO
    LD C,SCTRL
    LD A,M_SDNCS    ;SD CS=0
    CALL WRPORT
    ;начинаем обмен с картой с инициализации
    LD HL,CMD0
    CALL SENDCMD
WAIKARD    LD C,SD_SEND
    LD A,#FF
    CALL WRPORT
    LD C,SD_READ
    CALL RDPORT
    DEC A
    JR NZ,WAIKARD
WAINIT    CALL WFF
    LD HL,CMD1
    CALL SENDCMD
WNOTFF    LD C,SD_SEND
    LD A,#FF
    CALL WRPORT
    LD C,SD_READ
    CALL RDPORT
    CP #FF
    JR Z,WNOTFF
    RRA
    JR C,WAINIT
    CALL WFF
    RET
DEI_SDC    LD A,M_SETNCRL+M_SDNCS    ;SD CS=1
    LD C,SCTRL
    CALL WRPORT
    LD A,#FF
    LD C,SD_SEND
    CALL WRPORT
    RET
PLAYMP3    ;тут играем MP3-файл с нулевого сектора из карты
    CALL RDSECBEG    ;начинаем чтение сектора
    LD A,#FF    ;даем команду коду в NeoGS
    OUT (GSCOM),A    ;на пересылку 512 байт сектора
    IN A,(GSSTAT)    ;в MP3-декодер
    RRA
    JR C,$-3
    CALL RDSECEND    ;заключительные операции чтения и инкремент
        ;номера сектора
    LD DE,#4000    ;печать адреса (номер сектора*512)
    LD A,(CMD17+1)
    CALL PRIHEX
    LD A,(CMD17+2)
    CALL PRIHEX
    LD A,(CMD17+3)
    CALL PRIHEX
    LD A,(CMD17+4)
    CALL PRIHEX
    LD A,#7F
    IN A,(#FE)
    RRA
    JR C,PLAYMP3
    RET
WFF    LD C,SD_SEND
    LD A,#FF
    CALL WRPORT
    LD C,SD_READ
    CALL RDPORT
    INC A
    JR NZ,WFF
    RET
PRIHEX    ;hex from A
    PUSH AF
    RRA
    RRA
    RRA
    RRA
    CALL PHC
    POP AF
PHC    AND #0F
    CP 10
    JR C,PH_2
    ADD A,”A”-”0”-10
PH_2    ADD A,”0”
    CALL PRISYM
    RET
PRISYM    ;A - sym
    ;DE - scr addr (inc E)
    PUSH HL
    ADD A,A
    LD L,A
    LD H,#0F
    ADD HL,HL
    ADD HL,HL
    ;LD BC,#3C00
    ;ADD HL,BC
    PUSH DE
;----
    DUP 8    ;повторение фрагмента 8 раз
    LD A,(HL)
    LD (DE),A
    INC L
    INC D
    EDUP
;----
    ORG $-2
    POP DE
    INC E
    POP HL
    RET

Звуковая картa NeoGS – технически слож­ное устройство, требующее для успешного применения большое количество работы по­мимо просто сборки платы, в частности напи­сания софта (плееры, прошивки FPGA) и описа­ний (руководство программиста). Кроме того, группа NedoPC придерживается идеологии open-source, и на все устройства, производи­мые группой, доступны исходные коды проши­вок, схемы и печатные платы в CAD-форматах. Данный материал для NeoGS готовится к публи­кации и будет доступен в ближайшее время на http://www.nedopc.com.

Кроме того, работа над прошивками постоян­но продолжается, и постепенно добавляются но­вые возможности, такие как, например, DMA и контроллер прерываний. Следите за обновления­ми на нашем сайте.