Added a bunch of stuff.

This commit is contained in:
Bill Chatfield 2015-08-21 10:37:15 -04:00
parent 82c9aca4e7
commit 0af1b9b94b
7 changed files with 688 additions and 0 deletions

104
12hourclk.c Normal file
View File

@ -0,0 +1,104 @@
#include <stdio.h> /* printf, scanf */
#include <ctype.h> /* toupper */
#include "12hourclk.h"
static char *meridiem_text(meridiem_t m)
{
if (m == ANTE_MERIDIEM) {
return "am";
}
else {
return "pm";
}
}
void read_interactively(twleve_hour_clock_t *clock)
{
char meridiem_input[3];
printf("Hour:");
scanf("%2ui", &(clock->hours));
printf("Minute:");
scanf("%2ui", &(clock->minutes));
printf("AM or PM:");
scanf("%2s", meridiem_input);
clock->seconds = 0;
if (toupper(meridiem_input[0]) == 'A') {
clock->meridiem = ANTE_MERIDIEM;
}
else {
clock->meridiem = POST_MERIDIEM;
}
}
void add_one_second(twleve_hour_clock_t *clock)
{
if (clock->seconds < 59) {
++(clock->seconds);
}
else {
clock->seconds = 0;
if (clock->minutes < 59) {
++(clock->minutes);
}
else {
clock->minutes = 0;
if (clock->hours < 11) {
++(clock->hours);
}
else if (clock->hours == 11) {
++(clock->hours);
if (clock->meridiem == ANTE_MERIDIEM) {
clock->meridiem = POST_MERIDIEM;
}
else {
clock->meridiem = ANTE_MERIDIEM;
}
}
else {
clock->hours = 1;
}
}
}
}
void add_seconds(twleve_hour_clock_t *clock, uint8_t seconds)
{
uint16_t sum;
uint16_t minutes_carry;
uint16_t hours_carry;
sum = ((uint16_t) clock->seconds) + ((uint16_t) seconds);
if (sum >= 60) {
minutes_carry = sum / 60;
clock->seconds = sum % 60;
sum = ((uint16_t) clock->minutes) + minutes_carry;
if (sum >= 60) {
hours_carry = sum / 60;
clock->minutes = sum % 60;
sum = ((uint16_t) clock->hours) + hours_carry;
if (sum >= 12) {
}
}
else {
clock->minutes = sum;
}
}
else {
clock->seconds = sum;
}
}
void print_time(twleve_hour_clock_t *clock)
{
printf("%2u:%02u:%02u %2s", clock->hours, clock->minutes, clock->seconds, meridiem_text(clock->meridiem));
}
void reprint_time(twleve_hour_clock_t *clock)
{
printf("\b\b\b\b\b\b\b\b\b\b\b");
print_time(clock);
}

24
12hourclk.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef TWELVE_HOUR_CLOCK_H
#define TWELVE_HOUR_CLOCK_H
#include <stdint.h> /* uint8_t */
typedef enum {
ANTE_MERIDIEM, POST_MERIDIEM
} meridiem_t;
typedef struct {
uint8_t hours;
uint8_t minutes;
uint8_t seconds;
meridiem_t meridiem;
} twleve_hour_clock_t;
extern void read_interactively(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);
extern void reprint_time(twleve_hour_clock_t *clock);
#endif

BIN
ALARMCLK.dsk Normal file

Binary file not shown.

51
Makefile Normal file
View File

@ -0,0 +1,51 @@
# Builds the Alarm Clock app
#
# Requirements:
# 1. Gmake must be used.
# 2. The cc65 compiler must be properly setup. See setup-cc65.
#
ifndef CC65_TARGET
CC65_TARGET:=apple2enh
endif
PGM=alarmclk
OBJS=alarmclk.o 12hourclk.o clkfreq.o
PGM2=cpufreq
OBJS2=clkfreq.o
CC=cl65
AS=ca65
CFLAGS=-t $(CC65_TARGET) -O
ASFLAGS=-t $(CC65_TARGET)
LDFLAGS=-t $(CC65_TARGET)
DISK_VOL=ALARMCLK
DISK=$(DISK_VOL).dsk
AC=java -jar lib/AppleCommander-1.3.5.14.jar
MKDISK=$(AC) -pro140 $(DISK) $(DISK_VOL)
########################################
all: $(DISK)
$(DISK): $(PGM) $(PGM2)
$(AC) -d $(DISK) $<
$(AC) -cc65 $(DISK) $< BIN < $<
$(PGM): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $^
$(PGM2): clkfreq.s
$(AS) $(ASFLAGS) -o $@ $^
# Compile and assemble rules use the defuault rules after CC and CFLAGS
# are set.
clean:
$(RM) $(PGM) $(PGM2) *.o

334
alarmclk.c Normal file
View File

