Descrição
Relógio feito em linguagem assembly do nintendo 8 bits (6502).
O clock se baseia na NMI de um sistema NTSC (non-maskable interrupts - Período em que o feixe do televisor está retornando a posição zero após desenhar tela inteira) .
Tenho que admitir que o código não é lá essas coisas, pois muitos techos são redundantes. Mas foi minha primeira aventura com assembly maior do que somar o valor de 2 registradores! :)
Deve ser compilado com o nesasm (pode ser baixado em:
http://bobrost.com/nes/files/nbasic_2004_03_14.zip) e executado com um emulador de nintendo 8 bits.
[ Download:
relogio_nes.zip ]
[
Enviar nova versão ]
[ Esconder código-fonte ]
; pt_br: Um relogio simples - Feito por Paulo Sergio Travaglia em 21/06/2009
; pt_br: Utiliza a taxa de refresh do NTSC como base de contagem
; en: A simple clock - Made by Paulo Sergio Travaglia in 2009/06/21
; en: Uses NTSC refresh rate as base for counting time
; pstglia@gmail.com
.inesprg 1
.ineschr 1
.inesmir 1
.inesmap 0
.bank 0
.org $8000
Inicio:
; pt_br: Configura a PPU
; en: Set up PPU
lda #%10010000
sta $2000
lda #%00011110
sta $2001
; pt_br: Carregando as paletas
; en: Loading palletes
lda #$3F
sta $2006
lda #$00
sta $2006
ldx #$0
loop_pal:
lda pallete, x
sta $2007
inx
cpx #$20
bne loop_pal
; pt_br: Definindo valores iniciais para o horario (segundo, minuto, hora)
; en: Setting initial value for time (second, minute, hour)
lda #00
sta $0200
lda #00
sta $0201
lda #00
sta $0202
lda #0
; pt_br: Inicializa enderecos que guardam o tile com os digitos a serem impressos
; en: Initialize addresses to store the tiles that will be displayed on screen
sta $0230
sta $0231
sta $0232
sta $0233
sta $0234
sta $0235
; pr_br: Contador do timer
; en: timer counter
sta $020a
loop_main:
; pt_br: Incrementa os valores caso um v_blank esteja acontecendo
; en: Increase values when a v_blank is occuring
lda $2002
bpl inc_seg
jmp loop_main
inc_seg:
; pt_br: Verifica se ja se passaram 60 segundos (60 NMIs NTSC)
; en: check if 60 seconds has passed (60 NTSC NMIs)
ldx $020a
cpx #60
bne loop_main
ldx #0
stx $020a
inc $0200
lda $0200
cmp #60
beq inc_min
ldx #0
jsr calc_digitos
ldx #2
jsr calc_digitos
ldx #4
jsr calc_digitos
jmp loop_main
inc_min:
inc $0201
lda $0201
cmp #60
beq inc_hora
ldx #0
stx $0200
ldx #0
jsr calc_digitos
ldx #2
jsr calc_digitos
ldx #4
jsr calc_digitos
jmp loop_main
inc_hora:
inc $0202
lda $0202
cmp #24
beq reset_hora
ldx #0
stx $0200
stx $0201
ldx #0
jsr calc_digitos
ldx #2
jsr calc_digitos
ldx #4
jsr calc_digitos
jmp loop_main
reset_hora:
ldx #0
stx $0200
stx $0201
stx $0202
ldx #0
jsr calc_digitos
ldx #2
jsr calc_digitos
ldx #4
jsr calc_digitos
jmp loop_main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; pt_br: Desenha a tela durante a NMI
; en: Draw screen on NMI
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
desenha_tela:
pha
txa
pha
tya
pha
inc $020a
; pt_br: Obtem os digitos das horas
; en: Get hour digits
ldx #0
stx $2003
stx $2003
ldx #30
stx $2004 ; Y-coord
ldx $0234
stx $2004 ; Tile
ldx #0
stx $2004 ; Attr
stx $2004 ; X-coord
ldx #30
stx $2004 ; Y-coord
ldx $0235
stx $2004 ; Tile
ldx #0
stx $2004 ; Attr
ldx #9
stx $2004 ; X-coord
; pt_br: Obtem os digitos dos minutos
; en: Get minutes digits
ldx #30
stx $2004 ; Y-coord
ldx $0232
stx $2004 ; Tile
ldx #0
stx $2004 ; Attr
ldx #18
stx $2004 ; X-coord
ldx #30
stx $2004 ; Y-coord
ldx $0233
stx $2004 ; Tile
ldx #0
stx $2004 ; Attr
ldx #27
stx $2004 ; X-coord
; pt_br: Obtem os digitos dos segundos
; en: Get seconds digits
ldx #30
stx $2004 ; Y-coord
ldx $0230
stx $2004 ; Tile
ldx #0
stx $2004 ; Attr
ldx #36
stx $2004 ; X-coord
ldx #30
stx $2004 ; Y-coord
ldx $0231
stx $2004 ; Tile
ldx #0
stx $2004 ; Attr
ldx #45
stx $2004 ; X-coord
pla
tay
pla
tax
pla
rti
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; pt_br: Obtem os digitos para impressao e grava em $0230 e $0231
; en: Get the digits for printing and write on $0230 e $0231
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
calc_digitos:
lda #0
sta $0230,x
sta $0231,x
; pt_br: Em que casa de digitos estamos (10, 20, 30, 40 ou 50)
ldy #10
sty $0205
; pt_br: A cada 10 unidades, incrementa 1
ldy #0
sty $0206
loop_inc:
; Casa de 10 digitos
cpy $0205
bne prox_1
inc $0206
lda $0205
clc
adc #10
sta $0205
; pt_br: calculo do indice do 1o digito na SPR-RAM
sec
sbc $0206
sta $0207
lda $0205
sec
sbc $0207
sta $0230,x
prox_1:
; pt_br: calculo do indice do 2o. digito na SPR-RAM
tya
clc
adc #10
sec
sbc $0205
sta $0231,x
; pr_br: Checa o parametro passado para fazer o deslocamento correspondente
; en: Check the passed parameters to do the corresponding shift
txa
pha
cpx #4 ; IF X = 4 THEN $0202
bne nxt
ldx #2
jmp nxt2
nxt:
cpx #2 ; ELSE IF X = 2 THEN $0201
bne nxt2
ldx #1
nxt2:
lda $0200,x
sta $0210
pla
tax
cpy $0210
beq saida_calc_digitos
iny
jmp loop_inc
saida_calc_digitos:
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; pt_br: Paleta de cores do fundo e dos sprites. Tirada da pagina de tutorial do GbaGuy
; en: Background and colour palletes. It was taken from GbaGuy tutorial site
pallete:
.db $32,$01,$06,$2A,$32,$03,$10,$00
.db $32,$38,$33,$3C,$32,$21,$26,$02
.db $32,$16,$12,$14,$32,$07,$17,$27
.db $32,$0B,$07,$2D,$32,$3A,$35,$31
.bank 1
.org $FFFA
.dw desenha_tela
.dw Inicio
.dw 0
.bank 2
.org $0000
.incbin "pal_spr.scr"
.incbin "pal_bkg.scr"
Scripts recomendados
Hora do sistema
Fibonacci em assembly
Calcula ano de nascimento - C + Assembly
GAS Bubblesort
codigo em assembley que soma dois numeros
Comentários
[1] Comentário enviado por
pstglia em 29/06/2009 - 22:13h:
Só uma pequena errata de comentário no código:
A principio eu fazia os incrementos de valores (segundos, minutos e horas) durante um v_blank. Depois alterei para que fizesse isso quando um v_blank NÃO estiver ocorrendo.
O período da v_blank é muito curto e na maior parte dos casos deve ser reservado para atualizações de tela.