MSXInício
Capítulo 17Disponível

Falando direto com a memória: PEEK, POKE, VPEEK, VPOKE

Debaixo dos comandos amigáveis, tudo é memória. Aprender a ler e escrever bytes crus abre a porta para efeitos que nenhum comando de alto nível oferece.

1. Duas memórias, duas famílias de comandos

O MSX tem duas memórias separadas:

  • RAM (a memória do Z80) — onde ficam variáveis, código e a área de trabalho da BIOS. Manipulada com PEEK e POKE.
  • VRAM (a memória do VDP) — onde ficam padrões de tiles, tabela de nomes, sprites e paleta. Manipulada com VPEEK e VPOKE.

A regra de ouro: PEEK/POKE nunca falam com a VRAM, e VPEEK/VPOKE nunca falam com a RAM. Confundir as duas é o erro clássico do programador iniciante de MSX.

2. PEEK e POKE — a RAM do Z80

DIM v AS BYTE
v = PEEK($FCA9)       ' lê byte da RAM
POKE $C000, 42        ' escreve 42 na RAM em $C000

Endereços úteis:

EndereçoO que é
$FC9EJIFFY — contador de VBLANK (60 Hz)
$FCA9Status atual do PSG
$F3AE..$F3B7Cores de fundo, borda e texto de cada SCREEN

DIGITE E VEJA

Programa 17.1 — Cronômetro

USES SCREEN 1, KEYBOARD
SCREEN 1 : CLS
DIM t AS WORD
WHILE STRIG(0) = 0
  t = PEEK($FC9E)
  LOCATE 0,0
  PRINT "JIFFY = "; t; "   "
WEND

A cada 1/60 de segundo o número cresce.

3. VPEEK e VPOKE — a memória de vídeo

A VRAM é onde vive tudo que aparece na tela. Em SCREEN 1, o mapa lógico é:

Faixa VRAMConteúdo
$0000–$07FFPadrões dos tiles (256 tiles × 8 bytes)
$1800–$1AFFTabela de nomes (32×24 = o que aparece onde)
$2000–$27FFTabela de cores
$1B00–$1B7FAtributos de sprites (posição + cor)
$3800–$3FFFPadrões dos sprites

DIGITE E VEJA

Programa 17.2 — Pintando a tela direto na VRAM

USES SCREEN 1
SCREEN 1 : CLS
DIM addr AS WORD
DIM i AS WORD

' Escreve o caractere 'A' (código 65) na primeira linha inteira
FOR i = 0 TO 31
  VPOKE $1800 + i, 65
NEXT i

TELA ESPERADA

Uma linha cheia de "A"

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA no topo da tela. Você pintou direto na tabela de nomes, sem PRINT.

4. Casos onde VPEEK/VPOKE brilham

  • Ler o cenário para saber com o que o herói está colidindo (é um tijolo? uma escada?).
  • Efeitos de "scroll" fake copiando faixas de memória com FOR.
  • Salvar/restaurar um pedaço da tela antes de abrir um menu popup.
  • Ler pixels em SCREEN 2 para colisão pixel-perfect.

DICA

Bloco grande? Traga do cartucho, não byte a byte

VPOKE é feito para escritas pontuais. Para preencher a tela inteira, o caminho rápido é PAGELOAD (capítulo 21) ou GFXLOAD na MegaROM ASCII8 (seção 9 deste capítulo): o runtime escreve os bytes em rajadas, sem resolver endereço a cada byte. Um FOR de VPOKE sobre 27 KB é lento em qualquer MSX. Para mover um retângulo de dentro da própria VRAM, use V9968 COPY (só V9968).

5. XPTR: quando 64KB é pouco

Para acessar mais de 64KB de RAM (cartuchos com Mapper, expansões), use XPTR — coberto no capítulo 25 (LMM). A ideia é a mesma: PEEK(p) e POKE p, v, mas p carrega também o segmento.

6. OUT e IN — as portas do Z80

Além das duas memórias, o Z80 conversa com os chips (vídeo, som, cartuchos) por portas numeradas de 0 a 255.

  • OUT porta, valor — manda um byte para a porta.
  • IN(porta) — lê um byte da porta.
USES SCREEN 1
SCREEN 1 : CLS
DIM v AS BYTE
v = IN($A8)              ' qual slot está em cada página de memória
PRINT "SLOTS: "; v

ATENÇÃO

