Saturday, November 16, 2024

Dallas Time on the ZX81


A ZXIO Project: Intefacting with a DS12C887

Keeping track of the current date/time on a ZX81 serves no useful purpose in 2024, thus making it the perfect project for a ZX81, the perfect project for the ZXIO V2 interface cards and the perfect use of everybbodies favourite clock chip the Dallas DS12C887.


The Dallas Semiconductor DS12C887 RTC modules are well-known in retro computing circles for their integrated real-time clock and their gradually failing battery backup. However, they remain readily available, along with the core of the module the DS12885 which offers the same functionality only requiring an external battery backup. For simplicity's sake, and because I have some functional DS12C887 modules, this ZXIO project will use a complete module.


Configuration and Schematics

If you're unfamiliar with the ZXIO V2 or the 8255A I/O IC, be sure to check out the other articles in the ZXIO series on this site. In brief, the ZXIO V2 is an input/output card for the ZX81, built around the versatile 8255A IC. Notably, it's a memory-mapped device that allows its functions to be accessed from ZX81 BASIC.

Communicating with the DS12C887 RTC module is relatively straightforward. The general configuration, both in hardware and software, is:

  • Set up the ZXIO V2 / 8255A in Mode 0 for basic I/O.
  • Designate specific ports for communication with the RTC:
    • Port A: Data bus to exchange data with the RTC.
    • Port C: Control lines like chip select (CS),  read/write (R/W), Address Strobe (AS) and Data Strobe (DS).
The DS12C887 is set for Motorola timings, with the MOT pin connected to VCC. The Motorola mode seems to lend itself a little better to being interacted with. 

Interestingly, the Chip Select line on the RTC is active low, as is the Write signal on the R/W lines. I’ve chosen to invert these signals as this seems to make more sense when writing the BASIC program to control the clock. You'll notice on the schematic that I've used a CD74HC02 NOR gate to invert the signals.


As part of the Chip Select inversion, one input of the NOR gate is paired with another output from the CD74HC02, which is connected to ground. This setup creates a small delay, preventing the RTC’s memory from being cleared or reset during power cycles or resets, ensuring it retains its time and configuration data.


RTC for ZXIO V2 Circuit Schematic

A "Functional" Clock Program

Using the ZXIO V2 interface card, the ZX81 communicates with the RTC by sending and receiving signals through the I/O ports. Each I/O port, along with the Control Port, is memory-mapped to specific addresses on the ZX81. Port A corresponds to memory address 16380, Port B to 16381, Port C to 16382, and the Control Port to 16383. These addresses are used to send commands and data to the RTC. The time data stored in the RTC is in binary-coded decimal (BCD) format, and the program converts this data into a human-readable string for display on the ZX81.

The BASIC program to control all this is divided into two parts, or two separate programs, in reality. The "GET TIME" routine reads hours, minutes, and seconds from the RTC registers, formats them into a string, and displays the current time. The "SET TIME" routine, on the other hand, allows a new time to be programmed into the RTC by converting user-defined input into BCD and writing it back to the appropriate registers.

 
  10 REM **************
  15 REM ** GET TIME **
  20 REM ************** 
  25 LET Y=0
  30 LET A$=""
  35 LET T$=""
  40 FOR X=4 TO 0 STEP -2
  45 POKE 49151,128
  50 POKE 49150,130
  55 POKE 49148,X
  60 POKE 49151,144
  65 POKE 49150,132
  70 LET Y=PEEK 49148
  75 LET A$="0"+STR$ (10*INT (Y/16)+Y-INT (Y/16)*16)
  80 LET Y=LEN A$
  85 LET T$=T$+A$(Y-1 TO Y)+":"
  90 NEXT X
  95 PRINT AT 0,0;T$(1 TO 8)
 100 GOTO 170
 105 REM **************
 110 REM ** SET TIME **
 115 REM ************** 
 120 LET T$="225533"
 125 POKE 49151,128
 130 FOR X=0 TO LEN (T$)-1 STEP 2
 135 LET Y=VAL (T$(X+1 TO X+2))
 140 POKE 49150,130
 145 POKE 49148,LEN (T$)-X-2
 150 POKE 49150,133
 155 POKE 49148,Y-INT (Y/10)*10+INT (Y/10)*16
 160 PRINT Y-INT (Y/10)*10+INT (Y/10)*16,LEN (T$)-X-2
 165 NEXT X
 170 STOP
  

GET TIME (Lines 10–100)