@ -0,0 +1,334 @@
#include <stdio.h> /* scanf */
#include <stdint.h> /* uint8_t */
#include <stdbool.h> /* true */
#include <ctype.h> /* toupper */
#include <conio.h> /* clrscr, kbhit */
#include "12hourclk.h"
extern void clkfreq();
extern uint8_t ticks[4];
#define CLOCK_FREQUENCY 1023000L
#define CYCLES_PER_NOOP 2
#define NOOPS_PER_SEC 511500
#define CTRL_C '\x03'
#define ESC '\x1B'
void read_inputs(void);
void elapse_one_second(void);
void run_clock(void);
static twleve_hour_clock_t curr_time;
static twleve_hour_clock_t alarm_time;
void main(void)
{
clkfreq();
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);
read_inputs();
clrscr();
printf("\nAlarm Time: ");
print_time(&alarm_time);
printf("\nCurrent Time: ");
run_clock();
}
void read_inputs()
{
puts("Current Time");
read_interactively(&curr_time);
puts("Alarm Time");
read_interactively(&alarm_time);
}
void run_clock()
{
char c;
print_time(&curr_time);
while (true) {
elapse_one_second();
add_one_second(&curr_time);
reprint_time(&curr_time);
if (kbhit()) {
c = cgetc();
if (c == ESC || toupper(c) == 'Q' || c == CTRL_C) {
puts("");
break;
}
}
}
}
void elapse_one_second()
{
int i;
int max_loops;
max_loops = NOOPS_PER_SEC / 250;
for (i = 0; i < max_loops; ++i) {
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
}

175
clkfreq.s Normal file
View File

@ -0,0 +1,175 @@
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
vcNMI = $FFFA
Refresh = 450 ; NMI rate in Hz
.export _clkfreq
.export _ticks
_clkfreq:
ldx #<NMI ; installing the NMI vector
ldy #>NMI
stx vcNMI
sty vcNMI+1
lda #$40 ; on start NMI is off
sta InUse
Again:
lda #0
sta Flag
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
sta Timer+1
lda InUse ; turn on NMI
and #$BF
sta rgConfig
sta InUse
L1: bit Flag ; waiting for zeropoint minus 1 tick
bpl L1
lda #0
sta Flag
L2: bit Flag ; waiting for true zeropoint
bpl L2
lda #0
sta Flag
Main: ; main counting cycle
;number of ticks per command sum of ticks
; v v
lda _ticks ;4
clc ;2 6
sed ;2 8
adc #$53 ;2 10
sta _ticks ;4 14
lda _ticks+1 ;4 18
adc #0 ;2 20
sta _ticks+1 ;4 24
lda _ticks+2 ;4 28
adc #0 ;2 30
sta _ticks+2 ;4 34
lda _ticks+3 ;4 38
adc #0 ;2 40
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
clc ;2 12
sed ;2 14
adc #$95 ;2 16
sta _ticks ;4 20
lda _ticks+1 ;4 24
adc #0 ;2 26
sta _ticks+1 ;4 30
lda _ticks+2 ;4 34
adc #0 ;2 36
sta _ticks+2 ;4 40
lda _ticks+3 ;4 44
adc #0 ;2 46
sta _ticks+3 ;4 50
cld ;2 52
lda Timer ;4 56
cmp #<Refresh ;2 58
bne Main ;3 61 + 34 (from NMI ISR) = 95
lda Timer+1 ; 4
cmp #>Refresh ; 2
bne Main ; 3
lda InUse ; turn off NMI
ora #$40
sta rgConfig
sta InUse
ldx #0 ; send first string to the host
L3: lda Mes1,x
beq L4
jsr Send
inx
jmp L3
L4: lda _ticks+3
pha
lsr
lsr
lsr
lsr
beq L5 ; delete non-significant zero (clock < 10MHz)
jsr PrintDigit
L5: pla
and #15
jsr PrintDigit
lda #'.' ; decimal point
jsr Send
lda _ticks+2
jsr PrintTwoDigits
lda _ticks+1
jsr PrintTwoDigits
lda _ticks
jsr PrintTwoDigits
ldx #0 ; send second string to the host
L6: lda Mes2,x
beq L7
jsr Send
inx
jmp L6
L7: jmp Again ; repeat process
PrintTwoDigits:
pha
lsr
lsr
lsr
lsr
jsr PrintDigit
pla
and #15
jsr PrintDigit
rts
PrintDigit:
ora #$30
jsr Send
rts
Send:
bit rgStatus
bvc Send
sta rgTxD
rts
Mes1:
.byte 13
.byte "Current clock frequency is "
.byte 0
Mes2:
.byte " MHz"
.byte 0
_ticks: .res 4,0
Timer: .res 2,0
InUse: .byte 0
Flag: .byte 0
NMI: ;6
pha ;3 9
inc Timer ;6 15
bne L8 ;3 18
inc Timer+1 ; 5
L8: lda #$80 ;2 20
sta Flag ;4 24
pla ;4 28
rti ;6 34

Binary file not shown.