POKEs
Como um número escrito no sítio certo dava vidas infinitas no ZX Spectrum.
Uma instrução do BASIC que escreve um byte na memória tornou-se a batota de uma geração: os leitores descobriam os POKEs, as revistas publicavam-nos e as editoras protegiam-se. Ainda hoje há bases de dados que os guardam jogo a jogo, e emuladores que os vão buscar sozinhos.
- 11
- 7
- 47
Um byte de cada vez
Para o Spectrum, tudo o que está na memória são bytes, números entre 0 e 255. O manual de BASIC, escrito por Steven Vickers, pede-te que imagines a memória como uma longa fila de caixas numeradas, cada uma com um byte lá dentro. As caixas de 0 a 16383 são ROM: têm tampa de vidro, e só podes ler o que lá puseram na fábrica. As seguintes são RAM, e essas podes abrir e mudar [1].
Para ler uma caixa há o PEEK: PEEK 0 dá-te o primeiro byte da ROM. Para escrever há o POKE, na forma POKE endereço, valor. O exemplo do manual é POKE 31000,57, e PRINT PEEK 31000 mostra que o 57 lá ficou. O valor tem de estar entre -255 e 255, e aos negativos o Spectrum soma 256 [1].
A RAM está arrumada por zonas. Em 16384 começa a imagem do ecrã, em 22528 as cores de cada posição (os atributos), em 23296 a memória da impressora e de 23552 a 23733 as variáveis do sistema; só depois vêm o programa em BASIC, as suas variáveis e, lá no alto, as pilhas e os gráficos definidos pelo utilizador [1]. Num Spectrum de 16K, as caixas acima de 32767 nem sequer existem [1].
O manual não escondia o risco: o POKE dá-te um poder imenso sobre o computador, e um poder de destruição do mesmo tamanho, porque um valor errado no endereço errado deita fora num instante um programa que levou horas a escrever. Mas tranquilizava logo a seguir: não fazes nenhum mal permanente à máquina [1]. Foi com esta instrução que se fez a batota de uma geração.
Como se ganha uma vida
Um jogo em código máquina guarda o número de vidas numa destas caixas, e algures no código há uma instrução que lhe tira uma quando morres. No Manic Miner da Bug-Byte, a desmontagem completa do jogo mostra-o sem margem para dúvidas: as vidas ficam no endereço 33879 e, no endereço 35136, está a instrução DEC (HL), que diminui esse número em um [2].
No processador Z80, a instrução DEC (HL) é o byte 53, e o byte 0 é NOP, uma instrução que não faz nada [3]. O famoso POKE 35136,0 troca uma pela outra: o jogo continua a passar por ali quando morres, mas já não desconta nada, e as vidas ficam infinitas [4]. Por isso as listas de dicas também ensinavam o caminho de volta: POKE 35136,53 desliga o truque [5].
O Jet Set Willy, da Software Projects, faz o mesmo. A rotina que tira uma vida vai buscar o número ao endereço 34252 e tem o seu DEC (HL) em 35899, e é aí que cai o POKE 35899,0 [6][7].
Nem sempre se apagava a instrução que desconta. Numa dica para o Chuckie Egg publicada na Your Spectrum, Andrew Pennell avisava que o seu POKE não removia nenhum DEC: mudava um salto, o que resultava, mas fazia aparecer a mensagem de fim de jogo umas quantas vezes a meio da partida [8]. Outro valor que aparece muito nas listas é o 201, o código da instrução RET, que faz regressar de uma rotina [3]: no Saboteur!, por exemplo, POKE 40004,201 tira-te os cães do caminho [9].
E atenção às versões, porque os endereços mudam de uma edição para outra. O Manic Miner foi reeditado pela Software Projects, e aí o POKE das vidas já não é 35136 mas 35142 [5]. Os POKEs que vês nesta página são das edições indicadas.
Bastava um zero no sítio certo para o jogo se esquecer de te tirar a vida.
Sacos de cartas
Na Crash, as batotas viviam na secção Playing Tips, que trazia soluções e truques para facilitar os jogos. Nos primeiros anos era Robin Candy quem a fazia, e em abril de 1986 a revista chegou a oferecer um suplemento só com as suas dicas; depois veio Hannah Smith [10]. Quando ela saiu, um rapaz de 15 anos de Ludlow, Nick Roberts, escreveu a pedir o lugar e, dois meses depois, era ele o editor das dicas [11].
A matéria-prima chegava pelo correio. Roberts lembra-se de sacos de cartas todas as semanas, com mapas e cassetes cheias de rotinas de POKEs, que ele escolhia para publicar. Também procurava POKEs por conta própria, a vasculhar o código dos jogos com um Multiface, e conta que era sempre uma emoção encontrar lá mensagens deixadas pelos programadores [11].
A Sinclair User publicava as descobertas nas cartas dos leitores, com nome e terra. Em agosto de 1984, três leitores de Merseyside, do Wiltshire e de Birmingham mandaram o POKE das vidas infinitas do Jet Set Willy [12]. Dois anos depois, a revista tinha um cantinho dos POKEs com os clássicos para consulta rápida: Manic Miner, Jet Set Willy, Atic Atac [13].
Na Your Sinclair, a secção de dicas começou por se chamar Hack Free Zone, para se distinguir da Hacking Away, que era a dos POKEs para escrever; em 1987 as duas juntaram-se na Tipshop. A sucessora da Hacking Away foi a Practical Pokes, apresentada sobretudo por Jon North, com POKEs para escrever e para o Multiface [14]. Em janeiro de 1991 ainda lá estava, a abrir com Jon North a prometer POKEs em quantidade [15].
Em Espanha, a MicroHobby tinha a Tokes & Pokes. Em dezembro de 1990, um leitor de Barcelona escrevia a dizer que não percebia a explicação de como se metiam pokes no seu Spectrum +2; a revista respondia que era a mais simples possível e, no mesmo número, voltava a explicá-lo numa caixa à parte [16].
Chegar antes do jogo
Escrever o POKE era a parte fácil; o difícil era chegar à memória antes de o jogo arrancar. O método clássico, explicado pela MicroHobby: em vez de LOAD, escrevias MERGE "", que carrega o pequeno programa em BASIC do início da cassete e para sem o correr. Parava-se a fita, editava-se a linha com o RANDOMIZE USR, que é a que arranca o código máquina, e punham-se os POKEs imediatamente antes dele [16].
Nas revistas inglesas era igual. Para o Jet Set Willy, a Sinclair User mandava carregar com MERGE "", parar a fita, acrescentar a linha 37 POKE 35899,0, escrever GOTO 10 e voltar a pôr a cassete a tocar [12]. Mas a MicroHobby avisava que isto só funcionava em jogos desprotegidos: carregamentos turbo, a mais de 2000 baud, ou de cores oscilantes tornavam-no impraticável [16].
E as proteções eram cada vez mais. O Speedlock, de David Aubrey-Jones e David Looker, andou cerca de um ano a ser enviado às editoras sem que nenhuma lhe pegasse, até a Ocean o usar pela primeira vez no Daley Thompson's Decathlon, que a Crash analisou em novembro de 1984. Aubrey-Jones conta que o fez por estar cada vez mais farto do tempo que o carregamento normal demorava [17]. Com proteções assim, copiar a cassete com um programa de cópia tornou-se quase impossível, e os carregadores tinham de ser desmontados à mão [18].
Para esses jogos, as revistas publicavam listagens de hack: programas em BASIC, muitas vezes com linhas de DATA cheias de código máquina, que tomavam conta do carregamento e metiam os POKEs pelo caminho. Não era ciência exata: uma destas rotinas para o Underwurlde, publicada na Crash, vinha substituir outra, do número anterior, que não funcionava [19].
Em janeiro de 1991, a Your Sinclair ensinava a desmontar os Speedlock 1 e 2. A versão 2 tinha seis rotinas de desencriptação, e parte do código verificava se havia um Multiface ligado. O código aproveitava truques do Z80, como o registo R e os saltos que dependem da paridade, e começava de propósito com lixo, para te fazer pensar que estavas no endereço errado [15].
O botão vermelho
Em fevereiro de 1986, a Sinclair User apresentava o Multiface One, da Romantic Robot. Ao carregar num botão, copiava o programa que estivesse a correr para disquete, microdrive ou Wafadrive, e deixava ver o que estava na memória e fazer POKEs para chegar às pontuações altas [20].
O segredo estava no hardware. O botão ativa a interrupção não mascarável do Z80, e o Multiface toma conta da máquina com a sua própria ROM [21]. Como as proteções da época atuavam sobretudo durante o carregamento, ou logo a seguir, um jogo apanhado a meio já estava inteiro e desprotegido na memória [21].
Para a batota, bastava parar o jogo, escrever o endereço e o valor e voltar ao ponto onde estavas, sem MERGE nem listagens. As revistas passaram a publicar POKEs de Multiface todos os meses [21]. Havia até programas para os 8 KB de RAM do próprio aparelho, como o Lifeguard, que analisava a memória durante o jogo para descobrir que endereços mudar [21].
Depois do Multiface One, para o Spectrum de 48K, vieram o Multiface 128, em abril de 1987, e o Multiface 3, em novembro desse ano, para os modelos da Amstrad que o 128 não suportava [21].
Piratas ou curiosos?
Um aparelho que copiava qualquer jogo com um botão não era inocente, e ninguém fingia que era. A própria Sinclair User abria a análise ao Multiface a lembrar que as máquinas de cópias de segurança são sempre polémicas, e que esta ia ser a mais polémica de todas [20].
A fronteira entre batota e pirataria era fina. A MicroHobby dizia aos leitores que a melhor forma de meter os pokes era com um transfer [16], e entre os programas de cópia mais conhecidos estava o Trans Express, também da Romantic Robot [18]. Andrew Pennell, na dica do Chuckie Egg, preferiu não publicar um carregador próprio, para não pisar os calos a ninguém, e usou uma versão modificada do carregador do próprio jogo [8].
As proteções também tinham um preço. Quando a Ocean adotou o Speedlock, o fórum de leitores da Crash discutiu-o durante meses, e houve quem se queixasse de que os jogos passavam a carregar pior [17].
Às vezes era a própria editora a mandar POKEs. Em 1984, jogadores do Jet Set Willy morriam sem parar em vários sítios depois de passarem pelo sótão. A Software Projects garantiu à Sinclair User que aquilo não era um erro, mas uma forma deliberada de tornar o fim do jogo mais difícil, e publicou quatro POKEs para o anular [12]. A desmontagem moderna do jogo trata-o como aquilo que era, um erro, e explica que esses POKEs o corrigem, a par de outros problemas [7].
Os POKEs hoje
Os POKEs sobreviveram em ficheiros .POK, um formato criado para o programa SGD para aplicar POKEs a snapshots antes de abrir o emulador. Cada batota começa numa linha N, com o nome; as linhas M e Z têm os POKEs, sendo Z o último, com o banco de memória, o endereço, o valor novo e o valor original, para se poder desfazer; um valor de 256 quer dizer que o programa te pergunta o número; e um Y fecha o ficheiro [22].
No ficheiro do Manic Miner guardado no ZXDB, a linha das vidas infinitas é Z 8 35136 0 53 [23]. O 8 quer dizer que se ignora o banco, como em todos os jogos de 48K, o 0 é o valor novo e o 53 o original [22]: o mesmo DEC (HL) que a desmontagem encontra naquele endereço [3][2].
O ZXDB, a base de dados criada por Einar Saukas que alimenta o Spectrum Computing, junta a cada jogo o seu ficheiro de POKEs e a lista dos artigos de revista onde ele apareceu, com ligação para as páginas digitalizadas [23]. The Tipshop reúne as dicas publicadas nas revistas, com a indicação do número e da página de onde vieram [5].
Os emuladores fazem o resto. O Fuse procura sozinho um GAME.POK quando abres o GAME.TAP, e tem um localizador de POKEs parecido com o Lifeguard do Multiface: procuras o número de vidas que tens, perdes uma, procuras o novo número, e depressa sobra um endereço. No exemplo do manual do Fuse, a instrução que desconta a vida é depois trocada por um NOP [24], exatamente o que faz o POKE 35136,0 no Manic Miner.
Experimenta tu
Não precisas de um jogo para experimentar. Entre os endereços 23552 e 23733 ficam as variáveis do sistema, que guardam o estado do próprio Spectrum. O manual diz que as podes espreitar com PEEK e que algumas se podem mudar com POKE, com proveito [25].
Só algumas. O manual marca com um X as que não se devem mexer, porque o sistema pode ir abaixo, e com um N as que não têm efeito duradouro [25]. As que te propomos estão fora dessas duas listas e ocupam um byte só; as de dois bytes guardam primeiro o byte menos significativo, ao contrário do que seria de esperar [25].
No Spectrum de 48K, as palavras-chave não se soletram: no início da linha o cursor está em modo K, e a tecla em que carregas dá a palavra escrita nela [26]. E se alguma coisa correr mal, não estragas nada; basta reiniciar [1].
POKEs famosos
Só funcionam na versão original do jogo, carregada da cassete; noutra edição a memória pode estar arrumada de outra maneira.
| Jogo | Editora | Ano | POKE | Efeito | [n] |
|---|---|---|---|---|---|
| Manic Miner | Bug-Byte | 1983 | POKE 35136,0 | Vidas infinitas | [23][5][4][13] |
| Jet Set Willy | Software Projects | 1984 | POKE 35899,0 | Vidas infinitas | [27][28][7][12][13] |
| Atic Atac | Ultimate Play The Game | 1983 | POKE 36519,0 | Vidas infinitas | [29][30][13] |
| Knight Lore | Ultimate Play The Game | 1984 | POKE 53567,0 | Vidas infinitas | [31][32] |
| Chuckie Egg | A'n'F Software | 1983 | POKE 42837,0 | Vidas infinitas | [33][8] |
| Underwurlde | Ultimate Play The Game | 1984 | POKE 59375,0 | Vidas infinitas | [34][19] |
| Head over Heels | Ocean Software | 1987 | POKE 42195,0 | Vidas infinitas | [35][36] |
| Renegade (48K) | Imagine Software | 1987 | POKE 40366,0 | Tempo infinito | [37][38] |
| Horace Goes Skiing | Sinclair Research | 1983 | POKE 29270,0 | Sem trânsito | [39][40] |
| Sabre Wulf | Ultimate Play The Game | 1984 | POKE 39702,30 | Sem monstros | [41][42] |
| Saboteur! | Durell Software | 1985 | POKE 40004,201 | Sem cães | [43][9] |
Experimenta tu
Aqui tens um ZX Spectrum 128 a correr no browser. Escreve um destes POKEs, carrega em ENTER e vê o que muda na máquina; nenhum estraga nada, e para voltar ao início basta reiniciar.
Liga o Spectrum 128, escolhe 128 BASIC e escreve o comando letra a letra, seguido de ENTER. Num 48K verdadeiro a palavra POKE sai de uma só tecla, o O, e a vírgula é Symbol Shift com N.
POKE 23609,255Alonga o clique que o teclado dá a cada tecla, que de origem está a 0.POKE 23561,10Uma tecla mantida carregada começa a repetir ao fim de 10/50 de segundo, em vez dos 35/50 de origem.POKE 23562,1Depois de começar, a repetição passa a ser a cada 1/50 de segundo, em vez de 5/50.POKE 23608,255Alonga o zumbido de aviso, o que ouves quando a linha é comprida demais ou a memória está cheia; o normal é 64.POKE 23692,255O ecrã deixa de parar a perguntar scroll? e continua a correr durante 254 linhas; para nunca parar, os programas repetiam o POKE.POKE 23693,14Muda as cores permanentes para tinta amarela sobre papel azul (8 × 1 + 6 = 14), como PAPER 1: INK 6, e vês o efeito no que escreves a seguir e no ecrã inteiro depois de CLS.POKE 23658,8Liga o CAPS LOCK, que é o bit 3 desta variável; POKE 23658,0 volta a desligá-lo.
© 1982 Sinclair Research Ltd
Fontes
- [1]ZX Spectrum BASIC Programming, capítulo 24: The memory · Sinclair Research (manual de Steven Vickers; edição em linha do World of Spectrum), 1982
- [2]Manic Miner: Routine at 34574 (Main loop) · SkoolKit (desmontagem completa do Manic Miner, Richard Dymond)
- [3]Z80 Opcode Table · ClrHome
- [4]Manic Miner: Pokes · SkoolKit (desmontagem completa do Manic Miner, Richard Dymond)
- [5]Manic Miner (dicas, POKEs e hacks publicados nas revistas) · The Tipshop
- [6]Jet Set Willy: Routine at 35841 (Lose a life) · SkoolKit (desmontagem completa do Jet Set Willy, Richard Dymond)
- [7]Jet Set Willy: Pokes · SkoolKit (desmontagem completa do Jet Set Willy, Richard Dymond)
- [8]Chuckie Egg (dicas, POKEs e hacks publicados nas revistas) · The Tipshop
- [9]Saboteur! (dicas, POKEs e hacks publicados nas revistas) · The Tipshop
- [10]Crash (magazine) · Wikipedia
- [11]The story of Crash magazine · Eurogamer (Graeme Mason), 2017
- [12]Sinclair User n.º 29 (agosto de 1984), Letters: Hints for Jet Setters · Sinclair User (digitalização no Internet Archive), 1984
- [13]Sinclair User n.º 53 (agosto de 1986), Poke corner · Sinclair User (digitalização no Internet Archive), 1986
- [14]Your Sinclair · Wikipedia
- [15]Your Sinclair n.º 61 (janeiro de 1991): Practical Pokes e Speedlock · Your Sinclair (digitalização no Internet Archive), 1991
- [16]MicroHobby n.º 205 (dezembro de 1990): Tokes & Pokes · MicroHobby (digitalização no Internet Archive), 1990
- [17]The One David · Crash n.º 44 (Richard Eddy), Crash Online, 1987
- [18]ZX Spectrum software · Wikipedia
- [19]Underwurlde (dicas, POKEs e hacks publicados nas revistas) · The Tipshop
- [20]Sinclair User n.º 47 (fevereiro de 1986), Back up your troubles · Sinclair User (John Lambert; digitalização no Internet Archive), 1986
- [21]Multiface · Wikipedia
- [22]FAQ: File formats (POK Format v1.20) · World of Spectrum
- [23]Manic Miner (ficha com o ficheiro .POK e as referências nas revistas) · Spectrum Computing (ZXDB)
- [24]fuse(1): The Poke Finder e The Poke Memory · Fuse, the Free Unix Spectrum Emulator (manual, Debian)
- [25]ZX Spectrum BASIC Programming, capítulo 25: The system variables · Sinclair Research (manual de Steven Vickers; edição em linha do World of Spectrum), 1982
- [26]ZX Spectrum BASIC Programming, capítulo 1: Introduction · Sinclair Research (manual de Steven Vickers; edição em linha do World of Spectrum), 1982
- [27]Jet Set Willy (ficha com o ficheiro .POK e as referências nas revistas) · Spectrum Computing (ZXDB)
- [28]Jet Set Willy (dicas, POKEs e hacks publicados nas revistas) · The Tipshop
- [29]Atic Atac (ficha com o ficheiro .POK e as referências nas revistas) · Spectrum Computing (ZXDB)
- [30]Atic Atac (dicas, POKEs e hacks publicados nas revistas) · The Tipshop
- [31]Knight Lore (ficha com o ficheiro .POK e as referências nas revistas) · Spectrum Computing (ZXDB)
- [32]Knight Lore (dicas, POKEs e hacks publicados nas revistas) · The Tipshop
- [33]Chuckie Egg (ficha com o ficheiro .POK e as referências nas revistas) · Spectrum Computing (ZXDB)
- [34]Underwurlde (ficha com o ficheiro .POK e as referências nas revistas) · Spectrum Computing (ZXDB)
- [35]Head over Heels (ficha com o ficheiro .POK e as referências nas revistas) · Spectrum Computing (ZXDB)
- [36]Head over Heels (dicas, POKEs e hacks publicados nas revistas) · The Tipshop
- [37]Renegade (ficha com o ficheiro .POK e as referências nas revistas) · Spectrum Computing (ZXDB)
- [38]Renegade (dicas, POKEs e hacks publicados nas revistas) · The Tipshop
- [39]Horace Goes Skiing (ficha com o ficheiro .POK e as referências nas revistas) · Spectrum Computing (ZXDB)
- [40]Horace Goes Skiing (dicas, POKEs e hacks publicados nas revistas) · The Tipshop
- [41]Sabre Wulf (ficha com o ficheiro .POK e as referências nas revistas) · Spectrum Computing (ZXDB)
- [42]Sabre Wulf (dicas, POKEs e hacks publicados nas revistas) · The Tipshop
- [43]Saboteur! (ficha com o ficheiro .POK e as referências nas revistas) · Spectrum Computing (ZXDB)
- [44]Spectrum ROM: 23609, PIP · SkoolKit (The Complete Spectrum ROM Disassembly, de Ian Logan e Frank O'Hara)
- [45]ZX Spectrum BASIC Programming, capítulo 16: Colours · Sinclair Research (manual de Steven Vickers; edição em linha do World of Spectrum), 1982
- [46]Spectrum ROM: 23693, ATTR-P · SkoolKit (The Complete Spectrum ROM Disassembly, de Ian Logan e Frank O'Hara)
- [47]Spectrum ROM: 23658, FLAGS2 · SkoolKit (The Complete Spectrum ROM Disassembly, de Ian Logan e Frank O'Hara)