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