mirror of https://github.com/falsovsky/z80.git
Separar em projetos diferentes
This commit is contained in:
parent
1cf0517850
commit
2441814043
|
@ -17,9 +17,7 @@ Instalação
|
|||
```sh
|
||||
git clone https://github.com/falsovsky/z80.git
|
||||
cd z80/scroller
|
||||
pasmo -v --tapbas --err main_first.asm main_first.tap
|
||||
pasmo -v --tapbas --err main_second.asm main_second.tap
|
||||
|
||||
pasmo -v --tapbas --err main.asm main.tap
|
||||
```
|
||||
|
||||
Licença
|
Binary file not shown.
|
@ -0,0 +1,30 @@
|
|||
Scroller
|
||||
=========
|
||||
|
||||
Scroller é uma implementação um scroller de texto em Assembly no ZX Spectrum.
|
||||
|
||||
Requisitos
|
||||
-----------
|
||||
|
||||
O unico realmente necessário é o Assembler, mas para ver o resultado convem tambem ter um emulador, os verdadeiros podem converter o ficheiro [tap] para audio, passar para um leitor de mp3 e ligar a um Spectrum real :-D
|
||||
|
||||
* [Pasmo] - Assembler de Z80, é Open Source e Cross Platform
|
||||
* [ZX Spin] - Emulador de ZX Spectrum para Windows que inclui um Debugger
|
||||
|
||||
Instalação
|
||||
--------------
|
||||
|
||||
```sh
|
||||
git clone https://github.com/falsovsky/z80.git
|
||||
cd z80/scroller
|
||||
pasmo -v --tapbas --err main.asm main.tap
|
||||
```
|
||||
|
||||
Licença
|
||||
----
|
||||
|
||||
BSD
|
||||
|
||||
[tap]:http://www.worldofspectrum.org/faq/reference/formats.htm
|
||||
[Pasmo]:http://pasmo.speccy.org/
|
||||
[ZX Spin]:http://www.zophar.net/sinclair/zx-spin.html
|
|
@ -0,0 +1,45 @@
|
|||
attr_p equ $5c8d; Endereço que contem as cores permanentes
|
||||
bordcr equ $5c48; Endereço que contem a cor da borda
|
||||
rom_limpa_ecra equ $0daf; Rotina da ROM que limpa o ecrã
|
||||
rom_define_borda equ $2294; Rotina da ROM que define a borda
|
||||
|
||||
; Cores
|
||||
; Numero | Binario | Nome
|
||||
; 0 | 000 | Preto
|
||||
; 1 | 001 | Azul
|
||||
; 2 | 010 | Vermelho
|
||||
; 3 | 011 | Roxo
|
||||
; 4 | 100 | Verde
|
||||
; 5 | 101 | Cyan
|
||||
; 6 | 110 | Amarelo
|
||||
; 7 | 111 | Branco
|
||||
|
||||
; 8 bits para definir ink, paper, brightness e flash
|
||||
; |F |B |P2|P1|P0|I2|I1|I0|
|
||||
; F Flash
|
||||
; B Brightness
|
||||
; P Paper
|
||||
; I Ink
|
||||
|
||||
; Então para definir o flash desligado, o brightness ligado com o
|
||||
; fundo a preto e o texto a amarelo fica-se com:
|
||||
; 01000110 = 70 = $46
|
||||
; 01000000 = 64 = $40 - Tudo preto
|
||||
; 01000111 = 71 = $47 - Fundo preto Texto Branco
|
||||
screen_attribute equ $47
|
||||
|
||||
; Valor de 0 a 7
|
||||
border_color equ $0
|
||||
|
||||
clear_screen
|
||||
ld a, screen_attribute
|
||||
ld (attr_p), a ; Variavel de sistema que permite definir
|
||||
; o ink, paper, brightness e flash
|
||||
call rom_limpa_ecra ; Clear screen
|
||||
|
||||
ld a, border_color ; Cor do border
|
||||
call rom_define_borda+$7
|
||||
; Chama a rotina da ROM para actualizar a borda, mas salta 7
|
||||
; bytes à frente, porque são para ler o valor da borda do
|
||||
; BASIC. O valor fica guardado em 23624.
|
||||
ret
|
|
@ -0,0 +1,16 @@
|
|||
; Rotina de delay variavel, conforme o valor definido em A antes de a chamar
|
||||
; Ripada do Paradise Café
|
||||
delay
|
||||
push bc
|
||||
delay_start
|
||||
ld c, 10
|
||||
delay_loop2
|
||||
ld b, 0
|
||||
delay_loop1
|
||||
djnz delay_loop1 ; b--, se b != 0 corre novamente o loop1
|
||||
dec c ; c--
|
||||
jr nz, delay_loop2 ; Se c != 0 corre o loop2
|
||||
dec a ; a--
|
||||
jr nz, delay_start ; Se a != 0 volta ao inicio da rotina
|
||||
pop bc
|
||||
ret
|
Binary file not shown.
|
@ -0,0 +1,24 @@
|
|||
; printa numeros de 0 a 9 na linha definida em A
|
||||
printnumbers
|
||||
ld b, a ; guarda o valor de A em B
|
||||
ld a, $16 ; AT
|
||||
rst $10
|
||||
ld a, b ; Y = B
|
||||
rst $10
|
||||
ld a, $0 ; X = 0
|
||||
rst $10
|
||||
|
||||
ld b, $20 ; 32 colunas
|
||||
ld h, $30 ; chr "0"
|
||||
|
||||
printnumbers_loop
|
||||
ld a, h ; printa o chr em H
|
||||
rst $10
|
||||
inc h ; Incrementa
|
||||
ld a, h ; Guarda o valor em A
|
||||
cp $3a ; Compara com chr ":" (a seguir ao "0")
|
||||
jr nz, printnumbers_continue
|
||||
ld h, $30 ; Volta a meter a "0"
|
||||
printnumbers_continue
|
||||
djnz printnumbers_loop
|
||||
ret
|
|
@ -0,0 +1,79 @@
|
|||
;videoAddr equ 4840h ; Endereço de Memoria Video da Linha 10
|
||||
;videoAddr equ 4940h ; Faz o mesmo, tenho de entender porque
|
||||
|
||||
addractual1 db 0,0
|
||||
ultimoaddr db 0,0
|
||||
|
||||
; Rotina de scroll de texto da direita para a esquerda pixel a pixel
|
||||
; O endereço inicial tem de vir em HL
|
||||
scroll_esquerda
|
||||
; ld hl, videoAddr ; Endereço de Memoria Video a ser manipulado
|
||||
ld c, $8 ; Numero de vezes que a rotina vai correr
|
||||
; 8 é o numero de linhas de pixeis a scrollar
|
||||
|
||||
; Loop1
|
||||
scroll_esquerda_0
|
||||
ld (addractual1), hl ; Guarda o valor de HL em tmp1
|
||||
call scroll_esquerda_1 ; Scrolla
|
||||
ld hl, (addractual1) ; Le o valor de tmp1 para HL
|
||||
|
||||
inc h ; Incrementa H, mas como estamos a trabalhar com um
|
||||
; endereço de 16bits, na realidade vai adicionar
|
||||
; $100 a HL
|
||||
; Isto vai fazer com que a segunda rotina seja
|
||||
; chamada com os seguintes endereços em tmp1
|
||||
; videoAddr, videoAddr+$100 videoAddr+$200,
|
||||
; ..., videoAddr+$700
|
||||
|
||||
dec c ; Decrementa o contador C
|
||||
jr nz, scroll_esquerda_0; Se C != 0 corre novamente o Loop1
|
||||
ret
|
||||
|
||||
; Segunda rotina
|
||||
scroll_esquerda_1
|
||||
ld hl, (addractual1) ; Le o argumento tmp1 para HL
|
||||
|
||||
push bc
|
||||
ld bc, $1f ; Soma $1f ao endereço para começar
|
||||
adc hl, bc ; no fim da linha, tudo à direita
|
||||
; Cada linha tem 32 bytes
|
||||
|
||||
ld (ultimoaddr), hl ; Guarda o endereço do fim da linha
|
||||
pop bc
|
||||
|
||||
ld b, $20 ; Numero de vezes que vai correr
|
||||
|
||||
; Vai começar por fazer um rotate left à coluna mais à direita, e
|
||||
; guarda o bit que se perde na carry, que vai ser usado como o
|
||||
; bit 0 do proximo rotate left que for executado.
|
||||
|
||||
; Se no rotate da coluna mais à esquerda se perdeu alguma coisa,
|
||||
; então é para passar para a coluna mais a direita.
|
||||
; Se depois do ultimo rotate o carry estiver definido, faz-se um
|
||||
; OR ao bit 0 da coluna mais à direita.
|
||||
|
||||
; Loop2
|
||||
scroll_esquerda_2
|
||||
ld a, (hl) ; Faz um rotate left aos 8 pixels no
|
||||
rla ; endereço de video ram em HL, o bit
|
||||
; perdido fica na carry
|
||||
ld (hl), a ; Actualiza
|
||||
dec hl ; Anda uma coluna para a esquerda
|
||||
djnz scroll_esquerda_2 ; Se ainda nao chegou ao fim, repete
|
||||
|
||||
ld hl, (ultimoaddr) ; Le o valor do endereço da coluna
|
||||
ld a, (hl) ; mais à direita, em A
|
||||
|
||||
; Se não tem carry significa que não perdeu pixel nenhum
|
||||
; no ultimo rotate, então não é preciso passar nada para
|
||||
; a coluna mais à direita porque já tem o bit 0 a 0 devido
|
||||
; ao rotate inicial.
|
||||
jr nc, scroll_esquerda_sem_carry ; Não tem carry? vai para o fim
|
||||
|
||||
; Se tem carry é porque se perdeu um pixel no ultimo
|
||||
; rotate, então tem de se settar o bit 0 do coluna mais
|
||||
; à direita a 1
|
||||
or $1 ; bit 0 = 1
|
||||
scroll_esquerda_sem_carry
|
||||
ld (hl), a ; Actualiza
|
||||
ret
|
|
@ -13,8 +13,8 @@ udg equ $5c7b ; Endereço do primeiro user-defined graphics (2 bytes)
|
|||
udg_start equ $ff58 ; User-defined characters, vai até $ffff
|
||||
; São acessiveis com o caracter $90 até $a4
|
||||
|
||||
letra_pos db 0,0
|
||||
text_pos db 0,0
|
||||
char_pos db 0
|
||||
|
||||
scroll_text
|
||||
; Verificar se o valor de text_pos já foi alguma vez alterado
|
||||
|
@ -52,14 +52,14 @@ scroll_text_loop
|
|||
ld hl, font_start
|
||||
add hl, de ; $3C00 + $260 = $3E60
|
||||
|
||||
ld (letra_pos), hl ; Guarda o valor em letra_pos
|
||||
|
||||
call copia_para_udg ; Copia a letra para o UDG#1
|
||||
; O argumento para a rotina é o valor em HL
|
||||
|
||||
ld a, $90 ; Imprime UDG#1
|
||||
rst $10
|
||||
|
||||
pop hl ; Tira a posição na string da stack
|
||||
inc hl ; Anda para a frente
|
||||
|
||||
ld a, (hl) ; Le o proximo valor
|
||||
cp 0 ; Se for 0 estamos no fim da string
|
||||
jr z, reset ; Reset à posição
|
||||
|
@ -71,13 +71,13 @@ the_end
|
|||
ret
|
||||
|
||||
copia_para_udg
|
||||
ld hl, (letra_pos) ; Posição da font da letra a copiar
|
||||
; Está a contar que o endereço de origem esteja em HL
|
||||
ld b, $8 ; Copiar 8 bytes, cada letra são 8x8
|
||||
ld de, udg_start ; Destino
|
||||
copia_para_udg_r
|
||||
copia_para_udg_loop
|
||||
ld a, (hl) ; Le origem
|
||||
ld (de), a ; Copia para destino
|
||||
inc hl ; Incrementa ambos
|
||||
inc de
|
||||
djnz copia_para_udg_r ; b--, se b != 0 salta
|
||||
djnz copia_para_udg_loop ; b--, se b != 0 salta
|
||||
ret
|
Loading…
Reference in New Issue