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

Pop!Dev – Primeiro concurso de desenvolvimento de software para MSX (MegaRAM edition)

Memória de computador, um recurso tão infinito atualmente que a maioria das pessoas mais novas e mesmo os mais antigos não sabem ou se esqueceram que no passado esse recurso era algo precioso ou até mesmo inexistente devido a tecnologia pouco desenvolvida da época. Me lembro que em meados dos anos 80 os micros pessoais ou tinham 64Kb de RAM, exatamente o caso dos micros de 8Bits como o MSX, ou tinham de 512Kb a 640Kb por default, sendo esse o caso dos micros da linha IBM-PC.

Para piorar um pouco mais as coisas, aqui no Brasil vivíamos a famigerada reserva de mercado que nos impedia de ter acesso às mesmas tecnologias top de mercado existentes em outros países na época. Independente disso eu particularmente acredito que quando o ser humano enfrenta adversidades devido a alguma limitação física ou técnica, ele termina desenvolvendo soluções criativas para burlar tais limitações.

Enquanto isso no Japão.

O MSX ia de vento em popa no Japão e em diversos países da Europa e até por conta disso o consórcio MSX, capitaneado pela ASCII japonesa, decidiu aperfeiçoar o padrão a partir dos MSX2, o que possibilitou softwares mais complexos e que exploravam melhor a capacidade do padrão através do uso de mais memória nessas máquinas. Foi assim que nasceu a expansão de memória padrão do MSX, denominada Memory Mapper, solução essa que envolve padronização da camada física e lógica para ser ter acesso a mais memória nos micros do padrão.

MSX Memory Mapper
MSX Memory Mapper cartridge

Enquanto isso no Brasil

No Brasil estávamos muito distantes do resto do mundo em todos os quesitos tecnológicos não importando se o padrão era o IBM-PC, Amiga ou MSX. O fato é que precisávamos manter o mercado nacional aquecido de alguma forma, mesmo que acompanhando o mercado internacional utilizando soluções independentes e desenvolvendo assim um “padrão próprio”.

Nesse cenário em meados dos anos 80 um famoso projetista de periféricos de MSX, na época, desenvolveu um dispositivo de memória denominado MegaRAM e que poderia estender os míseros 64Kb do MSX para 256Kb, 512Kb e 768Kb, sendo esses os modelos mais comuns de MegaRAM naquela época. O nome desse projetista é Ademir Carchano, que é membro ativo da comunidade MSX nacional até os dias de hoje, onde lança constantemente diversos produtos relacionados ao universo MSX, sob o selo ACVS.

MegaRAM ACVS
MegaRAM ACVS

A criação da MegaRAM possibilitou que diversos usuários brasileiros tivessem acesso a jogos incríveis, lançados no Japão, que utilizavam mais do que 64Kb, só que armazenados em ROM e conhecidos lá fora como MegaROM.

Aleste é um dos games MegaROM, portados para MegaRAM.
Aleste é um dos games MegaROM, portados para MegaRAM.

MSX Today

Hoje o cenário de desenvolvimento de novos hardwares e softwares para MSX no Brasil está bem aquecido, como há anos não se via. Atualmente contamos com a fabricação de dispositivos IDE, incluindo a IDE com Memory Mapper, novos kits que convertem um MSX comum para MSX2+, como é o caso do M5X e também novos games como o Flappy Bird para MSX e music players como o Pop!Art.

Flappy Bird for MSX
Flappy Bird for MSX

Mas independente dos novos lançamentos, sempre há quem busque alguns antigos e consolidados dispositivos como é o caso da MegaRAM. Ainda mais depois do anuncio da nova MegaRAM de 2MB feito pelo próprio Ademir Carchano, na comunidade MSX Brasil no FaceBook.

Incentivo aos produtores nacionais.

Logo que recebi a notícia da nova MegaRAM de 2MB fiquei entusiasmado principalmente pelo fato de contarmos com um espaço de 2MB para futuras aplicações que assim desejarem usar essa área “infinita”  de memória. O meu primeiro impulso foi adquirir a minha MegaRAM de 2MB, mas como eu já estava com a mão na massa e também como já havia citado no grupo GDMSX do FaceBook e G+ sobre um possível concurso de desenvolvimento de software para retro-máquinas, decidi então patrocinar o primeiro concurso do grupo GDMSX e do meu blog, adquirindo uma MegaRAM 2MB que será entregue ao futuro vencedor da competição.

