Compilador ZX Basic 1.4 (beta) liberado

Todo sobre la creación, diseño y programación de nuevo software para
nuestro Spectrum

Moderador: Sir Cilve Sinclair

Boriel
Sabreman
Mensajes: 351
Registrado: Lun May 28, 2007 9:55 am
Ubicación: Tenerife
Contactar:

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por Boriel » Lun Feb 03, 2014 12:58 am

Se supone que se puede usar @nombredefuncion como dirección (el operador @ funciona). Pero lo acabo de probar sobre funciones y veo que da error (me habré olvidado de actualizar esa parte).
Voy a probar a ver.

Lo cierto es que para evitar el equilibrado de pila, lo mejor es no usar parámetros, y declarar la función con convenio FASTCALL.
También se puede hacer GOSUB dentro del cuerpo de la subrutina. Como bien indica la sentencia GO SUB es para SUBrutinas, porque el RETURN de una función puede ser distinto y el GOSUB se puede confundir (Freebasic arregla esto con la construcción RETURN FROM GOSUB).

Personalmente creo que los GOTOS y los GOSUBs nunca deben salir ni entrar del cuerpo de una función y en el futuro ese estará prohibido.

Iré mirando lo de la función.
Si lo que quieres hacer es una tabla de salto, lo mejor es usar etiquetas, creo yo, sacar su dirección con @etiqueta y meter ASM inline. Los constructos ON <expr> GOTO / GOSUB y el SELECT ... CASE están en la cola aún.

Avatar de Usuario
antoniovillena
Nonamed
Mensajes: 1164
Registrado: Dom Ene 09, 2011 8:55 am

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por antoniovillena » Lun Feb 03, 2014 2:11 am

A ver es una función que no puedo llamar directamente, es el engine el que se encarga de hacerlo en el momento apropiado. Yo lo único que debo hacer es pasarle al engine la dirección de la rutina.

Es para imprimir un marcador en la pantalla. En el caso de un 48K tan sólo se pinta una vez, pero en un 128K como hay doble buffering se debe pintar 2 veces, una en cada pantalla. Esto lo maneja el engine transparentemente, nosotros solo le pasamos la dirección de la función.
Imagen

Boriel
Sabreman
Mensajes: 351
Registrado: Lun May 28, 2007 9:55 am
Ubicación: Tenerife
Contactar:

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por Boriel » Lun Feb 03, 2014 10:32 am

antoniovillena escribió:A ver es una función que no puedo llamar directamente, es el engine el que se encarga de hacerlo en el momento apropiado. Yo lo único que debo hacer es pasarle al engine la dirección de la rutina.

Es para imprimir un marcador en la pantalla. En el caso de un 48K tan sólo se pinta una vez, pero en un 128K como hay doble buffering se debe pintar 2 veces, una en cada pantalla. Esto lo maneja el engine transparentemente, nosotros solo le pasamos la dirección de la función.

Pues se me ocurren 2 opciones:
  1. Declarar la función como SUB Fastacall MyFuncion (y usar @Myfuncion)
    @Myfuncion no funciona con subrutinas ni funciones ahora (es un bug), pero si con etiquetas. Coloca una etiqueta dentro de la función, y pasale @etiqueta
  2. Hacer una subrutina normal (de las que se llaman con GOSUB), y pasarle @etiqueta.

Avatar de Usuario
antoniovillena
Nonamed
Mensajes: 1164
Registrado: Dom Ene 09, 2011 8:55 am

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por antoniovillena » Lun Feb 03, 2014 11:05 am

Si es un bug me espero a que se arregle hasta liberar la versión definitiva, de momento funciona con un parche parecido a la primera opción que propones. Aquí dejo todo el código:

main.bas

Código: Seleccionar todo

#include <keys.bas>
#include "fase.bas"

dim dirbul(3) as ubyte
dim datos(19) as ubyte = { _
    $00, $42, $11, 0, _
    $08, $60, $60, 2, _
    $09, $a8, $48, 3, _
    $0a, $22, $02, 1, _
    $0b, $d0, $6e, 2}
