mirror of https://github.com/wwarthen/RomWBW.git
committed by
GitHub
6 changed files with 395 additions and 0 deletions
@ -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…
Reference in new issue