O concurso

Bom, definido o prêmio vamos ao nome do concurso e às regras do mesmo, e entrando na onda Pop!*, nomeei o concurso como Pop!Dev :). Quanto às regras, elas serão breves, simples, diretas e sem muita burocracia 🙂

Objetivo

Primeiro, o grande objetivo desse concurso é fomentar o desenvolvimento de software para a plataforma MSX, sendo assim só serão válidos softwares desenvolvidos para essa plataforma, não importando o modelo utilizado, seja MSX1, MSX2, MSX2+ ou MSX TurboR.

Outra questão principal é referente ao uso da MegaRAM, sendo que os softwares inscritos na competição deverão ser compatíveis com a MegaRAM, independente do modelo (256Kb, 512Kb, 768Kb ou 2MB) e fabricante, pois o intuito dessa competição é justamente fomentar o desenvolvimento e a troca de conhecimento sobre a MegaRAM, lembrando apenas que se alguém fizer algo que utilize uma MegaRAM de maior capacidade, esse terá uma vantagem sobre os demais competidores, pois quanto maior a capacidade de memória utilizado por um software, geralmente mais complexo ele tende a ser.

Com base nessas premissas, vamos às regras.

As regras

  1. O software participante deverá ser compatível com MSX, independente do modelo escolhido (MSX1, MSX2, MSX2+ ou TurboR).
  2. O software participante deverá ser compatível com a tecnologia MegaRAM, sendo independente de fabricante e modelo (256Kb,512Kb, 768Kb ou 2MB).
  3. Apenas participantes do grupo GDMSX, tanto do FaceBook quanto do G+ poderão participar da competição, portanto, se você quiser participar da competição entre em uma das comunidades do GDMSX (FaceBook ou G+) para que possa apresentar seu projeto e estar apto a participar da competição.
  4. Seu projeto deverá ser original, ou seja, ser de sua autoria. Não serão aceitos ports com base no código fonte ou binários de programas ou jogos feitos para outras plataformas, por outras pessoas/empresas, tendo sido apenas modificados por você. O software deve ser desenvolvido e concebido inteiramente por você. Claro que você pode utilizar técnicas concebidas por outras pessoas, mas o código deve ser implementado por você.
  5. O software poderá ser feito por um grupo de mais de uma pessoa, entretanto se os desenvolvedores optarem por fazer dessa forma, deverão marcar seus nomes no momento da apresentação do projeto no post em uma das comunidades do GDMSX.
  6. O código fonte deverá ser aberto e liberado por alguma licença open source, seja alguma GNU (como GPL), Creative Commons ou BSD, afinal o intuito do concurso é a troca de informações e experiências.
  7. O participante poderá inscrever mais de um software na competição.
  8. Os membros da comissão julgadora não poderão participar da competição.

 Votação

Vou escolher alguns membros do GDMSX que não estiverem participando da competição para formar a comissão julgadora e essa comissão será apresentada no decorrer do desenvolvimento do concurso. Quanto a parte técnica, o que mais contará pontos nesse concurso está relacionado a melhor arquitetura de software e solução desenvolvida. Mas o que isso quer dizer ?

Bem vou enumerar abaixo os itens mais relevantes.

  1. Software mais bem modularizado. Isso é importantíssimo para reuso futuro por outros membros da comunidade em outros projetos.
  2. Software mais bem documentado. Importante pelo mesmo motivo acima citado.
  3. Software que utilize MegaRAM de maior capacidade terá pontuação maior, ou seja, um software que utilize 512Kb terá maior peso sobre um feito para rodar com uma MegaRAM de 256Kb, no caso de um empate técnico.
  4. Qualidade “profissional” do software. Isso envolve interface com o usuário e usabilidade. Softwares com aparência mais profissional serão mais bem avaliados e pontuados. Isso não quer dizer que softwares gráficos serão mais bem avaliados do que softwares em texto, uma vez que existem softwares em modo texto que tem um visual “estupidamente” profissional, as vezes mais profissionais do que softwares em modo gráfico. Mas não adianta ser bonito e tecnicamente pobre pois em nosso concurso o “tecnicamente bom/ótimo” supera um que tenha apenas a interface com o usuário bonita, entretanto se o software for ótimo nos dois quesitos, teremos um campeão. 🙂

