extrn ?boot,?conin\r
extrn pr.inln,pr.crlf,pr.dec,pr.decl\r
extrn ioini1l,msginit,mmuinit,intinit,cpu_frq\r
+ extrn prt0ini,gs_rtc\r
extrn @civec,@covec,@aivec,@aovec,@lovec\r
extrn @cbnk,?bnksl\r
\r
ld (@aovec),hl\r
\r
\r
+ ld c,2\r
+ call gs_rtc ; get time and date\r
call intinit ; setup interrupts and vectors\r
+ call prt0ini ; init timer\r
+ ei\r
\r
xor a\r
ld (@cbnk),a ; right now in bank 0\r
title 'Time module for the Modular CP/M 3 BIOS'
- public ?time
+ public ?time, gs_rtc
+ public prt0ini
- extrn ?bank
extrn @date,@hour,@min,@sec
- extrn @cbnk
- extrn @bios$stack
+ extrn f_cpu
+ extrn ioiniml,div32_16
+ extrn msg.sm,msg.recv
include config.inc
include z180reg.inc
-
+;----------------------------------------------------------------------
+; c == 00h: get time
+; c == ffh: set time
cseg ; time must be done from resident memory
-
?time:
- ret ; no time (yet)
+ inc c ;zero if ff
+ ret nz ;nothing to do
+
+ ld c,3
+
+ ; fall thru
+
+;----------------------------------------------------------------------
+; c = 2: get time
+; c = 3: set time
+
+gs_rtc:
+
+ push hl
+ push de
+
+ ld hl,(@date)
+ push hl ;2
+ ld a,(@hour)
+ ld h,a
+ ld a,(@min)
+ ld l,a
+ push hl ;4
+ ld a,(@sec)
+ ld b,a ;b = sec, c = subcommand
+ push bc ;6
+ ld hl,3 * 256 + 0 ;h = command, l = 0
+ push hl ;8
+
+ ld h,l
+ add hl,sp
+ push hl
+ inc hl ;7
+
+ ld b,7
+ call msg.sm
+
+ pop hl ;8
+ ld b,8 ; max receive message len
+ call msg.recv
+
+ pop hl ;len/command
+ pop hl ;subc/sec
+ ld a,h
+ ld (@sec),a
+ pop hl
+ ld a,l
+ ld (@min),a
+ ld a,h
+ ld (@hour),a
+ pop hl
+ ld (@date),hl
+
+ pop de
+ pop hl
+ ret
+
+
+;----------------------------------------------------------------------
+; intit timer interrupt
+
+ dseg
+
+prt0ini:
+ in0 a,(tcr)
+ push af
+ and ~(M_TIE0+M_TDE0) ;stop timer 0
+ out0 (tcr),a
+
+ ld a,i
+ ld h,a
+ in0 a,(il)
+ and 0E0h
+ or IV$PRT0
+ ld l,a
+ ld de,isvprt0
+ ld (hl),e
+ inc hl
+ ld (hl),d
+
+ ld hl,(f_cpu)
+ ld de,(f_cpu+2)
+ ld bc,PRT_PRE * 100 ;1/100 s == 10 ms interrupt rate
+ call div32_16
+
+ out0 (tmdr0l),l
+ out0 (tmdr0h),h
+ out0 (rldr0l),l
+ out0 (rldr0h),h
+ pop af
+ or (M_TIE0+M_TDE0)
+ out0 (tcr),a
+ ret
+
+;----------------------------------------------------------------------
+; timer interrupt
+;
+; 10 ms clock tick
+
+
+ cseg ;common!
+isvprt0:
+ push af
+ in0 a,(tcr) ;reset TIF0 flag
+ in0 a,(tmdr0l)
+ in0 a,(tmdr0h)
+
+ ld a,(tim_ms) ;
+ inc a
+ cp 100 ;100 * 10ms ?
+ jr nz,iprt_1
+
+ ld a,(@sec)
+ inc a
+ daa
+ cp 60h
+ jr nz,iprt_2
+
+ ld a,(@min)
+ inc a
+ daa
+ cp 60h
+ jr nz,iprt_3
+
+ ld a,(@hour)
+ inc a
+ daa
+ cp 24h
+ jr nz,iprt_4
+
+ push hl
+ ld hl,(@date)
+ inc hl
+ ld (@date),hl
+ pop hl
+
+ xor a
+iprt_4:
+ ld (@hour),a
+ xor a
+iprt_3:
+ ld (@min),a
+ xor a
+iprt_2:
+ ld (@sec),a
+ xor a
+iprt_1:
+ ld (tim_ms),a
+ pop af
+ ei
+ ret
+
+tim_ms:
+ db 0
end