Acceso a disco desde código máquina con Spectrum +3
Moderador: Sir Cilve Sinclair
- Nat
- Herbert
- Mensajes: 95
- Registrado: Lun Mar 25, 2019 9:31 am
Acceso a disco desde código máquina con Spectrum +3
No estoy teniendo suerte buscando documentación específica sobre cómo acceder al disco en un Spectrum +3 utilizando código máquina, es decir, hacer las operaciones comunes de carga, grabación, borrado, catálogo del disco, etc. llamando directamente a las funciones de la ROM.
¿Es muy rebuscado o está disponible? Gracias.
¿Es muy rebuscado o está disponible? Gracias.
Saludos,
Nat
Nat
-
- Freddy Hardest
- Mensajes: 666
- Registrado: Vie Ago 15, 2008 2:43 pm
Re: Acceso a disco desde código máquina con Spectrum +3
Está todo en el capítulo 8, sección 27 del manual del +3. Salvo un pequeño error en fopen, está todo ahí.
Personalmente, he usado las funciones típicas (open, close, read, write, seek), pero no he utilizado las de catálogo ni borrado.
Personalmente, he usado las funciones típicas (open, close, read, write, seek), pero no he utilizado las de catálogo ni borrado.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...
- Nat
- Herbert
- Mensajes: 95
- Registrado: Lun Mar 25, 2019 9:31 am
Re: Acceso a disco desde código máquina con Spectrum +3
Muy bueno. Gracias.
No tengo experiencia más que con el gomas 48 pero es suficiente para empezar aunque esperaba algo más trabajado con ejemplos de uso para agilizar el desarrollo. Con mil sitios así para cualquier tarea con el gomas, me ha extrañado encontrarme con este desierto de resultados.
El manual lo encontré en WOS, una versión muy primitiva en texto entre tags <pre> que parece proceder de un escaneo con OCR, con infinidad de typos y errores HTML, como confundir a<b con a<b y que al intentar arreglarlo con búsquedas y reemplazos desde el editor les ha liado sin que se den cuenta unas bien gordas en varios capítulos. La sorpresa es la leonina defensa que hacen del manual que hace casi imposible descargarlo offline. He intentado con wget pero he tenido que ir completando con más y más headers y otros switches hasta conseguir evitar el terrible Error 403 Forbidden.
Después de corregirlo parcialmente tomando como fuente para la comparación el manual en PDF del ZX Spectrum +2 os facilito el texto completo en una cuenta de Dropbox que acabo de crear para el manual.
Encontré también esta versión en español del manual en Archive.org y otra versión del manual en inglés en
Spectrum Computing.
Edit: Miro ahora en RetrocodingUK que parecen tener algo de este tema.
No tengo experiencia más que con el gomas 48 pero es suficiente para empezar aunque esperaba algo más trabajado con ejemplos de uso para agilizar el desarrollo. Con mil sitios así para cualquier tarea con el gomas, me ha extrañado encontrarme con este desierto de resultados.
El manual lo encontré en WOS, una versión muy primitiva en texto entre tags <pre> que parece proceder de un escaneo con OCR, con infinidad de typos y errores HTML, como confundir a<b con a<b y que al intentar arreglarlo con búsquedas y reemplazos desde el editor les ha liado sin que se den cuenta unas bien gordas en varios capítulos. La sorpresa es la leonina defensa que hacen del manual que hace casi imposible descargarlo offline. He intentado con wget pero he tenido que ir completando con más y más headers y otros switches hasta conseguir evitar el terrible Error 403 Forbidden.
Después de corregirlo parcialmente tomando como fuente para la comparación el manual en PDF del ZX Spectrum +2 os facilito el texto completo en una cuenta de Dropbox que acabo de crear para el manual.
Encontré también esta versión en español del manual en Archive.org y otra versión del manual en inglés en
Spectrum Computing.
Edit: Miro ahora en RetrocodingUK que parecen tener algo de este tema.
Saludos,
Nat
Nat
-
- Freddy Hardest
- Mensajes: 666
- Registrado: Vie Ago 15, 2008 2:43 pm
Re: Acceso a disco desde código máquina con Spectrum +3
Si quieres te posteo un cargador de un juego. Yo he aprendido todo lo que sé con ese manual, desensamblar o el cargador del Camión Bubble y probando burradas con ZX Spin.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...
- Nat
- Herbert
- Mensajes: 95
- Registrado: Lun Mar 25, 2019 9:31 am
Re: Acceso a disco desde código máquina con Spectrum +3
Estoy haciendo alguna cosa con el manual, de momento he conseguido grabar el contenido de la pantalla en el disco.
Funciona sin problemas pero como mi objetivo es pasar juegos del 48 al +3 cuando intento después grabar grandes bloques de memoria, desde mi desconocimiento del +3, veo cosas raras como que al cargar lo grabado hay parte que no está. Creo que se deberá a algo relacionado con la paginación y demás, quizás para cargar bloques muy grandes -y algunos juegos de 48 tenían toda la memoria desde 16384 hasta 65535- haya que usar técnicas más específicas para +3. Por otra parte, con el manual delante advierto que la zona de variables de sistema se ha ampliado, comiéndose toda la zona reservada para el buffer de impresión y hay muchos juegos de 48 que hacen uso de esa zona de memoria para datos o variables. A saber qué ocurre si algún programa machaca el contenido de BANKM (05B5Ch).
Acabo de empezar y tengo que dedicarle bastante más tiempo pero no me vendrá mal ver ese cargador por si me da ideas porque cargadores son lo que justamente estoy escribiendo. Gracias.
PD: En Pluma veo el código perfectamente tabulado pero al pegarlo al foro, la fuente escogida para el BBCode code no lo muestra bien alineado. Mis disculpas.
Código: Seleccionar todo
STACK: equ $9FFF ; arbitrary value picked to be below BFE0h and above 4000h
BANKM: equ $5B5C ; system variable that holds the last value output to 7FFDh
BANKP: equ $7FFD ; address of ROM/RAM switching port in I/O map
DOS_WRITE: equ $0115
DOS_OPEN: equ $0106
DOS_CLOSE: equ $0109
DOS_REFHEAD:equ $010F
CDOSCREATE: equ 1 ; Create action
CDOSOPEN: equ 3 ; Open action
DOSTB_TYPE: equ 0 ; Byte: File type (0=BASIC, 1=Array...)
DOSTB_SIZE: equ 1 ; Word: Length
DOSTB_LINE equ 3 ; Word: $8000 OR BASIC LINE
DOSTB_LDAD: equ 3 ; Word: Load address
DOSTB_OFFP: equ 5 ; Word: Offset to prog
CDOSTCODE: equ 3 ; File type CODE/SCREEN$
CDOSSRCBUF: equ 5 ; Source buffer page 5 $4000...$7FFF
CDOSFILEn: equ 1 ; File # 1
DATASTART: equ $4000
DATASIZE: equ $1B00
org $8000
_START_: di ; disable interrupts before switching RAM/ROM
ld (SPBASICv+1),SP ; save BASIC's stack pointer
ld BC,BANKP ; the horizontal ROM switch/RAM switch I/O address
ld A,(BANKM) ; system variable that holds current switch state
res 4,A ; move right to left in horizontal ROM switch (ROM 3 to ROM 2)
or 7 ; switch in RAM page 7
ld (BANKM),A ; must keep system variable up to date (very important!)
out (C),A ; make the switch
ld SP,STACK ; make sure stack is above 4000h and below BFE0h
ei ; interrupts can now be enabled
; Open file
ld HL,FILENAME ; filename CANNOT include wildcards
ld B,CDOSFILEn ; file number set to one
ld C,0 ; zero C reg
set 1,C ; bit set (on)
ld D,CDOSCREATE ; Create action on
ld E,CDOSOPEN ; Open action on
call DOS_OPEN ; call to +DOS
; Header
ld B,CDOSFILEn ; file number set to 1
call DOS_REFHEAD ; get pointer to header
ld HL,DATASTART ; fill header data
ld DE,DATASIZE
ld (IX+DOSTB_TYPE),CDOSTCODE ; file type CODE/SCREEN$
ld (IX+DOSTB_SIZE),E ; set file length
ld (IX+DOSTB_SIZE+1),D
ld (IX+DOSTB_LDAD),L ; set load address
ld (IX+DOSTB_LDAD+1),H
; Write file
ld B,CDOSFILEn ; file number set to 1
ld HL,DATASTART
ld DE,DATASIZE
ld C,5
call DOS_WRITE ; write it
; Close file
ld B,CDOSFILEn ; file number set to 1
call DOS_CLOSE
di ; disable interrupts before switching RAM/ROM
push BC ; save number of files
ld BC,BANKP ; I/O address of horizontal ROM/RAM switch
ld A,(BANKM) ; get current switch state
set 4,A ; move left to right (ROM 2 to ROM 3)
and $F8 ; also want RAM page 0
ld (BANKM),A ; update the system variable (very important!)
out (C),A ; make the switch
pop BC ; get back the saved number of files in catalog
SPBASICv: ld SP,000 ; put BASIC's stack back (placeholder for BASIC's stack)
ret ; return to BASIC, value in BC is returned to USR
FILENAME: db "SCREEN",$FF ; the file name, must be terminated with $FF
_END_
Acabo de empezar y tengo que dedicarle bastante más tiempo pero no me vendrá mal ver ese cargador por si me da ideas porque cargadores son lo que justamente estoy escribiendo. Gracias.
PD: En Pluma veo el código perfectamente tabulado pero al pegarlo al foro, la fuente escogida para el BBCode code no lo muestra bien alineado. Mis disculpas.
Saludos,
Nat
Nat
-
- Freddy Hardest
- Mensajes: 666
- Registrado: Vie Ago 15, 2008 2:43 pm
Re: Acceso a disco desde código máquina con Spectrum +3
Cuidado con el número de fichero, yo suelo empezar en 5. Creo que los más bajos están "cogidos" por el sistema y pueden dar problemas.natohara escribió:Estoy haciendo alguna cosa con el manual, de momento he conseguido grabar el contenido de la pantalla en el disco.
Cuatro cosas cosas:natohara escribió:Funciona sin problemas pero como mi objetivo es pasar juegos del 48 al +3 cuando intento después grabar grandes bloques de memoria, desde mi desconocimiento del +3, veo cosas raras como que al cargar lo grabado hay parte que no está. Creo que se deberá a algo relacionado con la paginación y demás
- Lo que apuntaba del número de fichero, aunque puede que no de problemas.
- En ningún momento compruebas que haya habido errores. Carry a 0 significa error, carry a 1 significa OK. Te recomendaría que pongas breakpoints tras las llamadas... puede que tu problema sea algún error no controlado.
- Hay un error en el manual del +3, en la llamada dos open todos los números están corridos una unidad. Es decir, donde pone "2. Open the file read..." debería poner "1. Open the file read...". No sé la documentación que tienes tú está corregida.
- Cuidado con las cabeceras y las acciones asociadas. Hay dos modos de crear/usar un fichero: con y sin cabecera. Si hay cabecera, los primeros 128 bytes del fichero son la cabecera. El tema es que si creas un fichero con cabecera y luego lo abres SIN cabecera o le indicas a +3DOS que ignore la cabecera, los primeros 128 bytes que vas a leer son la cabecera en sí... lo que puede llevarte a confusión.
Las cabeceras son informativas y son las que permiten cargar desde BASIC sin demasiados problemas. Un fichero sin cabecera se puede copiar usando COPY, pero a la hora de cargarlo suele dar errores del estilo "Invalid File Type" o algo así. Personalmente, yo guardo y cargo todo SIN cabecera... así nunca me confundo
¡BUM! El sistema se cuelga. Te acabas de cargar las rutinas de paginación del Spectrum. Es algo que pasa en los 128k en general. Y te preguntarás... ¿por qué no se cuelga al cargar (p.ej.) el Humphrey que carga casi toda la RAM? Pues porque el problema lo vas a tener si retornas a BASIC. En esos juegos, el cargador salta directamente al c/m del juego, así que no tienes problemas.natohara escribió:Por otra parte, con el manual delante advierto que la zona de variables de sistema se ha ampliado, comiéndose toda la zona reservada para el buffer de impresión y hay muchos juegos de 48 que hacen uso de esa zona de memoria para datos o variables. A saber qué ocurre si algún programa machaca el contenido de BANKM (05B5Ch).
Lo que yo hago en esos casos es cargar la pantalla y toda la RAM desde 24576 hacia arriba normalmente. Los 1280 bytes que van desde 23296 hasta 24575 los cargo en la RAM 3 junto con una rutina que los reubique a su posición original, ponga la página 0 y salte al c/m del juego. Cuando termino con el disco (ya no hay riesgo de reventar nada), pagino la RAM 3 y llamo a la rutina en cuestión.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...
- Nat
- Herbert
- Mensajes: 95
- Registrado: Lun Mar 25, 2019 9:31 am
Re: Acceso a disco desde código máquina con Spectrum +3
Es una simple prueba de concepto, nada serio ni que vaya a acabar funcionando en un sistema real. Empiezo de esta forma para verificar que me entiendo con el +3DOS, que hace lo que se supone que debe hacer y que no he interpretado mal la documentación. Igual con la inexistente gestión de errores, no compensa dedicarle tiempo si hay un error de concepto y el código va a ser desechado. Todo eso lo dejo para las versiones finales más estables.zup escribió:Cuidado con el número de fichero, yo suelo empezar en 5. Creo que los más bajos están "cogidos" por el sistema y pueden dar problemas.
En cuanto a las acciones no hay problema en mi documentación, por eso probé el crear el fichero de forma que si existía generase automáticamente el .BAK así verifiqué la combinación 1/3 con una única comprobación. En el modo de acceso no estoy tan seguro, aún no he probado si exclusive-read o exclusive-write están intercambiados.zup escribió:- Hay un error en el manual del +3, en la llamada dos open todos los números están corridos una unidad. Es decir, donde pone "2. Open the file read..." debería poner "1. Open the file read...". No sé la documentación que tienes tú está corregida.
No son necesarias y siguiendo tu sistema tampoco pienso usarlas.zup escribió:- Cuidado con las cabeceras y las acciones asociadas. Hay dos modos de crear/usar un fichero: con y sin cabecera. Si hay cabecera, los primeros 128 bytes del fichero son la cabecera. El tema es que si creas un fichero con cabecera y luego lo abres SIN cabecera o le indicas a +3DOS que ignore la cabecera, los primeros 128 bytes que vas a leer son la cabecera en sí... lo que puede llevarte a confusión.
Algo muy parecido haré con la página 0 que no hay forma de cargar nada en ella porque +3DOS hace un uso intensivo de la página 7 pero aún tengo todo muy en el aire y solo hago pruebas y más pruebas.zup escribió:Lo que yo hago en esos casos es cargar la pantalla y toda la RAM desde 24576 hacia arriba normalmente. Los 1280 bytes que van desde 23296 hasta 24575 los cargo en la RAM 3 junto con una rutina que los reubique a su posición original, ponga la página 0 y salte al c/m del juego. Cuando termino con el disco (ya no hay riesgo de reventar nada), pagino la RAM 3 y llamo a la rutina en cuestión.
Gracias por tu colaboración.
Última edición por Nat el Jue May 23, 2019 10:26 am, editado 1 vez en total.
Saludos,
Nat
Nat
-
- Freddy Hardest
- Mensajes: 666
- Registrado: Vie Ago 15, 2008 2:43 pm
Re: Acceso a disco desde código máquina con Spectrum +3
No se trata de hacer una gestión de errores "completa", sino de que quede evidente cuando ha habido un error. Por ejemplo, hacer una minirutina que ponga el borde rojo y bloquee el equipo (dos instrucciones) y meter un jr nc a la rutina cada vez que haces una operación. Los errores de disco son bastante silenciosos, y te ayudará a ver rápidamente qué está bien hecho y qué mal (eso, o cada vez que metas algo nuevo tendrás que tirar de depurador).natohara escribió:Igual con la inexistente gestión de errores, no compensa dedicarle tiempo si hay un error de concepto y el código va a ser desechado.
Te lo comentaba porque el código de muestra (leído de manera muy rápida) parece que si las usaba.natohara escribió:No son necesarias y siguiendo tu sistema tampoco pienso usarlas.
Las problemáticas son la página 1 y la 7, la cero no da problemas para nada. Las funciones read y write tienen un parámetro para indicar la página que quieres cargar (va en c). De manera que (aunque para acceder a +3DOS tengas paginada ROM2/RAM7) para cargar 1280 bytes en la página 3 el código sería algo de este estilo:natohara escribió:Algo muy parecido haré con la página 0 que no hay forma de cargar nada en ella porque +3DOS hace un uso intensivo de la página 7 pero aún tengo todo muy en el aire y solo hago pruebas y más pruebas.
Código: Seleccionar todo
ld b,5
ld c,3
ld hl,49152
ld de,1280
call dos_read
Código: Seleccionar todo
ld b,5
ld c,0
ld hl,24576
ld de,40960
call dos_read
La página 1 está algo menos claro. El problema es que los primeros 4k de esta página se emplean para la caché de disco, así que cualquier cosa que pongas ahí será sobreescrita sin piedad. Si tienes planeado usar este área, no hay mucho problema... solo hay que decirle al sistema que NO emplee caché de disco. Para ello, hay que usar la función dos_set_1346 (en $013f), poniendo de y hl a 0.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...
-
- Freddy Hardest
- Mensajes: 666
- Registrado: Vie Ago 15, 2008 2:43 pm
Re: Acceso a disco desde código máquina con Spectrum +3
Tocho de código 1: un cargador para Mad Mix Game y Pepsi Challenge. Se usan tres ficheros separados (ahora no recuerdo si tienen o no cabecera) para las pantallas y los datos.
Tocho de código 2: algo un poquito más avanzado. Los mismos juegos, pero con todo (pantalla y código) en un único fichero.
A ver si luego encuentro algo de 128k, o algo que se lleve por delante casi toda la RAM...
Código: Seleccionar todo
dos_init equ 256
dos_open equ 262
dos_close equ 265
dos_abandon equ 268
dos_read equ 274
dos_write equ 277
dos_set_drive equ 301
dos_set1346 equ 319
dos_free_space equ 289
dos_set_pos equ 310
dd_l_off_motor equ 412
BANK678 equ 23399
BANKM equ 23388
ini_pant equ 16384
lon_pant equ 6912
ini_madmix equ 24576
lon_madmix equ 36790
lon_pepsi equ 36800
juego equ 24576
inicio equ 24400
org inicio
di
; cargar la pantalla
ld ix,ini_pant
ld de,lon_pant
ld a,0
ld hl,fich_pant
call cargar
; cargar el juego
ld ix,ini_madmix
ld de,lon_madmix
ld hl,fich_madmix
; Si 24576=0, se carga Mad Mix
; si no, se carga Pepsi Challenge
ld a,(juego)
or a
jr z, carga_juego
ld de,lon_pepsi
ld hl,fich_pepsi
carga_juego:
ld a,0
call cargar
; parar el disco y lanzar el juego
call parar_disco
ei
jp 24576
paginar:
ld bc,32765
ld (BANKM),a
out (c),a
ret
cargar:
; Esta rutina carga ficheros con +3DOS
; a=página donde se va a cargar
; ix=dirección inicial
; de=longitud de datos
; Si hay error -> reset
push af
push ix
push de
; poner ROM2/RAM7 para usar +3DOS
di
ld a,$07
call paginar
; abrir el fichero apuntado por hl
ld bc,$0501
ld de,$0001
call dos_open
jp nc,0
; Se cargan los datos
pop de
pop hl
pop af
ld b,5
ld c,a
call dos_read
jp nc,0
; se cierra el fichero
ld b,5
call dos_close
jp nc,0
; se vuelve a poner ROM0/RAM0
ld a,$10
call paginar
ret
parar_disco:
ld a,$07
call paginar
call dd_l_off_motor
ld a,$10
call paginar
ret
fich_pant:
db 'MADMIX.$',$ff
fich_madmix:
db 'MADMIX.C',$ff
fich_pepsi:
db 'PEPSI.C',$ff
Código: Seleccionar todo
dos_init equ 256
dos_open equ 262
dos_close equ 265
dos_abandon equ 268
dos_read equ 274
dos_write equ 277
dos_set_drive equ 301
dos_set1346 equ 319
dos_free_space equ 289
dos_set_pos equ 310
dd_l_off_motor equ 412
BANK678 equ 23399
BANKM equ 23388
ini_pant equ 16384
lon_pant equ 6912
ini_madmix equ 24576
lon_madmix equ 36790
lon_pepsi equ 36800
juego equ 24576
inicio equ 24400
org inicio
di
; poner ROM2/RAM7 para usar +3DOS
di
ld a,$07
call paginar
; abrir el fichero del juego
ld hl,fich_juego
ld bc,$0501
ld de,$0001
call dos_open
jp nc,0
; Se cargan la pantalla de presentación
ld hl,ini_pant
ld de,lon_pant
ld bc,$500
call dos_read
jp nc,0
ld hl,ini_madmix
ld de,lon_madmix
; Si 24576=0, se carga Mad Mix Game
; si no, se carga The Pepsi Challenge
ld a,(juego)
or a
jr z,carga_bloque_juego
; Nos saltamos el bloque de Mad Mix Game
ld b,5
ld e,0
ld hl,lon_pant+lon_madmix
call dos_set_pos
jp nc,0
ld hl,ini_madmix
ld de,lon_pepsi
carga_bloque_juego:
ld bc,$500
call dos_read
jp nc,0
; se cierra el fichero
ld b,5
call dos_close
jp nc,0
; se detiene el disco
call dd_l_off_motor
; se vuelve a poner ROM0/RAM0
ld a,$10
call paginar
; se ejecuta el juego
jp 24576
paginar:
ld bc,32765
ld (BANKM),a
out (c),a
ret
fich_juego:
db 'MADMIX.BIN',$ff
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...
- Nat
- Herbert
- Mensajes: 95
- Registrado: Lun Mar 25, 2019 9:31 am
Re: Acceso a disco desde código máquina con Spectrum +3
Como te decía era una prueba con la única intención de familializarme con el interfaz del +3DOS, habrás visto también que el código escribe en disco (el contenido de la pantalla) y de hecho para el cargador final no he necesitado escribir para nada porque los bloques definitivamente los he generado desde PC que me es más cómodo.zup escribió:No se trata de hacer una gestión de errores "completa",...
...
Te lo comentaba porque el código de muestra (leído de manera muy rápida) parece que si las usaba.
El problema en mi caso viene porque la parte libre de la RAM del Spectrum 48 está en la página 0, en la que está el cargador original y que además inicializa SP a 0 ¿Es posible ejecutar el cargador desde esa página? Imagino que solo la pila de retorno supone un obstáculo.zup escribió:Las problemáticas son la página 1 y la 7, la cero no da problemas para nada.
Las funciones read y write tienen un parámetro para indicar la página que quieres cargar (va en c). De manera que (aunque para acceder a +3DOS tengas paginada ROM2/RAM7) para cargar 1280 bytes en la página 3 el código sería algo de este estilo:
Muchas gracias zup, por la explicación y por el código (que me lo guardo), esto es muy interesante y sin duda supera las necesidades que tenía para este cargador pero, quién sabe, es más que posible que lo aproveche en el futuro.zup escribió:La página 1 está algo menos claro.
Saludos,
Nat
Nat
- Nat
- Herbert
- Mensajes: 95
- Registrado: Lun Mar 25, 2019 9:31 am
Re: Acceso a disco desde código máquina con Spectrum +3
Encontré más información sobre el acceso a disco en estos artículos de Juan Carlos Jaramago, Carlos Enrique Alcántara y Pedro José Rodríguez Larrañaga en MHoogle en este enlace:
http://mhoogle.speccy.org/mhoogle.php?b ... bajo+nivel
o para leerlos offline en este otro:
https://mega.nz/#!fzZglS4Q!ihuOErrLTsAM ... ONevohpze0
http://mhoogle.speccy.org/mhoogle.php?b ... bajo+nivel
o para leerlos offline en este otro:
https://mega.nz/#!fzZglS4Q!ihuOErrLTsAM ... ONevohpze0
Saludos,
Nat
Nat
¿Quién está conectado?
Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 36 invitados