martes, 8 de diciembre de 2020

creacion de entidades con un ECS usando CPCTelera

pequeñito ejemplo de como, usndo en entity component system (ECS), se crean dos entidades distintas, y se pintan en pantalla.


 ;;main.s

;; ejemplo de dibujado simple de cuadrados

.module main.s

.include "cpctelera.h.s"

.area _DATA

.area _CODE

;;declaracion de globales

.globl cpct_disableFirmware_asm

.globl cpct_getScreenPtr_asm

.globl cpct_drawSolidBox_asm

.globl cpct_waitVSYNC_asm

.globl entityman_create

.globl rendersys_update

.globl _entity_array

.globl _num_entities

.globl entityman_getEntityArray_IX

.globl rendersys_init

.globl entityman_getNumEntities_A


;;declaracion de etiquetas,constantes

;;x,y,ancho,alto,color,velocidad x,vy

player: .db 20,20,04,16,0xff,0,0

enemy: .db 30,30,06,16,0xf0,0,0


;;principal

_main::

   ;; Disable firmware to prevent it from interfering with string drawing

   call cpct_disableFirmware_asm

;;INIT SYSTEMS

call rendersys_init



ld hl,#player

call entityman_create

ld hl,#enemy

call entityman_create


loop:

call entityman_getEntityArray_IX

call entityman_getNumEntities_A

call rendersys_update

jr loop


parate:

jp parate

;;
;;render system
.module render_system.s
.globl cpct_getScreenPtr_asm
.globl cpct_drawSolidBox_asm
.globl entity_size

rendersys_init::
ret


;;input registro ix puntero a entidad 
;;a numero de entidades a render
rendersys_update::
;;dibujado de cuadrados en pantalla, incrementando x e y a cada paso
render_loop:
push af
ld de,#0xc000 ;;principio memoria video
ld b,1(ix) ;;carga x
ld c,0(ix) ;;carga y
call cpct_getScreenPtr_asm ;;funcio9n para localizar x e y en pantalla
ex de,HL ;;intercambia de y hl

ld a,4(ix) ;;color cuadrado
ld b,3(ix) ;;tamaño cuadrado; call cpct_drawSolidBox_asm ;;funcion dibujado cuadrado
  ld c,2(ix) ;; c alto, b ancho
call cpct_drawSolidBox_asm
pop af 

dec a
ret z
ld bc,#entity_size
add ix,bc
jr render_loop

 ret
.module entity_manager.s

entity_size  == 7 ;;tamaño de cada entidad
max_entities == 3 ;;numero maximo de entidades

_num_entities:: .db 0 ;;entidades creadas al principio,0
_last_element_ptr:: .dw _entity_array
_entity_array::
.ds entity_size*max_entities ;;creacion de espacio para entidades,tamaño por numero 


entityman_getEntityArray_IX::
ld ix,#_entity_array
ret
entityman_getNumEntities_A::
ld a,(_num_entities)
ret


;;input
;;hl->puntero a entidad ejemplo
entityman_create::
ld de,(_last_element_ptr) ;;creacion de nueva entidad,
ld bc,#entity_size ;;de a puntero de ultima entidad
ldir ;;bc tamaño de la entidad

ld a,(_num_entities) ;;incrementa en uno el numero de entidades
inc a
ld (_num_entities),a

ld hl,(_last_element_ptr)
ld bc,#entity_size
add hl,bc
ld (_last_element_ptr),hl
ret


domingo, 6 de diciembre de 2020

Dibujo cuadrado

rutina para dibujar unos sencillos cuadrados, incrementando x e y en 1 a cada paso

 ;;

;; ejemplo de dibujado simple de cuadrados


.module main.s


.include "cpctelera.h.s"

.area _DATA

.area _CODE

;;declaracion de globales

.globl cpct_disableFirmware_asm

.globl cpct_getScreenPtr_asm

.globl cpct_drawSolidBox_asm

.globl cpct_waitVSYNC_asm

;;declaracion de etiquetas,constantes

x: .db #20

y: .db #12

;;principal

_main::

   ;; Disable firmware to prevent it from interfering with string drawing

   call cpct_disableFirmware_asm

;;dibujado de cuadrados en pantalla, incrementando x e y a cada paso

loop:

ld de,#0xc000 ;;principio memoria video

ld hl,#x ;;carga en hl el valor de x

ld b,(hl) ;;pasa a b

inc (hl) ;;el valor de hl, HL=HL+1

inc HL ;;hl=hl+1

