Browse Source

Code for MC146818/DS1285/DS12885 PC style CLOCK DRIVER

pull/570/head
Martin Giese 8 months ago
parent
commit
e29fb43754
  1. 3
      Source/HBIOS/cfg_MASTER.asm
  2. 21
      Source/HBIOS/hbios.asm
  3. 1
      Source/HBIOS/hbios.inc
  4. 368
      Source/HBIOS/pcrtc.asm

3
Source/HBIOS/cfg_MASTER.asm

@ -202,6 +202,9 @@ DS7RTCMODE .EQU DS7RTCMODE_PCF ; DS7RTC: OPERATING MODE: DS7RTCMODE_[PCF]
; ;
DS5RTCENABLE .EQU FALSE ; DS5RTC: ENABLE DS-1305 SPI CLOCK DRIVER (DS5RTC.ASM) DS5RTCENABLE .EQU FALSE ; DS5RTC: ENABLE DS-1305 SPI CLOCK DRIVER (DS5RTC.ASM)
; ;
PCRTCENABLE .SET FALSE ; PCRTC: DISABLE DS12885 etc. RTC
PCRTC_BASE .SET $C0 ; Default port for PCRTC, like DSRTC.
;
SSERENABLE .EQU FALSE ; SSER: ENABLE SIMPLE SERIAL DRIVER (SSER.ASM) SSERENABLE .EQU FALSE ; SSER: ENABLE SIMPLE SERIAL DRIVER (SSER.ASM)
SSERCFG .EQU SER_9600_8N1 ; SSER: SERIAL LINE CONFIG SSERCFG .EQU SER_9600_8N1 ; SSER: SERIAL LINE CONFIG
SSERSTATUS .EQU $FF ; SSER: STATUS PORT SSERSTATUS .EQU $FF ; SSER: STATUS PORT

21
Source/HBIOS/hbios.asm

@ -4062,6 +4062,9 @@ HB_INITTBL:
#IF (EZ80RTCENABLE) #IF (EZ80RTCENABLE)
.DW EZ80RTC_INIT .DW EZ80RTC_INIT
#ENDIF #ENDIF
#IF (PCRTCENABLE)
.DW PCRTC_INIT
#ENDIF
#IF (CPUFAM == CPU_EZ80) #IF (CPUFAM == CPU_EZ80)
; INITALISE ONE OF THE SUPPORTED SYSTEM TIMER TICKS DRIVERS ; INITALISE ONE OF THE SUPPORTED SYSTEM TIMER TICKS DRIVERS
.DW EZ80_TMR_INIT .DW EZ80_TMR_INIT
@ -8977,6 +8980,15 @@ SIZ_DS5RTC .EQU $ - ORG_DS5RTC
MEMECHO " bytes.\n" MEMECHO " bytes.\n"
#ENDIF #ENDIF
; ;
#IF (PCRTCENABLE)
ORG_PCRTC .EQU $
#INCLUDE "pcrtc.asm"
SIZ_PCRTC .EQU $ - ORG_PCRTC
MEMECHO "PCRTC occupies "
MEMECHO SIZ_PCRTC
MEMECHO " bytes.\n"
#ENDIF
;
#IF (INTRTCENABLE) #IF (INTRTCENABLE)
ORG_INTRTC .EQU $ ORG_INTRTC .EQU $
#INCLUDE "intrtc.asm" #INCLUDE "intrtc.asm"
@ -9003,6 +9015,15 @@ SIZ_RP5RTC .EQU $ - ORG_RP5RTC
MEMECHO SIZ_RP5RTC MEMECHO SIZ_RP5RTC
MEMECHO " bytes.\n" MEMECHO " bytes.\n"
#ENDIF #ENDIF
#IF (DSRTCENABLE)
;
ORG_PCRTC .EQU $
#INCLUDE "pcrtc.asm"
SIZ_PCRTC .EQU $ - ORG_PCRTC
MEMECHO "PCRTC occupies "
MEMECHO SIZ_PCRTC
MEMECHO " bytes.\n"
#ENDIF
; ;
#IF (SSERENABLE) #IF (SSERENABLE)
ORG_SSER .EQU $ ORG_SSER .EQU $

1
Source/HBIOS/hbios.inc

