1
Ensamblador / Re:Rutinas de ensamblador con Laddh
« en: Mayo 17, 2024, 12:36:09 »
En esta entrega toca el ejemplo de scroll por hardware o scroll fino, pixel a pixel, que siempre diferencio nuestro c64 de otras máquinas de la época.
Lo primero de todo es poner la pantalla en modo 38 columnas para el scroll horizontal. Los tres primeros bits del registro $d016 controlan el scroll horizontal y los del registro $d011 el vertical, el funcionamiento es el mismo y afecta a toda la pantalla.
Con 3 bits llegamos de 0 a 7, o sea 8 pixeles, justo el tamaño de un carácter, con lo que sumando haríamos scroll a la derecha y restando hacia la izquierda, como en el ejemplo que os pongo hoy, la rutina left, pero ojo, justo al llegar a 0 toca hacer un scroll por soft de todas las líneas que queráis mover sino el scroll hard entraría en bucle y volvería a poner el carácter en su posición de inicio, en el listado lo tenéis comentado, junto con el ejecutable para que lo veáis en acción.
Con solo todas la rutinas que os he mostrado en estos mensajes, lo creáis o no, ya tenéis el armazón para construir vuestro propio primer juego en ensamblador, solo añadiendo la lógica que queráis que tenga vuestro programa. Es cuestión de probar y perseverar hasta que lo consigáis. Crear tu propio programa, parir tu propia creación os aseguro que llena de orgullo y satisfacción, mucho más que solo jugar partidas al juego que sea. Animo y queda este hilo para las dudas que os surjan.
Lo primero de todo es poner la pantalla en modo 38 columnas para el scroll horizontal. Los tres primeros bits del registro $d016 controlan el scroll horizontal y los del registro $d011 el vertical, el funcionamiento es el mismo y afecta a toda la pantalla.
Con 3 bits llegamos de 0 a 7, o sea 8 pixeles, justo el tamaño de un carácter, con lo que sumando haríamos scroll a la derecha y restando hacia la izquierda, como en el ejemplo que os pongo hoy, la rutina left, pero ojo, justo al llegar a 0 toca hacer un scroll por soft de todas las líneas que queráis mover sino el scroll hard entraría en bucle y volvería a poner el carácter en su posición de inicio, en el listado lo tenéis comentado, junto con el ejecutable para que lo veáis en acción.
Código: [Seleccionar]
; 10 SYS (2064) línea para que autoarranque el programa
*=$0801
BYTE $0E, $08, $0A, $00, $9E, $20, $28, $32, $30, $36, $34, $29, $00, $00, $00
screen_control_register1 = $d011
screen_control_register2 = $d016
*=$0810 ;inicio del programa
v = $d000 ;variable que apunta al chip VIC, el que gestiona todo lo gráfico
LDA screen_control_register2
AND #$F7 ;pon pantalla en 38 columnas
STA screen_control_register2
jsr sprites ;llamamos a la rutina para presentar el sprite en pantalla
loop jsr raster_wait ;sin esto no veríamos nada, el código máquina es raaaaaapido
jsr PlayerControl ;la rutina para controlar el joystick
jsr expande ;controla msb de los sprites, > o < de 255 x
jsr left ;rutina scroll
jmp loop ;vuelve al bucle principal
left ; scroll por hardware pixel a pixel
LDX screen_offset
DEX ; decrementa variable de 7 a 0
STX screen_offset
CPX #$FF
BEQ continue ;hemos llegado a 0? vuelve el valor a 7
JMP end
continue
LDX #$07
STX screen_offset
jsr move_rows_left
jsr advance_scroll
end
LDA screen_control_register2
AND #$F8 ;11111000 pone los 3 primeros bits del registro a 0
ORA screen_offset ; le va restando de 7 a 0
STA screen_control_register2 ; y lo guarda en el registro de scroll $d016
rts
move_rows_left ; scroll por soft, mueve una columna a la izquierda
LDX #$00
l2
lda $0429,x
sta $0428,x
LDA $0451,X
STA $0450,X
LDA $0479,X
STA $0478,X
LDA $04A1,X
STA $04A0,X
LDA $04C9,X
STA $04C8,X
LDA $04F1,X
STA $04F0,X
LDA $0519,X
STA $0518,X
LDA $0541,X
STA $0540,X
LDA $0569,X
STA $0568,X
LDA $0591,X
STA $0590,X
LDA $05B9,X
STA $05B8,X
LDA $05E1,X
STA $05E0,X
INX
CPX #39
BNE l2
rts
advance_scroll;efecto persiana, pasa la primera columna izquierda a la última por la derecha
lda $0428
sta $044f
lda $0450
sta $0477
lda $0478
sta $049f
lda $04a0
sta $04c7
lda $04c8
sta $04ef
lda $04f0
sta $0517
lda $0518
sta $053f
lda $0540
sta $0567
lda $0568
sta $058f
lda $0590
sta $05b7
lda $05b8
sta $05df
lda $05e0
sta $0607
rts
screen_offset byte $07
PlayerControl
LDA $DC00 ;LEEMOS JOY
AND #31 ;LA CUATRO DIRECCIONES ARRIBA ABAJO IZQ DER
CMP #30 ;MAS DIAGONALES Y FUEGO
BEQ ARR
CMP #29
BEQ ABJ
CMP #27
BEQ IZQ
CMP #23
BEQ DER
cmp #22
beq derar
cmp #21
beq derab
CMP #25
BEQ IZQab
CMP #26
BEQ IZQar
cmp #15
beq fuego
rts
arr dec spritepos+1 ;coordenada vertical del sprite 0
rts
abj inc spritepos+1
rts
izq dec spritepos ;coordenada horizontal del sprite 0
rts
der inc spritepos
rts
derar inc spritepos
dec spritepos+1
rts
derab inc spritepos
inc spritepos+1
rts
izqab dec spritepos
inc spritepos+1
rts
izqar dec spritepos
dec spritepos+1
rts
fuego inc $d020 ;cambia color del borde pantalla
rts
raster_wait ;espera línea raster 255, el raster pasa 50 veces por segundo
l LDA #$ff ;en pantalla
CMP $D012
BNE l
BIT $d011
BMI l
rts
sprites lda #1
sta v+21 ;activamos sprite 0
sta v+28 ;activamos modo multicolor del sprite 0
lda #128 ;puntero para indicar donde estan los datos del sprite, 128*64=8192 $2000
sta 2040
lda #1 ;color sprite
sta v+39
lda #14 ;color multicolor 1, para todos los sprites
sta v+37
lda #2 ;color multicolor 2, para todos los sprites
sta v+38
lda #100 ;coordenadas x,y del sprite 0
sta spritepos
sta spritepos+1
rts
expande ldx #$00 ;posición msb de los sprites
xloop lda spritepos+1,x
sta $d001,x
lda spritepos,x
asl ;x position is more
ror $d010 ;than 256 pixels
sta $d000,x
inx
inx
cpx #16
bne xloop
rts
*=$2000 ; la forma del sprite
byte 9,86,0
byte 37,86,0
byte 149,86,0
byte 85,86,0
byte 85,170,170
byte 86,37,86
byte 86,37,86
byte 86,37,86
byte 86,37,90
byte 86,42,168
byte 86,42,168
byte 86,47,250
byte 86,47,254
byte 86,47,254
byte 86,47,254
byte 86,42,170
byte 85,170,0
byte 85,86,0
byte 149,86,0
byte 37,86,0
byte 9,86,0
spritepos BYTE $00,$00 ;SPRITE 0 X/Y
BYTE $00,$00 ;SPRITE 1 X/Y
BYTE $00,$00 ;SPRITE 2 X/Y
BYTE $00,$00 ;SPRITE 3 X/Y
BYTE $00,$00 ;SPRITE 4 X/Y
BYTE $00,$00 ;SPRITE 5 X/Y
BYTE $00,$00 ;SPRITE 6 X/Y
BYTE $00,$00 ;SPRITE 7 X/Y
Con solo todas la rutinas que os he mostrado en estos mensajes, lo creáis o no, ya tenéis el armazón para construir vuestro propio primer juego en ensamblador, solo añadiendo la lógica que queráis que tenga vuestro programa. Es cuestión de probar y perseverar hasta que lo consigáis. Crear tu propio programa, parir tu propia creación os aseguro que llena de orgullo y satisfacción, mucho más que solo jugar partidas al juego que sea. Animo y queda este hilo para las dudas que os surjan.