ld c,(hl) ;;pasa a c

inc (hl) ;;valor de hl +1

call cpct_getScreenPtr_asm ;;funcio9n para localizar x e y en pantalla

ex de,HL ;;intercambia de y hl


ld a,#0xff ;;color cuadrado

ld bc,#0x0804 ;;tamaño cuadrado

call cpct_drawSolidBox_asm ;;funcion dibujado cuadrado

    call cpct_waitVSYNC_asm ;;funcion espera a retrazado

    ;; Loop forever

jr    loop ;;salta a bucle loop

lunes, 12 de octubre de 2020

Get key cpctelera

 cpct_keyID getKey() {

  // Traverse the keystatus vector from end to start, to help
  // the compiler better optimize this code
  u8 i = 10, *keys = cpct_keyboardStatusBuffer + 9;
  u16 keypressed;
 
  // Wait for a keypress
  do { cpct_scanKeyboard(); } while ( ! cpct_isAnyKeyPressed() );

  // Analyse which key has been pressed and return its keycode
  do {
    // We analyse groups of keys byte by byte (8 by 8, 1 bit per key)
    // If no single key is pressed in this group, all bits will be on, and the byte will be 0xFF
    // Then, XORing the byte with 0xFF will result in 0 unless some key from this group is pressed
    keypressed = *keys ^ 0xFF;
    if (keypressed)
       return (keypressed << 8) + (i - 1); // Convert to cpct_keyID format: 8 first bits = key mask, 8 next bits, keyboard row (0-9)
    --keys;
  } while(--i);

  // No key was pressed
  return 0;
}

 cpct_keyID getKey() {

  // Traverse the keystatus vector from end to start, to help
  // the compiler better optimize this code
  u8 i = 10, *keys = cpct_keyboardStatusBuffer + 9;
  u16 keypressed;
 
  // Wait for a keypress
  do { cpct_scanKeyboard(); } while ( ! cpct_isAnyKeyPressed() );

  // Analyse which key has been pressed and return its keycode
  do {
    // We analyse groups of keys byte by byte (8 by 8, 1 bit per key)
    // If no single key is pressed in this group, all bits will be on, and the byte will be 0xFF
    // Then, XORing the byte with 0xFF will result in 0 unless some key from this group is pressed
    keypressed = *keys ^ 0xFF;
    if (keypressed)
       return (keypressed << 8) + (i - 1); // Convert to cpct_keyID format: 8 first bits = key mask, 8 next bits, keyboard row (0-9)
    --keys;
  } while(--i);

  // No key was pressed
  return 0;
}

domingo, 11 de octubre de 2020

Includes en cpctelera

 Fran Gallego:

include hace lo que todos los includes hacen en cualquier lenguaje


es lo mismo que si copiaras y pegaras el archivo que incluyes


Pero es que eso es idéntico en C y en C++


Por eso, se usa para incluir sólo declaraciones, no definiciones


Como en C


no pones en los ficheros de cabecera definiciones


sólo declaraciones


El concepto es el mismo


Todos los ficheros se compilan siempre por separado


ningún fichero sabe nada de que existan otros ficheros


Entonces, cuando quieres usar un símbolo que está en otro fichero


simplemente en el fichero que lo vas a usar, lo declaras


Para que el ensamblador sepa que ese símbolo existe, aunque no sepa cuánto vale


Es después, cuando el linker recoge todos los ficheros compilados intermedios y los junta


cuando mira dónde está cada símbolo


Si tienes dos ficheros F1 y F2


Con esta estructura de símbolos


F1

  etiqueta1::

  etiqueta2::

F2 

  otra1::

  otra2::


F1 y F2 se ensamblan por separado, individualmente


ninguno sabe de la existencia del otro


Así que si quieres que F1 pueda usar la etiqueta "otra2", por ejemplo


harías esto


F1

  .globl otra2

  etiqueta1::

  etiqueta2::

F2 

  otra1::

  otra2::


Simplemente, le dices al ensamblador "existe un símbolo otra2, que es global"


Y lo usas


como lo que haces con las llamadas a las funciones de CPCtelera


que son etiquetas, que no están en tu código


Si ahora resulta que tienes una etiqueta "cpct_doGame", que vas a usar tanto en F1 como F2


harías esto


F1

  .globl cpct_doGame

  etiqueta1::

  etiqueta2::

F2 

  .globl cpct_doGame

  otra1::

  otra2::


Pero eso ya es duplicar código


mientras sólo sea una etiqueta vale