dim i, j, x, y, spacepressed, killed, numbullets as byte
dim tmpx, tmpy as ubyte

sub FASTCALL pausa( time as uinteger )
  asm
loop1:  ld      bc, 21
loop2:  djnz    loop2
        dec     c
        jr      nz, loop2
        dec     hl
        ld      a, l
        or      h
        jr      nz, loop1
        ret
  end asm
end sub

function abso( a as ubyte, b as ubyte ) as uinteger
  if b<a then
    return a-b
  else
    return b-a
  end if
end function

sub updatescreen()
  scr= y*mapw + x
  for j = 1 to 4
    if GetSpriteV(j) > $7f then
      SetSpriteV(j, GetSpriteV(j)-$80)
    end if
  next j
end sub

sub updatescoreboard()
updatescor:
  dim scr, dst as uinteger
  dim count as ubyte
  scr= $3d80+CAST(uinteger, killed)*8
  dst= $50de|CAST(uinteger, shadow)<<8
  for count = 0 to 7
    poke dst, (peek scr ~ $ff)
    scr= scr+1
    dst= dst+$100
  next count
end sub

sub removebullet( k as ubyte )
  if numbullets then
    numbullets= numbullets-1
    while k < numbullets
      dirbul(k)= dirbul(k+1)
      SetBulletX(k, GetBulletX(k+1))
      SetBulletY(k, GetBulletY(k+1))
      k= k+1
    end while
    SetBulletY(k, 255)
  end if
end sub

  DisableInt

start:
  killed= 0
  x= 0
  y= 0
  spacepressed= 0
  numbullets= 0
  shadow= 0

  updatescoreboard()

  Init

  for i = 0 to 4
    SetSpriteV(i, datos(i*4))
    SetSpriteX(i, datos(i*4+1))
    SetSpriteY(i, datos(i*4+2))
    SetSpriteZ(i, datos(i*4+3))
  next i
  for i = 0 to 3
    SetBulletY(i, 255)
  next i

  scr= 0

  while 1

    Frame

    for i = 1 to 4
      if GetSpriteV(i) < $80 then
        for j = 0 to numbullets-1
          if abso(GetSpriteX(i), GetBulletX(j))+abso(GetSpriteY(i), GetBulletY(j)) < 10 then
            SetSpriteV(i, GetSpriteV(i)-$80)
            removebullet(j)
            tmpx= GetSpriteX(i)>>4
            tmpy= GetSpriteY(i)>>4
            SetTile(tmpy*scrw+tmpx, 68)
            TilePaint(tmpx, tmpy, tmpx, tmpy)
            killed= killed+1
            if killed=10 then
              out $7ffd, $10
              dzx7b(@image-1, $5aff)
              pausa(100)
              goto start
            end if
            drwout= @updatescor-15
          end if
        next j
        if GetSpriteZ(i) & 1 then
          if GetSpriteY(i) > 0 then
            SetSpriteY(i, GetSpriteY(i)-1)
          else
            SetSpriteZ(i, GetSpriteZ(i) ~ 1)
          end if
        else
          if GetSpriteY(i) < scrh*16 then
            SetSpriteY(i, GetSpriteY(i)+1)
          else
            SetSpriteZ(i, GetSpriteZ(i) ~ 1)
          end if
        end if
        if GetSpriteZ(i) & 2 then
          if GetSpriteX(i) > 0 then
            SetSpriteX(i, GetSpriteX(i)-1)
          else
            SetSpriteZ(i, GetSpriteZ(i) ~ 2)
          end if
        else
          if GetSpriteX(i) < scrw*16 then
            SetSpriteX(i, GetSpriteX(i)+1)
          else
            SetSpriteZ(i, GetSpriteZ(i) ~ 2)
          end if
        end if
      end if
    next i

    for i = 0 to numbullets-1
      if dirbul(i) & 3 then
        if dirbul(i) & 1 then
          if GetBulletX(i) < scrw*16 then
            SetBulletX(i, GetBulletX(i)+2)
          else
            removebullet(i)
          end if
        else
          if GetBulletX(i) > 2 then
            SetBulletX(i, GetBulletX(i)-2)
          else
            removebullet(i)
          end if
        end if
      end if
      if dirbul(i) & 12 then
        if dirbul(i) & 4 then
          if GetBulletY(i) < scrh*16 then
            SetBulletY(i, GetBulletY(i)+2)
          else
            removebullet(i)
          end if
        else
          if GetBulletY(i) > 2 then
            SetBulletY(i, GetBulletY(i)-2)
          else
            removebullet(i)
          end if
        end if
      end if
    next i

    if multikeys(KEYP) then
      if GetSpriteX(0) < scrw*16 then
        SetSpriteX(0, GetSpriteX(0)+1)
      elseif x < mapw-1 then
        SetSpriteX(0, 0)
        x= x + 1
        updatescreen()
      end if
    end if
    if multikeys(KEYO) then
      if GetSpriteX(0) > 0 then
        SetSpriteX(0, GetSpriteX(0)-1)
      elseif x then
        SetSpriteX(0, scrw*16)
        x= x - 1
        updatescreen()
      end if
    end if
    if multikeys(KEYA) then
      if GetSpriteY(0) < scrh*16 then
        SetSpriteY(0, GetSpriteY(0)+1)
      elseif y < maph-1 then
        SetSpriteY(0, 0)
        y= y + 1
        updatescreen()
      end if
    end if
    if multikeys(KEYQ) then
      if GetSpriteY(0) > 0 then
        SetSpriteY(0, GetSpriteY(0)-1)
      elseif y then
        SetSpriteY(0, scrh*16)
        y= y - 1
        updatescreen()
      end if
    end if
    if multikeys(KEYSPACE) and (not spacepressed) and numbullets<4 then
      SetBulletX(numbullets, GetSpriteX(0))
      SetBulletY(numbullets, GetSpriteY(0))
      i= (multikeys(KEYQ)<<3&8 | multikeys(KEYA)<<2&4 | multikeys(KEYO|KEYP)&3) & 15
      if i then
        dirbul(numbullets)= i
      else
        dirbul(numbullets)= 1
      end if
      numbullets= numbullets+1
    end if
    spacepressed= multikeys(KEYSPACE)
  end while

  asm
        incbin  "ending.rcs.zx7b"
  end asm
