;-----------------------------------------------------------------------------
;                           Relogio Digital ZX-7.2
;                      Listagem do Codigo Fonte Assembly
;                          Por Cleber Jean Barranco
;                           cleberjean@hotmail.com
;                                 25/Jun/2006
;-----------------------------------------------------------------------------


;Buffers para armazenagem das horas

Hour:
    db   00h           ;buffer da hora (endereco 16514)

Minute:
    db   00h           ;buffer do minuto (endereco 16515)

Second:
    db   00h           ;buffer do segundo (endereco 16516)


;Inicio do programa (endereco 16517)
;Verifica a Frequencia Vertical do sistema e
;ajusta o valor para o timer de 1 segundo

Start:
    ld   a,(4028h)     ;obtem o valor de "MARGIN"
    cp   1Fh           ;verifica se o micro e' 60 Hz
    ld   a,0FFh        ;fator de retardo para 60 Hz (micros brasileiros e americanos)
    jr   z,$+4
    ld   a,0F5h        ;fator de retardo para 50 Hz (ZX81)
    ld   (4021h),a


;Gera o retangulo do relogio

    ld   hl,(400Ch)
    ld   de,0135h
    add  hl,de
    ld   de,0017h
    ld   c,03h
    ld   b,0Ah
    ld   (hl),$80
    inc  hl
    djnz $-3           ;LD (HL),$80
    add  hl,de         ;proxima linha
    dec  c
    jr   nz,$-9        ;salta para LD B,0Ah


;Verifica se o micro esta' em FAST e passa para SLOW se sim

    ld   a,(403Bh)
    bit  7,a           ;verifica se o computador esta' em FAST
    call z,0F2Bh       ;chama o modo SLOW


;Reseta o Segundo

    sub  a
    ld   (Second),a    ;zera o segundo


;Imprime as horas (inicio do loop de execucao do programa)

Print_Time:
    ld   hl,(400Ch)
    ld   bc,0157h
    add  hl,bc         ;calcula o endereco da impressao no video
    ld   de,Hour
    ld   b,03h         ;total de numeros a imprimir
    jr   $+06h         ;primeiro imprime o numero da hora

Print_Colon:
    ld   (hl),$8E      ;2 pontos (:)
    inc  hl
    inc  de
    ld   a,(de)
    push bc
    call Print_Number
    pop  bc
    djnz Print_Colon


;Verifica se as teclas Shift e Espaco estao pressionadas

    ld   hl,(4025h)    ;obtem o estado do teclado
    ld   a,h
    cp   0FCh          ;SHIFT esta' pressionado?
    jr   nz,Timer      ;se nao, continua com o programa
    ld   a,l
    cp   7Fh           ;SPACE esta' pressionado?
    ret  z             ;retorna ao BASIC se sim


;Temporizacao de 1 segundo

Timer:
    ld   a,(4021h)
    ld   (4034h),a        ;inicializa o contador de quadros do video

Wait_1_Second:
    ld   a,(4034h)
    cp   0C4h             ;ja' passou 1 segundo? (50/60 frames)
    jr   nc,Wait_1_Second ;continua aguardando se nao


;Incrementa o relogio

    ld   b,02h
    ld   a,(de)
    inc  a             ;incrementa o segundo/minuto
    ld   (de),a
    cp   60
    jr   c,Print_Time
    sub  a
    ld   (de),a        ;zera o segundo/minuto
    dec  de
    djnz $-0Ah         ;volta para a instrucao LD A,(DE) antes de CP 60
    ld   a,(de)
    inc  a             ;incrementa a hora
    ld   (de),a
    cp   24
    jr   c,Print_Time
    sub  a             ;zera a hora
    jr   $-06h         ;vai para a instrucao LD (DE),A antes de CP 24


;Rotina de impressao dos numeros

Print_Number:
    ld   c,0Ah
    call Bin2CHR       ;imprime a dezena do numero
    ld   c,01

Bin2CHR:
    ld   b,$9C         ;codigo CHR$ do numero 0 inverso
    sub  c
    jr   c,$+5
    inc  b
    jr   $-4
    add  a,c
    ld   (hl),b        ;imprime o algarismo
    inc  hl            ;proxima coluna de impressao na tela
    ret 