his part retrieves the current time from the RTC module and formats it into a readable string.

  1. Initialisation:

    • Lines 25–35: Variables Y, A$, and T$ are initialised. T$ will hold the final formatted time.
  2. Reading Time Data:

    • Lines 40–90: A loop iterates through the time registers in reverse order (the RTC stores hours, minutes, and seconds in separate registers).
      • Line 45: Writes 128 to the control register to prepare the RTC for a read operation.
      • Line 50: Writes 130 to select the time register.
      • Line 55: Specifies which time register to read (X corresponds to seconds, minutes, or hours).
      • Line 60: Executes the read operation.
      • Line 70: Retrieves the register value using PEEK.
  3. Formatting:

    • Lines 75–85: Converts the binary-coded decimal (BCD) value from the RTC into a two-digit decimal number:
      • Y/16 extracts the tens digit.
      • Y-INT(Y/16)*16 extracts the units digit.
      • The digits are concatenated into A$ and appended to the time string T$ with a colon separator.
  4. Display:

    • Line 95: Displays the formatted time (first 8 characters) at the top-left corner of the ZX81 screen.
  5. Repeat:

    • Line 100: Ends the routine and jumps to the time-setting routine if implemented further.

SET TIME (Lines 105–170)

This part writes a new time into the RTC module.

  1. Initialisation:

    • Line 120: The variable T$ is hardcoded with a new time in the format HHMMSS (e.g., "225533" = 22:55:33).
  2. Writing Time Data:

    • Lines 130–165: A loop iterates through the string T$ in pairs of digits to set the hours, minutes, and seconds registers:
      • Line 135: Extracts two digits from T$ and converts them into an integer.
      • Line 140: Prepares the RTC for a write operation by setting the appropriate control values.
      • Line 145: Specifies the time register to write to.
      • Line 150: Converts the decimal value into BCD format and writes it to the RTC.
  3. Debugging/Confirmation:

    • Line 160: Displays the BCD-encoded value and the register being written to for verification.

Time Loop

With Line 100 changed to "GOTO 35," the "GET TIME" portion of the program becomes a continuously running clock—though it updates slightly slower than real time. The program, as written, takes just under 2 seconds to update. This could be sped up to some degree by only looping through the seconds and minutes as needed, rather than reading the entire time (hours, minutes, and seconds) every time. The video demonstration bellow is taken from slightly earlier version of the program and is slightly slower (slightly).



And that’s a wrap on reading and interacting with the Dallas Real-Time Clock—at least for now. We've successfully coaxed the ZX81 into telling the time (with a slight delay, of course). If we’ve learned anything, it’s that time waits for no one… except maybe for the ZX81, which could probably use a little more time to catch up.



Reference: Dallas RTC DS12C887 Module Pinout

Pin Name Description
1 MOT Motorola Timing Select. Connect to VCC for Motorola timings.
2 X1 Connections for Standard 32.768kHz Quartz Crystal – Internal.
3 X2 Connections for Standard 32.768kHz Quartz Crystal – Internal.
4 D0 Data Bus Line 0 (part of the 8-bit data bus).
5 D1 Data Bus Line 1 (part of the 8-bit data bus).
6 D2 Data Bus Line 2 (part of the 8-bit data bus).
7 D3 Data Bus Line 3 (part of the 8-bit data bus).
8 D4 Data Bus Line 4 (part of the 8-bit data bus).
9 D5 Data Bus Line 5 (part of the 8-bit data bus).
10 D6 Data Bus Line 6 (part of the 8-bit data bus).
11 D7 Data Bus Line 7 (part of the 8-bit data bus).
12 GND Ground.
13 CS~ Chip Select, active low. Selects the RTC for communication.
14 AS Address Strobe. Latches address bits on the falling edge.
15 R/W Read/Write input. Determines whether data is read from or written to the RTC.
16 GND Ground.
17 DS Data Strobe, active low. Enables reading or writing data to the RTC.
18 RESET Reset input, active low. Resets the RTC registers when asserted.
19 IRQ~ Interrupt Request, active low. Signals alarms or periodic events.
20 VBAT Connection for a Primary Battery – Internal.
21 RCLR~ Active-Low RAM Clear. Pin is internally pulled up.
22 NC No Connection (not used).
23 SQW Square Wave output. Outputs a programmable frequency or 1 Hz for timekeeping.
24 VCC Power supply input (typically +5V).






No comments:

Post a Comment