Pop!Art VGM Player for MSX

Is known by the brazilian MSX community about the development of Pop!Art VGM player that I’m working on since middle 2014.

Some practical results about Pop!Art were reported in 2014 by one of the most important retrocomputing blogs in Brazil, the Retrocomputaria+ blog and by the biggest brazilian MSX community on FaceBook, the MSX Brasil Oficial.

Pop!Art VGM player already supports all existing chips on the MSX platform, like Konami SCC (K051649), PSG (AY8910), FM (YM2413), SFG01/05(YM2151), OPL3/OPL4 and the Philips Music Module (Y8950).

Note: Some months after I presented some Pop!Art results, another excellent VGM Player (VGMPLAY by Grauw) was released.

My first motivation to start this development was only for fun and also to start learning about how sound chips works. The second motivation was to start a big project in chiptune’s scene.

In fact to get information about these old chips was the biggest challenge because some of them just can be found on manufacturer’s data-sheet that sometimes are poorly written and with a small percentage of useful information.

In most cases these datasheet information are confused so the best alternative to these poor data-sheets are the Linux sound cards drivers source code.
After reading these drivers source code, I got some specific details about how several of these chips really work.

Custom chips like Konami SCC don’t have any data-sheets but fortunately are well documented by the international MSX community and sources like BiFi’s website were my main information source.

Another big source of information for MSX developers in general is the MSX Assembly Pages (brought by the same author of VGMPLAY, Grauw) that in my opinion is the best source of information for developers who want to make useful and cool things for MSX computers.

Presenting Pop!Art

Pop!Art is an original software made using Turbo Pascal 3, almost 97% of it’s code is written in Pascal, with some parts written in Z80 ASM. If you want to compile it’s source code and modify it, feel free because the source code was released under GPLv3 and can be reached at OldSkoolTech SVN’s repositories on SourceForge.net.

It is compatible with Borland Turbo Pascal 3.0 (CP/M80-MSXDOS), Turbo Pascal 3.3f from MSX Club Enschede, (MSXDOS 1 & 2), and it also can be ported to others newer Pascal compilers, like FreePascal (Lazarus) and maybe newer versions of Delphi compiler.

The source code is fully commented and several parts of Pop!Art software were incorporated to the framework that I’m developing since I had started the development of the MSXDUMP in 1995 (best known as PopolonY2k Framework).

This framework can deal with several technologies present on MSX architecture, like IDE device handling, MSXDOS and MSXBIOS function calls and direct console handling.

Pop!Art introduces some important features in the framework, like support to Z80 interrupts, all MSX sound chips handling (K051649 aka SCC, YM2413 aka FM, YM2151 aka SFG01/05, OPL3/OPL4, Y8950 aka Philips Music Module, AY8910 aka PSG) and a better and accurate “wait” routines that can deal with resolutions below 50Hz or 60Hz, fixing time errors caused by songs with “tempo” below these resolutions (50Hz or 60Hz), that minimizes any standard deviation.

The current Pop!Art engine also supports all existing chips for the MSX platform and in future, newer chips supported by the VGM format similar to any existing on MSX platform will be added to the Pop!Art engine.

The VGM file format

VGM, aka Video Game Music, is a logging format based on GYM format which is another video game format used specifically to store Sega Mega Drive (Genesis) songs, but contrary to GYM, the VGM format can be used with several other chips different to Mega Drive sound chip. The first version of VGM was released in 2005 and after this release, six new format specifications were released until the current 1.70.

Another curiosity about VGM is that the format was very popular with Winamp users because this music player was the first player capable of playing VGM songs through a plugin specially created for it.

GD3 tag format

The VGM format has a GD3 metadata present in file header specification. The GD3 format is the same format used by MP3 files to store several tracks information, like author, song name and so on.

Pop!Art VGM Support

Pop!Art supports all VGM version’s format, since 1.0 to 1.70 and the GD3 tag format is partially implemented in Pop!Art engine but will be finished in future releases.

The VGM format contains all data samples sent to the sound chips using a speed rate of 41,000 samples per second, so your library must be very fast and precise to deal with VGM files in an accurate way and basically just assembly codes can reach this performance using all of the chip’s power….right ???

Hummm…..maybe not.

Turbo Pascal

I’m really thinking to start writing code to MSX using modern compilers, like SDCC C compiler, which is known to be one of the most powerful and optimized compilers for small devices, but I have written a lot of code to the old Turbo Pascal 3 for CP-M80/MSX for years and my framework has increased a lot its capabilities to handle several standard devices present in MSX world.

Turbo Pascal

In fact I’m using this good, but not so optimized compiler, to learn about new optimization techniques and about the Turbo Pascal internals. And also how to avoid not optimized coding style when you’re programming for machines with low resources. Maybe in the future I can write a new, modern and optimized Pascal compiler (maybe a cross-compiler) for MSX machines, but this is another dream.

When I started writing this article in 2015, FreePascal compiler was not an alternative because it lacked Z80 binary generation support, but since beginning 2020 FreePascal started supporting Z80 platform.

https://wiki.freepascal.org/Z80