image:


fase.bas

Código: Seleccionar todo

#ifndef __LIBRARY_FASE__
#include "define.h"
#define __LIBRARY_FASE__

#define Init        \
    asm             \
        call $fffc  \
    end asm

#define Frame       \
    asm             \
        call $fff9  \
    end asm

#define DisableInt  \
    asm             \
        di          \
    end asm

#define SetSpriteV(number, value)   poke $5b00+(number)*4, (value)
#define GetSpriteV(number)          peek ($5b00+(number)*4)
#define SetSpriteX(number, value)   poke $5b01+(number)*4, (value)
#define GetSpriteX(number)          peek ($5b01+(number)*4)
#define SetSpriteY(number, value)   poke $5b02+(number)*4, (value)
#define GetSpriteY(number)          peek ($5b02+(number)*4)
#define SetSpriteZ(number, value)   poke $5b03+(number)*4, (value)
#define GetSpriteZ(number)          peek ($5b03+(number)*4)
 
#define SetBulletX(number, value)   poke $5b30+(number)*2, (value)
#define GetBulletX(number)          peek ($5b30+(number)*2)
#define SetBulletY(number, value)   poke $5b31+(number)*2, (value)
#define GetBulletY(number)          peek ($5b31+(number)*2)
#define SetTile(number, value)      poke $5b40+(number), (value)
#define GetTile(number)             peek ($5b40+(number))
#define TilePaint(from_x, from_y, to_x, to_y) repaint= CAST(uinteger, from_x|from_y<<4)|CAST(uinteger, to_x|to_y<<4)<<8
dim scr     as ubyte    at $5c00
dim shadow  as ubyte    at $5c01
dim repaint as uinteger at $5c02
dim drwout  as uinteger at $5c06

