+ 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