Borland Turbo Pascal 3.0 is an impressive compiler because it is a very fast compiler but unfortunately there are several things that were created to be generic and problem solving in a generic way are known to be slower than a more specialized code generation.

I’m dedicated to improve my framework to be so generic as possible but sometimes I’ll need to be more specific to resolve big performance problems using Turbo Pascal code instead using assembly code.

The small list below can help programmers who are thinking start coding in Turbo Pascal, C and another language different of ASM.

1) In Pascal avoid nested functions – This kind of structured feature is not optimized in Turbo Pascal 3;

2) In any high level language with floating point builtin data types support, like Pascal and C, try to avoid real time processing using these floating point types (float/double in C and Real in Pascal).
These data types can deal with an “excellent” precision but is known that when you have, or want, an “excellent” precision, the processor will pay the price for this precision, so avoid floating point real time operations if is possible. Sometimes this can be done performing some data pre-processing or using fixed point, instead floating point;

3) Use integer instead floating point data and byte instead of Integer data, depending on numeric range, for the same reason of previous item;

4) Try “think” your application in JUMP TABLES, instead nested IF’s or even switch-case (case-of for Pascal programmers);

5) Read this article before coding http://www.popolony2k.com.br/?p=2402

NOTE ABOUT THE 5th ITEM: I’m using GOTO in small pieces of code, because old compilers like Turbo Pascal 3 are very antique, so features like “break” and “continue”, widely used in loop iterations, can be “simulated” by using GOTO.

PopolonY2k framework

As I wrote at the beginning of this text that I’m working on a framework fully written in Turbo Pascal, with some parts in ASM, since I released the MSX DUMP (part of MSX Disk Doctor suite). I thought that this framework was optimized but I was completely wrong, because there’s no framework or any other piece of code which the performance can be measured when discs and slow devices are used by these codes.

So when I tested this framework using my MSX Turbo R machine, everything seemed to be 100% ok and fast, but when I tested the same code on a MSX, running a slower Z80 processor, some problems started to be more visible, then fixing these problems and keep everything working fast using a Z80 in the same way like a R800 processor is a hard work.

This framework was started 20 years ago, when I was leaving the university and in those days I just wrote code for old devices like, disk drives and some generic code code to access the MSXBIOS and MSXDOS (1).
When I restarted coding this framework in 2011, I quickly improved it by adding features to access new devices, like Sunrise IDE devices, Network socket API, UNAPI and RS232 support are still WIP (Work in Progress).

Bellow is the list of all features present on this framework

1) FOUNDATION MODULES – New modules to make Turbo Pascal “more compatible” with new Turbo Pascal releases. New features like Big Integer handling;

2) MSX INTERNALS MODULES – MSX related functions and information (e.g. MSX System Variables);

3) BIOS MODULES – MSX BIOS functions by category;

4) MSXDOS (1 & 2) MODULES – MSX DOS functions;

5) SLOT MANAGEMENT – Functions related to slot manipulation;

6) INTERRUPT HANDLING – Functions to enable interrupt vector function handling using Turbo Pascal;

7) COMMUNICATION – Functions related to communication (RS232 (Work in progress), Sockets);

8) COMMUNICATION DRIVERS – Drivers written to support the Sockets implementation above. Support to OPTONET cards;

9) UNAPI FRAMEWORK – Support to UNAPI framework in Turbo Pascal (Work in progress);

10) SOUND CHIP DRIVERS – Drivers for all sound chips found on MSX standard;

11) VGM PLAYER FRAMEWORK – Functions to play songs in VGM format;

12) IDE SUNRISE-LIKE FRAMEWORK – Functions to handle Sunrise-like IDE devices;

13) USER INTERFACE AND OPTIMIZED CONSOLE MODULES – New functions to increase the speed of console applications and to handle user interface;

14) UNIT TEST FRAMEWORKPopolonY2k TEST SUITE (PTEST) – Functions providing UNIT tests capabilities for Turbo Pascal 3 projects (widely used in the Big Integer implementation);

An updated framework features list can be reached here.

Pop!Art features list

  1. VGM file support (1.0 up to 1.70 – some commands are still disabled. eg. non MSX existing chip commands);
  2. Memory Mapper support (VGM files longer than 64Kb can be loaded and played);
  3. MSXDOS2 only support (sub-directories access). Maybe MSXDOS1 will be supported in future releases;
  4. AY8910 support;
  5. YM2413 support;
  6. YM2151 (SFG 01/05) support;
  7. Y8950 (Philips Music Module) support;
  8. YMF278 (OPL4) support;
  9. K051649 (SCC) support;

Known Pop!Art missing features in this release (0.0).

  1. VGZ file support (in fact is VGM inside a .tar.gz file);
  2. MSXDOS1 support;

Pop!Art memory layout

The application memory layout is described below:

  1. $0000-$3FFF – MSXDOS CP/M-80 + Turbo Pascal runtime workspace;
  2. $4000-$7FFF – Application object code;
  3. $8000-$BFFF – VGM Song data (16Kb memory mapped paged system);
  4. $C000-$FFFF – Unused;

Pop!Art in action

After writing a long story and mainly a lot of technical stuff, it is time to play some song using Pop!Art finally after 5 years 🙂

