program timecmos; type str5 = string[5]; const month_name: array[0..12] of string[3] =('Err','Jan','Feb','Mar','Apr','May', 'Jun','Jul','Aug','Sep','Oct','Nov','Dec'); day_of_week_name: array[0..6] of string[3] =('Mon','Tue','Wed','Thu','Fri','Sat','Sun'); CMOS_ID_port: byte =$70; CMOS_DATA_port: byte = $71; var hours, minutes, seconds, day_of_week, day, month, year, century_byte : byte; ch : char; CMOS_info : array[0..63] of byte; function valid_CMOS: boolean; begin port[CMOS_ID_port] := $0E; delay(1); valid_CMOS :=((port[CMOS_DATA_port])=0) end; function CMOS_busy: boolean; begin port[CMOS_ID_port] := $A; delay(1); CMOS_busy := port[CMOS_DATA_port] and $80 >0 end; function read_CMOS_reg(r: byte): byte; begin while CMOS_busy do delay(10); port[CMOS_ID_port] := r; delay(1); read_CMOS_reg := port[CMOS_DATA_port] end; function write_CMOS_reg(r,v: byte): boolean; begin while CMOS_busy do delay(10); port[CMOS_ID_port] := r; delay(1); port[CMOS_DATA_port] := v; write_CMOS_reg := (read_CMOS_reg(r) = v) end; function num_floppies: byte; begin if CMOS_info[$14] and $C0=0 then num_floppies := 1 else num_floppies := 2 end; function good_flag(v,f: byte): str5; const ok_st: str5 = 'good'; bad_st: str5 = 'bad'; begin if CMOS_info[v] and $80 = $80 then good_flag := ok_st else good_flag := bad_st end; procedure fill_CMOS_info; var i: byte; begin for i := 0 to 63 do CMOS_info[i] := read_CMOS_reg( i); seconds := CMOS_info[0]; minutes := CMOS_info[2]; hours := CMOS_info[4]; day_of_week := CMOS_info[6]; day := CMOS_info[7]; month := CMOS_info[8]; year := CMOS_info[9]; century_byte := CMOS_info[$32]; end; procedure display_INFO; var i: byte; begin writeln(hours shr 4,hours mod 16,':',minutes shr 4,minutes mod 16,':' ,seconds shr 4,seconds mod 16); write('Today (',day_of_week,') is: ',day_of_week_name[day_of_week]); writeln(', ',day shr 4,day mod 16,'. ' ,month_name[(10*(month shr 4))+(month mod 16) ],' ', century_byte shr 4, century_byte mod 16,year shr 4, year mod 16); writeln(' CMOS info: '); write('Bytes 0- 9: '); for i := 0 to 9 do write(CMOS_info[i]:4); writeln; write('Bytes 10-19: '); for i := 10 to 19 do write(CMOS_info[i]:4); writeln; write('Bytes 20-29: '); for i := 20 to 29 do write(CMOS_info[i]:4); writeln; write('Bytes 30-39: '); for i := 30 to 39 do write(CMOS_info[i]:4); writeln; write('Bytes 40-49: '); for i := 40 to 49 do write(CMOS_info[i]:4); writeln; write('Bytes 50-59: '); for i := 50 to 59 do write(CMOS_info[i]:4); writeln; write('Bytes 60-63: '); for i := 60 to 63 do write(CMOS_info[i]:4); writeln; writeln('Time is contained in bytes 0(sec), 2(minutes), 4(hours)'); writeln('Alarm is contained in bytes 1(sec), 3(min), 5(hours)'); writeln('Date is contained in bytes 7(day), 8(month), 9(year), 6(day of week)'); writeln('Bytes 10 .. 15 contain CMOS, RTC house keeping info'); writeln('Byte 13 MSB containes flag for good (1) battery power, bad = 0'); writeln('Battery power is ',good_flag(13,7),'.'); writeln('Bytes 30 and 31 contain the CMOS checksum: ', CMOS_info[30],' ', CMOS_info[31]); writeln('Byte 20, bits 6,7: floppy info: ',num_floppies,' drives.'); end; begin {Time} if not valid_CMOS then begin writeln('CMOS invalid'); exit end; fill_CMOS_info; display_info; write('HAK'); read(kbd,ch); if write_CMOS_reg(1,0)= true then begin if write_CMOS_reg(3,0) = true then begin fill_CMOS_info; display_info end end else writeln('Error writeing CMOS test byte'); end {Time}.