pero si ahora resulta que quieres usar 4 símbolos en ambos ficheros, la cosa crece


F1

  .globl cpct_doGame_1

  .globl cpct_doGame_2

  .globl cpct_doGame_3

  .globl cpct_doGame_4

  etiqueta1::

  etiqueta2::

F2 

  .globl cpct_doGame_1

  .globl cpct_doGame_2

  .globl cpct_doGame_3

  .globl cpct_doGame_4

  otra1::

  otra2::


Y si tienes que hacer lo mismo en 5 ficheros, va siendo más feo


y si luego necesitas en los 5 ficheros, añadir un símbolo nuevo


te toca acordarte de todos los ficheros y editarlos uno a uno


Para evitar hacer eso


creas un tercer fichero


Un fichero de cabecera


Y haces esto


FH

  .globl cpct_doGame_1

  .globl cpct_doGame_2

  .globl cpct_doGame_3

  .globl cpct_doGame_4

  .globl cpct_doGame_5

F1

  .include "FH"

  etiqueta1::

  etiqueta2::

F2 

  .include "FH"

  otra1::

  otra2::


Eso es exactamente igual que haberlo escrito en los ficheros F1 y F2


Pero la ventaja es que sólo lo escribes en un sitio y cuando lo edites lo cambias para todos los que necesitan esas declaraciones


Así puedes tener 20 ficheros que incluyan FH


y en ninguno de ellos incurres en ningún coste


es lo mismo que haberlo escrito en los 20


totalmente igual, pero más práctico


cuidado, eso sí


no pongas en FH nada que no sean directivas, como has visto


Las directivas .globl


Sólo son información para el programa ensamblador


no generan bytes en el binario resultante


no existen en código máquina


sólo es información para el ensamblador para saber cosas sobre sus símbolos, mientras ensambla


Si metes código o bytes en un fichero del que luego hagas include


como lo estás duplicando en todas partes donde haces include


en todas ellas se generará ese código o bytes


por eso hay que saber usarlo, y entender el proceso, como te cuento ahora


Porque include es eso


un copy/paste automatizado

Sumar decimales en asm

 Fran Gallego:

@Kalandras Explicación fácil


Pones un número en el acumulador (A)


que en hexadecimal no tenga números mayores de 9


es decir, ambos números hexadecimales entre 0 y 9


como si fuera decimal, en vez de hexadecimal


a partir de ese momento


haces cualquier operación con el número


por ejemplo


add b


add #20


sub #15


lo que quieras


Si es puntuación, estás sumando puntos


pero después de cada operación aritmética


ejecutas la instrucción


DAA


Esa instrucción lo que hace es ajustar el resultado de la operación aritmética


como si los dígitos A-F no existieran, como si estuvieras usando números decimales


por ejemplo


ld a, #9

add #2


Da como resultado A = 0B


pero


ld a, #9

add #2

daa


Da como resultado A = 11


Como si hubieras sumado en decimal


DAA ajusta el resultado de la operación, para que sea como si fueran decimales

sábado, 10 de octubre de 2020

Imprimir scores en cpctelera

 Fran Gallego:

Un ejemplo para un score de 4 dígitos


Si tienes el score en HL


y le sumas una puntuación que está en DE


ld hl, #0x4995

ld de, #0x0010

ld a, l

add e

daa

ld l, a

ld a, h

adc d

daa

ld h, a


con eso sumas y da 0x4995+ 0x10 = 0x5005


Es como si sumaras en decimal


Pues sacando cada dígito por separado


porque cada dígito está codificado en 4 bits


Son dígitos hexadecimales


Si tienes A = 0x95


Los primeros 4 bits son un 9 ( 1001 )


Los segundos 4 bits son un 5 ( 0101 )


Así que sólo tienes que hacer operaciones de bits para quedarte con cada parte


y luego sumarles 48 para convertirlos en ASCII


Por ejemplo, si A = 0x95 = 0b10010101


puedes hacer esto para imprimir el 5


and #0x0F

add #48

call cpct_drawCharM0_asm


Con el AND te quedas sólo con los 4 últimos bits (el 5 )


le sumas 48 y da 53 (carácter del 5 en ASCII)


y se lo pasas a drawChar para imprimir


Si quieres imprimir el 9 de A = 0x95


harías esto


rrca

rrca

rrca

rrca

and #0x0F

add #48

call cpct_drawCharM0_asm


Rotas los bits de A 4 veces para poner abajo los 4 bits de arriba


y haces lo mismo de antes


