Shadow of the Unicorn en ZX-Uno, sin cinta [solucionado]

Software para o relacionado con el core ZX Spectrum / Software for or related to the ZX Spectrum core
Avatar de Usuario
Uto
Mensajes: 1394
Registrado: 17 Dic 2015, 16:39

Shadow of the Unicorn en ZX-Uno, sin cinta [solucionado]

Mensaje por Uto » 14 Ene 2018, 14:40

SOLUCIONADO AQUI:

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.
                            
Sinceramente veo más probable un error en el assembler que en el pascal, pero soy todo oidos al respecto, porque obviamente si escribo es porque no me funciona :-D

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.
Última edición por Uto el 15 Ene 2018, 20:20, editado 2 veces en total.

Avatar de Usuario
Uto
Mensajes: 1394
Registrado: 17 Dic 2015, 16:39

Re: Shadow of the Unicorn en ZX-Uno, sin cinta

Mensaje por Uto » 14 Ene 2018, 14:51

Ah, se me olvidaba, la ROM la he parametrizado así:

Timing 128K, teclado issue 3, sin DivMMC, sin NMI-DivMMC, con memoria contenida, SD por deshabilitado, MMU Timex sin habilitar, AY y AY secundarios deshabilitados, y fuera los modos radastan, timex y ulaplus. Las cuatro opciones de la paginacion de RAM las he dejado por defecto, enabled por tanto.

zx81
Mensajes: 56
Registrado: 08 Ene 2018, 16:55

Re: Shadow of the Unicorn en ZX-Uno, sin cinta

Mensaje por zx81 » 14 Ene 2018, 14:54

El SotU era para 48k, no para 128k. Lo que sí recuerdo es que alguien se curró un método para ejecutarlo en el +2a/+3 poniendo la máquina en modo All-Ram y poniendo la ROM directamente en 0x0000. No lo he probado nunca, pero debería funcionar...

Zup
Mensajes: 112
Registrado: 16 Sep 2016, 20:22

Re: Shadow of the Unicorn en ZX-Uno, sin cinta

Mensaje por Zup » 14 Ene 2018, 15:25

El mayor problema es la rutina de carga y grabación, que creo que no está ubicada en las mismas direcciones que en la ROM de Sinclair (por lo que no salta el divMMC).

Se podría partir de la versión all-ram y hacer parches en las rutinas de grabación y de carga para que usen las rutinas de la ROM, pero no es fácil.

Avatar de Usuario
spark2k06
Mensajes: 1188
Registrado: 12 Feb 2016, 13:58

Re: Shadow of the Unicorn en ZX-Uno, sin cinta

Mensaje por spark2k06 » 14 Ene 2018, 15:52

Probad con el loader128k y 128sna2rom que hice yo en su momento:

https://github.com/spark2k06/zxuno/tree ... /loader128

Es que todo eso que haces de copiar a VRAM el cargador y ponerle el snapshot es precisamente lo que hago yo.

Enviado desde mi Thor mediante Tapatalk
Última edición por spark2k06 el 14 Ene 2018, 15:52, editado 1 vez en total.

Avatar de Usuario
Uto
Mensajes: 1394
Registrado: 17 Dic 2015, 16:39

Re: Shadow of the Unicorn en ZX-Uno, sin cinta

Mensaje por Uto » 14 Ene 2018, 16:05

Antonio me ha indicado que me faltaba inicializar la pila al principio, y tiene razón, la pila se queda en 0 y por tanto en empieza a rellenar por arriba del todo de la RAM y en algun momento machaco esa RAM.

Luego lo pruebo.

Avatar de Usuario
Uto
Mensajes: 1394
Registrado: 17 Dic 2015, 16:39

Re: Shadow of the Unicorn en ZX-Uno, sin cinta

Mensaje por Uto » 14 Ene 2018, 16:06

zx81 escribió:El SotU era para 48k, no para 128k. Lo que sí recuerdo es que alguien se curró un método para ejecutarlo en el +2a/+3 poniendo la máquina en modo All-Ram y poniendo la ROM directamente en 0x0000. No lo he probado nunca, pero debería funcionar...
Si, esto lo discutimos y descartamos como posibilidad ayer, puedes poner AllRAM y cargar la ROM en la RAM, pero luego ya tienes que cargar el resto, los otros 48K, de cinta, porque la carga de SOTU además no es la estandar de la ROM.

Avatar de Usuario
Uto
Mensajes: 1394
Registrado: 17 Dic 2015, 16:39

Re: Shadow of the Unicorn en ZX-Uno, sin cinta