Check the video below where I explain technical details about how Pop!Art works internally.

Pop!Art in action (portuguese video only)

Downloading Pop!Art

Pop!Art binaries can be downloaded here, https://sourceforge.net/projects/oldskooltech/files/MSX/Pop%21Art/

Enter the version directory you want (e.g v0.0, etc) and download a preferred compressed file (pop_art_v_?_?.zip or pop_art_v_?_?.lhz).

After downloading and decompressing the chosen file, popvgm.com and popplay.chn files will be extracted, put them together in the same directory and then execute popvgm.com.

These files are the two main modules of Pop!Art described below.

  • popvgm.com is the VGM loader;
  • popplay.chn is the VGM player itself.

Hidden gems

Unfortunately all Turbo Pascal 3.x for MSX, both Borland and MSX Club Enschede, are too old products and are both an one pass compiler, so generated binaries are not so optimized as newer compilers like Free Pascal compiler.

Borland did an excellent work when decided create a powerful runtime not just placing the biggest part of standard library there but all comparison test routines are placed there too.

Using this model, the amount of binary code generated by the compiler was decreased considerably but on the other hand they sacrificed performance with this strategy.

I realized that all If’s in the main Pop!Art streaming routine was jumping to the respectives runtime routines and this behavior was decreasing performance a lot, so after a long time think about this problem finally I decided to change the Borland Turbo Pascal 3.0 binary by adding an extra pre-processing compiler directive to generate inline code for all comparison routines and consider Integer (-32768 .. 32767) like Word/Unsigned int (0 .. 65535).

But changing this behavior could turn specific code written to this specific Turbo Pascal version, incompatible with both Borland and MSX Club Enschede, so instead using the standard compiler directive {$ }, I created an extended compiler directive {% } that is considered by Borland and MSX Club Enschede Turbo Pascal as a regular comment but for my modified Turbo Pascal version is an extended compiler directive.

The first extended directive is {%W} and is a scoped directive, so to activate the starting scope the programmer must start with {%W+} and finish the scope with {%W-}.

This will inform the compiler to treat comparison routines as unsigned integer and generating inline code from starting point {%W+} to ending point {%W-}.

Below a small piece of Pop!Art code using this technique:

Procedure __MoveMapper16BitData{( __pSndChipArrayParms : Pointer )};
  Begin
    {%W+}
    If( nCurrentStreamPos < __ctMapperBufferEndAddr ) Then
    {%W-}
    Begin
      __pSndChipArrayParms := Ptr( nCurrentStreamPos );
      nCurrentStreamPos := nCurrentStreamPos + 2;

      (* Direct jump to command processing routine *)
      Inline( $2A/nFnJmpAddr   { LD HL,(nFnJmpAddr) }
              /$E9             { JP (HL)            } );
    End
    Else
    Begin
      __pSndChipArrayParms := Ptr( Addr( aSndBuffer ) );
      aSndBuffer[0] := Mem[nCurrentStreamPos];
      __ExecMapperPaging;
      aSndBuffer[1] := Mem[nCurrentStreamPos];
      nCurrentStreamPos := Succ( nCurrentStreamPos );

      (* Direct jump to command processing routine *)
      Inline( $2A/nFnJmpAddr   { LD HL,(nFnJmpAddr) }
              /$E9             { JP (HL)            } );
    End;
  End;

All comparison structures below are covered by this extended directive:

  • While .. Do
  • Repeat .. Until
  • If… Then … Else

Conclusion

Pop!Art can still be considered a work in progress and soon some extra and useful features will be added to it’s core engine, like:

  • Add support to VGZ (compressed VGM) file format;
  • Chip sound drivers improvement, adding chip specific extra features still not implemented;
  • Core engine speed optimization (improving Turbo Pascal performance);
  • Add full support to VGM 1.70;

So, I hope you enjoy Pop!Art and thanks for reading.

[]’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

Hungarian rapsody

A computação é uma ciência “recente”, que se move quase que na velocidade da luz em comparação com as demais ciências.

Em pouco tempo diversas mudanças ocorrem e tecnologias dominantes são praticamente varridas quase que para baixo do tapete em “segundos”.

É uma área em constante mudança que acontecem desde a concepção da tecnologia em seus mínimos detalhes, mesmo os invisíveis a olho nú, até aqueles estruturais e que abalam o ecossistema todo, ecoando através dos tempos deixando sua marca nos mais diversos meios de comunicação.

Nesse cenário a indústria de desenvolvimento de software moderna tem aprendido muito através do desenvolvimento de novas ferramentas que auxiliam a construção de tecnologias e produtos, entretanto nem sempre existiram IDE’s poderosas capazes de integrar com debuggers e analisadores estáticos, dentre outros ferramentais disponíveis na atualidade.

Borland Turbo C 2.0

No inicio dos anos 90, IDE’s como Turbo Pascal 5.0 e Turbo C 2.0, da Borland, começavam a revolucionar a forma como softwares eram desenvolvidos, com seus debuggers integrados, excelentes editores de código com seus syntax highlighting.