sub FASTCALL dzx7b( source as uinteger, addr as uinteger )
  asm
        pop     af
        pop     de
        push    af
        jp      dzx7a
  end asm
end sub

#endif
Imagen

Boriel
Sabreman
Mensajes: 351
Registrado: Lun May 28, 2007 9:55 am
Ubicación: Tenerife
Contactar:

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por Boriel » Lun Feb 03, 2014 11:12 am

Te interesaría colaborar directamente?
No sé si tienes experiencia en usar repositorios de código de esos (bitbucket, github), para proyectos distribuidos (yo poca, precisamente porque hasta ahora he trabajado solo). Pero si quieres, puedes poner directamente esas librerías, haces un pull request y ya las añado al proyecto. Describo el proceso aquí, para los que quieran contribuir:

  1. Haz una bifurcación del código (Fork) de http://bitbucket.org/boriel/zxbasic (tendrás que crearte una cuenta en bitbucket, creo) y he trabajado con mercurial (hg) y no git, aunque son prácticamente idénticos (mis preferencias por hg se deben a que inicialmente era más simple de usar).
  2. Coloca las bibliotecas en library/ si son archivos .bas, o library-asm/ si son archivos .asm
  3. Añade los archivos al proyecto y súbelos a tu bitbucket.
  4. Elige Pull Request (petición de fusión?). Así me envías los parches y solo tengo que aprobarlos (y además, se vería en el repo que lo has hecho tú).

Pronto publicaré esto en inglés (es que es un tema, la jodida documentación), ya que hay unos portugueses que han hackeado el ZX Basic y están programando... para MSX :shock: y estaría bien que se unieran.

Avatar de Usuario
antoniovillena
Nonamed
Mensajes: 1164
Registrado: Dom Ene 09, 2011 8:55 am

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por antoniovillena » Lun Feb 03, 2014 11:26 am

Por otro lado hay algo que no me convence y no sé cómo quitar:

Código: Seleccionar todo

        org 32768
        ; Defines HEAP SIZE
ZXBASIC_HEAP_SIZE EQU 4768
__START_PROGRAM:
        di
        push ix
        push iy
        exx
        push hl
        exx
        ld hl, 0
        add hl, sp
        ld (__CALL_BACK__), hl
        ei
        call __MEM_INIT
#line 71
        di
#line 72
__LABEL__start:
        xor a


Durante un tiempo (la llamada a __MEM_INIT) las interrupciones están habilitadas. Es un tiempo relativamente corto en el cual es poco probable que la interrupción ocurra, pero la probabilidad está ahí.
Imagen

Avatar de Usuario
antoniovillena
Nonamed
Mensajes: 1164
Registrado: Dom Ene 09, 2011 8:55 am

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por antoniovillena » Lun Feb 03, 2014 11:33 am

Boriel escribió:Te interesaría colaborar directamente?
No sé si tienes experiencia en usar repositorios de código de esos (bitbucket, github), para proyectos distribuidos (yo poca, precisamente porque hasta ahora he trabajado solo). Pero si quieres, puedes poner directamente esas librerías, haces un pull request y ya las añado al proyecto. Describo el proceso aquí, para los que quieran contribuir:

  1. Haz una bifurcación del código (Fork) de http://bitbucket.org/boriel/zxbasic (tendrás que crearte una cuenta en bitbucket, creo) y he trabajado con mercurial (hg) y no git, aunque son prácticamente idénticos (mis preferencias por hg se deben a que inicialmente era más simple de usar).
  2. Coloca las bibliotecas en library/ si son archivos .bas, o library-asm/ si son archivos .asm
  3. Añade los archivos al proyecto y súbelos a tu bitbucket.
  4. Elige Pull Request (petición de fusión?). Así me envías los parches y solo tengo que aprobarlos (y además, se vería en el repo que lo has hecho tú).

Pronto publicaré esto en inglés (es que es un tema, la jodida documentación), ya que hay unos portugueses que han hackeado el ZX Basic y están programando... para MSX :shock: y estaría bien que se unieran.


