Commodore manía
Commodore 64 => Desarrollo => Mensaje iniciado por: darro99 en Enero 27, 2019, 11:53:15
-
Hola buenas a todos!
Estoy intentando integrar un grabación de records en disco, pero estoy teniendo problemas.
El caso es que para la grabación del fichero sin que exista anteriormente funciona correctamente. El problema viene cuando hay que reemplazar este fichero con uno nuevo.
El codigo que estoy usando lo he sacado de este link:
https://www.lemon64.com/forum/viewtopic.php?t=64677&sid=3b6de77b5fde4e3f9c6b0ad214ad5ea6 (https://www.lemon64.com/forum/viewtopic.php?t=64677&sid=3b6de77b5fde4e3f9c6b0ad214ad5ea6)
Usa las funciones del Kernal para grabar/cargar el fichero desde el disco.
Este el código (realmente es la parte que falla, la que llaman scratch):
.const file_start = $25a6 // Inicio datos C64
.const file_end = $25b2
// most likely errors:
// a = $05 (device not present)
// a = $04 (file not found)
// a = $1d (load error)
// a = $00 (break, run/stop has been pressed during loading)
//Constantes del kernal
.const K_close = $ffc3
.const K_open = $ffc0
.const K_setnam = $ffbd
.const K_setlfs = $ffba
.const K_clrchn = $ffcc
.const K_load = $ffd5
.const K_save = $ffd8
.const temp1 = $c1
.const temp2 = $c2
scratch:
.text "S0:"
fname:
.text "RECORDS"
fname_end:
lastDevice:
.byte 8 // Range 8-11
saveData:
jsr loadprepare
// ** SCRATCH OLD FILE **
lda #$0f // Logical
ldy #$0f // Secondary
jsr loadsetlfs2
lda #fname_end-scratch
ldx #<scratch // XY ptr
ldy #>scratch
jsr K_setnam
jsr K_open
bcc noError2
sta errorLevel
inc ioError
noError2:
lda #$0f // Logical
jsr K_close
jsr K_clrchn
jsr cargaMiZp
lda #$35 //desactivacion de las funciones Kernal
sta $01
lda #$01
sta $d01a //turn on raster irq.
cli
rts
// Prepare hardware for IO operation
loadprepare:
sei // Disable IRQ
lda #0
sta $d01a //turn off raster irq.
jsr grabaMiZp
jsr cargaZp
lda #$36 // Kernal on
sta $01
lda #0 // Reset rs 232
sta $02a1
sta $d404 // Sid silent
sta $d404+7
sta $d404+14
sta $9d // Disable KERNAL messages
sta ioError // Clear error return flag
rts
loadsetlfs:
lda #$01 // Logical
ldy #$00 // Secondary
loadsetlfs2:
ldx lastDevice
jmp K_setlfs
Cuando se ejecuta este código, no aparecen errores en las variables ioError/errorLevel. Por eso tampoco sé lo que se está haciendo mal :(
He estado comprobando otra pagina de referencia para comandos del DOS:
https://en.wikipedia.org/wiki/Commodore_DOS (https://en.wikipedia.org/wiki/Commodore_DOS)
Y parece que para el borrado de fichero se usa el comando:
OPEN 15,8,15,"S0:file name":CLOSE 15
que creo que es el se está usando en el código.
Alguien puede echarme una manilla con esto.
Gracias de antemano.
-
Donde lo pruebas en VICE ? en una 1541 real ? en un SD2IEC ?
-
Donde lo pruebas en VICE ? en una 1541 real ? en un SD2IEC ?
Lo estoy probando con el VICE
-
Jolin, yo me acuerdo que Silicebit me enseño a borrar ficheros de un Disk pero de no hacerlo se me olvido al final, recuerdo que es muy sencillo, con una simple instruccion lo haces, de las del tipo: Load "xxx",8,..pero en vez de load simplemente ponia una letra y ya esta.
Recuerdo que era sencillisimo, como te digo con una sola letra ya borrabas el archivo entrecomillado, siento no poder ayudarte mas, pero como te digo indaga que es mas sencillo de lo que parece, no necesitas rutinas.
Siento no poder ayudarte mas...Un saludo.
-
leyendo mi mensaje, anda que no me repito en las frases, el asm me esta dejando la mente en bucle,..ja,j,aj,ja,j,a
-
En el vice el numero de device creo que es 0 no 8 si usas una carpeta del sistema en vez de una imagen d64.
-
Hola de nuevo.
con una simple instruccion lo haces, de las del tipo: Load "xxx",8,..pero en vez de load simplemente ponia una letra y ya esta.
Creo que sé a lo que te refieres, puede ser esto?
OPEN 15,8,15,"S0:file name":CLOSE 15
En realidad es lo que estoy intentando usar, solo que en asm, para hacer el borrado del fichero pero no parece funcionar.
leyendo mi mensaje, anda que no me repito en las frases, el asm me esta dejando la mente en bucle,..ja,j,aj,ja,j,a
Es lo que tiene el pensamiento para el código spaghetti generado con el asm. Al final a todos nos alcanza :D
En el vice el numero de device creo que es 0 no 8 si usas una carpeta del sistema en vez de una imagen d64.
La prueba la realizo montado un fichero d64, y el device es 8. De hecho si no existe el fichero en el disco lo graba correctamente. Pero al intentar sobreescribirlo no lo hace, ni borra, ni lo reescribe. Ademas no parece generar ningun error ???
Según la documentación que he consultado hay que borrarlo y a continuación grabarlo de nuevo. Pero no estoy consiguiendo borrarlo.
Gracias por las respuestas, seguiré estrujando un poco las meninges a ver si doy con ello :)
-
En el ejemplo de lemon no usan "S0:" sino esto:
scratch byte $53,$30,$3A ;"s0:" $13 / $53
A ver si va a tener algo que ver con la conversión ASCII -> PETSCII que hace el ensamblador.
-
Desde luego el comando S0 yo lo he utilizado alguna vez en una 1541. Y sí, lo hice para reescribir un fichero también.
Lo que rulas comentó de borrar con un comando de una letra debe ser un wedge de disco tipo jiffydos.
Lo que comenta mj supongo que te has asegurado que el nombre del fichero es idéntico al grabar y borrar que en ese listado veo una mezcla importante de letras mayusculas y minúsculas.
Esas rutinas del kernal no las he usado nunca pero sí otras y usarlas no tiene nada de especial o sea que no sé.
-
Además si distingue, las buenas son las minúsculas
-
A ver si va a tener algo que ver con la conversión ASCII -> PETSCII que hace el ensamblador.
Esto es lo que puede ser, pero al mirar como aparecen en el monitor del VICE, las letras aparecen correctas si lo ejecuto con la etiqueta .text
En el ejemplo de lemon no usan "S0:" sino esto:
Llevas razón, antes había probado con diferentes combinaciones de números, pero me di cuenta que realmente ponía S0:, y como no funcionaba decidí cambiarlas por el texto a ver si con esto lo conseguía, pero no ha habido suerte.
He vuelto a probar con diferentes códigos de 'S' a través de esta pagina:
http://sta.c64.org/cbm64scr.html (http://sta.c64.org/cbm64scr.html)
He probado con:
.byte $13,$30,$3A
.byte $93,$30,$3A
.byte $53,$30,$3A
.byte $D3,$30,$3A
(En todas estas prueba no he tenido suerte)
Solo he cambiado la S, por que tanto los ':', como el cero solo aparecen una vez en la lista.
-
Has probado con 's' minuscula?
-
Buenas de nuevo!!!
Por fin he conseguido hacer el borrado y la grabación ;D
El problema venia por mi propia aplicación al intentar realizar la grabación de los datos. Existía un problema de sincronización entre la salida de la rutina de borrado/grabado y la ejecución del resto del programa, incluido el estado y orden de ejecución de las irqs.
Para averiguarlo he sacado la rutina completa a un programa aparte para ver si funcionaba, y resulta que el código corría correctamente.... Bueno he tenido que cambiar los registros en la invocación a la rutina open del kernal ;)
El tema de la 'S' es con el código $53.
Aquí dejo la rutina completa, funciona correctamente
.pc = $2200
.const file_start = $25a6 // Inicio datos C64
.const file_end = $25b2
jsr loadprepare
// ** SCRATCH OLD FILE **
lda #fname_end-scratch
ldx #<scratch // XY ptr
ldy #>scratch
jsr K_setnam
lda #$01 // Logical
ldy #$0F // Secondary
ldx #8
jsr K_setlfs
jsr K_open
bcc noError2
sta errorLevel
inc ioError
lda #2
sta BORDER
noError2:
lda #$01 // Logical
jsr K_close
jsr K_clrchn
// ** SAVE NEW FILE **
jsr loadsetlfs
jsr loadsetnam
lda #<file_start // ZP ptr to start address
sta temp1
lda #>file_start
sta temp2
ldx #<file_end // XY = end address
ldy #>file_end
lda #temp1 // ZP ptr, 1st byte
jsr K_save
bcc noError3
sta errorLevel
inc ioError
noError3:
//jmp closeExit
// Close open file and return
closeExit:
lda #$01 // Logical
jsr K_close
jsr K_clrchn
jsr cargaMiZp
lda #$35 //desactivacion de las funciones Kernal
sta $01
lda #$01
sta $d01a //turn on raster irq.
cli
lda #1
sta BORDER
jmp *
// Prepare hardware for IO operation
loadprepare:
sei // Disable IRQ
lda #0
sta $d01a //turn off raster irq.
jsr grabaMiZp
jsr cargaZp
lda #$36 // Kernal on
sta $01
lda #0 // Reset rs 232
sta $02a1
sta $d404 // Sid silent
sta $d404+7
sta $d404+14
sta $9d // Disable KERNAL messages
sta ioError // Clear error return flag
rts
// SETLFS. Set file parameters.
// Input: A = Logical number// X = Device number// Y = Secondary address.
loadsetlfs:
lda #$01 // Logical
ldy #$00 // Secondary
loadsetlfs2:
ldx lastDevice
jmp K_setlfs
// SETNAM. Set file name parameters.
// Input: A = File name length// X/Y = Pointer to file name.
loadsetnam:
lda #fname_end-fname
ldx #<fname // XY ptr
ldy #>fname
jmp K_setnam
Unas ultimas aclaraciones:
Hay que guardar anteriormente la memoria de la pagina cero, por ejemplo nada mas arrancar el programa.
Antes de usar las rutinas kernal se restaura esa memoria anteriormente guardada, guardando la propia pagina cero de tu programa, para una vez llamadas las funciones del kernal restaurar de nuevo la pagina cero propia.
Todo esto, si tu programa usa la pagina cero claro.
Este vaivén de cargas y grabaciones de memoria es debido a que las rutinas del kernal usan la pagina cero.
Gracias a todos por sus comentarios 8)