Entretanto nessa época os desenvolvedores, em sua grande maioria, não terceirizavam sua confiança e competência nas IDE’s e na maioria das vezes utilizavam ou desenvolviam técnicas para auxiliar a organização, compreensão e depuração do código.

Charles Simonyi

Nessa mesma época, Charles Simonyi, um jovem engenheiro de software nascido na Hungria e que havia sido recrutado por Bill Gates para trabalhar no desenvolvimento da suite Microsoft Office na Microsoft, começou a popularizar uma técnica que já havia sido criada por ele em seu antigo emprego na Xerox PARC.

Essa técnica consiste em uma notação de código, independente de plataforma e linguagem, que tenta padronizar prefixo de nomes de variáveis de acordo com seus tipos e comportamento, bem como estilo de nomes de funções (se estendendo a classes) de forma a deixar o desenvolvimento uniforme e com um padrão conhecido e documentado, auxiliando a compreensão principalmente em grandes projetos e por pessoas diferentes.

Esse padrão é conhecido como notação húngara (hungarian notation) e foi popularizada pela Microsoft em suas literaturas oficiais, principalmente nos anos 90, sendo ainda um padrão forte dentro da empresa até os dias atuais.

Programming Windows 3.1

Eu mesmo conheci essa notação em 1993, quando adquiri a terceira edição de Programming Windows 3.1, de Charles Petzold – Microsoft Press, esse também um dos melhores escritores de livros técnicos que eu já li (menção honrosa também a Peter Norton), me apresentando assim essa notação.
Me rendendo ao entusiasmo de Petzold, decidi tentar escrever todo software que eu pudesse, utilizando notação hungara para saber se traria algum benefício, não só por isso mas também porque meus softwares começavam a se tornar cada vez maiores e complexos, portanto eu deveria tornar as coisas mais compreensíveis para o EU do futuro.

Apesar de ser alguém, corportivamente falando, com raízes fortíssimas no UNIX, tendo iniciado no XENIX, passado por SCO UNIX, IBM-AIX e Sun Solaris, confesso que era bastante influenciado pelo estilo Microsoft, antes dela se tornar esse elefante branco que é hoje, pois ela era a Google da época e portanto uma forte influenciadora dentre os jovens programadores, algo em proporções muito maiores do que ela mesmo representa nos dias atuais junto aos programadores mais jovens.
Pessoalmente, a Microsoft foi um dos pais do padrão MSX, portanto era “alguém” por quem eu tinha um certo carinho até então e por isso usar uma notação difundida pela Microsoft e não pela galera do UNIX, a qual eu estava mais corporativamente inserido, não foi nada estranho.

Sobre a notação húngara, abaixo vou deixar alguns exemplos retirados desse documento, que é bem simples e direto e que faço questão de deixar aqui em meu site, mas também fazer referência ao link original onde ele originalmente está hospedado aqui e que me pareceu ser uma plataforma de ensino inglesa bem interessante.

[]’s
PopolonY2k

Print Friendly, PDF & Email

Desenvolvendo com OpenMSX

Acredito que toda, ou grande parte da comunidade MSX conheça o excelente emulador OpenMSX, principalmente os usuários de Linux e MacOSX.

Bom, confesso que depois de voltar a ativa no mundo MSX, eu utilizo uma máquina real em 100% do meu tempo desenvolvendo coisas, até porque não jogo no MSX há anos. Entretanto desde o último ano, não tenho conseguido tempo para estar à frente da minha máquina de desenvolvimento preferida, que é o meu MSX TurboR A1ST com 1MB de RAM, IDE Tecnobytes com 8GB de Compact Flash, Expansor de slots ACVS, placa de rede Obsonet Tecnobytes, dentre outras coisas que estão conectadas nessa máquina.

Desde o início dos anos 2000, senão me engano lá por 2002 ou 2003, quando a “batalha de emuladores” era mais intensa entre os RuMSX, ParaMSX, fMSX e seus mais diversos sabores, duas opções “definitivas” começaram a se fundamentar no meio da comunidade MSX mundial e hoje reinam absolutas em sua preferência.

Estou falando do BlueMSX e do OpenMSX.

BlueMSX LogoBlueMSX logo

Usei muito o BlueMSX, principalmente quando jogava no emulador, mas como desenvolvedor, percebi desde cedo que o OpenMSX se tratava de um projeto mais aberto e poderoso no que diz respeito a sua utilização no desenvolvimento de novos projetos, sejam de hardware ou de software, além do fato de seu projeto ser extremamente bem feito, com um código muito bem escrito e documentado, além de ser multiplataforma.

openmsxOpenMSX logo

OpenMSX como plataforma de desenvolvimento.

Além de já ter sido vastamente utilizado como plataforma para desenvolvimento de hardware, em projetos como o MSXARM, o OpenMSX é uma excelente plataforma de desenvolvimento de software, principalmente pelo fato do mesmo emular quase todos (ou todos) os dispositivos que podem ser conectados a um MSX real, como os famosos LaserDiscs, por exemplo.