De hecho, igual este año lo comento en clase porque es algo que nunca he explicado y creo que puede ser útil

sábado, 22 de agosto de 2020

Escribir frases

 Rutina de ejemplo para escribir frases predefinidas.

la he sacado del foro amstrad.es. 

https://www.amstrad.es/forum/viewtopic.php?f=6&t=5591&p=77489&hilit=Message%3A+db+%27hola+mundo%21%27%2C255#p77489



org &4200                ;origen de la rutinaPrintchar equ &Bb5a      ;instrucción para imprimir un caracter      

ld hl,Message            ;carga en hl la dirección de message
Call PrintString        ;llama a la rutina printstring
ret                    ;vuelve desde donde le llamaron   
    
    PrintString:        ;loop para imprimir
ld a,(hl)                ;carga en a la dirección de memoria ubicada en hl
cp 255                ;compara si a es 255
ret z                    ; y vuelve si es asi
inc hl                 ;incrementa en uno la posición de memoria de hl   
call PrintChar        ;imprime el carácter ubicado en a
jr PrintString        ;salta a printstring

Message: db 'hola mundo!',255    ;frase de ejemplo,termina en ,255 para control


Rutina detección teclado

un ejemplo de rutina  de detección de teclado. dar las gracias a artaburu por su permiso para poder publicarla.


Aquí cuelgo las rutinas que uso para detectar el teclado sin usar las opciones del firmware. Como ejemplo incluyo la detección de las teclas del cursor y del escape. 



CÓDIGO: SELECCIONAR TODO

; -----------------------------------------------------------------------------
; |Rutinas para detección de teclado leyendo diréctamente el hardware del CPC |
; |Raúl Simarro (Artaburu) 2006 |
; -----------------------------------------------------------------------------

;_______________________________________________________________________________
; Ejemplo
;_______________________________________________________________________________

ORG &4000

xor a
ld (salir),a

_bucle_teclado
call detecta_teclas_hardware
ld a,(salir)
cp 1 ;termina al pulsar esc
jp nz,_bucle_teclado

ret
salir db 0
;______________________________________________________________________________
detecta_teclas_hardware ; cada vez que se quieran detectar
di ; las teclas pulsadas se debe
call comprobacion_teclas_pulsadas ; ejecutar esta rutina
ei

ld a,(teclado)
;_________________________________________________
; movimientos extras
;_________________________________________________
;cp %00000101
;jr z,arriba_derecha
;cp %00000110
;jr z,arriba_izquierda
;cp %0001001
;jr z,arriba_corto_derecha
;cp %00001010
;jr z,arriba_corto_izquierda
;_________________________________________________

cp %00000100
jp z, tecla_arriba

cp %00001000
jp z, tecla_abajo

cp %00000010
jp z, tecla_izquierda

cp %00000001
jp z, tecla_derecha
ret



comprobacion_teclas_pulsadas
xor a
ld (teclado),a ;Reinicia a 0 la vble teclado


ld hl,tecla_izquierda_x+1
ld a,(HL)
ld (linea_a_buscar+1),a ;cambia la línea a explorar
XOR A
call detecta_teclado_x ; esta rutina lee la línea del teclado correspondiente
DEC hl ; pero sólo nos interesa una de las teclas.
and (HL) ;para filtrar por el bit de la tecla (puede haber varias pulsadas)
CP (hl) ;comprueba si el byte coincide
call z,tecla_izquierda_pulsada

ld hl,tecla_derecha_x+1
ld a,(HL)
ld (linea_a_buscar+1),a
XOR A
call detecta_teclado_x
DEC hl
and (HL)
CP (hl)
call z,tecla_derecha_pulsada

ld hl,tecla_arriba_x+1
ld a,(HL)
ld (linea_a_buscar+1),a
XOR A
call detecta_teclado_x
DEC hl
and (HL)
CP (hl)
call z,tecla_arriba_pulsada

ld hl,tecla_abajo_x+1
ld a,(HL)
ld (linea_a_buscar+1),a
XOR A
call detecta_teclado_x
DEC hl
and (HL)
CP (hl)
call z,tecla_abajo_pulsada



; Comprueba si se ha pulsado ESC
ld a,8
ld (linea_a_buscar+1),a
XOR A
di
call detecta_teclado_x
ei
cp 4
jp z, esc_pulsado
ret


esc_pulsado
ld a,1
ld (salir),a
ret

