Implement date/time

This commit is contained in:
Juhani Krekelä 2021-09-26 13:43:38 +03:00
parent 68030372b7
commit b9c83b11cd
1 changed files with 145 additions and 18 deletions

163
io.asm
View File

@ -22,7 +22,7 @@ data ends
iogroup group code, constants, data
code segment
assume cs:iogroup, ds:iogroup, es:iogroup
assume cs:iogroup
org 0
; Jump table
@ -36,9 +36,9 @@ jmp unimplemented ; 0012 Serial write
jmp near ptr diskread ; 0015
jmp diskwrite ; 0018
jmp near ptr diskchange ; 001b
jmp setdate ; 001e
jmp settime ; 0021
jmp gettime ; 0024
jmp near ptr setdate ; 001e
jmp near ptr settime ; 0021
jmp near ptr gettime ; 0024
jmp near ptr flush ; 0027
jmp near ptr mapdev ; 002a
@ -99,11 +99,11 @@ init:
int 10h
; Set random record field 0
mov word ptr command_fcb+33, 0
mov word ptr command_fcb+35, 0
mov word ptr iogroup:command_fcb+33, 0
mov word ptr iogroup:command_fcb+35, 0
; Set record size to 1 byte
mov word ptr command_fcb+14, 1
mov word ptr iogroup:command_fcb+14, 1
; Read command.com into memory
mov ah, 27h
@ -326,7 +326,7 @@ chs proc
; cylinder = LBA / sectorspertrack / heads
; head = LBA / sectorspertrack % heads
; sector = LBA % sectorspertrack + 1
div cs:sectorspertrack
div iogroup:sectorspertrack
; ax = LBA / sectorspertrack
; dx = LBA % sectorspertrack
@ -335,7 +335,7 @@ chs proc
inc cl
xor dx, dx
div cs:heads
div iogroup:heads
; ax = LBA / sectorspertrack / heads
; dx = LBA / sectorspertrack % heads
@ -374,15 +374,132 @@ diskchange proc far
ret
diskchange endp
setdate:
mov al, 'd'
jmp error
settime:
mov al, 't'
jmp error
gettime:
mov al, 'T'
jmp error
; IN:
; ax = days since 1980-01-01
setdate proc far
mov iogroup:days_since_epoch, ax
ret
setdate endp
; IN:
; ch = hour
; cl = minute
; dh = second
; dl = 1/100 second
settime proc far
push ax
push bx
push cx
push dx
push si
push di
; Save second & 1/100 second in bx
mov bx, dx
; Hour
mov al, ch
cbw
mul iogroup:doubleticks_per_hour
shl ax, 1
rcl dx, 1
; Store the partial sum in si:di
mov di, ax
mov si, dx
; Minute
mov al, cl
cbw
mul iogroup:ticks_per_minute
add di, ax
adc si, dx
; Second
mov al, bh
cbw
mul iogroup:ticks_per_second
add di, ax
adc si, dx
; 1/100 second
mov al, bl
cbw
div iogroup:cs_per_tick
xor ah, ah
add di, ax
adc si, 0
; Move result to cx:ds and set timer
mov cx, si
mov dx, di
mov ah, 01h
int 1ah
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
settime endp
; OUT:
; ax = days since 1980-01-01
; ch = hour
; cl = minute
; dh = second
; dl = 1/100 second
gettime proc far
; TODO: Use RTC if available
push bx
; Get ticks since midnight and day rollover flag
xor ah, ah
int 1ah
; al is nonzero if day has changed
test al, al
jz same_day
inc iogroup:days_since_epoch
same_day:
; Divide the ticks by 2, to keep all our arithmetic within bounds
shr cx, 1
rcr dx, 1
; int 1ah / ah=00 returns the ticks in cx:dx, div operates on dx:ax
mov ax, dx
mov dx, cx
div iogroup:doubleticks_per_hour
mov ch, al ; Hour
; Remainder in dx, range [0,doubleticks_per_hour[ represents an hour
; Multiply by 60, divide by doubleticks_per_hour to get the minute
mov ax, dx
mul iogroup:sixty
div iogroup:doubleticks_per_hour
mov cl, al ; Minute
; Do same again to get seconds
mov ax, dx
mul iogroup:sixty
div iogroup:doubleticks_per_hour
mov bl, al ; Save seconds in bl, since dh gets destroyed by next muldiv
; For 1/100th of a second, multiply by 100 instead
mov ax, dx
mul iogroup:hundred
div iogroup:doubleticks_per_hour
mov dh, bl ; Second
mov dl, al ; 1/100 second
mov ax, iogroup:days_since_epoch
pop bx
ret
gettime endp
flush proc far
push ax
@ -444,6 +561,14 @@ parameters_320k:
dw 112 ; Number of directory entries
dw 320*2 ; Number of sectors
doubleticks_per_hour dw 32772 ; 1800B0h / 2 / 24
ticks_per_minute dw 1092 ; 1800B0h / 24 / 60
ticks_per_second dw 18 ; 1800B0h / 24 / 60 / 60
cs_per_tick db 5 ; 24 * 60 * 60 * 100 / 1800B0h
sixty dw 60
hundred dw 100
constants ends
data segment
@ -453,6 +578,8 @@ command_fcb:
db "COMMAND COM"
db 25 dup (?)
days_since_epoch: dw 0
data ends
code segment