Separar em projetos diferentes

This commit is contained in:
Pedro de Oliveira 2014-08-12 04:05:06 +01:00
parent 1cf0517850
commit 2441814043
16 changed files with 203 additions and 11 deletions

View File

@ -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

BIN
scroller1/main.tap Normal file

Binary file not shown.

30
scroller2/README.md Normal file
View File

@ -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

45
scroller2/clear.asm Normal file
View File

@ -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

16
scroller2/delay.asm Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
ret
djnz copia_para_udg_loop ; b--, se b != 0 salta
ret