quinta-feira, 5 de março de 2020

Paginação em 128K (II)

Como vistos no post anterior, em paginação no 128K (I) , os modelos da Amstrad permitem paginar um banco/página de RAM no endereço $000-$3FFF (em cima da ROM).

Neste artigo apresentamos um exemplo de um programa em assembly, que carrega uma imagem de uma ROM em memória alta, pagina-a em cima da ROM, e salta para ela.

Neste caso, mudados o stack de código máquina e os stacks aplicacionais para um endereço abaixo de 32768, já que ao mudar para o modo especial 2, as duas páginas superiores vão ser mudadas.

Configuração por defeito, no arranque:
$FFFF
-
$C000
Bank 0
$BFFF
-
$8000
Bank 2

$7FFF
-
$4000
Bank 5
(screen 0)

$3FFF
-
$0000
ROM 0

Depois mudamos o banco 0 no topo, pelo banco 4.

$5b5c/$7ffd AND     $f8 / OR $04
Port
Bit
7
6
5
4
3
2
1
0
$7ffd
=
=
=
=
=
100  ($4)               

Nova paginação:
$FFFF
-
$C000
Bank 4
$BFFF
-
$8000
Bank 2

$7FFF
-
$4000
Bank 5
(screen 0)

$3FFF
-
$0000
ROM 0

Fazemos o load da imagem da ROM a partir de 49152/$C000, para carregar esse banco com uma imagem de ROM com um tamanho máximo de 16KB (LOAD "" CODE 49152).

Carregada a imagem de ROM, solicitamos ficar no modo especial 2, para o banco 4, e consequentemente a imagem da ROM, ficar disponível a partir da posição $0000. Note-se a saída dos bancos 2 e 4, e daí a necessidade do stack/CLEAR ter tido de ficar abaixo de $7FFF.

$5b67/$1ffd  OR      $07 / XOR     $02 
Port
Bit
7
6
5
4
3
2
1
0
$1ffd
=
=
=
=
=
10 ($2)
1

Nova paginação:
$FFFF
-
$C000
Bank 3
$BFFF
-
$8000
Bank 6

$7FFF
-
$4000
Bank 5
(screen 0)

$3FFF
-
$0000
Bank 4

Se quisermos uma compatibilidade melhor com 48K apenas, podemos também desactivar a paginação (passo opcional, comentado no assembly).

$5b5c/$7ffd OR $20
Port
Bit
7
6
5
4
3
2
1
0
$7ffd
=
=
1
=
=
=
=
=

Finalmente então saltamos para $0000, para executar a imagem de ROM que carregamos.

;
; Routine for the 128K+2/2A/3 to load bank 4 with a ROM
; and map it on top of ROM/address $0000
;
; (C) Rui Ribeiro Fev 2020
;
; Invoked from 128K mode BASIC
;
; By default memory banks will be ROM 0->Bank 5 (screen)->Bank 2->Bank 0
; Each RAM bank is 16KB
;
; Requirements before calling it, CLEAR 30999 ; if it not done it will crash 
; as stack needs to be bellow 32768 by the end of this routine, as
; bank 0 and bank 2 will shift positions
;
; see https://www.worldofspectrum.org/faq/reference/128kreference.htm
;
; CLEAR 30999: LOAD "THIS" CODE : RAND USR 31000 : LOAD "ROM" CODE 49152 : RAND USR 31001 
;
; Short note: USR BASIC routine loads BC with called address

ORG 31000
NOP
LD A,C               ; point of entry for 2nd time calling
AND 1   
JR NZ,SPECIAL_MODE   ; if BC odd, go to SPECIAL_MODE


; First moves bank 4 to $C000 (49152) replacing  Bank 0
;
; called with RANDOMIZE USR 31000 (first time)
;
; Paging variable from 128K model onwards
; $7ffd - Bits 0-2: RAM page (0-7) to map into memory at 0xc000.

LD      A,($5b5c)      ; system copy of $7ffd

AND     $f8        ; reset bit 0-2
       ; RAM page/bank to load at $C000
OR      4              ; Select bank 4

LD      BC,$7ffd
DI
LD      ($5b5c),A      ; save copy of the new value

OUT     (C),A        ; change bank 0 for bank 4 at $C000
RET

; After LOAD "" CODE 49152
; called with RANDOMIZE USR 31001
;
;
; for loading the "ROM" in Bank 4 at $C000

; shift for special mode 2
;
; bank 4 $C000->$FFFF which we LOADed"" will be moved to $0000->$3FFF
;
; Bank 4->Bank 5->Bank 6->Bank 3
;
; Paging variable from 128K +2A Onwards
; $1ffd - Bit 0: Paging mode. 0=normal, 1=special
;         Bit 2=1 and Bit 1=0 : Banks 4->5->6->3

SPECIAL_MODE:

LD      A,($5b67) ; system copy of $1ffd

OR      $07
XOR     $02 ; Special mode, mode 2

LD      BC,$1ffd
DI
LD      ($5b67),A ; save copy of the new value

OUT     (C),A ; change for special mode 2
; 4->5->6->3

; possible addition to improve 48K compatibility
        ; disabling paging
        ;
        ;LD      A,($5b5c)      ; system copy of $7ffd

        ;OR      $20            ; disable paging

        ;LD      BC,$7ffd
        ;DI
        ;LD      ($5b5c),A      ; save copy of the new value

        ;OUT     (C),A          ; disable paging


JP      0 ; JUMP to the beginning of the "new" "ROM"

END 31000

PS. Note-se que se pode alterar esta rotina, para desactivar o paging e criar um modo 48K mais compatível com software, nomeadamente nos jogos (exemplo: Jetpac). Ver os comentários do setup da porta $7ffd.

Activando o bit 5 da porta $7ffd, o paging fica desactivado até se desligar o computador.

asm source code

TZXs para carregar a partir de modo 128+2A/+2B/+3


ROM de ZX Spectrum 48K (100% identica, ao contrario da ROM de 48K alterada nos modelos 128)
ROM de TK95
ROM de SE BASIC 3.1.2
ROM de diagnóstico da Retroleum
ROM de Shadow of Unicorn, que permite carregar os TZX de tape do World of Spectrum

Sem comentários:

Publicar um comentário