diff --git a/12hourclk.c b/12hourclk.c index f8e9ee9..0419e62 100644 --- a/12hourclk.c +++ b/12hourclk.c @@ -1,7 +1,20 @@ #include /* printf, scanf */ +#include /* bool */ +#include /* strerror */ +#include /* time_t, time, localtime */ #include /* toupper */ +#include /* errno */ + #include "12hourclk.h" +#define TIME_ERR_RESULT ((time_t) -1) +#define LOCALTIME_ERR_RESULT NULL +#define ERR_MSG_SIZE 128 + +static void set_err_msg(char *prefix, int errno); + +static char G_err_msg[ERR_MSG_SIZE]; + static char *meridiem_text(meridiem_t m) { if (m == ANTE_MERIDIEM) { @@ -12,6 +25,49 @@ static char *meridiem_text(meridiem_t m) } } +bool set_clock(twleve_hour_clock_t *clock, struct tm *t) +{ + clock->seconds = t->tm_sec; + clock->minutes = t->tm_min; + if (t->tm_hour == 0) { + clock->hours = 12; + clock->meridiem = ANTE_MERIDIEM; + } + else if (t->tm_hour < 12) { + clock->meridiem = ANTE_MERIDIEM; + } + else if (t->tm_hour == 12) { + clock->meridiem = POST_MERIDIEM; + } + else { + clock->hours = t->tm_hour - 12; + clock->meridiem = POST_MERIDIEM; + } + return true; +} + + +void set_err_msg(char *what_failed, int err_code) +{ + snprintf(G_err_msg, ERR_MSG_SIZE, "%s: %s", what_failed, strerror(err_code)); +} + +bool load_system_time(twleve_hour_clock_t *clock) +{ + time_t now; + bool is_successful = false; /* It will not be successful until it is. */ + struct tm *curr_time; + + if (time(&now) != TIME_ERR_RESULT) + if ((curr_time = localtime(&now)) != LOCALTIME_ERR_RESULT) + is_successful = set_clock(clock, curr_time); + else + set_err_msg("Localtime function failed", errno); + else + set_err_msg("Time function failed", errno); + return is_successful; +} + void read_interactively(twleve_hour_clock_t *clock) { char meridiem_input[3]; diff --git a/12hourclk.h b/12hourclk.h index 44b2ba5..ae35e32 100644 --- a/12hourclk.h +++ b/12hourclk.h @@ -15,6 +15,7 @@ typedef struct { } twleve_hour_clock_t; extern void read_interactively(twleve_hour_clock_t *clock); +extern bool load_system_time(twleve_hour_clock_t *clock); extern void add_one_second(twleve_hour_clock_t *clock); extern void add_seconds(twleve_hour_clock_t *clock, uint8_t seconds); extern void print_time(twleve_hour_clock_t *clock); diff --git a/Makefile b/Makefile index 51583c8..a5f92d8 100644 --- a/Makefile +++ b/Makefile @@ -13,17 +13,18 @@ endif PGM=alarmclk OBJS=alarmclk.o 12hourclk.o clkfreq.o -PGM2=cpufreq -OBJS2=clkfreq.o +PGM2=calibrate +OBJS2=calibrate.o CC=cl65 AS=ca65 +LD=ld65 CFLAGS=-t $(CC65_TARGET) -O ASFLAGS=-t $(CC65_TARGET) LDFLAGS=-t $(CC65_TARGET) -DISK_VOL=ALARMCLK +DISK_VOL=alarmclk DISK=$(DISK_VOL).dsk AC=java -jar lib/AppleCommander-1.3.5.14.jar @@ -36,12 +37,14 @@ all: $(DISK) $(DISK): $(PGM) $(PGM2) $(AC) -d $(DISK) $< $(AC) -cc65 $(DISK) $< BIN < $< + $(AC) -d $(DISK) $(PGM2) + $(AC) -cc65 $(DISK) $(PGM2) BIN < $(PGM2) $(PGM): $(OBJS) $(CC) $(LDFLAGS) -o $@ $^ -$(PGM2): clkfreq.s - $(AS) $(ASFLAGS) -o $@ $^ +$(PGM2): $(OBJS2) + $(CC) $(LDFLAGS) -o $@ $^ # Compile and assemble rules use the defuault rules after CC and CFLAGS # are set. diff --git a/alarmclk.c b/alarmclk.c index 23f4ad5..cea6020 100644 --- a/alarmclk.c +++ b/alarmclk.c @@ -5,8 +5,8 @@ #include /* clrscr, kbhit */ #include "12hourclk.h" -extern void clkfreq(); -extern uint8_t ticks[4]; +extern void ClockFreq(); +extern uint8_t Ticks[4]; #define CLOCK_FREQUENCY 1023000L #define CYCLES_PER_NOOP 2 @@ -23,17 +23,18 @@ static twleve_hour_clock_t alarm_time; void main(void) { - clkfreq(); + ClockFreq(); printf("%c%c.%c%c%c%c%c%c MHz\n", - ticks[0] & 0x70, - ticks[0] & 0x07, - ticks[1] & 0x70, - ticks[1] & 0x07, - ticks[2] & 0x70, - ticks[2] & 0x07, - ticks[3] & 0x70, - ticks[3] & 0x07); + Ticks[0] & 0x70, + Ticks[0] & 0x07, + Ticks[1] & 0x70, + Ticks[1] & 0x07, + Ticks[2] & 0x70, + Ticks[2] & 0x07, + Ticks[3] & 0x70, + Ticks[3] & 0x07); + clrscr(); read_inputs(); clrscr(); @@ -46,8 +47,10 @@ void main(void) void read_inputs() { - puts("Current Time"); - read_interactively(&curr_time); + if (! load_system_time(&curr_time)) { + puts("Current Time"); + read_interactively(&curr_time); + } puts("Alarm Time"); read_interactively(&alarm_time); } diff --git a/alarmclk.dsk b/alarmclk.dsk new file mode 100644 index 0000000..de3662d Binary files /dev/null and b/alarmclk.dsk differ diff --git a/alarmclk.s b/alarmclk.s new file mode 100644 index 0000000..992ca52 --- /dev/null +++ b/alarmclk.s @@ -0,0 +1,515 @@ +; +; File generated by cc65 v 2.15 - Git 6f24c07 +; + .fopt compiler,"cc65 v 2.15 - Git 6f24c07" + .setcpu "65C02" + .smart on + .autoimport on + .case on + .debuginfo off + .importzp sp, sreg, regsave, regbank + .importzp tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 + .macpack longbranch + .forceimport __STARTUP__ + .import _printf + .import _puts + .import _toupper + .import _clrscr + .import _kbhit + .import _cgetc + .import _read_interactively + .import _load_system_time + .import _add_one_second + .import _print_time + .import _reprint_time + .import _ClockFreq + .import _Ticks + .export _read_inputs + .export _elapse_one_second + .export _run_clock + .export _main + +.segment "RODATA" + +L0009: + .byte $25,$63,$25,$63,$2E,$25,$63,$25,$63,$25,$63,$25,$63,$25,$63,$25 + .byte $63,$20,$4D,$48,$7A,$0A,$00 +L001F: + .byte $0A,$41,$6C,$61,$72,$6D,$20,$54,$69,$6D,$65,$3A,$20,$20,$20,$00 +L0024: + .byte $0A,$43,$75,$72,$72,$65,$6E,$74,$20,$54,$69,$6D,$65,$3A,$20,$00 +L002C: + .byte $43,$75,$72,$72,$65,$6E,$74,$20,$54,$69,$6D,$65,$00 +L0031: + .byte $41,$6C,$61,$72,$6D,$20,$54,$69,$6D,$65,$00 +L004B := L0009+22 + +.segment "BSS" + +_curr_time: + .res 5,$00 +_alarm_time: + .res 5,$00 + +; --------------------------------------------------------------- +; void __near__ read_inputs (void) +; --------------------------------------------------------------- + +.segment "CODE" + +.proc _read_inputs: near + +.segment "CODE" + + lda #<(_curr_time) + ldx #>(_curr_time) + jsr _load_system_time + jsr bnega + jeq L0028 + lda #<(L002C) + ldx #>(L002C) + jsr _puts + lda #<(_curr_time) + ldx #>(_curr_time) + jsr _read_interactively +L0028: lda #<(L0031) + ldx #>(L0031) + jsr _puts + lda #<(_alarm_time) + ldx #>(_alarm_time) + jsr _read_interactively + rts + +.endproc + +; --------------------------------------------------------------- +; void __near__ elapse_one_second (void) +; --------------------------------------------------------------- + +.segment "CODE" + +.proc _elapse_one_second: near + +.segment "CODE" + + jsr decsp4 + ldx #$07 + lda #$FE + ldy #$00 + jsr staxysp + ldx #$00 + lda #$00 + ldy #$02 + jsr staxysp +L0050: ldy #$03 + jsr ldaxysp + jsr pushax + ldy #$03 + jsr ldaxysp + jsr tosltax + jne L0053 + jmp L0051 +L0053: nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + ldy #$02 + ldx #$00 + lda #$01 + jsr addeqysp + jmp L0050 +L0051: jsr incsp4 + rts + +.endproc + +; --------------------------------------------------------------- +; void __near__ run_clock (void) +; --------------------------------------------------------------- + +.segment "CODE" + +.proc _run_clock: near + +.segment "CODE" + + jsr decsp1 + lda #<(_curr_time) + ldx #>(_curr_time) + jsr _print_time + jmp L003A +L0038: jsr _elapse_one_second + lda #<(_curr_time) + ldx #>(_curr_time) + jsr _add_one_second + lda #<(_curr_time) + ldx #>(_curr_time) + jsr _reprint_time + jsr _kbhit + tax + jeq L003A + jsr _cgetc + ldy #$00 + sta (sp),y + ldy #$00 + ldx #$00 + lda (sp),y + cmp #$1B + jsr booleq + jne L0046 + ldy #$00 + ldx #$00 + lda (sp),y + ldx #$00 + jsr _toupper + cpx #$00 + bne L0048 + cmp #$51 +L0048: jsr booleq + jne L0046 + ldy #$00 + ldx #$00 + lda (sp),y + cmp #$03 + jsr booleq + jne L0046 + ldx #$00 + lda #$00 + jeq L0049 +L0046: ldx #$00 + lda #$01 +L0049: jeq L003A + lda #<(L004B) + ldx #>(L004B) + jsr _puts + jmp L0039 +L003A: jmp L0038 +L0039: jsr incsp1 + rts + +.endproc + +; --------------------------------------------------------------- +; void __near__ main (void) +; --------------------------------------------------------------- + +.segment "CODE" + +.proc _main: near + +.segment "CODE" + + ldy #$00 + jsr _ClockFreq + lda #<(L0009) + ldx #>(L0009) + jsr pushax + ldx #$00 + lda _Ticks + ldx #$00 + and #$70 + jsr pushax + ldx #$00 + lda _Ticks + ldx #$00 + and #$07 + jsr pushax + ldx #$00 + lda _Ticks+1 + ldx #$00 + and #$70 + jsr pushax + ldx #$00 + lda _Ticks+1 + ldx #$00 + and #$07 + jsr pushax + ldx #$00 + lda _Ticks+2 + ldx #$00 + and #$70 + jsr pushax + ldx #$00 + lda _Ticks+2 + ldx #$00 + and #$07 + jsr pushax + ldx #$00 + lda _Ticks+3 + ldx #$00 + and #$70 + jsr pushax + ldx #$00 + lda _Ticks+3 + ldx #$00 + and #$07 + jsr pushax + ldy #$12 + jsr _printf + jsr _clrscr + jsr _read_inputs + jsr _clrscr + lda #<(L001F) + ldx #>(L001F) + jsr pushax + ldy #$02 + jsr _printf + lda #<(_alarm_time) + ldx #>(_alarm_time) + jsr _print_time + lda #<(L0024) + ldx #>(L0024) + jsr pushax + ldy #$02 + jsr _printf + jsr _run_clock + rts + +.endproc + diff --git a/calcClkfreq.c b/calcClkfreq.c new file mode 100644 index 0000000..b637092 --- /dev/null +++ b/calcClkfreq.c @@ -0,0 +1,9 @@ +/* This file is only here to make clkfreq.s load successfully. */ + +#include "clkfreq.h" + +void main() +{ + clkfreq(); +} + diff --git a/calibrate.s b/calibrate.s new file mode 100644 index 0000000..f07f647 --- /dev/null +++ b/calibrate.s @@ -0,0 +1,93 @@ +.forceimport __STARTUP__ +.export _main + +.segment "RODATA" + +; All numbers are going to be this size and type. +Unsigned_Integer_Size = 4 +; Standard character output routine +COUT = $fded + +.segment "BSS" + +Sleep_Loop_Count: .res Unsigned_Integer_Size,0 ; Byte values initialized to 0 + +; ************************************* +; +; Macros +; +; ************************************* + +; Number++ +.macro Increment Number + .local Next_Byte + .local Done + ldx #0 ; X := 0 +Next_Byte: + inc Number,X ; Increment the value at Count+X address + bne Done ; Incrementing Count did not cause it to roll over to 0. + inx ; Increment X to the next byte + cpx #Unsigned_Integer_Size ; Compare X with 4. + bmi Next_Byte ; If X < Count_Size continue with next byte. +Done: +.endmacro + +; Minuend = Minuend - Subtrahend +.macro Subtract Minuend, Subtrahend + .local Next_Byte + ldx #0 + clc +Next_Byte: + lda Addr1,X + sbc Addr2,X + inx + cpx #Unsigned_Integer_Size + bmi Next_Byte +.endmacro + +; ************************************* +; +; Main +; +; ************************************* + +.segment "CODE" + +.proc _main: near + +.segment "CODE" + +Sleep_Loop: + +; Do nothing 10 times. + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + Increment Sleep_Loop_Count + lda #1 + cmp Sleep_Loop_Count+3 + bmi Sleep_Loop + +; Output result + + ldx #0 +Next_Byte: + lda Sleep_Loop_Count,X + jsr COUT + inx + cpx #Unsigned_Integer_Size + bmi Next_Byte + + rts ; from _main + +.endproc + diff --git a/clkfreq b/clkfreq new file mode 100644 index 0000000..36ea607 Binary files /dev/null and b/clkfreq differ diff --git a/clkfreq.h b/clkfreq.h new file mode 100644 index 0000000..70c3545 --- /dev/null +++ b/clkfreq.h @@ -0,0 +1,10 @@ +#ifndef CLKFREQ_H +#define CLKFREQ_H + +#include /* uint8_t */ + +extern void clkfreq(void); +extern uint8_t ticks[4]; + +#endif + diff --git a/clkfreq.s b/clkfreq.s index 470e928..a41a8ae 100644 --- a/clkfreq.s +++ b/clkfreq.s @@ -1,3 +1,18 @@ + .setcpu "65C02" + .smart on + .autoimport on + .case on + .debuginfo off + .importzp sp, sreg, regsave, regbank + .importzp tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 + .macpack longbranch + .forceimport __STARTUP__ + .import _fputc + .import _stdout + + .export _Ticks + .export _ClockFreq + rgConfig = $6000 ; write: D6=1 - NMI is off, D6=0 - NMI is on rgStatus = $6000 ; read: D6=0 - UART is busy rgTxD = $5000 ; write: data to send via UART @@ -6,9 +21,12 @@ vcNMI = $FFFA Refresh = 450 ; NMI rate in Hz -.export _clkfreq -.export _ticks -_clkfreq: +.segment "CODE" + +.proc _ClockFreq: near + +.segment "CODE" + ldx #NMI stx vcNMI @@ -19,10 +37,10 @@ _clkfreq: Again: lda #0 sta Flag - sta _ticks ; initializing counter - sta _ticks+1 - sta _ticks+2 - sta _ticks+3 + sta _Ticks ; initializing counter + sta _Ticks+1 + sta _Ticks+2 + sta _Ticks+3 lda #$FE ; initializing NMI counter (zeropoint minus 2 ticks) sta Timer lda #$FF @@ -45,40 +63,40 @@ L2: bit Flag ; waiting for true zeropoint Main: ; main counting cycle ;number of ticks per command sum of ticks ; v v - lda _ticks ;4 + lda _Ticks ;4 clc ;2 6 sed ;2 8 adc #$53 ;2 10 - sta _ticks ;4 14 - lda _ticks+1 ;4 18 + sta _Ticks ;4 14 + lda _Ticks+1 ;4 18 adc #0 ;2 20 - sta _ticks+1 ;4 24 - lda _ticks+2 ;4 28 + sta _Ticks+1 ;4 24 + lda _Ticks+2 ;4 28 adc #0 ;2 30 - sta _ticks+2 ;4 34 - lda _ticks+3 ;4 38 + sta _Ticks+2 ;4 34 + lda _Ticks+3 ;4 38 adc #0 ;2 40 - sta _ticks+3 ;4 44 + sta _Ticks+3 ;4 44 cld ;2 46 bit Flag ;4 50 bpl Main ;3 53 lda #0 ;2 sta Flag ;4 6 - lda _ticks ;4 10 + lda _Ticks ;4 10 clc ;2 12 sed ;2 14 adc #$95 ;2 16 - sta _ticks ;4 20 - lda _ticks+1 ;4 24 + sta _Ticks ;4 20 + lda _Ticks+1 ;4 24 adc #0 ;2 26 - sta _ticks+1 ;4 30 - lda _ticks+2 ;4 34 + sta _Ticks+1 ;4 30 + lda _Ticks+2 ;4 34 adc #0 ;2 36 - sta _ticks+2 ;4 40 - lda _ticks+3 ;4 44 + sta _Ticks+2 ;4 40 + lda _Ticks+3 ;4 44 adc #0 ;2 46 - sta _ticks+3 ;4 50 + sta _Ticks+3 ;4 50 cld ;2 52 lda Timer ;4 56 cmp # + +void main(void) +{ + putc('A', stdout); +} diff --git a/putc.s b/putc.s new file mode 100644 index 0000000..54eae22 --- /dev/null +++ b/putc.s @@ -0,0 +1,25 @@ + .file "putc.c" + .text + .globl main + .type main, @function +main: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movq stdout(%rip), %rax + movq %rax, %rsi + movl $65, %edi + call _IO_putc + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size main, .-main + .ident "GCC: (GNU) 5.1.1 20150618 (Red Hat 5.1.1-4)" + .section .note.GNU-stack,"",@progbits