tecla_izquierda_pulsada
ld a,(teclado)
or %00000001
ld (teclado),a
ret
tecla_derecha_pulsada
ld a,(teclado)
or %00000010
ld (teclado),a
ret
tecla_arriba_pulsada
ld a,(teclado)
or %00000100
ld (teclado),a
ret
tecla_abajo_pulsada
ld a,(teclado)
or %00001000
ld (teclado),a
ret

detecta_teclado_x ;Tomado de las rutinas básicas que aparecen
;en los documentos de Kevin Thacker

ld bc,&f7*256+%10000010
out (c),c ;PPI A OUT. RESET.

ld bc,&f400+14 ;Registro 14 del PSG (Puerta A)
out (c),c ;(contains keyboard line data)

ld b,&f6 ;PSG control
ld c,%11000000 ;Select Register 14 for use
out (c),C ;send

ld c,0 ;PSG inactive
out (c),c ;send

ld b,&f7 ;8255 PPI control
ld c,%10010010 ;Port A and Port C (upper) - Operating mode 0
;Port A input, Port C (upper) output.

;Port B and Port C (lower) - Operating mode 0
;Port B input, Port C (lower) output

out (c),c ;send control byte

;;READ KEYBOARD LINE

ld b,&F6 ;PSG control + keyboard line wanted
ld a,%01000000 ;PSG control - read

; >> linea a buscar <<
linea_a_buscar
; >> linea a buscar <<
or 1 ;keyboard line 1 ;Cambio esta línea para explorar distintas
;líneas del teclado.
out (c),a ;send it
ld b,&F4 ;Port to get PSG port A (register 14) data
in a,(c) ;Keyboard data from keyboard line 9
cpl
ret



teclado db 0 ;Este byte indicará qué teclas han sido pulsadas
;después de un ciclo de exploración
linea db 0
bte db 0
tecla_0 dw &0204
;teclado_usable ; teclas del cursor, cada tecla está definida por su bit y su línea.
tecla_izquierda_x dw &0002 ; bit 0, línea 2
tecla_derecha_x dw &0101 ; bit 1, línea 1
tecla_arriba_x dw &0001 ; bit 0, línea 1
tecla_abajo_x dw &0004 ; bit 0, línea 4




tecla_arriba
;operaciones
ld a,65
call &bb5a ; como ejemplo, imprime la letra A,
; &BB5A es la rutina del firmware que escribe un caracter en pantalla.
ret
tecla_abajo
;operaciones
ld a,66
call &bb5a ; como ejemplo, imprime la letra B
ret
tecla_izquierda
;operaciones
ld a,67
call &bb5a ; como ejemplo, imprime la letra C
ret
tecla_derecha
;operaciones
ld a,68
call &bb5a ; como ejemplo, imprime la letra D
ret
Salu2,
Arta

Rutinas cpc ensamblador

 Aquí voy a ir poniendo rutinas creo y espero que útiles para el micro cpc de amstrad.

Son recopilatorios de varios sitios

lunes, 1 de junio de 2020

Instalar samba en raspbian

Instrucciones a seguir



sudo apt-get install samba samba-common-bin
sudo cp /etc/samba/smb.conf smb.old
sudo nano -w /etc/samba/smb.conf

[pi 16GB]
comment = USB Share
path = /media/16GB
writeable = Yes
create mask = 0777
directory mask = 0777
browseable = Yes
valid users @users
force user = pi
sudo smbpasswd -a pi

sudo /etc/init.d/smbd restart



jueves, 28 de mayo de 2020

He probado el ubuntu Server en la Raspberry. Dos minutos ha durado el pobre, he vuelto a poner raspbian.
Lento, al abrir Firefox y la página de winape es un suplicio.
Todo porque me gusta probar cosas en la pi, y le instalo muchas cosas que luego no se sacarles provecho. Y no se desinstalarla o configurarlos bien
Me paso con boinc( aprovechar el tiempo muerto de la CPU para investigación del coronavirus).
El pihole, para quitar publicidad al navegar por internet ( no noto mejoría ninguna)
uTorrent, que por gui se configura y no sirve para configurar por terminal.
Winape, que me gusta trastear con los cpc, estoy intentando aprender ensamblador , y no logro ejecutarlo
 Bueno, por ahora es todo.


lunes, 13 de abril de 2020

Mucho tiempo

Llevo mucho son escribir. Ahora con móvil, sin ordenador.
Uso una Raspberry,peleándome con ella. Uso raspbian, intento poner amule,torrent,jdownloader y plex server. Y a veces funciona.
Iré poniendo ideas de cómo manejarlo todo.