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.
 
 
 
 
 
 

325 lines
9.0 KiB

;
;==================================================================================================
; NATIONAL SEMICONDUCTOR MM58167B MICROPROCESSOR REAL TIME CLOCK
;==================================================================================================
;
; THIS DRIVER IS FOR THE S100 INTERFACE TO THE MM58167B RTC. THE
; S100 INTERFACE USES 2 IO PORTS, ONE TO SELECT THE RTC REGISTER FOR
; SUBSEQUENT READ/WRITE AND ONE TO PERFORM THE READ/WRITE.
;
; THIS RTC HAS NO YEAR VALUE REGISTER. WE STORE THE YEAR VALUE IN
; REGISTER $09 AS A STATIC VALUE.
;
; THIS RTC DEVICE HAS NO NVRAM!
;
; REGISTER ADDRESSES (HEX / BCD):
;
; +-----+----------------------------------------------+--------+
; | REG | FUNCTION | RANGE |
; +-----+----------------------------------------------+--------+
; | $00 | COUNTER - MILLISECONDS | 0-9 |
; | $01 | COUNTER - HUNDREDTHS AND TENTHS OF SECONDS | 0-99 |
; | $02 | COUNTER - SECONDS | 0-59 |
; | $03 | COUNTER - MINUTES | 0-59 |
; | $04 | COUNTER - HOURS | 0-23 |
; | $05 | COUNTER - DAY OF WEEK | 1-7 |
; | $06 | COUNTER - DAY OF MONTH | 1-31 |
; | $07 | COUNTER - MONTH | 1-12 |
; | $08 | RAM - MILLISECONDS | 0-9 |
; | $09 | RAM - HUNDREDTHS AND TENTHS OF SECONDS | 0-99 |
; | $0A | RAM - SECONDS | 0-59 |
; | $0B | RAM - MINUTES | 0-59 |
; | $0C | RAM - HOURS | 0-23 |
; | $0D | RAM - DAY OF WEEK | 1-7 |
; | $0E | RAM - DAY OF MONTH | 1-31 |
; | $0F | RAM - MONTHS | 1-12 |
; | $10 | INTERRUPT STATUS REGISTER | |
; | $11 | INTERRUPT CONTROL REGISTER | |
; | $12 | COUNTERS RESET | |
; | $13 | RAM RESET | |
; | $14 | STATUS BIT | |
; | $15 | GO COMMAND | |
; | $16 | STANDBY INTERRUPT | |
; | $1F | TEST MODE | |
; +-----+----------------------------------------------+--------+
;
MMRTC_IO .EQU $A4
MMRTC_SEL .EQU MMRTC_IO + 0
MMRTC_DATA .EQU MMRTC_IO + 1
;
DEVECHO "MMRTC:"
;
DEVECHO " IO="
DEVECHO MMRTC_IO
DEVECHO "\n"
;
;--------------------------------------------------------------------------------------------------
; HBIOS MODULE HEADER
;--------------------------------------------------------------------------------------------------
;
ORG_MMRTC .EQU $
;
.DW SIZ_MMRTC ; MODULE SIZE
.DW MMRTC_INITPHASE ; ADR OF INIT PHASE HANDLER
;
MMRTC_INITPHASE:
; INIT PHASE HANDLER, A=PHASE
;CP HB_PHASE_PREINIT ; PREINIT PHASE?
;JP Z,MMRTC_PREINIT ; DO PREINIT
CP HB_PHASE_INIT ; INIT PHASE?
JP Z,MMRTC_INIT ; DO INIT
RET ; DONE
;
; RTC DEVICE PRE-INITIALIZATION ENTRY
;
MMRTC_PREINIT:
XOR A ; SIGNAL SUCCESS
RET ; DONE
;
; RTC DEVICE INITIALIZATION ENTRY
;
MMRTC_INIT:
CALL NEWLINE ; FORMATTING
PRTS("MMRTC: $")
;
; PRINT RTC PORT ADDRESS
PRTS(" IO=0x$") ; LABEL FOR IO ADDRESS
LD A,MMRTC_IO ; GET IO ADDRESS
CALL PRTHEXBYTE ; PRINT IT
;
CALL MMRTC_DETECT ; HARDWARE DETECTION
JR Z,MMRTC_INIT1 ; CONTINUE IF FOUND
;
; HANDLE HARDWARE MISSING
PRTS(" NOT PRESENT$") ; NOT ZERO, H/W NOT PRESENT
OR $FF ; SIGNAL FAILURE
RET ; BAIL OUT
;
MMRTC_INIT1:
; DISPLAY CURRENT TIME
CALL PC_SPACE
LD HL,MMRTC_TIMBUF
CALL MMRTC_RDCLK
LD HL,MMRTC_TIMBUF
CALL PRTDT
;
; REGISTER THE RTC
LD BC,MMRTC_DISPATCH
CALL RTC_SETDISP
;
XOR A ; SIGNAL SUCCESS
RET
;
; RTC DEVICE FUNCTION DISPATCH ENTRY
; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR
; B: FUNCTION (IN)
;
MMRTC_DISPATCH:
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,MMRTC_GETTIM ; GET TIME
DEC A
JP Z,MMRTC_SETTIM ; SET TIME
DEC A
JP Z,MMRTC_GETBYT ; GET NVRAM BYTE VALUE
DEC A
JP Z,MMRTC_SETBYT ; SET NVRAM BYTE VALUE
DEC A
JP Z,MMRTC_GETBLK ; GET NVRAM DATA BLOCK VALUES
DEC A
JP Z,MMRTC_SETBLK ; SET NVRAM DATA BLOCK VALUES
DEC A
JP Z,MMRTC_GETALM ; GET ALARM
DEC A
JP Z,MMRTC_SETALM ; SET ALARM
DEC A
JP Z,MMRTC_DEVICE ; REPORT RTC DEVICE INFO
;
SYSCHKERR(ERR_NOFUNC)
RET
;
; NVRAM FUNCTIONS ARE NOT AVAILABLE
; ALARM FUNCTIONALITY NOT IMPLEMENTED
;
MMRTC_GETBYT:
MMRTC_SETBYT:
MMRTC_GETBLK:
MMRTC_SETBLK:
MMRTC_GETALM:
MMRTC_SETALM:
SYSCHKERR(ERR_NOTIMPL)
RET
;
; RTC GET TIME
; BUFFER FORMAT IS BCD: YYMMDDHHMMSS
; 24 HOUR TIME FORMAT IS ASSUMED
;
MMRTC_GETTIM:
PUSH HL ; SAVE ADR OF OUTPUT BUF
;
LD HL,MMRTC_TIMBUF ; POINTER TO CLK DATA
CALL MMRTC_RDCLK ; READ IT
;
; 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,MMRTC_TIMBUF ; SOURCE ADR
POP DE ; DEST ADR
LD BC,6 ; LENGTH IS 6 BYTES
#IF (INTMODE == 1)
DI
#ENDIF
CALL HB_BNKCPY ; COPY THE CLOCK DATA
#IF (INTMODE == 1)
EI
#ENDIF
;
; CLEAN UP AND RETURN
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
; RTC SET TIME
; BUFFER FORMAT IS BCD: YYMMDDHHMMSS
; 24 HOUR TIME FORMAT IS ASSUMED
;
MMRTC_SETTIM:
; COPY INCOMING TIME DATA TO OUR TIME BUFFER
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,MMRTC_TIMBUF ; DEST ADR
LD BC,6 ; LENGTH IS 6 BYTES
#IF (INTMODE == 1)
DI
#ENDIF
CALL HB_BNKCPY ; COPY THE CLOCK DATA
#IF (INTMODE == 1)
EI
#ENDIF
;
; WRITE TO CLOCK
LD HL,MMRTC_TIMBUF ; POINTER TO CLK DATA
CALL MMRTC_WRCLK ; WRITE TO THE CLOCK
;
; CLEAN UP AND RETURN
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
; REPORT RTC DEVICE INFO
;
MMRTC_DEVICE:
LD D,RTCDEV_MM ; D := DEVICE TYPE
LD E,0 ; E := PHYSICAL DEVICE NUMBER
LD H,0 ; H := MODE
LD L,MMRTC_IO ; L := BASE I/O ADDRESS
XOR A ; SIGNAL SUCCESS
RET
;
; DETECT RTC HARDWARE PRESENCE
;
; WE USE THE DAY OF WEEK RAM REGISTER WHICH WILL ONLY STORE THE
; LOW 4 BITS OF THE BYTE.
;
MMRTC_DETECT:
LD C,$0D ; RAM - DAY OF WEEK
LD A,$AA ; TEST VALUE
CALL MMRTC_WRREG ; WRITE IT
CALL MMRTC_RDREG ; READ IT BACK
CP $0A ; EXPECTED VALUE?
RET
;
; READ CLOCK DATA INTO BUFFER AT HL (YYMMDDHHMMSS)
;
MMRTC_RDCLK:
PUSH HL ; SAVE IN CASE OF RE-READ
LD C,$09 ; START WITH YEAR REG
CALL MMRTC_RDCLK1 ; DO YEAR (REG $09)
DEC C ; SKIP RAM MILLISECONDS (REG $08)
CALL MMRTC_RDCLK1 ; DO MONTH (REG $07)
CALL MMRTC_RDCLK1 ; DO DAY OF MONTH (REG $06)
DEC C ; SKIP DAY OF WEEK (REG $05)
CALL MMRTC_RDCLK1 ; DO HOUR (REG $04)
CALL MMRTC_RDCLK1 ; DO MINUTE MONTH (REG $03)
CALL MMRTC_RDCLK1 ; DO SECOND (REG $02)
POP HL ; RESTORE IN CASE OF RE-READ
;
; CHECK FOR ROLLOVER IN PROGRESS
LD C,$14 ; STATUS BIT
CALL MMRTC_RDREG ; READ IT
BIT 0,A ; BIT 0 IS ROLLOVER ACTIVE
JR NZ,MMRTC_RDCLK ; IF ACTIVE, RE-READ CLOCK
;
XOR A ; SIGNAL SUCCESS
RET ; DONE
;
MMRTC_RDCLK1:
CALL MMRTC_RDREG ; GET IT
LD (HL),A ; STORE IN BUF
INC HL ; BUMP BUF PTR
DEC C ; DEC REGISTER
RET
;
; WRITE CLOCK DATA FROM BUFFER AT HL
;
MMRTC_WRCLK:
;
LD C,$09 ; START WITH YEAR REG
CALL MMRTC_WRCLK1 ; DO YEAR (REG $09)
DEC C ; SKIP RAM MILLISECONDS (REG $08)
CALL MMRTC_WRCLK1 ; DO MONTH (REG $07)
CALL MMRTC_WRCLK1 ; DO DAY OF MONTH (REG $06)
DEC C ; SKIP DAY OF WEEK (REG $05)
CALL MMRTC_WRCLK1 ; DO HOUR (REG $04)
CALL MMRTC_WRCLK1 ; DO MINUTE MONTH (REG $03)
CALL MMRTC_WRCLK1 ; DO SECOND (REG $02)
;
XOR A ; SIGNAL SUCCESS
RET ; DONE
;
MMRTC_WRCLK1:
LD A,(HL) ; GET VALUE
CALL MMRTC_WRREG ; WRITE IT
INC HL ; BUMP BUF PTR
DEC C ; DEC REGISTER
RET
;
; READ REGSITER
; C=REGISTER
; A=VALUE
;
MMRTC_RDREG:
LD A,C ; REGSITER TO A
OUT (MMRTC_SEL),A ; SELECT IT
IN A,(MMRTC_DATA) ; GET REG VALUE
RET ; DONE
;
; WRITE REGSITER
; C=REGSITER
; A=VALUE
;
MMRTC_WRREG:
PUSH AF ; SAVE VALUE TO WRITE
LD A,C ; REGSITER TO A
OUT (MMRTC_SEL),A ; SELECT IT
POP AF ; RECOVER VALUE TO WRITE
OUT (MMRTC_DATA),A ; GET REG VALUE
RET ; DONE
;
; MMRTC_TIMBUF IS DRIVER'S INTERNAL CLOCK DATA BUFFER
;
MMRTC_TIMBUF .FILL 6,0 ; 6 BYTES FOR GETTIM, YYMMDDHHMMSS
;
;--------------------------------------------------------------------------------------------------
; HBIOS MODULE TRAILER
;--------------------------------------------------------------------------------------------------
;
END_MMRTC .EQU $
SIZ_MMRTC .EQU END_MMRTC - ORG_MMRTC
;
MEMECHO "MMRTC occupies "
MEMECHO SIZ_MMRTC
MEMECHO " bytes.\n"