viewtopic.php?f=39&t=1956&start=10#p21003
Hola, ayer estuvimos hablando Jevilon y yo sobre como meter el SOTU en ZX-Uno sin cargar de cinta, lo cual es un poco incómodo porque lleva ROM propia, y por tanto paginar DIVMMC es un problema, asi que si no se puede usar DivMMC y no queremos usar cinta, solo queda una solución: que sea una ROM, como las que vienen con juegos de más de 16K en el ZX-Uno, pero incluyendo la ROM y todo, con lo cual sería 64K de ROM (como un +3 vamos).
Luego nos estuvo ayudando Antonio Villena y vimos un poco como hacerlo, resumiendo tenemos que cargar una ROM de 64K que consista en los tres bloques de RAM primero y la ROM del SOTU al final, en el último banco. Y luego parchearla en 0000 (que corresponderá a la zona de pantalla con lo cual guarreamos un poco pero no pasa nada) con una rutina que
1) Vaya paginando las otras paginas de ROM y copiando en el sitio adecuado de la RAM cada una
2) Finalmente pagine el 4º slot de ROM para que quede la ROM del SOTU en 0000
3) Restaure registros a tal y como estaban cuando se hizo el snapshot de la RAM original y haga un RET
Para hacer eso tengo dos códigos, uno en assembler con la rutina parche que hace todo eso, del que dudo, porque no me funciona. Muy probablemente estoy haciendo algo mal:
Código: Seleccionar todo
ORG $0000
PAG128KA EQU $7ffd
PAG128kB EQU $1ffd
START DI
LD DE, $4000
CALL ROM2RAM
JP $4000 + RestorePages
ROM2RAM LD HL, $0000
LD BC, $4000
LDIR
RET
RestorePages ; Page in second ROM bank
LD BC, PAG128KA
LD A, 00010000b ; Low ROM bit selector = 1
OUT (C), A
LD BC, PAG128kB
XOR A ; High ROM bit selector = 0, ROM==> 01
OUT (C), A
LD DE, $8000
CALL $4000 + ROM2RAM
; Page in third ROM bank
LD BC, PAG128KA
XOR A ; Low ROM bit selector = 0
OUT (C), A
LD BC, PAG128kB
LD A, 00000100b ; High ROM bit selector = 1, ROM==> 10
OUT (C), A
LD DE, $C000
CALL $4000 + ROM2RAM
; Page in 4th ROM bank, the real SOTU ROM, and keep it there
LD BC, PAG128KA
LD A, 00010000b ; Low ROM bit selector = 1
OUT (C), A
LD BC, PAG128kB
LD A, 00000100b ; High ROM bit selector = 1, ROM==> 10
OUT (C), A
; Finally, restore all register and other status from snapshot and return
RestoreSnapshot XOR A
OUT (254),a ; Border 0
LD I, A
LD A, $62
LD R, A
LD SP, $FFF0
EXX
EX AF, AF'
LD HL, $B6A0
PUSH HL
POP AF
LD HL, $2E7D
LD DE, $2BD5
LD BC, $00AA
EXX
EX AF, AF'
LD HL, $4204
PUSH HL
POP AF
LD HL, $00F4
LD DE, $0050
LD BC, $0042
LD HL, $0A00
LD IY, $800A
LD IX, $9C1D
; Nothing to do with interrupt as Snapshot is in DI status, and IM = 0
RET ; Return, taking address from stack as when the snapshot was made it was pushed
Y otro en Pascal, que coge la ROM del SOTU, un SNA grabado con el SOTU ya cargado, y el binario del parche, y genera al ROM SOTUNO.ROM
Código: Seleccionar todo
program sotupatch;
var SNAFile : file;
ROMFile : file;
OutputFile: file;
PatchFile: file;
Memory: array[0..$FFFF] of byte;
SNAHeader: array[0..26] of byte;
begin
AssignFile(OutputFile, 'SOTUZXUNO.ROM');
AssignFile(ROMFile, 'SOTU.ROM');
AssignFile(SNAFile, 'SOTU.SNA');
AssignFile(PatchFile, 'SOTUPATCH.BIN');
Rewrite(OutputFile, 1);
Reset(SNAFile, 1);
Reset(ROMFile,1);
Reset(PatchFile, 1);
(* Place SOTU ROM in last bank *)
BlockRead(ROMFile, Memory[$C000], $4000);
(* Read SNA header *)
BlockRead(SNAFile, SNAHeader, 27);
BlockRead(SNAFile, Memory, $C000);
(* And now, patch the RAM *)
BlockRead(PatchFile, Memory, FileSize(PatchFile));
(* Close all input files *)
CloseFile(SNAFile);
CloseFile(ROMFile);
CloseFile(PatchFile);
(* Write final ROM *)
BlockWrite(OutputFile, Memory, $10000);
CloseFile(OutputFile);
end.
Nota: los valores que meto en los registros al final del código Assembler los he cogido de la cabecera del SNA, si no ve nadie nada en el resto, lo repasaré minuciosamente, no sea algo tan tonto como que no he restaurado bien los valores.