- title 'Time module for the Modular CP/M 3 BIOS'
-
- public ?time, gs_rtc
- public prt0ini
-
-
- extrn @date,@hour,@min,@sec
- extrn f_cpu
- extrn ioiniml,div32_16
- extrn msg.sm,msg.recv
- extrn _b0call
-
- include config.inc
- include z180reg.inc
-
-
-;----------------------------------------------------------------------
-; c == 00h: get time
-; c == ffh: set time
-
- cseg ; time must be done from resident memory
-?time:
- inc c ;zero if ff
- ret nz ;nothing to do
-
- ld c,3
-
- b0call gs_rtc
- ret
-
-;----------------------------------------------------------------------
-; c = 2: get time
-; c = 3: set time
-
- dseg
-gs_rtc:
-
- push hl
- push de
-
- di
- ld hl,(@date)
- ld a,(@hour)
- ld d,a
- ld a,(@min)
- ld e,a
- ld a,(@sec)
- ei
- ld b,a ;b = sec, c = subcommand
- push hl ;2
- push de ;4
- push bc ;6
- ld hl,3 * 256 + 0 ;h = command, l = 0
- push hl ;8
-
- ld h,l ;hl = 0
- 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 (discard)
- pop bc ;subc/sec
- pop de
- pop hl
- ld a,b
- di
- ld (@sec),a
- ld a,e
- ld (@min),a
- ld a,d
- ld (@hour),a
- ld (@date),hl
- ei
-
- 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,(counter_10ms) ;
- 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 (counter_10ms),a
- pop af
- ei
- ret
-
-counter_10ms:
- db 0
-
- end
+ title 'Time module for the Modular CP/M 3 BIOS'\r
+\r
+ public ?time, gs_rtc\r
+ public prt0ini\r
+ public gtimer,gstimer\r
+\r
+ extrn @date,@hour,@min,@sec\r
+ extrn f_cpu\r
+ extrn ioiniml,div32_16\r
+ extrn msg.sm,msg.recv\r
+ extrn _b0call\r
+\r
+ include config.inc\r
+ include z180reg.inc\r
+\r
+\r
+;----------------------------------------------------------------------\r
+; c == 00h: get time\r
+; c == ffh: set time\r
+\r
+ cseg ; time must be done from resident memory\r
+?time:\r
+ inc c ;zero if ff\r
+ ld c,3\r
+ jr z,time_set\r
+\r
+ ld a,(time_to)\r
+ or a\r
+ ret nz\r
+\r
+ dec c\r
+time_set:\r
+ b0call gs_rtc\r
+ ld a,0ffh\r
+ ld (time_to),a\r
+ ret\r
+\r
+;----------------------------------------------------------------------\r
+; c = 2: get time\r
+; c = 3: set time\r
+\r
+ dseg\r
+gs_rtc:\r
+\r
+ push hl\r
+ push de\r
+\r
+ ld hl,(@date)\r
+ ld a,(@hour)\r
+ ld d,a\r
+ ld a,(@min)\r
+ ld e,a\r
+ ld a,(@sec)\r
+ ld b,a ;b = sec, c = subcommand\r
+ push hl ;2\r
+ push de ;4\r
+ push bc ;6\r
+ ld hl,3 * 256 + 0 ;h = command, l = 0\r
+ push hl ;8\r
+\r
+ ld h,l ;hl = 0\r
+ add hl,sp\r
+ push hl\r
+ inc hl ;7\r
+\r
+ ld b,7\r
+ call msg.sm\r
+\r
+ pop hl ;8\r
+ ld b,8 ; max receive message len\r
+ call msg.recv\r
+\r
+ pop hl ;len/command (discard)\r
+ pop bc ;subc/sec\r
+ pop de\r
+ pop hl\r
+ ld a,b\r
+ ld (@sec),a\r
+ ld a,e\r
+ ld (@min),a\r
+ ld a,d\r
+ ld (@hour),a\r
+ ld (@date),hl\r
+\r
+ pop de\r
+ pop hl\r
+ ret\r
+\r
+;----------------------------------------------------------------------\r
+\r
+;uint32_t get_timer(uint32_t base)\r
+;{\r
+; uint32_t ret;\r
+; ATOMIC_BLOCK(ATOMIC_FORCEON)\r
+; {\r
+; ret = timestamp;\r
+; }\r
+; return ret - base;\r
+;}\r
+\r
+ dseg ; called from banked only\r
+gstimer:\r
+ push de\r
+ ex de,hl\r
+ ld hl,(uptime)\r
+ or a\r
+ sbc hl,de\r
+ pop de\r
+ ret\r
+\r
+;----------------------------------------------------------------------\r
+\r
+gtimer:\r
+ push bc\r
+ ld b,h\r
+ ld c,l\r
+ or a\r
+ di\r
+ ld hl,(uptime)\r
+ sbc hl,bc\r
+ push hl\r
+ ei\r
+ ld hl,(uptime+2)\r
+ sbc hl,de\r
+ ex de,hl\r
+ pop hl\r
+ pop bc\r
+ ret\r
+\r
+;----------------------------------------------------------------------\r
+; intit timer interrupt\r
+\r
+ dseg\r
+\r
+prt0ini:\r
+ in0 a,(tcr)\r
+ push af\r
+ and ~(M_TIE0+M_TDE0) ;stop timer 0\r
+ out0 (tcr),a\r
+\r
+ ld a,i\r
+ ld h,a\r
+ in0 a,(il)\r
+ and 0E0h\r
+ or IV$PRT0\r
+ ld l,a\r
+ ld de,isvprt0\r
+ ld (hl),e\r
+ inc hl\r
+ ld (hl),d\r
+\r
+ ld hl,(f_cpu)\r
+ ld de,(f_cpu+2)\r
+ ld bc,PRT_PRE * 800 ;1/800 s == 1,25 ms interrupt rate\r
+ call div32_16\r
+\r
+ out0 (tmdr0l),l\r
+ out0 (tmdr0h),h\r
+ out0 (rldr0l),l\r
+ out0 (rldr0h),h\r
+ pop af\r
+ or (M_TIE0+M_TDE0)\r
+ out0 (tcr),a\r
+ ret\r
+\r
+\r
+;----------------------------------------------------------------------\r
+; timer interrupt\r
+;\r
+; 1,25 ms clock tick\r
+\r
+\r
+ cseg ;common!\r
+isvprt0:\r
+ push af\r
+ in0 a,(tcr) ;reset TIF0 flag\r
+ in0 a,(tmdr0l)\r
+ in0 a,(tmdr0h)\r
+\r
+ push hl ;11\r
+ ld hl,uptime ; 9\r
+ inc (hl) ;10\r
+ jr nz,iprt_1 ;6/8 38\r
+ inc hl ; 4\r
+ inc (hl) ;10\r
+ jr nz,iprt_1 ;6/8 58\r
+ inc hl ; 4\r
+ inc (hl) ;10\r
+ jr nz,iprt_1 ;6/8\r
+ inc hl ; 4\r
+ inc (hl) ;10\r
+iprt_1:\r
+ pop hl ; 9\r
+ ld a,(time_to)\r
+ sub a,1\r
+ jr c,iprt_0\r
+ ld (time_to),a\r
+iprt_0:\r
+ pop af\r
+ ei\r
+ ret\r
+\r
+uptime:\r
+ dw 0,0\r
+time_to:\r
+ db 0\r
+\r
+ end\r