PopolonY2k Framework Memory Mapper support

Após alguns meses do lançamento da última versão do PopolonY2k Framework, venho trabalhando em alguns programas de exemplo para reforçar os conceitos implementados no framework bem como na difusão de conhecimento de tudo o que tem nele desenvolvido.

A comunidade nacional tem utilizado muitas partes do framework e principalmente a comunidade internacional tem reportado alguns problemas encontrados, principalmente no Pop!Art, o que me levou a verificar que de fato os problemas estão relacionados a algumas peças do framework e que brevemente serão ajustadas ainda esse ano.

No grupo de WhatsApp “MSX Pascal, C, ASM e etc” temos discutido muito sobre assuntos relacionados a desenvolvimento para retro-machines, principalmente para o MSX e em algumas dessas discussões surgiram alguns questionamentos sobre o uso das rotinas de uso da mapper do PopolonY2k Framework.

Por esse motivo, preparei um sample com um código bem elucidativo sobre o uso das principais rotinas de alocação e paginação da mapper que fazem uso das rotinas do MSXDOS2 disponíveis no framework, conforme análise e explicação pode ser vista no vídeo abaixo.

MSXDOS2 Mapper PopolonY2k Framework routines

O framework também contempla uso da mapper através do acesso direto a portas de I/O, o que torna o seu uso mais rápido, entretanto essas rotinas são as chamadas “mal comportadas” e devem ser utilizadas com muita cautela principalmente quando se tem completa certeza de que não há conflitos com áreas pré-alocadas pelo próprio MSXDOS2 via suas rotinas padrão.

O Pop!Art faz isso com extrema segurança, onde o mesmo aloca e preenche os dados da música VGM usando as rotinas de mapper padrão do MSXDOS2 e usa as de acesso direto, apenas no momento em que está tocando quando está apenas fazendo paginação dos segmentos da mapper pré-alocados pelas rotinas do MSXDOS2.

Os exemplos estão sendo adicionados diretamente no repositório do projeto na OldSkoolTech no SourceForge.net e podem ser consultados nesse link aqui.

O sample de uso da mapper (maprtest.pas) está completamente comentado sendo bem auto-explicativo, além de ter uma análise bem completa no vídeo acima, podendo seu código ser conferido abaixo:

(*<maprtest.pas>
 * Memory mapper routines test.
 *
 * - Routines tested:
 * - InitMapper;
 * - GetMapperPageByAddress;
 * - PutMapperPageByAddress;
 * - AllocMapperSegment;
 * - FreeMapperSegment;
 *
 * CopyLeft (c) since 1995 by PopolonY2k.
 *)

(**
  *
  * $Id$
  * $Author$
  * $Date$
  * $Revision$
  * $HeadURL$
  *)

{-----------------------------------------------------------------------------}
{                      PopolonY2k Framework dependencies                      }
{-----------------------------------------------------------------------------}

{$i types.pas}
{$i helpchar.pas}
{$i msxbios.pas}
{$i extbio.pas}
{$i maprbase.pas}
{$i maprallc.pas}
{$i maprpage.pas}

{-----------------------------------------------------------------------------}
{                             Module definitions                              }
{-----------------------------------------------------------------------------}

Type TMappedBuffer = Array[0..ctMaxMapperPageSize] Of Char; { Mapped 16K bufr }


{-----------------------------------------------------------------------------}
{                              Helper functions                               }
{-----------------------------------------------------------------------------}

(**
  * Print part of a buffer content passed as reference.
  * @param aBuffer Reference to buffer to be printed;
  *)
Procedure PrintBuffer( Var aBuffer : TMappedBuffer );
Const
       __ctMaxCol   : Byte = 10;

Var
       x, y  : Byte;

Begin
  For y := 0 To __ctMaxCol Do
    For x := 0 To __ctMaxCol Do
    Begin
      GotoXY( ( x + 1 ), ( y + 1 ) );
      Write( aBuffer[( x + y ) * __ctMaxCol] );
    End;

  WriteLn;
  WriteLn( 'Press <enter> to continue' );
  ReadLn;
  ClrScr;
End;

{-----------------------------------------------------------------------------}
{                    Main program variables and constants                     }
{-----------------------------------------------------------------------------}

Const
           ctDefaultPage  = $8000;     { Default page for data - Page 2 }

