quinta-feira, agosto 23, 2018

CP/M-80: Parte 2

Nesta segunda parte vamos falar um pouco sobre a interface de programação (API) fornecida pelo CP/M-80. Ecos desta interface existem até hoje no Windows.

Trecho de um programa CP/M-80 que eu escrevi em 87

A interface de programação do CP/M-80 está ligada ao conteúdo dos primeiros 256 bytes da memória. Os programas são carregados logo após esta região, a partir do endereço 0x100, e chamam serviços do sistema através de uma instrução "CALL 5", com o número da função desejada no registrador C.

Como indicado no manual (que você pode baixar daqui), o CP/M 2.2. define 39 funções (duas das quais desaconselhadas):


As funções 1 a 11 dizem respeito ao acesso ao console e dispositivos auxiliares. Um redirecionamento do console é possível através do IOBYTE (detalhes no capítulo 6 do manual). O CP/M não impõe grandes requisitos a estes dispositivos, muitas vezes os consoles eram terminais externos conectados por uma interface serial e recursos como posicionamento do cursor ou limpeza de tela eram obtidos através de caracteres de controle e sequências especiais (que variavam de terminal para terminal).

As funções de acesso a disco são mais interessantes. A primeira coisa importante é a unidade de disco. O CP/M suporta até 16 unidades, identificadas na API pelos números de 1 a 16 e na interface com o operador pelas letras de A a P seguidas de ':'. O número 0 nas chamadas à API indica a unidade padrão. Estes conceitos (letras para as unidades e unidade padrão) continuam existindo no Windows.

Uma função curiosa é a "Reset Disk System". Na linha de colocar exigências mínimas no computador, o CP/M não requer que o hardware informe que pode ter ocorrido uma troca de disco. O procedimento padrão para troca de disco é o operador pressionar Control C (no prompt do sistema) para comandar um warm start que atualiza os discos presentes. Se um disco for trocado sem executar este warm start e o CP/M perceber isto, o disco será marcado como apenas de leitura. A função Reset Disk System é a forma de uma aplicação comandar um warm start.

Do ponto de vista do CP/M, um arquivo tem um nome (no famoso formato 8+3) e uma quantidade de registros de tamanho fixo 128 bytes. No caso de arquivos texto os programas costumam adotar a convenção de sinalizar o fim do texto com um caracter 0x1A (Control Z).

Para acessar um arquivo, o programa tem que montar uma estrutura de 33 ou 36 bytes, chamada FCB (File Control Block).  O primeiro byte indica a unidade (0 = padrão, 1 = A, etc). Em seguida vem o nome (8 bytes) e o tipo (3 bytes). A posição, para leitura e escrita sequencial, é controlada por dois bytes: a extensão (0 a 31) e a contagem do registro (0 a 127). Nesta forma de operação, o programa deve iniciar estes dois bytes com zero e o CP/M os avança a cada leitura/escrita. Neste tipo de acesso um arquivo pode ter até 32*128 = 4096 registros.

Para confundir um pouco, temos também as funções de leitura e escrita randômicas. Estas funções exigem uma FCB de 36 bytes; os três bytes finais indicam o registro que será lido/escrito. Para facilitar a mudança entre os dois tipos de acesso, a extensão e a contagem de registro são atualizados. Apesar de serem três bytes com o número do registro, o terceiro deve ser zero na leitura e escrita (é usado somente na consulta ao tamanho do arquivo em bytes). Os dois bytes restantes permitem ter até 65536 registros em um arquivo.

Para facilitar o programador, existe uma área reservada para uma FCB a partir do endereço 0x5C. O nome de arquivo nesta FCB é automaticamente preenchido pelo interpretador de comandos com o primeiro parâmetro do comando.

As funções de leitura e escrita usam um buffer de 128 bytes, no chamado "DMA Address". Por default este buffer fica no endereço 0x80.

A forma de controle dos arquivos e da alocação em disco é peculiar. Cada entrada no diretório possui, além do nome do arquivo, uma lista de até 16 blocos alocados ao arquivo. Um bloco consiste em um número fixo de setores e é a unidade mínima de alocação. Caso um arquivo ocupe mais de 16 blocos, ele possui mais de uma entrada no diretório. Quando um arquivo é deletado, o CP/M simplesmente coloca 0xE5 no primeiro byte das entradas correspondentes, o que torna trivial recuperar um arquivo apagado (se nada foi gravado depois).

Nenhum comentário: