¿Se podría crear un core que cargase otro core desde la tarjeta SD?

Dudas, cuestiones, sugerencias y peticiones en general sobre el proyecto / Questions and requests about the project
Avatar de Usuario
Uto
Mensajes: 1394
Registrado: 17 Dic 2015, 16:39

Re: ¿Se podría crear un core que cargase otro core desde la tarjeta SD?

Mensaje por Uto » 04 Nov 2016, 18:14

Quest escribió:
Uto escribió:Es que no es así, solo arrancas un core con .runcore si es un core que no está cargado, para el resto de los casos no tiene sentido. ...
Pero vamos a ver, Que no es así ¿el qué?
¿Has mirado de qué va el hilo? Va de "arrancar cores desde SD", y para "arrancar cores desde SD" hay que grabar el core de SD a flash sí o sí, y por tanto hay que esperar el tiempo de grabado, sí o sí. Lo que comentas, me parece una obviedad, sobre todo porque yo estaba hablando, evidentemente, del tema del hilo (no de cómo se cargan los cores normales que ya están grabados en flash, que por otro lado, es evidente).
Pues perdona la confusión, esta claro que no he entendido el sentido de tu "tener que esperar siempre 30 segundos para cargar", pensaba que decías cada vez que arrancas cualquier core y no solo cuando haces el "fake-SD-to-FPGA" del que estábamos hablando, el cual obviamente requiere esos 30 segundos (o los que sean) igual que si lo haces desde la BIOS.

Quest escribió: Por el resto de tu respuesta, es evidente que no estábamos hablando de lo mismo... :roll:
Pues debe ser que no, porque yo hablaba ya de ese "fake-SD-to-FPGA", y por eso te ponía la diferencia entre usar un comando y usar la BIOS, que es abismal en comodidad.
Quest escribió: Pero vamos, que no voy a darle más vueltas a este tema... estoy con Antonio, y desde luego el que desee hacer el comando, adelante, un nuevo desarrollo para el ZX-UNO siempre es bien recibido :)
Sí, yo también estoy de acuerdo con Antonio. Y en cuanto al comando, si algún día siento la necesidad, seguro que lo hago, es retocar un poco el .ROMSUPGR. :-)

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

Re: ¿Se podría crear un core que cargase otro core desde la tarjeta SD?

Mensaje por Uto » 04 Nov 2016, 18:18

hikoki escribió:Uto, a mí si que me va el rollo Papa Uto con su .runcore y pitidicos para que el ZX-Uno sea como un iPadete.
Además cuando más chino-friendly más posibilidades hay que algún chino lo fabrique como churros. Además es bonita la parte de automática en la palabra informática :mrgreen:
Quizá sería mejor un comando...

Código: Seleccionar todo

.COREUPGR <slot> <fichero>
y que no reinicie, porque para eso está el .CORE

Así en modo ultra-vago uno se puede hacer unos taps para cargar desde la NMI de ESXDOS que te arranquen cores, grabando un programilla basic:

Código: Seleccionar todo

10 .COREUPGR 7 msx : .CORE 7
Lo único que por seguridad habría que poner ciertas restricciones o dificultades adicionales al slot 1, el core de Spectrum.

Bueno, lo dicho, si siento la necesidad, o si me aburro mucho un día, lo mismo me pongo :roll:

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

Re: ¿Se podría crear un core que cargase otro core desde la tarjeta SD?

Mensaje por Uto » 29 Nov 2016, 23:53

Hola,

He estado dedicando unos días a hacer ese COREUPGR, y en realidad lo tengo programado completo, pero no lo voy a terminar. La razón es que no encuentro un entorno de debug adecuado para hacerlo, y me parece una herramienta suficientemente delicada como para hacer un debug muy concienzudo, para el que no vale hacer ñapas a la antigua usanza en plan escribir cosas en pantalla, o cambiar el color de tal caracter, tiene que ser algo más serio.

Es posible que en el futuro, cuando haya un emulador que me permita hacer eso pueda plantearmelo, pero como ese futuro no se si será cercano o lejano, voy a dejar aquí el código, advirtiendo previamente que:

1) Seguro que tiene bugs, si alguien lo retoma, que no lo de por bueno, no he podido hacer debug del mismo.
2) Seguramente es optimizable en tiempo y espacio. No es un asunto que me haya preocupado porque siendo uno de mis primeros programas en ensamblador de Z80 serios, lo que más me preocupaba era la legibilidad.
3) Se compila con sjasmplus (sjasmplus coreupgr.asm), y parte de una mezcla del ROMSUPGR y el UPGRADE de Antonio Villena.
4) El modo de uso lo podéis ver en la rutina "Syntax"

Código: Seleccionar todo

; (C) 2016 Uto - some parts are (C) Antonio Villena
; LICENSE: CC BY-SA
; TO BE COMPILED WITH SJASMPLUS
                
                output  COREUPGR


                macro wreg  dir, value
                    call    rst28
                    defb    dir, value
                endm

                ; ** ZX-UNO PORTS **
                define  ZXUNO_PORT      $FC3B
                define  MASTERCONF     0
                define  FLASHSPI       2
                define  FLASHCS        3
                define  SCANDBLCTRL    11

                ; ** ESXDOS VARS **
                define  FA_READ         $01
                define  M_GETSETDRV     $89
                define  F_OPEN          $9A
                define  F_CLOSE         $9B
                define  F_READ          $9D
                define  F_FSTAT         $A1
 
     
                org     $2000                       ; ESXDOS dot command org


                ; ** CHECK ROOTED ROM **
Main        ;    ld      bc, ZXUNO_PORT
            ;    out     (c), MASTERCONF
            ;    inc     b
            ;    in      f, (c)
            ;    jp      p, Nonlock
            ;    call    Print
            ;    dz      'ROM not rooted'
            ;    ret


                ; **  CHECK IF PARAMS AVALIABLE **
Nonlock         ld      a, h
                or      l
                jp      z, Syntax                   ; No params, show Syntax

                ; ** PARSE PARAM1 **
                ld      a,(hl)
                cp      '2'                         ; less than 2
                jp      c, Syntax  
                cp      ':'                         ; plus than 9  (colon is ASCII char after '9')
                jp      nc, Syntax 
                sub     48
                ld      (coreSlot+1), a             ; modify code so core slot number is used later

                ; ** CHECK THERE IS A SPACE **                    
                inc     hl
                ld      a,(hl)
                cp      ' '
                jp      nz, Syntax         

                ; ** PARSE PARAM2 **                    
                ld      bc, 0                       ; Will count filename length
fileNameLoop    inc hl
                ld      a, (hl)                     ; Copying second parameter to Filename Variable
                cp      13
                jr      z, fileNameEnd              ; Found a zero, filename finished
                cp      32
                jp      z, Syntax                   ; Found a space, no more parameters allowed, show Syntax
                ld      (de), a
                cp      '.'
                jr      nz, filenameNoDot
                ld      (dotFound), a               ; Make dotFound be non zero
filenameNoDot   inc     de
                jr      fileNameLoop

                ; ** ADD ZX1 EXTENSION IF NO EXTENSION **
fileNameEnd     ld      a, (dotFound)               ; Check if file name had a dot
                or      a
                jr      nz, fileNameEnd2

                ld      hl, zx1Extension            ; Otherwise, add .ZX1 extension to file name
                ld      b, 4
                ldir

                ; ** GET FILE NAME LENGTH AT BC **
fileNameEnd2    ld      hl, de
                ld      bc, FileName + 1            ; +1 as de already points to next position after last character                      
                sub     hl, bc
                ld      bc, hl

                xor     a
                ld      (de), a                     ; Add ASCIIZ zero mark 


                ; ** CHECK FILENAME NO LONGER THAN 32 CHARS **
                ld      a, b
                or      a
                jp      nz, Syntax                  ; 256 or more characters!
                ld      a, c
                cp      32
                jp      nc, Syntax                  ; more than 32 characters
                ld      a, 32
                sub     c                           ; get how many spaces will be needed to fill up to 32 chars
                ld      (fillSpaces+1), a           ; modify code below so later the name is filled up to 32 bytes with spaces

                ; ** SET TURBO MODE 28 MHz FOR FASTER UPDATE **
                ld      a, SCANDBLCTRL  ; 
                dec     b
                out     (c), a
                inc     b
                in      a, (c)
                ld      (TurboValue+1), a           ; Store current turbo value so speed is brought back to previous value on exit
                or      $c0
                out     (c), a

                ; ** CHECK SD CARD READY **
                xor     a                           ; A=0 (current unit)
                rst     $08
                db      M_GETSETDRV     
                ret     c


                ; ** OPEN FILE **
                ld      b, FA_READ      
                ld      hl, FileName                ; HL = Pointer to ASCIIZ filename
                rst     $08
                db      F_OPEN          
                jr      nc, FileFound
                ld      hl, FileFolder              ; If file not found, try again in  /CORES folder
                rst     $08
                db      F_OPEN
                ret     c

                ; ** GET CODE READY FOR READING FILE **
FileFound       ld      (handle+1), a               ; Modifies code so "ld a, 0" at (handle) becomes "ld a, <handle>"


                ;** CHECK CORE SIZE ** 
CheckSize       rst     $08
                db      F_FSTAT                     ; Size must be ($00054000 / 344,064 bytes)
                ret     c
                ld      hl, FileName+7
                ld      a,(hl)
                or      a
                jp      nz, SizeError
                inc     hl
                ld      a,(hl)
                cp      $40
                jp      nz, SizeError
                inc     hl
                ld      a,(hl)
                cp      $05
                jp      nz, SizeError
                inc     hl
                ld      a,(hl)
                or      a
                jp      z, Start
SizeError       call    Print
                db      'Core file must be 344,064 bytes long', 13
                ret


                ; ** WRITE START MESSAGE **                
Start           call    Print
                dz      'Upgrading CORE from SD', 13
                

                ; ** CALCULATE CORE POSITION IN FLASH **
                exx
                ld      hl, $0040                   ; position of CORE 1 in flash minus $540 (core 1 is at $580[00])
                ld      de, $0540
coreSlot        ld      a, 0                        ; this code is modified above so it actually will be ld a, <core slot number>
                ld      b,a
flashPtrLoop    add     hl, de
                djnz    flashPtrLoop
                ld      de, hl
                exx                

                ; ** WRITE CORE **
MainWriteLoop   ld      hl, $8000
                ld      bc, $4000
handle          ld      a, 0                        ; This code is modified above si actually will be ld a, <handle> when executed
                rst     $08
                db      F_READ                      ; Read 16K at $8000
                jp c, ReadError

                ; ** CHECK EOF **
                ld a, b
                or c
                jp z, WriteFinished                 ; Exit if 0 bytes read (EOF)


                ; ** WRITE 16K TO SPI FLASH **
                ld      a, 64                       ; write 64 pages of 256 bytes (16K)
                ld      hl, $8000                   ; located at $8000
                exx 
                call    writeFlash 
                inc de
                exx

                ; ** WRITE DOTS AS PROGRESS MARK**
                ld      a, '.'
                exx
                push    de
                rst     $10
                pop     de
                exx

                jp MainWriteLoop


                ; ** CLOSE FILE **
WriteFinished   ld      a, (handle+1)               ; Take handle value from preceding code
                rst     $08
                db      F_CLOSE

                ;** READ CORE NAMES FROM FLASH **
readCoreNames   ld      de, $8000                   ; Core names are located at $007100, 32 bytes per core, 8 core names (2 to 9), 256 total bytes
                ld      hl, $0071                   
                ld      a,1
                call    readFlash

                ;** MAKE HL POINT TO REQUESTED CORE NAME **
                ld      a, (coreSlot+1)             ; get core slot number from code aboves
                dec     a                           ; Decrements 1 cause core 1 ==> 0 offset, core 2 => $20 offset, etc.
                ld      de, $0071                   
                ld      h, 0
                ld      l, a                       
                add     hl, hl
                add     hl, hl
                add     hl, hl
                add     hl, hl                      ; HL = A * 32
                add     hl, de                      ; HL = A * 32 + $0071

                ;** UPDATE CORE NAME IN MEMORY **
updateCoreName  ld      de, FileName
coreNameLoop    ld      a, (de)
                or      a
                jr      z, fillSpaces
                ld      (hl), a
                inc     hl
                jr      coreNameLoop 

                ;** FILL WITH SPACES UP TO 32 BYTES **
fillSpaces      ld      b, 0                        ; That 0 is replaced by numer of spaces above (self-modified code)
                ld      a, $20
fillSpLoop      ld      (hl), a
                inc     hl
                djnz    fillSpLoop

                ; ** SAVE CORE NAMES TO FLASH **
saveCoreNames   ld      de, $8000
                ld      hl, $0071
                ld      a,1
                call    writeFlash
              
                ; ** RESTORE PREVIOUS TURBO MODE **
                ld      bc, ZXUNO_PORT
                ld      a, SCANDBLCTRL
                out     (c), a
                inc     b
TurboValue      ld      a, 0
                out     (c), a

                ; ** WRITE SUCCESS MESSAGE AND EXIT **                
                call    Print
                dz      13, 'Core upgraded sucessfully', 13
                ret


ReadError       call Print
                dz 13,'Unexpected error while reading the file',13
                ret


Syntax          call Print
                db 'Syntax:',13,13
                db '.COREUPGR <core slot> <file>', 13, 13
                db '<core slot> : 2-9', 13
                dz '<filename> : max 32 bytes long', 13
                ret



;***********************************************************************************
;                                  AUX FUNCTIONS                                   *
;***********************************************************************************

; -----------------------------------
; Print ASCIIZ String
; Parameters:
;   None, just DB with ASCIIZ string 
;   after the "call Print"
; -----------------------------------

Print           pop     hl
                db      $3e
Print1          rst     $10
                ld      a, (hl)
                inc     hl
                or      a
                jr      nz, Print1
                jp      (hl)


; ------------------------------------------
; Read from SPI flash
; Parameters:
;   DE: destination address
;   HL: source address without last byte
;    A: number of pages (256 bytes) to read
; ------------------------------------------
readFlash       ex      af, af'
                xor     a
                push    hl
                wreg    FLASHCS, 0     ; activamos spi, enviando un 0
                wreg    FLASHSPI, 3    ; envio FLASHSPI un 3, orden de lectura
                pop     hl
                push    hl
                out     (c), h
                out     (c), l
                out     (c), a
                ex      af, af'
                ex      de, hl
                in      f, (c)
rdfls1          ld      e, $20
rdfls2          ini
                inc     b
                ini
                inc     b
                ini
                inc     b
                ini
                inc     b
                ini
                inc     b
                ini
                inc     b
                ini
                inc     b
                ini
                inc     b
                dec     e
                jr      nz, rdfls2
                dec     a
                jr      nz, rdfls1
                wreg    FLASHCS, 1
                pop     hl
                ret

; ------------------------
; Write to SPI flash
; Parameters:
;    A: number of pages (256 bytes) to write
;   DE: target address without last byte  ($xxxx00)
;  HL': source address from memory
; ------------------------
writeFlash      ex      af, af'
                xor     a
wrfls1          wreg    FLASHCS, 0     ; disable spi, sending 0
                wreg    FLASHSPI, 6    ; send write enable
                wreg    FLASHCS, 1     ; deactivate spi, send 1
                wreg    FLASHCS, 0     ; activate spi, send 0
                wreg    FLASHSPI, $20  ; send erase sector
                out     (c), d
                out     (c), e
                out     (c), a
                wreg    FLASHCS, 1     ; deactivate spi, send 1
wrfls2          call    waits5
                wreg    FLASHCS, 0     ; activate spi, send 0
                wreg    FLASHSPI, 6    ; send write enable
                wreg    FLASHCS, 1     ; deactivate spi, send 1
                wreg    FLASHCS, 0     ; activate spi, send 0
                wreg    FLASHSPI, 2    ; page program
                out     (c), d
                out     (c), e
                out     (c), a
                ld      a, $20
                exx
                ld      bc, ZXUNO_PORT+$100
wrfls3          inc     b
                outi
                inc     b
                outi
                inc     b
                outi
                inc     b
                outi
                inc     b
                outi
                inc     b
                outi
                inc     b
                outi
                inc     b
                outi
                dec     a
                jr      nz, wrfls3
                exx
                wreg    FLASHCS, 1     ; deactivate spi, send 1
                ex      af, af'
                dec     a
                jr      z, waits5
                ex      af, af'
                inc     e
                ld      a, e
                and     $0f
                jr      nz, wrfls2
                ld      hl, wrfls1
                push    hl
waits5          wreg    FLASHCS, 0     ; activate spi, send 0
                wreg    FLASHSPI, 5    ; send read status
                in      a, (c)
waits6          in      a, (c)
                and     1
                jr      nz, waits6
                wreg    FLASHCS, 1     ; deactivate spi, send 1
                ret
        
rst28           ld      bc, ZXUNO_PORT + $100
                pop     hl
                outi
                ld      b, (ZXUNO_PORT >> 8)+2
                outi
                jp      (hl)

;*******************************************************************************
;                                  VARIABLES                                   *
;*******************************************************************************
zx1Extension    db '.ZX1'
dotFound        db 0                          ; wether the core file name parameter contained a dot or not
FileFolder      db '/CORES/'
FileName        db 0


Avatar de Usuario
antoniovillena
Mensajes: 2621
Registrado: 27 Sep 2015, 20:41

Re: ¿Se podría crear un core que cargase otro core desde la tarjeta SD?

Mensaje por antoniovillena » 30 Nov 2016, 00:27

Lo que tú llamas ñapas a la antigua usanza es para muchos la forma correcta de programar. El hecho de disponer un depurador es un accesorio que bien utilizado te puede hacer ganar tiempo, pero que si abusas de él adoptarás malos hábitos y al final perderás bastante más tiempo.

Yo al principio (cuando empecé con el ensamblador del 8086) también me hice muy dependiente del depurador. El código que solía escribir echaba aguas por todos los lados y me tiraba el 95% del tiempo en el debugger y el 5% en el editor. En cuanto te acostumbras a no usar debugger no sólo escribes código con más cuidado. También tardas menos en detectar fallos revisando el código. Sólo en el caso de que me tire mucho tiempo con un bug tiro de depurador. No sin antes haber revisado bien el código, probando las ñapas del borde o que te muestren valores por pantalla.

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

Re: ¿Se podría crear un core que cargase otro core desde la tarjeta SD?

Mensaje por Uto » 30 Nov 2016, 09:43

antoniovillena escribió:Lo que tú llamas ñapas a la antigua usanza es para muchos la forma correcta de programar. El hecho de disponer un depurador es un accesorio que bien utilizado te puede hacer ganar tiempo, pero que si abusas de él adoptarás malos hábitos y al final perderás bastante más tiempo.

Yo al principio (cuando empecé con el ensamblador del 8086) también me hice muy dependiente del depurador. El código que solía escribir echaba aguas por todos los lados y me tiraba el 95% del tiempo en el debugger y el 5% en el editor. En cuanto te acostumbras a no usar debugger no sólo escribes código con más cuidado. También tardas menos en detectar fallos revisando el código. Sólo en el caso de que me tire mucho tiempo con un bug tiro de depurador. No sin antes haber revisado bien el código, probando las ñapas del borde o que te muestren valores por pantalla.
La verdad es que todo eso está muy bien, pero yo simplemente no tengo tiempo para acostumbrarme, al menos no en mi situación personal actual, dado que programo en ratos sueltos de 15-20 minutos, y si no tienes las herramientas adecuadas para cuando te pones lo tienes que dejar. Por otro lado, he leido y releido mi código varias veces antes de intentar ejecutarlo, precisamente para tratar de detectar errores, y he visto muchos, los que siga habiendo, ya simplemente mi nivel de ensamblador no me permite verlos, de ahí que necesite un debugger.

Dejo el código disponible por dos razones, la primera es por si alguien lo quiere retomar, que puede que sea yo mismo si aparecen herramientas adecuadas a mi perfil, pero podría ser otra persona. La segunda es porque creo que, bugs aparte, el código profusamente comentado y en ocasiones incluso redundante (a veces no he optimizado intencionadamente para mejorar legibilidad) puede servir de ejemplo didáctico. En este dot command se ven cosas como:

- Determinar si la ROM es rooted
- Parseado de parámetros en dot commands
- Lectura de disco
- Determinar tamaño de ficheros
- Lectura y escritura en flash
- Cambio a modo turbo

Son en realidad cosas que están también en tus aplicaciones UPGRADE y ROMSUPGR, pero mucho menos comentadas y a veces con muchos "trucos" de optimización que lo hacen menos legible y por tanto menos didáctico. Ojo que no critico tu código, es perfecto en cuanto a rendimiento, pero para los novatos a veces cuesta entenderlo, aunque cuando finalmente lo entiendes te quedas pensando ¡joder que máquina! :-)

Avatar de Usuario
antoniovillena
Mensajes: 2621
Registrado: 27 Sep 2015, 20:41

Re: ¿Se podría crear un core que cargase otro core desde la tarjeta SD?

Mensaje por antoniovillena » 30 Nov 2016, 09:58

Es cierto que mis herramientas (romsupgr, upgrade) no son el mejor ejemplo para alguien que quiere aprender, así que se agradece que compartas las tuyas más accesibles para alguien que esté aprendiendo. Respecto a tener mejores herramientas: puedes hacer cualquier otro proyecto para spectrum 48K que no sea exclusivo para ZX-Uno. Así te vale cualquier emulador, que hay muchos, y encontrarás un debugger a tu gusto. El que más me gusta a mi es el del Spectaculator.

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

Re: ¿Se podría crear un core que cargase otro core desde la tarjeta SD?

Mensaje por Uto » 30 Nov 2016, 10:12

antoniovillena escribió:Es cierto que mis herramientas (romsupgr, upgrade) no son el mejor ejemplo para alguien que quiere aprender, así que se agradece que compartas las tuyas más accesibles para alguien que esté aprendiendo. Respecto a tener mejores herramientas: puedes hacer cualquier otro proyecto para spectrum 48K que no sea exclusivo para ZX-Uno. Así te vale cualquier emulador, que hay muchos, y encontrarás un debugger a tu gusto. El que más me gusta a mi es el del Spectaculator.
Sí sí, para lo que no tengo herramientas es para depurar un dot command que graba cores en flash, es demasiado ambicioso para mi con las herramientas actuales, pero seguramente para dot commands mas sencillos y/o menos peligrosos, o para otras cosas que no sean dot commands, puedo usar las herramientas que hay (Spectaculator por ejemplo, pero tambuén ZXSpin que soporta DivIDE o ES.Pectrum que soporta modo Radastan y TimexHiColor y ambos tienen debugger).

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

Re: ¿Se podría crear un core que cargase otro core desde la tarjeta SD?

Mensaje por spark2k06 » 30 Nov 2016, 10:29

En mi caso el loader de ROMs de 128K basadas en snapshot tambien de 128K para que cargue a partir del menú principal de ROMs del ZXUno lo hice partiendo de ROMSBACK, y lo documenté bastante bien, o eso creo :silbando: :

https://github.com/spark2k06/zxuno/blob ... er128k.asm

A mí también me resultó imprescindible el uso de un debugger, y me decanté por el único que se puede utilizar para ello, ZESarUX. Me costó un poco acostumbrarme al principio, pero realmente me resultó muy útil para conseguir mi objetivo.

ManuFerHi
Mensajes: 752
Registrado: 15 Nov 2015, 17:50

Re: ¿Se podría crear un core que cargase otro core desde la tarjeta SD?

Mensaje por ManuFerHi » 04 Dic 2016, 20:57

Esta sería mi selección de los mejores 1+8 cores, ¿me dejo alguno?
Imagen

Avatar de Usuario
carmeloco
Mensajes: 751
Registrado: 25 Dic 2015, 12:02

Re: ¿Se podría crear un core que cargase otro core desde la tarjeta SD?

Mensaje por carmeloco » 04 Dic 2016, 23:49

ManuFerHi escribió:Esta sería mi selección de los mejores 1+8 cores, ¿me dejo alguno?
Imagen
Esa es la lista de cores de mi :zxuno: , y casi en el mismo orden.

Responder