Mensaje por Uto » 14 Ene 2018, 16:08

Zup escribió:El mayor problema es la rutina de carga y grabación, que creo que no está ubicada en las mismas direcciones que en la ROM de Sinclair (por lo que no salta el divMMC).

Se podría partir de la versión all-ram y hacer parches en las rutinas de grabación y de carga para que usen las rutinas de la ROM, pero no es fácil.
Eso ya sería rizar el rizo, por ahora solo queriamos que cargara el SOTU sin tener que meter cintas, para grabar partida me temo que no hay más remedio porque DIvMMC es altamente incompatible con la ROM de SOTU.

zx81
Mensajes: 56
Registrado: 08 Ene 2018, 16:55

Re: Shadow of the Unicorn en ZX-Uno, sin cinta

Mensaje por zx81 » 14 Ene 2018, 16:25

Uto escribió:
zx81 escribió:El SotU era para 48k, no para 128k. Lo que sí recuerdo es que alguien se curró un método para ejecutarlo en el +2a/+3 poniendo la máquina en modo All-Ram y poniendo la ROM directamente en 0x0000. No lo he probado nunca, pero debería funcionar...
Si, esto lo discutimos y descartamos como posibilidad ayer, puedes poner AllRAM y cargar la ROM en la RAM, pero luego ya tienes que cargar el resto, los otros 48K, de cinta, porque la carga de SOTU además no es la estandar de la ROM.
No puede usar la estándar de la ROM porque eso es lo primero que quita de en medio, la ROM del Spectrum, que es lo que va en el add-on.

Eso sí, lo de grabar partidas, chungo. Yo en JSpeccy lo hago grabando las partidas a microdrive, pero aquí no tenemos esa opción. (¿aún?). ;)

Avatar de Usuario
Uto
Mensajes: 1394
Registrado: 17 Dic 2015, 16:39

Re: Shadow of the Unicorn en ZX-Uno, sin cinta

Mensaje por Uto » 14 Ene 2018, 18:28

He actualizado el código metiendo el registro SP al principio, y controlando en todo momento donde está la pila para no liarla, pero me sigue pasando lo mismo, cuando cargo esta ROM el ZX-Uno se desincroniza (dejo de ver la pantalla como si cambiara a VGA) y además no responde (no funciona el hard reset), por lo que me toca apagar y encender.

He añadido comentarios profusamente por facilitar la compresión, y recuerdo que cuando cargo la ROM está en cada una de los 4 bancos de ROM lo que habia en el juego cargado en la siguientes direcciones:

[ROM 0][ROM 1][ROM 2][ROM 3]
[16384][32768][49152][0]

Por tanto primero está toda la RAM tal y como estaba, y al final está la ROM (la del Mikroplus claro).

No se, yo no le veo nada, pero obviamente se me escapa algo:

Código: Seleccionar todo

		ORG $0000	


PAG128KA 	EQU $7ffd
PAG128kB 	EQU $1ffd


START		DI				; Not required as Z80 starts with interrupt disabled, but just to make sure
		LD 	SP, $FF00		; Place stack in last RAM bank
		
		LD 	DE, $4000               ; Copy whole ROM 0-16383 to first ram bank at $4000 (16384)
		CALL 	ROM2RAM                 ; This routine copies whole ROM into address at DE
		LD 	SP, $4200		; Now that we have copied RAM in first RAM bank, put stack there, in video RAM so any push just affects screen
		JP 	$4000 + RestorePages    ; Jump to next instruction, but in the clone we have just made in RAM

ROM2RAM		LD 	HL, $0000		; From 0000, to what it's in DE
		LD 	BC, $4000		; 16384 bytes
		LDIR				; copies ROM to RAM
		RET

RestorePages	; Page in second ROM bank
	 	LD      BC, PAG128KA
		LD 	A, 00010000b          	; Low ROM bit selector = 1   (00- 0 = memory paging enabled - 1= ROM 1 - 0=Normal screen - 000 = RAM page 0 )
		OUT 	(C), A
		LD 	BC, PAG128kB
		XOR 	A		      	; High ROM bit selector = 0, ROM==> 01
		OUT 	(C), A

		LD 	DE, $8000		; Copy  second ROM bank into $8000 (32768)
		CALL 	$4000 + ROM2RAM		; By calling the copy of ROM2RAM we made at first RAM bank, as the original at ROM bank is no longer there

		; 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		; Copy third ROM bank into $C000 (49152)
		CALL $4000 + ROM2RAM		; By calling the copy of ROM2RAM we made at first RAM bank, as the original at ROM bank is no longer there

		; 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

Responder