Portas mexem direto no hardware

Um OUT errado no chip de vídeo ($98–$9B) ou nos slots ($A8) pode travar a máquina. Prefira os comandos prontos da linguagem e use portas só quando souber o que o chip espera.

7. ⚠ Cuidados

ATENÇÃO

Endereços proibidos

Escrever em $F380–$FFFF sem saber o que faz trava o MSX. Essa faixa é a área de trabalho da BIOS. Antes de qualquer POKE acima de $F000, confirme o endereço em uma tabela de referência.

8. Resumo do capítulo

  • PEEK/POKE → RAM do Z80. VPEEK/VPOKE → VRAM do VDP.
  • Nunca misture as duas famílias.
  • A VRAM tem endereços mapeados por SCREEN — decore os principais de SCREEN 1 e 2.
  • Bloco grande: PAGELOAD, GFXLOAD (seção 9) ou V9968 COPY. VPOKE fica para escritas pontuais.
  • Para além de 64KB, veja XPTR no capítulo 25.
  • OUT porta, valor e IN(porta) falam direto com os chips pelas portas do Z80.

9. Dados gráficos na MegaROM ASCII8

A opção MegaROM ASCII8 nos editores SCR Edit, TILES e SPRITES, ou o formato MegaROM ASCII8 na exportação do Graphics Studio, guarda os dados gráficos fora dos primeiros 32 KB do cartucho. O código continua nessa área; música e gráficos ocupam os bancos adicionais, sem sobreposição. É uma opção explícita: as exportações ASM/ARRAY e os tocadores normais continuam iguais.

Isso usa o mapper do cartucho, não a memória mapper interna da máquina. Funciona também no MSX1 com cartucho ASCII8. A mapper nativa com DSK fica para uma versão futura. A VRAM não aumenta: só os dados de origem ficam na MegaROM.

ComandoOperação
USES GRAPHICSBANKHabilita gráficos em bancos, somente para ROM.
GFXDATA nome, bytes...Declara bytes literais 0–255; linhas com o mesmo nome concatenam. Não ocupa RAM nem os 32 KB do programa.
GFXLOAD nome, endereço [, offset, quantidade [, página64K]]Copia bytes crus diretamente para VRAM. Endereço, offset, quantidade e página são literais.
GFXCOPY nome, array [, offset, quantidade]Copia para um ARRAY OF BYTE em RAM já declarado, com capacidade suficiente.

offset é relativo ao começo do bloco; omitido, copia o bloco inteiro. Cada chamada copia 1–65535 bytes. SCREEN 1/2/3 têm limite de 16 KB de VRAM; SCREEN 4/5/7/8 permitem endereço 0–65535 e página64K 0 ou 1 (128 KB). O compilador rejeita intervalos fora do bloco ou da memória de destino. O cartucho tem até 2 MB, incluindo os 32 KB do programa; não há segmentação de código.

MEMORY 32
USES GRAPHICSBANK, SCREEN 2, SPRITES, TILES
SCREEN 2
CLS
' Padrão e cores do tile 1, repetidos nas três zonas
GFXDATA tile_ship, 24,60,126,255,126,60,24,0, 241,241,241,241,241,241,241,241
GFXLOAD tile_ship, $0008, 0, 8
GFXLOAD tile_ship, $0808, 0, 8
GFXLOAD tile_ship, $1008, 0, 8
GFXLOAD tile_ship, $2008, 8, 8
GFXLOAD tile_ship, $2808, 8, 8
GFXLOAD tile_ship, $3008, 8, 8
TILE 12, 10, 1
' Sprite 8x8, padrão 0
GFXDATA sprite_ship, 24,60,126,255,126,60,24,0
GFXLOAD sprite_ship, $3800
SPRITE 0, 120, 80, 0, 8
WHILE 1
  WAIT
WEND

Telas SCREEN 5: a exportação Mapper exige largura 256 e altura até 212. São pixels crus 4bpp, não o arquivo comprimido usado por PAGELOAD. Uma linha tem 128 bytes. A página SCREEN 5 0 começa em endereço 0/página64K 0; a 1 em 32768/0; a 2 em 0/1; a 3 em 32768/1. Selecione SCREEN 5 antes de carregar.

Várias telas no mesmo cartucho