@ -431,6 +431,7 @@ RTCDEV_DS7 .EQU $04 ; DS1307 (I2C)
RTCDEV_RP5 .EQU $05 ; RP5C01 RTCDEV_RP5 .EQU $05 ; RP5C01
RTCDEV_DS5 .EQU $06 ; DS1305 (SPI) RTCDEV_DS5 .EQU $06 ; DS1305 (SPI)
RTCDEV_EZ80 .EQU $07 ; EZ80 ON-CHIP RTC RTCDEV_EZ80 .EQU $07 ; EZ80 ON-CHIP RTC
RTCDEV_PC .EQU $08 ; PC style parallel RTC
; ;
; DSKY DEVICE IDS ; DSKY DEVICE IDS
; ;

368
Source/HBIOS/pcrtc.asm

@ -0,0 +1,368 @@
;
;==================================================================================================
; MC146818/DS1285/DS12885 PC style CLOCK DRIVER
;==================================================================================================
;
PCRTC_BUFSIZ .EQU 6 ; SIX BYTE BUFFER (YYMMDDHHMMSS)
;; Addressing is via first writing the address byte to IO port PCRTC_BASE
;; Then read from or write to PCRTC_DAT
;; PCRTC_BASE must be set in config files
PCRTC_REG .EQU PCRTC_BASE
PCRTC_DAT .EQU PCRTC_BASE + $01
REG_SEC .EQU $00
REG_SEC_ALM .EQU $01
REG_MIN .EQU $02
REG_MIN_ALM .EQU $03
REG_HOUR .EQU $04
REG_HOUR_ALM .EQU $05
REG_DOW .EQU $06 ; day of week
REG_DAY .EQU $07
REG_MONTH .EQU $08
REG_YEAR .EQU $09
REG_CTLA .EQU $0A
REG_CTLB .EQU $0B
REG_CTLC .EQU $0C
REG_CTLD .EQU $0D
CTLA_VAL .EQU $2F
CTLB_VAL .EQU $0A
PCRTC_NVBASE .EQU $10
PCRTC_NVSIZE .EQU $30 ; 64 bytes in total is what DS1285 and MC146818 had
DEVECHO "PCRTC: IO="
DEVECHO PCRTC_BASE
DEVECHO "\n"
PCRTC_INIT:
LD A, (RTC_DISPACT) ; RTC DISPATCHER ALREADY SET?
OR A ; SET FLAGS
RET NZ ; IF ALREADY ACTIVE, ABORT
CALL NEWLINE ; FORMATTING
PRTS("PC RTC: $")
; PRINT RTC REGISTER NR PORT ADDRESS
PRTS("IO=0x$") ; LABEL FOR IO ADDRESS
LD A,PCRTC_REG ; GET IO ADDRESS
CALL PRTHEXBYTE ; PRINT IT
CALL PC_SPACE ; FORMATTING
; CHECK PRESENCE STATUS
CALL PCRTC_DETECT ; HARDWARE DETECTION
JR Z, PCRTC_INIT1 ; IF ZERO, ALL GOOD
PRTS("NOT PRESENT$") ; NOT ZERO, H/W NOT PRESENT
OR $FF ; SIGNAL FAILURE
RET ; BAIL OUT
PCRTC_INIT1:
CALL PCRTC_RDTIM
; DISPLAY CURRENT TIME
LD HL, PCRTC_BCDBUF ; POINT TO BCD BUF
CALL PRTDT
;
LD BC, PCRTC_DISPATCH
CALL RTC_SETDISP
;
XOR A ; SIGNAL SUCCESS
RET
;
; DETECT RTC HARDWARE PRESENCE
;
PCRTC_DETECT:
LD C, 0 ; NVRAM INDEX 0
CALL PCRTC_GETBYT ; GET VALUE
LD A, E ; TO ACCUM
LD L, A ; SAVE IT
XOR $FF ; FLIP ALL BITS
LD E, A ; TO E
LD C, 0 ; NVRAM INDEX 0
CALL PCRTC_SETBYT ; WRITE IT
LD C, 0 ; NVRAM INDEX 0
CALL PCRTC_GETBYT ; GET VALUE
LD A, L ; GET SAVED VALUE
XOR $FF ; FLIP ALL BITS
CP E ; COMPARE WITH VALUE READ
LD A, 0 ; ASSUME OK
JR Z, PCRTC_DETECT1 ; IF MATCH, GO AHEAD
LD A, $FF ; ELSE STATUS IS ERROR
PCRTC_DETECT1:
PUSH AF ; SAVE STATUS
LD E, L ; GET SAVED VALUE
LD C, 0 ; NVRAM INDEX 0
CALL PCRTC_SETBYT ; SAVE IT
POP AF ; RECOVER STATUS
OR A ; SET FLAGS
RET
;
; RTC DEVICE FUNCTION DISPATCH ENTRY
; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR
; B: FUNCTION (IN)
;
PCRTC_DISPATCH:
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,PCRTC_GETTIM ; GET TIME
DEC A
JP Z,PCRTC_SETTIM ; SET TIME
DEC A
JP Z,PCRTC_GETBYT ; GET NVRAM BYTE VALUE
DEC A
JP Z,PCRTC_SETBYT ; SET NVRAM BYTE VALUE
DEC A
JP Z,PCRTC_GETBLK ; GET NVRAM DATA BLOCK VALUES
DEC A
JP Z,PCRTC_SETBLK ; SET NVRAM DATA BLOCK VALUES
DEC A
JP Z,PCRTC_GETALM ; GET ALARM
DEC A
JP Z,PCRTC_SETALM ; SET ALARM
DEC A
JP Z,PCRTC_DEVICE ; REPORT RTC DEVICE INFO
SYSCHKERR(ERR_NOFUNC)
RET
;
; RTC GET NVRAM BYTE
; C: INDEX
; E: VALUE (OUTPUT)
; A:0 IF OK, ERR_RANGE IF OUT OF RANGE
;
PCRTC_GETBYT:
LD A, C
CP PCRTC_NVSIZE
JR NC, PCRTC_BADIDX
ADD A, PCRTC_NVBASE
EZ80_IO
OUT (PCRTC_REG), A
EZ80_IO
IN A, (PCRTC_DAT)
LD E, A
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
PCRTC_BADIDX:
LD E, 00
LD A, ERR_RANGE
RET
;
; RTC SET NVRAM BYTE
; C: INDEX
; E: VALUE
; A:0 IF OK, ERR_RANGE IF OUT OF RANGE
;
PCRTC_SETBYT:
LD A, C
CP PCRTC_NVSIZE
JR NC, PCRTC_BADIDX
ADD A, PCRTC_NVBASE
EZ80_IO
OUT (PCRTC_REG), A
LD A, E
EZ80_IO
OUT (PCRTC_DAT), A
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
PCRTC_GETBLK:
PCRTC_SETBLK:
PCRTC_GETALM:
PCRTC_SETALM:
SYSCHKERR(ERR_NOTIMPL)
RET
;
; RTC GET TIME
; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR
; HL: DATE/TIME BUFFER (OUT)
; BUFFER FORMAT IS BCD: YYMMDDHHMMSS
; 24 HOUR TIME FORMAT IS ASSUMED
;
PCRTC_GETTIM:
; GET THE TIME INTO TEMP BUF
PUSH HL ; SAVE PTR TO CALLERS BUFFER
;
CALL PCRTC_RDTIM
; NOW COPY TO REAL DESTINATION (INTERBANK SAFE)
LD A,BID_BIOS ; COPY FROM BIOS BANK
LD (HB_SRCBNK),A ; SET IT
LD A,(HB_INVBNK) ; COPY TO CURRENT USER BANK
LD (HB_DSTBNK),A ; SET IT
LD HL,PCRTC_BCDBUF ; SOURCE ADR
POP DE ; DEST ADR
LD BC,PCRTC_BUFSIZ ; LENGTH
CALL HB_BNKCPY ; COPY THE CLOCK DATA
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
;
; RTC SET TIME
; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR
; HL: DATE/TIME BUFFER (IN)
; BUFFER FORMAT IS BCD: YYMMDDHHMMSSWW
; 24 HOUR TIME FORMAT IS ASSUMED
;
PCRTC_SETTIM:
; COPY TO BCD BUF
LD A,(HB_INVBNK) ; COPY FROM CURRENT USER BANK
LD (HB_SRCBNK),A ; SET IT
LD A,BID_BIOS ; COPY TO BIOS BANK
LD (HB_DSTBNK),A ; SET IT
LD DE,PCRTC_BCDBUF ; DEST ADR
LD BC,PCRTC_BUFSIZ ; LENGTH
CALL HB_BNKCPY ; COPY THE RPC DATA
;
LD A, REG_CTLA ; Set Ctl Reg A
EZ80_IO
OUT (PCRTC_REG), A
LD A, CTLA_VAL
EZ80_IO
OUT (PCRTC_DAT), A
LD A, REG_CTLB ; Set Ctl Reg B
EZ80_IO
OUT (PCRTC_REG), A
LD A, CTLB_VAL|0x80 ; Set the SET bit to stop updates
EZ80_IO
OUT (PCRTC_DAT), A
LD A, REG_SEC ; Set seconds
EZ80_IO
OUT (PCRTC_REG), A
LD A, (PCRTC_SS)
EZ80_IO
OUT (PCRTC_DAT), A
LD A, REG_MIN ; Set minutes
EZ80_IO
OUT (PCRTC_REG), A
LD A, (PCRTC_MM)
EZ80_IO
OUT (PCRTC_DAT), A
LD A, REG_HOUR ; Set hours
EZ80_IO
OUT (PCRTC_REG), A
LD A, (PCRTC_HH)
EZ80_IO
OUT (PCRTC_DAT), A
LD A, REG_DAY ; Set date
EZ80_IO
OUT (PCRTC_REG), A
LD A, (PCRTC_DT)
EZ80_IO
OUT (PCRTC_DAT), A
LD A, REG_MONTH ; Set month
EZ80_IO
OUT (PCRTC_REG), A
LD A, (PCRTC_MO)
EZ80_IO
OUT (PCRTC_DAT), A
LD A, REG_YEAR ; Set year
EZ80_IO
OUT (PCRTC_REG), A
LD A, (PCRTC_YR)
EZ80_IO
OUT (PCRTC_DAT), A
LD A, REG_CTLB ; Set Ctl Reg B
EZ80_IO
OUT (PCRTC_REG), A
LD A, CTLB_VAL ; Reset the SET bit to start clock
EZ80_IO
OUT (PCRTC_DAT), A
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
; REPORT RTC DEVICE INFO
;
PCRTC_DEVICE:
LD D,RTCDEV_PC ; D := DEVICE TYPE
LD E,0 ; E := PHYSICAL DEVICE NUMBER
LD H,0 ; H := 0, DRIVER HAS NO MODES
LD L, PCRTC_BASE ; L := 0, NO I/O ADDRESS
XOR A ; SIGNAL SUCCESS
RET
;
; READ OUT THE TIME
PCRTC_RDTIM:
;; Need to wait until update-in-progress flag is reset
LD A, REG_CTLA ; Set Ctl Reg A
EZ80_IO
OUT (PCRTC_REG), A
EZ80_IO
IN A, (PCRTC_DAT)
BIT 7, A
JP NZ, PCRTC_RDTIM ; Jump back if update in progress.
LD A, REG_SEC ; Set seconds
EZ80_IO
OUT (PCRTC_REG), A
EZ80_IO
IN A, (PCRTC_DAT)
LD (PCRTC_SS), A
LD A, REG_MIN ; Set minutes
EZ80_IO
OUT (PCRTC_REG), A
EZ80_IO
IN A, (PCRTC_DAT)
LD (PCRTC_MM), A
LD A, REG_HOUR ; Set hours
EZ80_IO
OUT (PCRTC_REG), A
EZ80_IO
IN A, (PCRTC_DAT)
LD (PCRTC_HH), A
LD A, REG_DAY ; Set day
EZ80_IO
OUT (PCRTC_REG), A
EZ80_IO
IN A, (PCRTC_DAT)
LD (PCRTC_DT), A
LD A, REG_MONTH ; Set month
EZ80_IO
OUT (PCRTC_REG), A
EZ80_IO
IN A, (PCRTC_DAT)
LD (PCRTC_MO), A
LD A, REG_YEAR ; Set year
EZ80_IO
OUT (PCRTC_REG), A
EZ80_IO
IN A, (PCRTC_DAT)
LD (PCRTC_YR), A
RET
;
; REGISTER EXTRACTED VALUES
;
PCRTC_BCDBUF:
PCRTC_YR .DB $25
PCRTC_MO .DB $01
PCRTC_DT .DB $01
PCRTC_HH .DB $00
PCRTC_MM .DB $00
PCRTC_SS .DB $00
Loading…
Cancel
Save