Autor Tema: Borrado de un fichero en disco  (Leído 5507 veces)

darro99

  • Desarrolladores
  • Commodorista
  • ******
  • Mensajes: 57
  • PRESS PLAY ON TAPE
    • Ver Perfil
Borrado de un fichero en disco
« 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

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):
Código: [Seleccionar]
.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
Y parece que para el borrado de fichero se usa el comando:
Código: [Seleccionar]
OPEN 15,8,15,"S0:file name":CLOSE 15que creo que es el se está usando en el código.

Alguien puede echarme una manilla con esto.
Gracias de antemano.
« última modificación: Enero 27, 2019, 12:09:42 por darro99 »

javierglez

  • Commodore Master
  • *****
  • Mensajes: 453
  • terminator not seen
    • Ver Perfil
Re:Borrado de un fichero en disco
« Respuesta #1 en: Enero 27, 2019, 13:44:16 »
Donde lo pruebas en VICE ? en una 1541 real ? en un SD2IEC ?

darro99

  • Desarrolladores
  • Commodorista
  • ******
  • Mensajes: 57
  • PRESS PLAY ON TAPE
    • Ver Perfil
Re:Borrado de un fichero en disco
« Respuesta #2 en: Enero 27, 2019, 13:49:54 »

Citar
Donde lo pruebas en VICE ? en una 1541 real ? en un SD2IEC ?
Lo estoy probando con el VICE

R. INTERNATIONAL

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 667
  • THE NEW IRON AGE HAS COME!!
    • Ver Perfil
Re:Borrado de un fichero en disco
« Respuesta #3 en: Enero 27, 2019, 22:20:50 »
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.

R. INTERNATIONAL

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 667
  • THE NEW IRON AGE HAS COME!!
    • Ver Perfil
Re:Borrado de un fichero en disco
« Respuesta #4 en: Enero 27, 2019, 22:22:16 »
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

javierglez

  • Commodore Master
  • *****
  • Mensajes: 453
  • terminator not seen
    • Ver Perfil
Re:Borrado de un fichero en disco
« Respuesta #5 en: Enero 28, 2019, 12:57:48 »
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.

darro99

  • Desarrolladores
  • Commodorista
  • ******
  • Mensajes: 57
  • PRESS PLAY ON TAPE
    • Ver Perfil
Re:Borrado de un fichero en disco
« Respuesta #6 en: Enero 28, 2019, 18:54:09 »
Hola de nuevo.
 
Citar
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?
Código: [Seleccionar]
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.

Citar
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

Citar
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  :)

mjj

  • Commodore Master
  • *****
  • Mensajes: 456
  • SYS 0
    • Ver Perfil
Re:Borrado de un fichero en disco
« Respuesta #7 en: Enero 28, 2019, 20:41:27 »
En el ejemplo de lemon no usan "S0:" sino esto:

Código: [Seleccionar]
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.

javierglez

  • Commodore Master
  • *****
  • Mensajes: 453
  • terminator not seen
    • Ver Perfil
Re:Borrado de un fichero en disco
« Respuesta #8 en: Enero 29, 2019, 12:53:46 »

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é.

javierglez

  • Commodore Master
  • *****
  • Mensajes: 453
  • terminator not seen
    • Ver Perfil
Re:Borrado de un fichero en disco
« Respuesta #9 en: Enero 29, 2019, 13:10:56 »
Además si distingue, las buenas son las minúsculas

darro99

  • Desarrolladores
  • Commodorista
  • ******
  • Mensajes: 57
  • PRESS PLAY ON TAPE
    • Ver Perfil
Re:Borrado de un fichero en disco
« Respuesta #10 en: Enero 29, 2019, 16:43:51 »
Citar
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

Citar
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
He probado con:
Código: [Seleccionar]
.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.

marcos64

  • Commodore Master
  • *****
  • Mensajes: 2970
    • Ver Perfil
    • http://marcos64.orgfree.com/
Re:Borrado de un fichero en disco
« Respuesta #11 en: Enero 29, 2019, 21:39:57 »
Has probado con 's' minuscula?
http://marcos64.orgfree.com/
Actualizacion 22/4/2018: Actualizada Load'N'Run numero 5 con nuevos TAPs y PRGs.

darro99

  • Desarrolladores
  • Commodorista
  • ******
  • Mensajes: 57
  • PRESS PLAY ON TAPE
    • Ver Perfil
Re:Borrado de un fichero en disco
« Respuesta #12 en: Febrero 02, 2019, 14:44:16 »
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
Código: [Seleccionar]
.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)