Var
      maprHandle       : TMapperHandle;
      chKey            : Char;
      nActiveSegmentId : Byte;
      aSegments        : Array[0..1] Of Byte;
      aDataBuffer      : TMappedBuffer Absolute ctDefaultPage;


{-----------------------------------------------------------------------------}
{                          Main program entry point                           }
{-----------------------------------------------------------------------------}

Begin    { Main program entry }
  ClrScr;

  { Initialize mapper system }
  If( Not InitMapper( maprHandle ) )  Then
  Begin
    WriteLn( 'Error to initialize Mapper' );
    Exit;
  End;

  WriteLn( 'Mapper succesfully initialized' );

  { Get the current segment used by data buffer on stack }
  aSegments[0] := GetMapperPageByAddress( maprHandle, Addr( aDataBuffer ) );

  WriteLn( 'Main Segment -> ', aSegments[0], ' on page 2' );
  WriteLn( 'Press <enter> to see it''s content' );
  ReadLn;
  ClrScr;

  { Fill page 2 on Main Segment, fully with X character }
  FillChar( aDataBuffer, SizeOf( aDataBuffer ), 'X' );
  PrintBuffer( aDataBuffer );

  { Alloc new segment to put data (MSXDOS2 BIOS) }
  If( Not AllocMapperSegment( maprHandle,
                              maprHandle.nPriMapperSlot,
                              UserSegment, aSegments[1] ) )  Then
  Begin
    WriteLn( 'Mapper segment allocation failed' );
    Exit;
  End;

  WriteLn( 'New Segment -> ', aSegments[1], ' successfully allocated' );
  WriteLn( 'Type <enter> to see it''s content' );
  ReadLn;
  ClrScr;

  { Activate page 2 content to the New Segment allocated }
  PutMapperPageByAddress( maprHandle, aSegments[1], Addr( aDataBuffer ) );

  { Fill page 2 on New Segment fully with Y character }
  FillChar( aDataBuffer, SizeOf( aDataBuffer ), 'Y' );

  PrintBuffer( aDataBuffer );

  nActiveSegmentId := aSegments[1];

  { Handle user switch segment contents }
  Repeat
    GotoXY( 1, 19 );
    WriteLn( 'Active Segment -> ', nActiveSegmentId );
    WriteLn;
    WriteLn( '0 - Switch to Main Segment ', aSegments[0] );
    WriteLn( '1 - Switch to New Segment  ', aSegments[1] );
    WriteLn( 'ESC - exit' );
    chKey := ReadKey;

    If( chKey In ['0', '1'] ) Then
    Begin
      nActiveSegmentId := aSegments[Byte( chKey ) - Byte( '0' )];

      { Activate page 2 content to segment chosen by user }
      PutMapperPageByAddress( maprHandle,
                              nActiveSegmentId,
                              Addr( aDataBuffer ) );

      { Show segment content }
      PrintBuffer( aDataBuffer );
    End;
  Until( chKey = #27 );

  WriteLn;

  { Release all segments allocated by the application }
  If( Not FreeMapperSegment( maprHandle,
                             maprHandle.nPriMapperSlot,
                             aSegments[1] ) ) Then
  Begin
    WriteLn( 'SegmentId -> ', aSegments[1], ' deallocation failed' );
    Exit;
  End;

  WriteLn( 'All segments successfully deallocated' );
End.

Em tempo, Ricardo Jurczyk Pinheiro desenvolveu um excelente e mais completo exemplo que faz uso das rotinas de mapper do framework de maneira mais completa, explorando inclusive outras funções de suporte a mapper do framework.

Seu exemplo pode ser visto no link abaixo:

https://github.com/ricardojpinheiro/test/blob/master/mappdemo.pas

Enjoy coding 🙂

Referências

Print Friendly, PDF & Email

Yamaha YM2151

Yamaha é uma conhecida e antiga companhia japonesa, com mais de 100 anos, cuja área de atuação vai desde a fabricação de motocicletas até equipamentos eletrônicos, mais notavelmente equipamentos musicais eletrônicos e não eletrônicos, sendo esse último segmento o que mais traz o reconhecimento da marca pelo público em geral.

Assim como a maioria das empresas japonesas, a Yamaha expandiu seus horizontes para além das fronteiras orientais entre os anos 60 e 70 onde adquiriu expertise suficiente para que enfim nos anos 80 conseguisse o reconhecimento da indústria e demais profissionais da musica, através de seus aclamados sintetizadores da série DX mais notavelmente o DX-7, usado por diversas bandas, como A-Ha, Whitney Houston, Phil Collins, dentre outros.

DX Series tribute

DX7 – classic logo

FM synthesis everywhere

A década de 80 foram os anos de ouro dos teclados e sintetizadores baseados em síntese FM, ou sintese de frequência modulada.

O que se conhecia de aplicação relativa a Frequência Modulada (FM), até o fim dos anos 60, estava relacionado a transmissões de rádio, sendo essa a aplicação a mais conhecida até os dias atuais sendo amplamente difundida através das rádios FM espalhadas pelo planeta.

No final dos anos 60, o professor, compositor e músico, John M. Chowning, descobriu e desenvolveu na Universidade de Stanford, o algorítmo de síntese baseado em Frequência Modulada (FM), tendo essa técnica sido patenteada por John e a Universidade de Stanford e posteriormente licenciada em 1974 para a Yamaha que no mesmo ano fez seu primeiro protótipo de um sintetizador baseado em FM.

Entretanto um sintetizador FM comercial da Yamaha, de fato só apareceu no mercado em 1980 através daquele que se tornou o primeiro produto comercial da empresa com sintetização FM, o Yamaha GS-1.

Um dos grandes diferenciais dos sintetizadores FM era justamente a sua capacidade de ser controlado “programáticamente”, algo até então impensável para os sintetizadores analógicos como os dominantes Moog da época.

O próprio GS-1 tinha um mecanismo rudimentar de carga e armazenamento de programas que poderiam modificar as “vozes” do sintetizador, o que era feito através cartões magnéticos desenvolvidos especificamente para esse sintetizador.

Tal técnica me levou a “fazer uma engenharia reversa mental aqui” e a concluir que tal mecanismo não é nada mais do que um leitor de fita magnética bem mais limitado, porém nos mesmos moldes conceituais dos utilizados nos micro computadores da década de 70 e 80, para ler e armazenar programas em uma era pré-dispositivo de armazenamento em massa (aka disquetes de 360 Kb e 720 Kb).

GS1 demo (GS1 voice library)

The Yamaha YM2151

O YM2151 é o primeiro sintetizador FM auto-contido em um único chip que não necessita de chips e circuitos adicionais para realizar uma sintetização de som FM e cuja aplicação inicial era para uso embarcado em teclados Yamaha, como o DX21 e o DX100.

Além disso o YM2151 também foi bastante usado em máquinas de arcade da Atari, Konami, Capcom e Namco e em computadores da linha MSX através de modelos da própria Yamaha, CX5M e também através das expansões SFG-01 e SFG-05 feitas pela própria Yamaha para computadores da linha MSX.

Além de teclados e computadores fabricados pela própria Yamaha, um outro dispositivo conhecido por embarcar um YM2151 internamente é o módulo MIDI FB-01, também da própria Yamaha.

Vampire Killer on Yamaha FB-01

O FB-01 é um módulo MIDI de baixo custo, portanto sem muitas features para edição de “vozes” e quaisquer controles adicionais, sendo possível fazê-lo através de editores de MIDI como Unisyn e talvez até o meu preferido Aria Maestosa (o mesmo usado no vídeo acima).

YM2151 meets MSX

Conforme descrito anteriormente, a própria Yamaha participou do consórcio MSX com os seus modelos CX5M e também com seus módulos externos SFG-01 e SFG-05, esses dois últimos também integrados aos CX5M via slot de expansão dessas máquinas.

A diferença entre a SFG-01 e a SFG-05 fica por conta do software embarcado em ROM desses módulos que são bem diferentes e também pelo fato do SFG-01 não poder receber comandos de entrada via porta MIDI, com isso esse módulo não pode ser conectado a um teclado via porta MIDI padrão, ficando restrito apenas à porta proprietária do módulo, compatível apenas com alguns teclados da Yamaha feitos exclusivamente para uso nesse módulo.

Já o SFG-05, além de melhorias no software embarcado em ROM, pode se conectar com qualquer dispositivo MIDI via porta de entrada padrão MIDI (IN) e receber comandos MIDI, possibilitando assim a integração do SFG-05 com qualquer dispositivo compatível com MIDI existente no mercado.

Lara plays, playlist (CX5M/SFG-05)

Além das diferenças descritas acima, os módulos SFG-05 receberam o chip YM2164 ao invés do YM2151, sendo ambos são compatíveis com pequenas diferenças, apenas na mudança dos registradores de teste e reset do operador de baixa frequência (Low Frequence Operator ou simplesmente LFO) e também no Timer B que teve sua resolução de tempo duplicada, de 1024 ciclos no YM2151 para 2048 ciclos no YM2164.

Apesar da diferença nos chips ser pequena e bem sutil, a parte de software pode sim ser influenciada a ponto de gerar incompatibilidade ou até mesmo um funcionamento indesejado, entretanto como a ROM BIOS desses módulos também foram mudadas, a própria Yamaha se encarregou de deixar as coisas funcionais, considerando o seu software sequenciador interno em ROM que, diga-se de passagem, no SFG-05 foi bastante modificado principalmente na parte da interface com o usuário.

Ainda no MSX, temos pelo menos dois programas reconhecidos por fazer uso do YM2151/YM2164. Um deles é o VGMPlay e o outro é o Pop!Art VGM Player, ambos tocadores de músicas no formato VGM, que é um formato que possibilita a reprodução de musicas de vídeo games nos mais variados chips de som suportados pelo formato, incluindo o próprio YM2151/YM2164.

Pop!Art first preview playing on SFG-05 card

YM2151 today

Atualmente chips com capacidade de sintetização FM, como o YM2151, devem estar cada vez mais restritos a nichos de música, uma vez que mesmo os vídeo games modernos tem uma capacidade fenomenal de processamento e com isso terminaram por abolir o uso desses chips como parte central de sua capacidade multimídia nesses consoles.

Com isso é bastante comum que a indústria de video-games se utilize cada vez mais de orquestras e sons gravados analogicamente, o que possibilita a convergência dos chips de som desses consoles para circuitos DACs de alta resolução.

Entretanto apesar de seu uso estar cada vez menor pelo mainstream, chips como o YM2151 encontraram um ótimo nicho no universo DIY (Do It Yourself), também conhecido como maker.

YM2151 Arcade Classic VGM Player (hardware)

Assim o “espírito da sintetização FM” deve permanecer preservado e garantido para as futuras gerações.

Resta apenas saber se empresas como a Yamaha continuarão fabricando chips como o YM2151, YM2164 e YM2413, futuramente….esperamos que sim 🙂

[]’s
PopolonY2k

Print Friendly, PDF & Email

Do It Yourself (ou não)

Há algum tempo tenho feito alguns “experimentos” no meu canal do YouTube, afim de aprimorar também essa plataforma para que se torne um complemento desse blog.

Algumas lives sobre programação e principalmente, alguns mini projetos relacionados ao MSX e computação em geral, tem sido feitos nesse interim, como a live onde demonstrei o código da engine 3D portado a partir do vídeo e código apresentados em “Code it yourself – First person shooter” do excelente canal do Javidx9.

Pop!Live Stream Code It yourself-First person shooter on MSX-TR (Quick and simple Turbo Pascal 3.3F)
Pop! Live Stream – Code It yourself – First person shooter (Quick and simple Free Pascal)

Hoje finalmente liberei mais um formato, que acredito ainda precisar de aprimoramentos de maneira geral.

É o quadro “Faça você mesmo (ou não)”, para isso já até criei a playlist só para facilitar a busca nos vídeos dessa série em meu canal.

Entretanto podemos dizer que esse formato ainda é WIP (Work In Progress) e que estaremos ajustando nos próximos vídeos.

Toda sugestão é bem vinda.

MSX 1.1 Expert XP800 Capacitor Recap e CPU upgrade (Z80 6Mhz)

[]’s
PopolonY2k

Print Friendly, PDF & Email

Super Laydock Mission Striker

Um dos melhores jogos de shoot ’em up já feitos para o MSX pela lendária T&E Soft e apesar da limitação do MSX1, os desenvolvedores da T&E Soft conseguiram, nesse jogo, trazer a mesma experiência dos arcades para o computador, na época.

Super Laydock Mission Striker

O jogo foi um sucesso e transformou uma empresa de 2 irmãos, Toshiro e Eiji Yokoyama (daí o nome T&E), cujo headquarter diz a lenda era seu quarto, em um dos maiores estúdios de games da década de 80, rivalizando com gigantes como a Konami, Sega e Taito.

Esse sucesso inicial colocou a T&E Soft na mira dos grandes produtores de hardware a ponto de bem antes do lançamento do MSX2 pela ASCII Corp Japan, a T&E Soft receber atualizações de BIOS diárias da nova máquina que estava por ser lançada, pois a ASCII tinha grande interesse que empresas como a T&E Soft lançassem jogos e softwares exclusivos para o seu novo MSX2.

Assim começou o desenvolvimento de Laydock, uma continuação de Super Laydock só que para MSX2. Entretanto a cada mudança de BIOS recebida, o jogo quebrava dificultando a conclusão de seu desenvolvimento no prazo.

Laydock

No final da história, Laydock não conseguiu superar Super Laydock, apesar do hardware e capacidade gráficas superiores do MSX2 frente ao MSX1.

PopolonY2k

Print Friendly, PDF & Email

Nemesis Lonestar – 8080-Z80 ASM

A cada ano centenas, milhares ou até milhões de páginas na internet são criadas, removidas, atualizadas ou abandonadas até que sejam naturalmente esquecidas, dependendo apenas dos snapshots providenciados pela Wayback Machine da Internet Archive.

Com isso muito material é agregado ao ecossistema da web e também muitos deles são perdidos para sempre, que para mim é um ciclo natural na rede.

Entretanto muita informação jamais deveria desaparecer da internet, principalmente aquelas sobre tecnologias antigas que na maioria das vezes nos mostram a criatividade e as técnicas utilizadas no passado pelos pioneiros da tecnologia.

Infelizmente o site MSX Info Pages do Hans Otten, fechou as portas no dia 02 de abril de 2019 e com isso perdemos muito material importante não só para a comunidade de MSX, bem como para a comunidade de retrocomputação em geral, uma vez que o mesmo continha muita informação técnica agregada em uma única fonte.

É nesse contexto que apresento àqueles que não conheciam, o site Nemesis Lonestar que costumava estar nesse link aqui, mas que agora infelizmente está quebrado desde o dia 16 de janeiro de 2019, segundo o último snapshot gerado pelo Internet Archive.

O Nemesis Lonestar tinha muita informação técnica principalmente sobre programação Z80, dentre as quais uma tabela muito bem feita contendo todo o Instruction Set dos processadores 8080-Z80, muito bem organizado em colunas e que podia ser encontrado aqui nesse link que também deve estar quebrado.

Toda vez que eu programava em ASM e procurava por uma referência rápida do Z80, eu consultava essa página que está nos meus favoritos até agora, apesar de não mais existir no endereço original.

Felizmente temos a WayBack Machine, que pode ser sempre consultada para se obter o último snapshot dessa página que contém essa tabela de mnemônicos do Z80, entretanto apesar da Internet Archive manter esse snapshot, tomei a liberdade de baixá-lo (apenas dessa tabela de mnemônicos do Z80) e criar uma seção em meu blog para futuras consultas a quem interessar e também para agregar, gradativamente, ao material de referência de ASM e Z80 no blog.

Apesar de todas as mensagens de Copyright (c) do autor original da página e principalmente do mesmo citar que é expressamente proibida a reprodução de qualquer material do Nemesis Lonestar, acredito que a essa altura do campeonato ele não irá reclamar essa página, ou se reclamar no futuro, aí conversamos e tentamos resolver, mas no momento eu quero é ajudar na manutenção desse conteúdo.

Por isso deixo abaixo o endereço dessa tabela do instruction set do 8080-Z80, que costumava estar no site do Nemesis Lonestar mas que agora pode ser consultado aqui no meu blog nos endereços abaixo:

HTML version
http://popolony2k.com.br/xtras/programming/asm/nemesis-lonestar/8080-z80-instruction-set.html

Text version
http://popolony2k.com.br/xtras/programming/asm/nemesis-lonestar/opcodes.txt

[]’s
PopolonY2k


Print Friendly, PDF & Email