Por esse motivo e também incentivado pela série que vem sendo escrita no site de Javier Lavanderia, sobre programação para MSX utilizando MSX C, eu decidi que era hora de testar o nível de compatibilidade do OpenMSX, bem como todas as capacidades desse emulador, no desenvolvimento de novos projetos para MSX.

OpenMSX console

O OpenMSX possui um console embutido, que você ativa toda vez que pressiona F10 e a partir daí, em paralelo com a emulação, é possível interagir com a máquina utilizando um conjunto extenso de comandos disponíveis no emulador, conforme pode ser visto nesse link aqui.

Inclusive, via comandos Tcl, você pode controlar o emulador utilizando uma interface através de alguns meios de comunicação disponíveis no emulador, como pipes, named pipes, a saída padrão (stdio), TCP Sockets e UNIX domain sockets, ou seja, é um emulador modular ao extremo, permitindo até que você escreva seu próprio launcher, caso não esteja satisfeito com o OpenMSX Catapult, que para mim poderia ter sua interface tão poderosa e até mais do que a do emulador BlueMSX por exemplo.

Abaixo segue um excelente vídeo demonstrando essa integração do OpenMSX com Tcl/Tk, através do console de Tcl embutido nesse emulador.

Integrando OpenMSX com Tcl

Preparando seu disco.

Apresentado o console do OpenMSX, agora vale a pena citar um comando muito especial e poderoso, o diskmanipulator.

Resumidamente, o diskmanipulator é capaz de criar imagens de disco bem como gerenciar seu conteúdo. As imagens criadas são compatíveis com FAT12 e FAT16 e poderão ser utilizadas no OpenMSX como floppy disks comuns e também como hard disks  IDE.

OpenMSXOpenMSX console

A página de instruções do diskmanipulator contém diversas explicações de como criar imagens para discos flexíveis de 720Kb, discos rígidos com partições de FAT12 e FAT16, bem como instruções de como importar dados para esses discos a partir do disco local da máquina host em que o OpenMSX está sendo executado.

Como o objetivo desse post é justamente apresentar o OpenMSX como uma plataforma real para desenvolvimento de softwares para MSX, então preparei um disco com duas partições, sendo a primeira FAT12 e outra FAT16, com diversos softwares específicos para o desenvolvimento de software no MSX. Segue abaixo a lista do que atualmente está contido no disco criado e pronto para usar:

DRIVE A: (FAT12)

MSXDOS2 operating system compatible

[DEV]     (Editors, compilers, assemblers and general purpose development tools)
—|———[M80] (Microsoft/ASCII – Z80 Assembler)
—|———[DEVPAC80] (HiSoft Z80 Assembler)
—|———[TP33] (MSX Computer club Turbo Pascal 3.3 compiler)
—|———[TP3] (Borland Turbo Pascal 3.00A compiler)
—|———[TED] (MSX2.0 and higher Text Editor)
—|———[APED] (MSX2.0 and higher Text Editor)
—|———[TOR] (MSX1&2 text editor)

DRIVE B: (FAT16)

[PROJECTS]   (Projects source code)
——-|—-[PASCAL] (Turbo Pascal compatible source code)
——-|———|
——-|———|——[PCX]  (Source code for PCX file format handling)
——-|———|——[INLASS] (Turbo Pascal Inline assembler)
——-|———|——[MKINL] (Another Turbo Pascal Inline assembler)
——-|———|——[PMLINK] (Another Turbo Pascal Inline assembler)
——-|———|——[INLINE] (Another Turbo Pascal Inline assembler)
——-|———|——GRAPH.INC (Graphical library for MSX)
——-|———|——PARSE.INC (Command line parameter parser)

Lembrando que essa é apenas uma configuração de disco inicial em que ainda estou trabalhando, portanto no futuro certamente serão adicionados a esse hard disk, os pacotes do MSXC (1 e 2), HiSoftC, dentre outras excelentes ferramentas destinadas ao desenvolvimento de software para o MSX.

Baixando e usando o hard disk

O harddisk citado acima, pode ser encontrado nessa URL aqui, e de fato é um compartilhamento de minha pasta do DropBox que deixo disponível à comunidade. Os arquivos dessa URL serão atualizados com o tempo, visando a adição de novos compiladores e ferramentas de desenvolvimento para a plataforma MSX.

Nesse mesmo link você encontrará dois arquivos, os quais descrevo abaixo:

dev_hd.dsk -A imagem de 64MB com as duas partições (A: FAT12 e B: FAT16) pronta para uso no OpenMSX;
dev_hd.tcl  – Script Tcl utilizado para dar boot no OpenMSX, usando a imagem de disco acima;
Passos para utilização do disco no OpenMSX:
    1. Baixe esses dois arquivos em qualquer diretório de sua máquina. O único ponto de atenção a ser tomado é que esses dois arquivos devem estar no mesmo diretório pois o script TCL <dev_hd.tcl>, busca pela imagem do hard disk no mesmo diretório em que o script está sendo executado;
    1. Abra o OpenMSX utilizando a sua configuração de máquina preferida;
    1. Com o OpenMSX rodando, pressione a tecla F10, para invocar o console Tcl do OpenMSX;
    1. Já na tela do console, digite o comando abaixo:
      source <caminho_onde_você_baixou_a_imagem_de_disco_e_o_arquivo_tcl/dev_hd.tcl>
    1. Pressione <ENTER>
  1. Divirta-se 🙂

