mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
396 lines
8.5 KiB
396 lines
8.5 KiB
;
|
|
;==================================================================================================
|
|
; 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
|
|
|
|
PCRTC_REG_SEC .EQU $00
|
|
PCRTC_REG_SEC_ALM .EQU $01
|
|
PCRTC_REG_MIN .EQU $02
|
|
PCRTC_REG_MIN_ALM .EQU $03
|
|
PCRTC_REG_HOUR .EQU $04
|
|
PCRTC_REG_HOUR_ALM .EQU $05
|
|
PCRTC_REG_DOW .EQU $06 ; day of week
|
|
PCRTC_REG_DAY .EQU $07
|
|
PCRTC_REG_MONTH .EQU $08
|
|
PCRTC_REG_YEAR .EQU $09
|
|
PCRTC_REG_CTLA .EQU $0A
|
|
PCRTC_REG_CTLB .EQU $0B
|
|
PCRTC_REG_CTLC .EQU $0C
|
|
PCRTC_REG_CTLD .EQU $0D
|
|
|
|
PCRTC_CTLA_VAL .EQU $2F
|
|
PCRTC_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"
|
|
|
|
;
|
|
;--------------------------------------------------------------------------------------------------
|
|
; HBIOS MODULE HEADER
|
|
;--------------------------------------------------------------------------------------------------
|
|
;
|
|
ORG_PCRTC .EQU $
|
|
;
|
|
.DW SIZ_PCRTC ; MODULE SIZE
|
|
.DW PCRTC_INITPHASE ; ADR OF INIT PHASE HANDLER
|
|
;
|
|
PCRTC_INITPHASE:
|
|
; INIT PHASE HANDLER, A=PHASE
|
|
;CP HB_PHASE_PREINIT ; PREINIT PHASE?
|
|
;JP Z,PCRTC_PREINIT ; DO PREINIT
|
|
CP HB_PHASE_INIT ; INIT PHASE?
|
|
JP Z,PCRTC_INIT ; DO INIT
|
|
RET ; DONE
|
|
;
|
|
PCRTC_INIT:
|
|
LD A, (RTC_DISPACT) ; RTC DISPATCHER ALREADY SET?
|
|
OR A ; SET FLAGS
|
|
RET NZ ; IF ALREADY ACTIVE, ABORT
|
|
|
|
CALL NEWLINE ; FORMATTING
|
|
PRTS("PCRTC: $")
|
|
|
|
; 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, PCRTC_REG_CTLA ; Set Ctl Reg A
|
|
EZ80_IO
|
|
OUT (PCRTC_REG), A
|
|
LD A, PCRTC_CTLA_VAL
|
|
EZ80_IO
|
|
OUT (PCRTC_DAT), A
|
|
|
|
LD A, PCRTC_REG_CTLB ; Set Ctl Reg B
|
|
EZ80_IO
|
|
OUT (PCRTC_REG), A
|
|
LD A, PCRTC_CTLB_VAL|$80 ; Set the SET bit to stop updates
|
|
EZ80_IO
|
|
OUT (PCRTC_DAT), A
|
|
|
|
LD A, PCRTC_REG_SEC ; Set seconds
|
|
EZ80_IO
|
|
OUT (PCRTC_REG), A
|
|
LD A, (PCRTC_SS)
|
|
EZ80_IO
|
|
OUT (PCRTC_DAT), A
|
|
|
|
LD A, PCRTC_REG_MIN ; Set minutes
|
|
EZ80_IO
|
|
OUT (PCRTC_REG), A
|
|
LD A, (PCRTC_MM)
|
|
EZ80_IO
|
|
OUT (PCRTC_DAT), A
|
|
|
|
LD A, PCRTC_REG_HOUR ; Set hours
|
|
EZ80_IO
|
|
OUT (PCRTC_REG), A
|
|
LD A, (PCRTC_HH)
|
|
EZ80_IO
|
|
OUT (PCRTC_DAT), A
|
|
|
|
LD A, PCRTC_REG_DAY ; Set date
|
|
EZ80_IO
|
|
OUT (PCRTC_REG), A
|
|
LD A, (PCRTC_DT)
|
|
EZ80_IO
|
|
OUT (PCRTC_DAT), A
|
|
|
|
LD A, PCRTC_REG_MONTH ; Set month
|
|
EZ80_IO
|
|
OUT (PCRTC_REG), A
|
|
LD A, (PCRTC_MO)
|
|
EZ80_IO
|
|
OUT (PCRTC_DAT), A
|
|
|
|
LD A, PCRTC_REG_YEAR ; Set year
|
|
EZ80_IO
|
|
OUT (PCRTC_REG), A
|
|
LD A, (PCRTC_YR)
|
|
EZ80_IO
|
|
OUT (PCRTC_DAT), A
|
|
|
|
LD A, PCRTC_REG_CTLB ; Set Ctl Reg B
|
|
EZ80_IO
|
|
OUT (PCRTC_REG), A
|
|
LD A, PCRTC_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, PCRTC_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, PCRTC_REG_SEC ; Set seconds
|
|
EZ80_IO
|
|
OUT (PCRTC_REG), A
|
|
EZ80_IO
|
|
IN A, (PCRTC_DAT)
|
|
LD (PCRTC_SS), A
|
|
|
|
LD A, PCRTC_REG_MIN ; Set minutes
|
|
EZ80_IO
|
|
OUT (PCRTC_REG), A
|
|
EZ80_IO
|
|
IN A, (PCRTC_DAT)
|
|
LD (PCRTC_MM), A
|
|
|
|
LD A, PCRTC_REG_HOUR ; Set hours
|
|
EZ80_IO
|
|
OUT (PCRTC_REG), A
|
|
EZ80_IO
|
|
IN A, (PCRTC_DAT)
|
|
LD (PCRTC_HH), A
|
|
|
|
LD A, PCRTC_REG_DAY ; Set day
|
|
EZ80_IO
|
|
OUT (PCRTC_REG), A
|
|
EZ80_IO
|
|
IN A, (PCRTC_DAT)
|
|
LD (PCRTC_DT), A
|
|
|
|
LD A, PCRTC_REG_MONTH ; Set month
|
|
EZ80_IO
|
|
OUT (PCRTC_REG), A
|
|
EZ80_IO
|
|
IN A, (PCRTC_DAT)
|
|
LD (PCRTC_MO), A
|
|
|
|
LD A, PCRTC_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
|
|
;
|
|
;--------------------------------------------------------------------------------------------------
|
|
; HBIOS MODULE TRAILER
|
|
;--------------------------------------------------------------------------------------------------
|
|
;
|
|
END_PCRTC .EQU $
|
|
SIZ_PCRTC .EQU END_PCRTC - ORG_PCRTC
|
|
;
|
|
MEMECHO "PCRTC occupies "
|
|
MEMECHO SIZ_PCRTC
|
|
MEMECHO " bytes.\n"
|
|
|