mirror of https://github.com/zxdos/zxuno.git
164 lines
6.6 KiB
NASM
164 lines
6.6 KiB
NASM
; rtc.asm - return date for esxdos call on $2700
|
|
;
|
|
; Copyright (C) 2022 Antonio Villena/McLeod_ideafix
|
|
;
|
|
; This program is free software: you can redistribute it and/or modify
|
|
; it under the terms of the GNU General Public License as published by
|
|
; the Free Software Foundation, version 3.
|
|
;
|
|
; This program is distributed in the hope that it will be useful,
|
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
; GNU General Public License for more details.
|
|
;
|
|
; You should have received a copy of the GNU General Public License
|
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
;
|
|
; Compatible compilers:
|
|
; SjAsmPlus, <https://github.com/z00m128/sjasmplus>
|
|
;
|
|
;-------------------------------------------------------------------------------
|
|
|
|
output RTC.SYS
|
|
|
|
define SCL0SDA0 00b
|
|
define SCL0SDA1 01b
|
|
define SCL1SDA0 10b
|
|
define SCL1SDA1 11b
|
|
define I2CADDR_R $a3
|
|
define I2CADDR_W $a2
|
|
|
|
include zxuno.def
|
|
include esxdos.def
|
|
|
|
org $2700
|
|
|
|
ld bc, ZXUNOADDR
|
|
ld a, i2creg
|
|
out (c), a ; selecciono el registro I2C.
|
|
inc b
|
|
ld hl, Params
|
|
SendW ld a, SCL1SDA1 ;Transmito E bytes apuntados por HL al bus I2C (escritura)
|
|
out (c), a ;Envío condición de START al bus (SDA a 0 mientras mantengo SCL a 1)
|
|
dec a ;ld a,SCL1SDA0
|
|
out (c), a
|
|
ld a, I2CADDR_W ;Envío la dirección I2C de escritura del RTC
|
|
call SendByte
|
|
ld a, 2 ;y en un bucle, me pongo a enviar uno tras otro, los E bytes a los que apunta HL
|
|
call SendByte
|
|
call Send0 ;después de enviar el ultimo byte, envío la condición de STOP al bus (envío un 0, con lo que se queda SDA a 0 y SCL a 1, y a continuación pongo SDA a 1)
|
|
inc d ;ld d, SCL1SDA1
|
|
out (c), d
|
|
ld e, 7
|
|
ld a, SCL1SDA1 ;Recibo E bytes que se guardarán a partir de donde indique HL
|
|
out (c), a
|
|
dec a ;Envío la condición de START al bus I2C
|
|
out (c), a
|
|
ld a, I2CADDR_R ;Envío la dirección I2C de lectura del RTC
|
|
call SendByte
|
|
LoopSendR call nz, Send0 ;enviar un ACK es enviar un 0
|
|
call RcvByte ;y en un bucle, me pongo a recibir un byte detrás de otro. Tras cada byte, menos el último, envío ACK
|
|
ld (hl), a
|
|
inc hl
|
|
dec e
|
|
jr nz, LoopSendR
|
|
call Send1 ;aquí llego si acabo de recibir el último byte. Envío un NACK (un 1)
|
|
call Send0 ;y a continuación envío la condición de STOP al bus I2C
|
|
inc d ;ld d, SCL1SDA1
|
|
out (c), d
|
|
ld hl, Params
|
|
ld b, %01111110 ;Segundos
|
|
call BCDtobin
|
|
rrca ;Segundos / 2
|
|
ld e, a ;Guarda en E
|
|
ld b, %01111111 ;Minutos
|
|
call BCDtobin
|
|
rrca
|
|
rrca
|
|
rrca
|
|
ld d, a
|
|
and %11100000
|
|
or e
|
|
ld e, a
|
|
ld b, %00111111 ;Horas
|
|
call BCDtobin
|
|
rlca
|
|
rlca
|
|
rlca
|
|
xor d
|
|
and %11111000
|
|
xor d
|
|
ld d, a
|
|
push de
|
|
ld b, %00111111 ;Días
|
|
call BCDtobin
|
|
ld e, a
|
|
inc hl
|
|
ld b, %00011111 ;Siglo/Mes
|
|
ld c, (hl)
|
|
call BCDtobin
|
|
rrca
|
|
rrca
|
|
rrca
|
|
ld d, a
|
|
and %11100000
|
|
or e
|
|
ld e, a
|
|
dec b
|
|
call BCDtobin
|
|
bit 7, c
|
|
jr z, Milnov
|
|
add 100
|
|
Milnov sub 80
|
|
rr d
|
|
adc a, a
|
|
ld b, a
|
|
ld c, e
|
|
pop de
|
|
ret
|
|
|
|
BCDtobin ld a, (hl)
|
|
inc hl
|
|
and b
|
|
ld b, 0
|
|
Repite inc b
|
|
sub $10
|
|
jr nc, Repite
|
|
Suma10 add a, 10
|
|
djnz Suma10
|
|
add a, 6
|
|
ret
|
|
|
|
Params db 0, 0, 0, 0, 0, 0, 0 ;La hora a la que quieres poner el reloj
|
|
; S M H D W Mo Y En lectura, estos datos se machacan con la hora leída del RTC
|
|
|
|
SendByte scf ;Enviar un byte por I2C. Byte en A. BC=puerto de datos del ZXUNO ya
|
|
adc a, a ;apuntando a I2CREG. Usa y modifica: A, D, flags
|
|
Trans call c, Send1
|
|
call nc, Send0
|
|
add a, a
|
|
jr nz, Trans
|
|
Send1 ld d, SCL0SDA1
|
|
out (c), d
|
|
ld d, SCL1SDA1
|
|
out (c), d ;Transmito un bit 1 para dejar SDA en modo de alta impedancia y que el receptor puedo ponerlo a 0
|
|
ld d, SCL0SDA1
|
|
out (c), d
|
|
ret ; S flag 0 = ACK received, S flag 1 = ACK not received
|
|
|
|
RcvByte ld a, 1 ;byte a recibir en A. BC=puerto de datos del ZXUNO ya apuntando a I2CREG. Usa y modifica: A, D, flags
|
|
RcvBit call Send1 ;envío un pulso de reloj con SDA a alta impedancia
|
|
in d, (c) ;el RTC pone aquí el dato (1 o 0) y lo leo (está en bit 7 de D)
|
|
sll d ;bit 7 a carry
|
|
adc a, a ;carry a bit 0 de A, y desplazo a la izquierda
|
|
jr nc, RcvBit
|
|
ret
|
|
|
|
Send0 ld d, SCL0SDA0
|
|
out (c), d
|
|
ld d, SCL1SDA0
|
|
out (c), d
|
|
ld d, SCL0SDA0
|
|
out (c), d
|
|
ret
|