Pronto, o seu OpenMSX irá reiniciar já fazendo boot com a imagem de hard disk que você baixou no link acima.

Isso é apenas uma pequenina amostra do potencial desse que, para mim, é o melhor e mais completo emulador da plataforma MSX, na atualidade.

Fiquem antenados nos novos updates da imagem de disco, que disponibilizei no link do Dropbox.

[]’s
PopolonY2k

Referência na internet

OpenMSX home
http://openmsx.org/

Linux (Wikipedia)
https://en.wikipedia.org/wiki/Linux

MacOSX (Wikipedia)
https://en.wikipedia.org/wiki/OS_X

RuMSX home
http://www.lexlechz.at/en/software/RuMSX.html

ParaMSX (MSX.org)
http://www.msx.org/news/emulation/en/paramsx-048b

fMSX home
http://fms.komkon.org/fMSX/

BlueMSX home
http://www.bluemsx.com/

MSXARM primeiro teste de hardware (PopolonY2k Rulezz)
http://www.popolony2k.com.br/?p=2074

LaserDisc (Wikipedia)
https://en.wikipedia.org/wiki/LaserDisc

Relearning MSX (Lavanderia.net)
http://www.lavandeira.net/relearning-msx/

OpenMSX console commands.
http://openmsx.org/manual/commands.html

Tcl Tk home
https://www.tcl.tk/

Controlling OpenMSX
http://openmsx.org/manual/openmsx-control.html

Pipe communication
http://www2.cs.uregina.ca/~hamilton/courses/330/notes/unix/pipes/pipes.html

Named Pipes (Wikipedia)
https://en.wikipedia.org/wiki/Named_pipe

Network socket (Wikipedia)
https://en.wikipedia.org/wiki/Network_socket

UNIX domain sockets
https://en.wikipedia.org/wiki/Unix_domain_socket

DiskManipulator (OpenMSX)
http://openmsx.org/manual/diskmanipulator.html

PopolonY2k’s OpenMSX development hard disk (DropBox sharing)
https://www.dropbox.com/sh/smo2dz1kwl6wvfm/AAAYfFbZGjoksmoIRE4TlwPGa?dl=0

DropBox website
http://www.dropbox.com

Print Friendly, PDF & Email

10 regras da NASA para desenvolver código seguro.

Recentemente postei nas comunidades GDMSX do FaceBook e do G+ um texto bem interessantante sobre algumas dicas da NASA de como desenvolver código seguro.

Isso é muito interessante principalmente para aqueles que desenvolvem código para sistemas/dispositivos que nunca pode se dar ao luxo de uma exceção não tratada ou um core dump, comuns no mundo UNIX ou os famosos GPF’s bem conhecidos para programadores do mundo Windows.

Alguns membros da comunidade GDMSX me pediram para traduzir, então eu decidi fazer uma tradução livre, com algumas considerações pessoais que estão marcadas no texto como “(*) Notas do tradutor” 🙂 .

Vamos ao texto.

10 regras da NASA para desenvolver código seguro.

NASA Computers
NASA Computers

A NASA tem escrito software de missão crítica para a exploração espacial por décadas e agora a organização está transformando esses guias de programação em um padrão de desenvolvimento de software da indústria.

O laboratório de propulsão a jato da NASA para softwares confiáveis (JPL), recentemente publicou um conjunto de guias de programação (code guidelines), “Potência de 10 – Regras para o desenvolvimento seguro de código crítico“. O autor do texto, o cientista chefe Gerard J. Holzmann, explicou que a quantidade de codificação existente é inconsistente e cheia de regras arbitrarias, raramente permitindo tarefas essenciais como verificação de conformidade de código baseado em ferramentas de checagem de código. Os guias existentes, ele disse, inundam os programadores com regras vagas, diminuindo a qualidade do código da maioria das aplicações críticas.