Es que no se trata de una simple librería, sino de un engine que necesita de su propio ecosistema (ensamblador, compresor, ejecutables ad-hoc que procesen los gráficos).
Imagen

Avatar de Usuario
antoniovillena
Nonamed
Mensajes: 1164
Registrado: Dom Ene 09, 2011 8:55 am

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por antoniovillena » Lun Feb 03, 2014 11:36 am

Para que te hagas una idea, el código .bas de arriba tras compilarlo y juntarlo con el engine produce esta demo:

http://www.mojontwins.com/mojoniaplus/d ... hp?id=4363
Imagen

Boriel
Sabreman
Mensajes: 351
Registrado: Lun May 28, 2007 9:55 am
Ubicación: Tenerife
Contactar:

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por Boriel » Lun Feb 03, 2014 11:45 am

wow! Entiendo.
Yo me refería solamente a la interfaz ZX Basic (el/los archivos que contienen las funciones que el programador llamaría). Pero tienes razón, si es tanto, es mejor dejarlo aparte. Hay otro engine que cheveron se está currando, ZX][odus (no sé si lo escribí bien), que es por el estilo, y que tampoco irá, porque es, al igual que este, un proyecto con herramientas, etc.

En cuanto a lo que comentas, efectivamente, voy a cambiar el orden del ei (debería ir a continuación de MEM_INIT) y además poner la opción de omitir la secuencia de entrada y salida al BASIC (era algo pendiente), de manera que todo ese código no se emita.

Avatar de Usuario
jevilon
Manic Miner
Mensajes: 288
Registrado: Mié Jul 23, 2008 1:15 pm
Ubicación: La Rioja

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por jevilon » Lun Feb 03, 2014 12:50 pm

Genial.... a ver si este "empujon" del compilador, me "empuja" a mi, y termino con mi juego... que esta casi, pero el tema "malotes" me esta dando dolores de cabeza asako....

Avatar de Usuario
antoniovillena
Nonamed
Mensajes: 1164
Registrado: Dom Ene 09, 2011 8:55 am

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por antoniovillena » Lun Feb 03, 2014 4:57 pm

Gracias. Ya he visto que has actualizado y ahora funciona el @funcion
Imagen

Boriel
Sabreman
Mensajes: 351
Registrado: Lun May 28, 2007 9:55 am
Ubicación: Tenerife
Contactar:

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por Boriel » Lun Feb 03, 2014 5:48 pm

antoniovillena escribió:Gracias. Ya he visto que has actualizado y ahora funciona el @funcion

¿¿Cómo te has enterado??
Acabo de llegar (hoy es fiesta en Tenerife) a casa, iba a comentártelo... :lol:

Avatar de Usuario
antoniovillena
Nonamed
Mensajes: 1164
Registrado: Dom Ene 09, 2011 8:55 am

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por antoniovillena » Lun Feb 03, 2014 8:02 pm

Boriel escribió:
antoniovillena escribió:Gracias. Ya he visto que has actualizado y ahora funciona el @funcion

¿¿Cómo te has enterado??
Acabo de llegar (hoy es fiesta en Tenerife) a casa, iba a comentártelo... :lol:


Me lo ha dicho tu repositorio

http://code.boriel.com/zxbasic/commits/all
Imagen

Boriel
Sabreman
Mensajes: 351
Registrado: Lun May 28, 2007 9:55 am
Ubicación: Tenerife
Contactar:

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por Boriel » Jue Feb 06, 2014 11:11 am

Bueno, pues ya he sacado la versión 1.4.0s1853 que aparte de corregir algunos bugs un poco raros, añade una librería con soporte para Spectranet :)

Avatar de Usuario
Imanolea
rst 0
Mensajes: 9
Registrado: Lun Feb 10, 2014 7:40 am
Ubicación: Bilbao

Re: Compilador ZX Basic 1.4 (beta) liberado

Mensaje por Imanolea » Lun Feb 10, 2014 11:23 am

