Em março-maio deste ano, passei várias semanas (à noite e nos fins de semana) transportando o brinquedo Lode Runner da BK-0010 para o UKSC.Captura de tela do menu portado:
Tela do jogo da versão portada: O
BK-0010 é um computador doméstico do final dos anos 80 e início dos anos 90 e parcialmente um computador escolar (classes KUVT-86). UKSC é um computador escolar dos anos 90. BC e UKSC são parcialmente compatíveis em arquitetura e sistema de comando - ambos os computadores remontam à família PDP-11.Seleção de jogo
Até este ano, eu não escrevia nada sério no UKSC, mas tinha que entender o código da máquina. Havia um desejo de escrever algo, mas geralmente tenho grandes problemas com o tempo livre, por isso dificilmente funcionaria do zero. E para iniciantes, é melhor facilitar a tarefa. Ao portar, a quantidade de trabalho geralmente é muito menor do que ao escrever do zero - você encontra principalmente problemas de incompatibilidade entre os dois sistemas.No fórum zx.pk.ru (um dos sites em que os fãs de retrocomputação em geral e as máquinas compatíveis com PDP-11 em particular participam), o participante do hobot elogiou a implementação do Lode Runner no BC - esse foi realmente o motivo: para começar, tentei "olhar" o código do brinquedo , bem, se envolveu.Menu da versão original:
A tela do jogo da versão original (no monitor colorido):
Engenharia reversa
Algumas semanas à noite e nos fins de semana, passei um tempo analisando e desmontando. No emulador, o BKBTL adicionou a capacidade de coletar um rastreamento - ou seja, cada instrução é desmontada e salva em um arquivo de texto.Eu faço uma execução da seção que me interessa em registrar o rastreio, depois desligo o rastreio (sort & uniq) - recebo fragmentos da lógica. Eu adiciono comentários a isso, gradualmente recebo um arquivo comum.Parece simples, mas, na verdade, é um trabalho bastante complicado, baseado em conjecturas e sua confirmação ou refutação. Por exemplo, observamos que o endereço 001756 antes do início do jogo recebe o valor 10 e, em seguida, é decrementado, quando chega a 0, o jogo termina - aparentemente esse é o número de vidas. Encontramos confirmação disso, colocamos comentários no texto em que esse endereço ocorre. Este é um exemplo bastante simples: em casos mais complexos, passei muito tempo descobrindo o que estava acontecendo.Quando o volume recebido se tornou bastante grande (mais de 40 KB de texto, mais de 1.500 linhas) e eu descobri pelo menos em termos gerais o que estava acontecendo, como ele era armazenado e exibido - comecei a pensar em como traduzi-lo para o UKSC.Aqui você pode ver a lista final resultante da desmontagem:github.com/nzeemin/uknc-loderunner/blob/master/original/loderunner.lstLabirinto
Cada labirinto é de 20 linhas de 30 blocos, um total de 600 blocos.O tipo de bloco é codificado por um número de 0 a 7 - três bits, tripleto. Para uma palavra de 16 bits, são obtidos 5 trigêmeos completos.Ao trabalhar com máquinas do tipo PDP-11, um sistema com 8 casas decimais é amplamente utilizado, portanto, é bastante conveniente usar trigêmeos.Como resultado, cada labirinto se encaixa em 240 bytes.Tipos de bloco:; 0
; 1
; 2
; 3
; 4
; 5
; 6
; 7
Os sprites desses objetos são organizados na ordem de numeração dos tipos de bloco. Quando um labirinto é decodificado, ao mesmo tempo, uma "imagem de labirinto" é criada na memória (por byte por bloco) e o estado inicial do labirinto é desenhado na tela.Organização da tela
No BC, a tela é endereçada diretamente acessando a memória, as linhas vão uma após a outra, na verdade, é um "framebuffer", e eu diria que está tudo bem - é muito conveniente para programar gráficos. Linha BC - 256 pixels coloridos, 64 bytes por linha. Mas quantos pixels em uma fileira dependem de como você conectou o monitor:se estiver em preto e branco, serão 512 pb / p em uma fileira (1 bit por pixel, 8 pixels por byte)e se é para saída em cores , são 256 pixels em cores por linha (2 bits por pixel, 4 pixels por byte).No UKSC, a organização da tela é completamente diferente e muito mais complicada. A tela está em três blocos de memória, três "planos". E cada pixel tem três bits, um pouco em cada plano - temos 8 cores. No UKSC, temos vários modos de vídeo - 640 × 288, 320 × 288, 160 × 288, mais precisamente, sempre temos exatamente 288 linhas e você pode aplicar seu próprio divisor a cada linha individual, obtendo diferentes resoluções horizontais. Para a unidade central de processamento (CPU), os planos de tela não são acessíveis diretamente, apenas através do acesso às portas. Além disso, apenas dois de três planos estão disponíveis para a CPU.Nesse caso, o modo 320 × 288 me serviu bem - a linha é obtida em 320 pixels coloridos de 80 bytes de comprimento em cada um dos três planos. Se você usar dois planos, os pixels também terão quatro cores - quase como em um BC.Síntese
Ele começou a escrever exemplos na montadora da UKSC e ficou um pouco deprimido - porque o ciclo "compilado - vinculado - lançado" é bastante lento. O problema está nas ferramentas. Há um MACRO11 de assembler cruzado, embora seja um pouco buggy. Mas não há cross-linker. Mas, felizmente, há pouco tempo, a Patron postou o console RT-11: zx-pk.ru/showthread.php?t=24755 - na verdade, é um emulador de uma máquina compatível com PDP11 que interage com a linha de comando do SO, como em um terminal. Assim, tornou-se possível compilar e vincular os meios nativos do RT-11. Isso eu considero um avanço real, acelerou bastante o trabalho.Depois disso, as coisas correram bem, fiz um desenho do quadro de campo de jogo, renderizando sprites, descobri como misturar os bits nos sprites (escrevi um programa em C # para misturá-los) e, em blocos, comecei a transferir o código do arquivo compartilhado com desasma para as novas fontes. Peguei um despejo de memória do BC, aloquei um bloco onde estão os níveis, o utilitário RT11 DUMP fez um livro didático para os níveis.Primeiro, transferi um bloco de código que exibe o nível e depurei a saída de sprites. Então ele começou a transferir a lógica do jogo. Essa. em geral, a transferência é quase individual, com exceção dos locais onde a tela é exibida. Portanto, há lugares na lógica em que eu não entendo como eles funcionam (o mesmo inferno da IA), mas isso não importa - o principal é que eles funcionam.Como resultado, no início de maio (quando o trabalho principal me absorveu novamente), uma opção de trabalho foi obtida, embora sem som.Foto de um jogo de trabalho em uma máquina real (obrigado hobot):
Referências