“Projetos mais sérios de desenvolvimento de software usam guias de codificação,” escreveu Holzmann. “Esses guias destinam-se a firmar as regras básicas para o qual o software está sendo escrito: como ele deveria ser estruturado e quais características da linguagem deveriam e não deveriam ser usadas. Curiosamente, existe um pouco de consenso sobre o que é um bom padrão de codificação.”

 Holzmann definiu 10 regras rígidas para o desenvolvimento de software, tendo em mente a segurança do código. As regras foram especificamente escritas levando em consideração a linguagem C (uma linguagem recomendada pela NASA devido a sua longa história no desenvolvimento de software crítico e seguro e também pelo extensivo suporte de ferramentas a essa linguagem como por exemplo analisadores de código, depuradores, ferramentas de testes, dentre outras), embora essas regras possam ser facilmente generalizadas para codificação em qualquer outra linguagem, principalmente as que tem forte similaridade com C no nível de estruturação, como é o caso de Pascal e suas variantes.

  1.  Restrinja toda a construção de seu código a um fluxo de controle muito simples. Não use declarações GOTO, construções com setjmp ou longjmp, ou recursividade direta ou indireta;

    (*) Nota do tradutor:
    Quanto ao GOTO não é preciso nem escrever muito a seu respeito pois um de seus “males”, que é o de deixar o código confuso através de saltos incondicionais, já são amplamente conhecidos ao longo dos anos. O mesmo acontece com a dupla setjmp/longjmp que causam o mesmo efeito do GOTO, mas infelizmente esse recurso ainda é muito defendido por programadores experientes de C que muitas vezes se recusam a abandoná-los.
    Quanto à recursividade direta ou indireta, realmente essas tornam o código mais complexo entretanto por diversas vezes o seu código pode se tornar mais eficaz do que utilizando métodos tradicionais para resolução de um problema. Um exemplo é o algoritmo de multiplicação reconhecidamente veloz conhecido como algoritmo de Karatsuba e que é recursivo.
    Eu particularmente sugiro que se utilize métodos recursivos pequenos e de baixa complexidade, pois dessa forma pode-se evitar possíveis pontos de falhas que são invisíveis na maioria das vezes em tempo de desenvolvimento, mas que são comuns em uma situação de missão crítica.
    Quando se optar por implementar métodos recursivos, tenha em mente que a cobertura de seus testes unitários deverá ser extremamente abrangente a ponto de se testar as mínimas situações de falha.

  2. Todos os loops devem ter um limite superior fixo. Isso deve ser trivial para uma ferramenta de checagem que prove, estaticamente, que um dado limite no número de iterações não pode ser excedido. Se o limite do loop não puder ser comprovado estaticamente, a regra é considerada violada. Caso os limites sejam violados, o método deverá disparar um assert a ser verificado pelo chamador.

    (*) Nota do tradutor:
    Essa regra pode ser checada através da implementação de testes unitários com os devidos cenários mapeados.

  3. Não use alocação dinâmica de memória após a inicialização.

    (*) Nota do tradutor
    Realmente alocação dinâmica em linguagens que não são gerenciadas por um Garbage Collector é algo crítico e que deve ser utilizado de maneira cuidadosa, principalmente para principiantes no desenvolvimento de software. No artigo original, o autor cita diversos dos problemas conhecidos em se utilizar alocação dinâmica como a não liberação de recursos corretamente, o que causam os famosos vazamentos de memória ou memory leaks, e também cita sobre o cuidado de não ultrapassar os limites da memória alocada, esse último sendo também um problema quando se está usando memória alocada estaticamente em C.
    Entretanto existem casos que a alocação dinâmica é necessária e não há como escapar, nesses casos o mais comum a se fazer é alocar o buffer desejado em um ponto único, fazer toda e qualquer referência a esse buffer através de ponteiros passados para as funções que irão manipulá-lo e por fim liberá-lo nesse mesmo ponto único em que foi alocado, de preferência. Dessa forma você restringe toda a construção de seu código a um fluxo de controle muito simples, que é exatamente o primeiro item sugerido por esse guideline.
    Muitos dos desenvolvedores de softwares novatos sequer tem conhecimento de problemas de fragmentação de memória, decorrentes do abuso excessivo de alocação e liberação dinâmica de memória, principalmente em dispositivos de missão crítica que geralmente são hardwares embarcados dedicados e com recursos limitadíssimos de memória e armazenamento.

  4. Nenhuma função deve ser tão extensa que não possa ser impressa em uma única folha de papel (em uma referência ao formato padrão com uma linha por instrução e uma linha por declaração). Tipicamente isso significa não mais do que 60 linhas de código por função.

    (*) Nota do tradutor
    Manter o código com poucas linhas por função é sempre uma excelente prática pois facilita na manutenção do mesmo, entretanto algumas vezes principalmente em se tratando de código que gerencia máquinas de estado complexas, é melhor que a função fique um pouco maior do que as 60 linhas sugeridas ao invés de quebrá-las em mais funções para que comporte as 60 linhas, pois se ganha em performance, uma vez que se reduz o custo das passagens de parâmetros entre funções, ainda mais em se tratando de passagem de parâmetros de grandes estruturas por valor, que nesse caso é também uma péssima prática e que deveria ser substituída por passagem por referência ou ponteiro. Em linguagens orientadas a objeto, a regra de 60 linhas por método (função) é mais plausível e fácil de se atingir por conta da capacidade de encapsulamento dessas linguagens.

  5. A quantidade de asserts por função deve ser de no mínimo duas por função. Asserts não devem causar nenhum efeito colateral no código e deveriam ser definidos como testes booleanos.

    (*) Nota do tradutor
    Linguagens com um rico pré-processador como são C e C++ são propensas a inserção de asserts que estarão ativos dependendo do modelo de compilação em que o  binário/executável foi gerado, com isso pode-se gerar compilações de software específicas para testes.

  6. Dados devem ser declarados no menor nível de escopo possível.

    (*) Nota do tradutor
    O uso de variáveis globais é algo que vem sendo desestimulado no decorrer dos anos, pois é reconhecido que manter os dados encapsulados em escopos cada vez menores é um grande facilitador na hora de se descobrir bugs ou realizar qualquer tipo de manutenção ou melhorias no código, então declarar variáveis específicas de cada escopo é uma boa prática de programação.

  7. Cada função chamadora deve checar o retorno de funções não void (que retornam valores) e a validade dos parâmetros devem ser checadas dentro de cada função.

    (*) Nota do tradutor
    Isso é algo óbvio……bom, pelo menos deveria ser 🙂 .

  8. Uso de pré-processador deve ser limitado a inclusão de arquivos header e definição simples de macros. Macros complexas como as recursivas e com listas de argumentos variáveis, devem ser evitadas.

    (*) Nota do tradutor No texto original o autor descreve que o uso de macros de compilação condicional é algo dúbio entretanto não pode ser sempre ignorado. Eu concordo plenamente com a ideia de que não pode ser ignorado, uma vez que sempre tivemos diversas plataformas diferentes e dominantes na história da computação moderna, e o uso do pré-processador para se ter suporte a compilação condicional é uma excelente técnica que tem possibilitado manter um código portátil entre as diversas plataformas que vão desde os diversos sistemas operacionais disponíveis em PC’s até aos diversos dispositivos mobile existentes hoje.

  9. O uso de ponteiros deve ser restrito. Especificamente, não mais do que um nível de deferenciação é permitido. Operações de deferenciação de ponteiro não podem estar escondidas em macros ou dentro de declarações typedef. Ponteiros de função não são permitidos.

    (*) Nota do tradutor.
    Talvez esse seja o mais polêmico item do guia. Operações com ponteiros são algumas vezes complexas dependendo do nível de deferenciação. São raros os casos em que é necessário o uso de ponteiros duplos ou triplos, entretanto pode ser evitado e sugiro que seja evitado.
    Quanto ao uso de macros para deixar a deferenciação mais “limpa e clara”, para mim isso tem um nome e se chama “armadilha”. Fuja de quaisquer construções que “escondam” a complexidade de alguma operação, e essa regra não deve ser considerada apenas nas operações de ponteiros.
    Entretanto há ressalvas quanto ao uso de typedefs na declaração de um tipo ponteiro,  como por exemplo as definições de ponteiros para funções amplamente utilizadas nas API’s do Windows e UNIXes em geral, nesse caso não há como escapar uma vez que esses sistemas operacionais fazem uso extensivo de callbacks para proporcionar respostas a eventos requeridos e necessários para a aplicação do usuário.
    Quanto a proibição de ponteiros para função, talvez para a maioria das aplicações comuns de desktop seu uso realmente não seja necessário, entretanto para aplicações de missão crítica embarcadas como as que utilizam algum kernel real-time, como por exemplo o uC de Jean Labrosse e que fazem extenso uso de ponteiros para função para implementar as diversas tasks da aplicação do usuário, o uso de ponteiro de função é algo bem comum.
    A construção de softwares kernel real-time é repleta de ponteiros de função, até mesmo para proporcionar uma abstração de tasks, timers dentre outras estruturas típicas desse tipo de software.

  10. Todo código deve ser compilável desde o primeiro dia de desenvolvimento, com todos warnings do compilador ativados. Todo código deve compilar com essa configuração, sem gerar nenhum warning ou erro. Todo código deve ser checado diariamente com pelo menos um – de preferência mais do que um – excelente analisador de código estático (o que ele cita como analisador estado-da-arte), e a análise deve passar sem warning algum.

    (*) Nota do tradutor
    Quanto ao detalhe dos warnings de compilação, acredito que já seja bem comum em grandes projetos, entretanto a parte do analisador “estado-da-arte”, não creio que sequer mercados corporativos em países avançados a utilizem, exceto empresas de altíssima tecnologia que dependam de que seus softwares funcionem 24×7 ou de forma embarcada em algum dispositivo.

 Holzmann incluiu diversos comentários no documento original para cada uma das regras descritas acima, mas a essência do documento é que quando as regras forem utilizadas em conjunto, garantam um fluxo claro e transparente que tornem fácil a construção, testes e análise de código amplamente aceitos como livres de falhas. A JPL tem desenvolvido softwares automatizados para missões espaciais como a Mars Curiosity and a Voyager, e o laboratório já está usando essas regras em uma base experimental para escrever software de missão crítica.

Holzmann acredita que seguir as regras da NASA minuciosamente, pode diminuir a carga sobre os desenvolvedores e levar a uma melhor segurança e clareza do código.

“Se as regras parecerem draconianas no inicio, tenha em mente que elas foram criadas para que se possa checar códigos onde a sua vida pode depender muito de que haja precisão: código utilizado para controlar o avião em que você voa, a usina nuclear a poucas milhas de onde você vive, as aeronaves que carregam os astronautas em órbita”, escreve ele.

“As regras agem como o cinto de segurança em seu carro: Inicialmente eles parecem ser um pouco desconfortáveis, mas depois de um tempo seu uso se torna natural e não usá-los se torna inimaginável.”

O texto acima foi traduzido do original que pode encontrado no link do site SDTimes abaixo:

http://sdtimes.com/nasas-10-rules-developing-safety-critical-code/

[]’s
PopolonY2k

Print Friendly, PDF & Email