Duração do concurso.

A duração do concurso será de 6 meses a partir da publicação desse post, ou seja, 25 de Abril de 2015 o concurso será finalizado e entrará em fase de avaliação dos projetos participantes. No mês seguinte deverá ser anunciado o vencedor, tanto aqui no blog quanto nas comunidades do GDMSX no FaceBook e G+.

O que poderá ser desenvolvido

Tudo o que você quiser, desde jogos, utilitários de disco, editores gráficos, editores musicais, music players, demos, enfim, a sua imaginação é o limite. 🙂

Em que linguagem posso desenvolver.

Qualquer uma, desde ASM, C, Turbo Pascal, MUMPS, ADA, Prolog, ou seja, qualquer uma que você domine.

Premiação

O vencedor do concurso será premiado com uma MegaRAM 2MB da ACVS.

Conclusão

Esse é o primeiro de muitos concursos que estarei organizando, via blog e GDMSX e espero que consigamos desenvolver muita coisa legal para a plataforma MSX. Futuramente vou buscar patrocínios de fabricantes nacionais e talvez até internacionais que atuam no cenário MSX, mas esse primeiro é 100% patrocinado pelo Blog PopolonY2k e comunidades GDMSX.

Divirtam-se.

[]’s
PopolonY2k

Referências na internet

Memória RAM (Wikipedia)
http://en.wikipedia.org/wiki/Random-access_memory

Default (Wikipedia)
http://en.wikipedia.org/wiki/Default_%28computer_science%29

Reserva de Mercado (Wikipedia)
http://pt.wikipedia.org/wiki/Reserva_de_mercado

ASCII Entertainment
http://www.ign.com/companies/ascii-entertainment

Memory Mapper (Blog MSX All)
http://blog.msxall.com/2011/01/memory-mapper.html

ACVS (Ademir Carchano)
http://www.carchano.com.br/loja/

MegaRAM (Marcelo Eiras blog)
http://www.marceloeiras.com.br/msxsite/msxmega.htm

MegaROM (BiFi website)
http://bifi.msxnet.org/msxnet/tech/megaroms.html

M5X (OptoTech)
http://optotech.net.br/fzanoto/m5x.htm

Dissecando o Flappy Bird (Retrocomputaria blog)
http://www.retrocomputaria.com.br/plus/?p=8843

Pop!Art – Music Player (Retrocomputaria blog)
http://www.retrocomputaria.com.br/plus/?p=8015

MegaRAM 2MB (ACVS website)
http://www.carchano.com.br/loja/produtos_descricao.asp?lang=pt_BR&codigo_produto=43

MSX Brasil (FaceBook)
https://www.facebook.com/groups/182223775136806/

GDMSX (FaceBook)
https://www.facebook.com/groups/gdmsx/

GDMSX (G+)
https://plus.google.com/u/0/communities/105926991534247611226

GPL (Wikipedia)
http://en.wikipedia.org/wiki/GNU_General_Public_License

Creative Commons (Wikipedia)
http://en.wikipedia.org/wiki/Creative_Commons

BSD Licenses (Wikipedia)
http://en.wikipedia.org/wiki/BSD_licenses

ASM language (Wikipedia)
http://en.wikipedia.org/wiki/Assembly_language

C language (Wikipedia)
http://en.wikipedia.org/wiki/C_%28programming_language%29

Turbo Pascal (Wikipedia)
http://en.wikipedia.org/wiki/Turbo_Pascal

MUMPS (Wikipedia)
http://en.wikipedia.org/wiki/MUMPS

ADA language (Wikipedia)
http://en.wikipedia.org/wiki/Ada_%28programming_language%29

Prolog language (Wikipedia)
http://en.wikipedia.org/wiki/Prolog