title KRNL_CLK -- Real Time Clock Support for OS/25
.xlist
.xcref
include MASM.INC ; Handy macros
include V25.INC ; Setup for V25 CPU
include MSDOS.INC ; DOSCALL function equates
include SEGMENTS.INC ; Define segments and groups
include KRNLVARS.INC ; External definitions
.cref
.list
page
_BSS segment ; Begin _BSS segment
WATCH_DATA label byte ; Date read/written from/to the SmartWatch
WATCH_HUNDRETH db ? ; 1/10 and 1/100 seconds
WATCH_SECOND db ? ; 10 and 1 seconds
WATCH_MINUTE db ? ; 10 and 1 minutes
WATCH_HOUR db ? ; 10 and 1 hours, 12/24 and AM/PM bits
WATCH_WEEKDAY db ? ; Day of week, OSC and RESET bits
WATCH_DAY db ? ; 10 and 1 days
WATCH_MONTH db ? ; 10 and 1 months
WATCH_YEAR db ? ; 10 and 1 years
WATCH_DUMMY db ? ; Dummy byte written to during UNLOCK_WATCH
_BSS ends ; End _BSS segment
_TEXT segment ; Begin _TEXT segment
assume cs:ROMGRP ; Tell the assembler
page
READ_WATCH proc near public ; Read the date and time out of the SmartWatch
assume ds:DGROUP, es:nothing, ss:nothing
COMMENT|
Read date and time out of the SmartWatch
|
pusha ; Save caller's registers
cli ; Allow no interrupts while reading the clock
cld ; Forward
; Perform 65 dummy reads to close the SmartWatch
lea bx,WATCH_DUMMY ; Location to absorb dummy writes
mov cx,65 ; 65 dummy reads
@@:
mov al,[bx] ; Dummy read to reset the key pattern matcher
loop @B ; Do 'em all
; Send the 64-bit key to unlock the SmartWatch
lea si,WATCH_KEY ; ROMGRP:SI ==> SmartWatch key
mov cx,8 ; # of bytes in the key
READ_WATCH_OL:
mov dl,8 ; # of bits per byte
lods WATCH_KEY[si] ; Pick up next byte of the key
READ_WATCH_IL:
mov [bx],al ; Send next byte of key out D0
shr al,1 ; Move next bit of key into position
dec dl ; Account for another bit
jnz READ_WATCH_IL ; Do all 8 bits
loop READ_WATCH_OL ; Do all 8 bytes of the key
; Read the 64-bit SmartWatch data
lea bx,WATCH_DUMMY ; Location to absorb dummy reads
; Byte 0
mov cx,8 ; Number of bits per byte
@@:
mov al,[bx] ; Read a bit from the SmartWatch
and al,1 ; Isolate D0
ror ax,1 ; Move it over, leaving room for the next bit
loop @B ; Get all 8 bits
mov dl,ah ; Save byte 0
; Byte 1
mov cx,8 ; Number of bits per byte
@@:
mov al,[bx] ; Read a bit from the SmartWatch
and al,1 ; Isolate D0
ror ax,1 ; Move it over, leaving room for the next bit
loop @B ; Get all 8 bits
mov dh,ah ; Save byte 1
mov si,dx ; SI = bytes 0, 1
; Byte 2
mov cx,8 ; Number of bits per byte
@@:
mov al,[bx] ; Read a bit from the SmartWatch
and al,1 ; Isolate D0
ror ax,1 ; Move it over, leaving room for the next bit
loop @B ; Get all 8 bits
mov dl,ah ; Save byte 2
; Byte 3
mov cx,8 ; Number of bits per byte
@@:
mov al,[bx] ; Read a bit from the SmartWatch
and al,1 ; Isolate D0
ror ax,1 ; Move it over, leaving room for the next bit
loop @B ; Get all 8 bits
mov dh,ah ; Save byte 3
mov di,dx ; DI = bytes 2, 2
; Byte 4
mov cx,8 ; Number of bits per byte
@@:
mov al,[bx] ; Read a bit from the SmartWatch
and al,1 ; Isolate D0
ror ax,1 ; Move it over, leaving room for the next bit
loop @B ; Get all 8 bits
mov dl,ah ; Save byte 4
; Byte 5
mov cx,8 ; Number of bits per byte
@@:
mov al,[bx] ; Read a bit from the SmartWatch
and al,1 ; Isolate D0
ror ax,1 ; Move it over, leaving room for the next bit
loop @B ; Get all 8 bits
mov dh,ah ; Save byte 5
mov bp,dx ; BP = bytes 4, 5
; Byte 6
mov cx,8 ; Number of bits per byte
@@:
mov al,[bx] ; Read a bit from the SmartWatch
and al,1 ; Isolate D0
ror ax,1 ; Move it over, leaving room for the next bit
loop @B ; Get all 8 bits
mov dl,ah ; Save byte 6
; Byte 7
mov cx,8 ; Number of bits per byte
@@:
mov al,[bx] ; Read a bit from the SmartWatch
and al,1 ; Isolate D0
ror ax,1 ; Move it over, leaving room for the next bit
loop @B ; Get all 8 bits
mov dh,ah ; Save byte 7
; DX = bytes 6, 7
lea bx,WATCH_DATA ; DGROUP:SI ==> SmartWatch data buffer
mov [bx],si ; Save bytes 0, 1
mov [bx+2],di ; Save bytes 2, 3
mov [bx+4],bp ; Save bytes 4, 5
mov [bx+6],dx ; Save bytes 6, 7
sti ; Allow interrupts
popa ; Restore caller's registers
ret ; Return to caller
assume ds:nothing, es:nothing, ss:nothing
READ_WATCH endp ; End READ_WATCH procedure
page
WRITE_WATCH proc near public ; Write new data and time into the SmartWatch
assume ds:DGROUP, es:nothing, ss:nothing
COMMENT|
Write new date and time into the SmartWatch
|
pusha ; Save caller's registers
REGSAVE <es> ; Save caller's segment registers
cli ; Allow no interrupts while reading the clock
cld ; Forward
; Load registers with new SmartWatch data
lea bx,WATCH_DATA ; DGROUP:SI ==> SmartWatch data buffer
mov es,[bx] ; Pick up bytes 0, 1 (seconds)
assume es:nothing ; Tell the assembler
mov di,[bx+2] ; Pick up bytes 2, 3
mov bp,[bx+4] ; Pick up bytes 4, 5
mov dx,[bx+6] ; Pick up bytes 6, 7
lea bx,WATCH_DUMMY ; Location to absorb dummy writes
; Perform 65 dummy reads to close the SmartWatch
mov cx,65 ; 65 dummy reads
@@:
mov al,[bx] ; Dummy read to reset the key pattern matcher
loop @B ; Do 'em all
; Send the 64-bit key to unlock the SmartWatch
lea si,WATCH_KEY ; ROMGRP:SI ==> SmartWatch key
mov cx,8 ; # of bytes in the key
WRITE_WATCH_OL:
lods WATCH_KEY[si] ; Pick up next byte of the key
mov [bx],al ; Send next byte of key out D0
shr al,1 ; Move next bit of key into position
mov [bx],al ; Send next byte of key out D0
shr al,1 ; Move next bit of key into position
mov [bx],al ; Send next byte of key out D0
shr al,1 ; Move next bit of key into position
mov [bx],al ; Send next byte of key out D0
shr al,1 ; Move next bit of key into position
mov [bx],al ; Send next byte of key out D0
shr al,1 ; Move next bit of key into position
mov [bx],al ; Send next byte of key out D0
shr al,1 ; Move next bit of key into position
mov [bx],al ; Send next byte of key out D0
shr al,1 ; Move next bit of key into position
mov [bx],al ; Send next byte of key out D0
loop WRITE_WATCH_OL ; Do all 8 bytes of the key
; Write the 64-bit SmartWatch data
; Byte 0
mov cx,8 ; Number of bits per byte
mov ax,es ; Bytes 0 and 1
@@:
mov [bx],al ; Write a bit to the SmartWatch
shr al,1 ; Move next bit down
loop @B ; Get all 8 bits
; Byte 1
mov cx,8 ; Number of bits per byte
mov al,ah ; Byte 1
@@:
mov [bx],al ; Write a bit to the SmartWatch
shr al,1 ; Move next bit down
loop @B ; Get all 8 bits
; Byte 2
mov cx,8 ; Number of bits per byte
mov ax,di ; Bytes 2 and 3
@@:
mov [bx],al ; Write a bit to the SmartWatch
shr al,1 ; Move next bit down
loop @B ; Get all 8 bits
; Byte 3
mov cx,8 ; Number of bits per byte
mov al,ah ; Byte 3
@@:
mov [bx],al ; Write a bit to the SmartWatch
shr al,1 ; Move next bit down
loop @B ; Get all 8 bits
; Byte 4
mov cx,8 ; Number of bits per byte
mov ax,bp ; Bytes 4 and 5
@@:
mov [bx],al ; Write a bit to the SmartWatch
shr al,1 ; Move next bit down
loop @B ; Get all 8 bits
; Byte 5
mov cx,8 ; Number of bits per byte
mov al,ah ; Byte 5
@@:
mov [bx],al ; Write a bit to the SmartWatch
shr al,1 ; Move next bit down
loop @B ; Get all 8 bits
; Byte 6
mov cx,8 ; Number of bits per byte
mov ax,dx ; Bytes 6 and 7
@@:
mov [bx],al ; Write a bit to the SmartWatch
shr al,1 ; Move next bit down
loop @B ; Get all 8 bits
; Byte 7
mov cx,8 ; Number of bits per byte
mov al,ah ; Byte 7
@@:
mov [bx],al ; Write a bit to the SmartWatch
shr al,1 ; Move next bit down
loop @B ; Get all 8 bits
sti ; Allow interrupts
REGREST <es> ; Restore caller's segment registers
assume es:nothing ; Tell the assembler
popa ; Restore caller's registers
ret ; Return to caller
assume ds:nothing, es:nothing, ss:nothing
WRITE_WATCH endp ; End WRITE_WATCH procedure
page
; Constant data
public WATCH_KEY
WATCH_KEY db 0C5h, 03Ah, 0A3h, 05Ch, 0C5h, 03Ah, 0A3h, 05Ch
db 00h ; Hundreth
db 00h ; Second
db 30h ; Minute
db 18h ; Hour
db 11h ; OSC, RESET, and Day of week
db 09h ; Day
db 10h ; Month
db 91h ; Year
_TEXT ends ; End _TEXT segment
MEND ; End KRNL_CLK module