Cada imagem é um bloco GFXDATA com nome próprio. Declare cada uma uma única vez, no nível do programa — o compilador rejeita GFXDATA dentro de WHILE, FOR ou IF. Todas ficam gravadas nos bancos do cartucho (juntas até ~2 MB menos os 32 KB do programa) e nenhuma delas ocupa RAM.

Para exibir, repita o GFXLOAD quantas vezes quiser, em qualquer ponto do programa, com o SCREEN correspondente ativo. A cópia vai da mapper para a VRAM: o original no cartucho não se gasta, então a mesma tela pode voltar depois de um CLS, de um menu ou de outra fase.

Quero…Faço
Mostrar a tela 1GFXLOAD tela1, 0 com SCREEN 5 ativo
Mostrar a tela 2GFXLOAD tela2, 0 — escreve por cima da anterior
Editar os bytes de uma telaGFXCOPY tela1, buf → mexe em buf → escreva buf na VRAM com VPOKE

GFXLOAD sempre traz os bytes originais do cartucho. Se você editou buf, a alteração precisa voltar para a VRAM (laço de VPOKE); chamar GFXLOAD de novo descarta a edição e restaura a imagem como foi exportada.

Troca limpa. GFXLOAD escreve na página que está sendo mostrada, então uma tela grande aparece em construção. Para trocar de imagem sem ver o redesenho, apague a tela, carregue e reacenda:

SCREEN OFF          ' apaga a imagem enquanto a cópia roda
GFXLOAD tela2, 0
SCREEN ON           ' a tela nova aparece inteira

DIGITE E VEJA

Programa 17.3 — Duas telas alternando por uma tecla

Precisa de MSX 2 ou superior. SCREEN 5 não existe no MSX 1: lá o modo gráfico não muda, os bytes do GFXLOAD caem na tela de texto e aparecem como caracteres/pixels soltos no topo, com o cursor piscando. No RUN da IDE a máquina troca para MSX 2 sozinha; na página Emulador, escolha uma máquina MSX 2 (ou superior) no seletor antes de abrir a ROM.

MEMORY 32
USES GRAPHICSBANK, SCREEN 5
SCREEN 5
' Em um programa real, a exportação Mapper do Studio traz os bytes de cada
' tela (32768 para uma SCREEN 5 cheia). Aqui cada bloco tem 64 bytes: uma
' faixa de 128 pixels no topo da tela, preta (tela1) ou branca (tela2).
GFXDATA tela1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
GFXDATA tela2, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
WHILE 1
  SCREEN OFF : GFXLOAD tela1, 0 : SCREEN ON
  INPUT$(1)
  SCREEN OFF : GFXLOAD tela2, 0 : SCREEN ON
  INPUT$(1)
WEND

Aperte qualquer tecla: a faixa branca do topo alterna com a preta.

Paleta: telas exportadas com paletas diferentes precisam da paleta certa no momento em que são exibidas; os 16 valores 4bpp são só índices.

Página exibida: GFXLOAD escreve, mas não escolhe qual página aparece. Quem muda a página mostrada é PAGELOAD nome, pagina ou BOB FLIP com BOB PAGEFLIP ON (capítulo 21). Carregar na página 1 sem exibi-la deixa a segunda tela pronta na VRAM, mas continua na tela a página 0.

Tiles e sprites: os editores mantêm a ordem dos padrões 8×8 e as três zonas de SCREEN 2/4. O editor de sprites gera o layout de SCREEN 2; em SCREEN 5 os padrões de sprites ficam em $7800, portanto ajuste o destino ao trocar de modo. Mapas usados pelo scroll e objetos BOB podem precisar de um buffer temporário em RAM: GFXCOPY libera a ROM do programa, não essa área de trabalho.

Música: PLAYBANK/TICKBANK continuam usando os bancos iniciais de dados. GFXLOAD/GFXCOPY restauram o banco do programa entre pequenos blocos protegidos contra interrupção. TICKBANK cooperativo não avança sozinho durante uma cópia; chame-o no laço ou no seu VBLANK, como antes.

RUN e exportação: RUN seleciona ASCII8 automaticamente. O arquivo exportado é main[ASCII8].rom; em outros emuladores, escolha o cartucho ASCII 8K.

Comunidade

Discussão · Falando direto com a memória: PEEK, POKE, VPEEK, VPOKE

Curta, marque como lido e comente o que achou deste capítulo.

0 comentários
Entre para participar
Crie uma conta ou faça login para curtir, marcar como lido e comentar.

Carregando comentários…