Aupa,
Ando desarrollando un juego con este compilador, y llegados a la parte final del desarrollo hay una rutina en ensamblador que estoy cogiendo de ejemplo para realizar el pintado de tiles (ya que no tengo demasiada idea de ensamblador) que no consigo que compile con ZX Basic. El tema viene de un post en otro foro, en concreto este http://www.mojontwins.com/mojoniaplus/viewtopic.php?f=12&t=1539.

Agradecería mucho una ayudita en ese aspecto. Paso ahora a detallar el código y la salida del compilador. El autor de la rutina es el usuario Bubu de http://www.fasebonus.net:

Código: Seleccionar todo

asm
   call prn_tile
end asm
sub prueba()
   asm
      ;Constantes
      ATTR_ADDR   EQU $5800
      PAPER_BLUE  EQU 1*8
      INK_YELLOW  EQU 6
         

      ld ix, tile_01
      call prn_tile
      noend: jr noend


      ; Imprime en pantalla un tile monocromo
      ; El tile presenta la siguiente estructura:
      ;   dirección del tileset, fila, columna, ancho, alto, color, t1, t2, ...
      ; IN:  ix = puntero al tile a imprimr

      tile_01:
      DEFW fonts
      DEFB 5, 10, 16, 2, PAPER_BLUE + INK_YELLOW
      DEFB "HOLA IMANOLEA   "
      DEFB "SOY BUBU, JAJAJA"
       
      prn_tile:
      ; Colorea el rectángulo
      ld h, (ix +2)
      ld l, (ix +3)
      call calc_attr
      ld b, (ix +4)
      ld c, (ix +5)
      ld a, (ix +6)
      call color_square

      ; Imprime una fila
      ld h, (ix +2)
      ld e, (ix +5)

      push ix
      pop iy
      ld bc, 7
      add iy, bc

      ld c, (ix +0)
      ld b, (ix +1)

      prn_tile_02:
      ld d, (ix +4)
      ld l, (ix +3)

      prn_tile_01:
      ld a, (iy)
      call prn_tilechar
      inc l
      inc iy
      dec d
      jr nz, prn_tile_01
      inc h
      dec e
      jr nz, prn_tile_02 

      ret



      prn_tilechar:
      ; Imprime en pantalla un carácter de un tile
      ; IN:  a=carácter a imprimir 
      ;      bc=dirección del tileset
      ;      hl=posición (fila, col)


      push af
      push bc
      push de
      push hl
      call calc_vram

      ld l, a
      ld h, 0
      add hl, hl
      add hl, hl
      add hl, hl
      add hl, bc

      ld b, 8
      prn_tilechar_01:
      ld a, (hl)
      ld (de), a
      inc d
      inc hl
      djnz prn_tilechar_01
      pop hl
      pop de
      pop bc
      pop af
      ret

      calc_attr:
      ; Calcula la dirección de atributos
      ; IN:  hl = posición (fila, col)
      ; OUT: hl = dirección ATTR
      ld e, l
      ld d, 0
      ld l, h
      ld h, 0
      add hl, hl
      add hl, hl
      add hl, hl
      add hl, hl
      add hl, hl
      add hl, de
      ld de, ATTR_ADDR
      add hl, de
      ret


      ; Colorea un recuadro
      ; IN:  hl=dir. atributos
      ;      b=ancho, c=alto
      ;      a=color
      color_square:

      ld de, $20
      color_square_02:
      push bc
      push hl
      color_square_01:
      ld (hl), a
      inc hl
      djnz color_square_01
      pop hl
      add hl, de
      pop bc
      dec c
      jr nz, color_square_02
      ret


      calc_vram:
      ; Calcula la posición de vídeoRAM dadas una fila y columna
      ; IN:  hl=posición (fila, col)
      ; OUT: de=posición en la vídeomemoria

      push af
      push hl
      ld a, h
      and 7
      rrca
      rrca
      rrca
      or l
      ld e, a
      ld a, h
      and $18
      or $40
      ld d, a
      pop hl
      pop af
      ret

   end asm
end sub


La salida del compilador es esta:

(En la línea de call color_square)
Error: Syntax error. Unexpected token ')' [RP]

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 3 invitados