Skip to content

Commit

Permalink
4.7.1 add apple2gs clock functionality and rearrange the apple2 platf…
Browse files Browse the repository at this point in the history
…orm source dirs
  • Loading branch information
markjfisher committed Sep 21, 2024
1 parent df98441 commit 52a2001
Show file tree
Hide file tree
Showing 54 changed files with 210 additions and 40 deletions.
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

## [4.7.1] - 2024-09-21

- [clock] add apple2gs clock implementation (untested)

## [4.7.0] - 2024-09-20

- [clock] a simple clock library to interface with FujiNet clock device with atari/apple2 (cc65) implementations
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,28 @@ got_id:
jsr pusha ; store the destination device for call to sp_control

; copy timezone string into sp_payload, including the null terminator
pushax #(_sp_payload + 2)
pushax tmp_tz_ptr
pushax #(_sp_payload + 2) ; push destination for memcpy
pushax tmp_tz_ptr ; push src for memcpy AND set A/X for strlen - doubling down!

jsr _strlen

; increment for the null terminator of the string
clc
adc #$01
bcc :+
inx

; store the length for sp_control call, and A/X is correctly set for memcpy
: sta _sp_payload + 0
stx _sp_payload + 1
jsr _memcpy

; destination was stored on s/w stack already
; src/dst were both stored on s/w stack already
lda #'T' ; set 'T'imezone
jsr _sp_control

; convert to fujinet error
; convert to fujinet ok/error code
jmp _fn_error


.bss
tmp_tz_ptr: .res 2
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
21 changes: 21 additions & 0 deletions apple2/apple2gs/fn_clock/clock_get_time.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include <stdint.h>
#include <string.h>

#include "fujinet-clock.h"
#include "fujinet-bus-apple2.h"

// these correspond to the enum TimeFormat
const char format_cmds[] = { 'T', 'P', 'A', 'B', 'S', 'Z' };

uint8_t clock_get_time(uint8_t* tz, TimeFormat format) {
uint8_t result;

sp_get_clock_id();
if (sp_clock_id == 0) return FN_ERR_IO_ERROR;

result = sp_status(sp_clock_id, 'G');
if (result == 0) return FN_ERR_IO_ERROR;

memcpy(tz, sp_payload, sp_count);
return FN_ERR_OK;
}
18 changes: 18 additions & 0 deletions apple2/apple2gs/fn_clock/clock_get_tz.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <stdint.h>
#include <string.h>

#include "fujinet-clock.h"
#include "fujinet-bus-apple2.h"

uint8_t clock_get_tz(uint8_t *tz) {
uint8_t result;

sp_get_clock_id();
if (sp_clock_id == 0) return FN_ERR_IO_ERROR;

result = sp_status(sp_clock_id, 'G');
if (result == 0) return FN_ERR_IO_ERROR;

memcpy(tz, sp_payload, sp_count);
return FN_ERR_OK;
}
22 changes: 22 additions & 0 deletions apple2/apple2gs/fn_clock/clock_set_tz.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <stdint.h>
#include <string.h>

#include "fujinet-clock.h"
#include "fujinet-bus-apple2.h"

uint8_t clock_set_tz(char *tz) {
uint16_t len;
int8_t result;

sp_get_clock_id();
if (sp_clock_id == 0) return FN_ERR_IO_ERROR;

len = strlen(tz) + 1;

sp_payload[0] = len & 0xFF;
sp_payload[1] = len >> 8;
memcpy(&sp_payload[2], tz, len);

result = sp_control(sp_clock_id, 'T');
return fn_error(result);
}
3 changes: 3 additions & 0 deletions apple2/src/bus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# bus

Only common C files for all apple2 platforms should go in here.
3 changes: 3 additions & 0 deletions apple2/src/fn_clock/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# fn_clock

Only common C files for all apple2 platforms should go in here.
4 changes: 2 additions & 2 deletions commodore/src/fn_fuji/get_fuji_status.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "fujinet-fuji-cbm.h"

// Use 0x, and NOT string literals to avoid CC65 charmap translations. These are bytes not chars.
uint8_t status_cmd[2] = { 0x01, 0x53 };
uint8_t fuji_status_cmd[2] = { 0x01, 0x53 };

// An internal version of fuji_status called at the end of the open_ commands
// which uses the currently open connection to write the status command to.
Expand All @@ -19,7 +19,7 @@ bool get_fuji_status(bool should_close)
memset(&_fuji_status.raw[0], 0, sizeof(FNStatus));

// do a status call to find out if anything went wrong. Using the current open channel, so just write our bytes
bytes_written = cbm_write(CBM_CMD_CHANNEL, status_cmd, 2);
bytes_written = cbm_write(CBM_CMD_CHANNEL, fuji_status_cmd, 2);
if (bytes_written != 2) {
// always close on an error
cbm_close(CBM_CMD_CHANNEL);
Expand Down
8 changes: 4 additions & 4 deletions commodore/src/fn_network/network_status.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
#include "fujinet-network.h"
#include "fujinet-network-cbm.h"

uint8_t *status_cmd = "statusb,N";
uint8_t *nw_status_cmd = "statusb,N";

// we only really need the device id, not the full devicespec in all network_status calls.
uint8_t network_status(char *devicespec, uint16_t *bw, uint8_t *c, uint8_t *err)
{
// if we do a read on the status_cmd channel, we get the status for the specified devicespec, but we have to tell FN which device we want the status for first
// if we do a read on the nw_status_cmd channel, we get the status for the specified devicespec, but we have to tell FN which device we want the status for first
const char *after;
uint8_t status[4];
uint16_t temp_bw = 0;
Expand All @@ -18,9 +18,9 @@ uint8_t network_status(char *devicespec, uint16_t *bw, uint8_t *c, uint8_t *err)

// a "binary status" command, requires up to date firmware
uint8_t data_channel = getDeviceNumber(devicespec, &after) + CBM_DATA_CHANNEL_0;
status_cmd[8] = data_channel + '0'; // overwrite with network device id
nw_status_cmd[8] = data_channel + '0'; // overwrite with network device id

if (cbm_write(CBM_CMD_CHANNEL, status_cmd, 9) != 9) {
if (cbm_write(CBM_CMD_CHANNEL, nw_status_cmd, 9) != 9) {
return FN_ERR_IO_ERROR;
}

Expand Down
96 changes: 68 additions & 28 deletions makefiles/build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ ASMEXT = .s
-include ./makefiles/os.mk
-include ./makefiles/compiler.mk

# CC := cl65

SRCDIR := src
BUILD_DIR := build
OBJDIR := obj
Expand All @@ -27,23 +25,62 @@ PLATFORM_SRC_DIR := $(CURRENT_PLATFORM)/$(SRCDIR)

PROGRAM_TGT := $(PROGRAM).$(CURRENT_TARGET)

SOURCES := $(call rwildcard,$(PLATFORM_SRC_DIR),*.c)
SOURCES += $(call rwildcard,$(PLATFORM_SRC_DIR),*.c)
SOURCES += $(call rwildcard,$(PLATFORM_SRC_DIR),*$(ASMEXT))
SOURCES += $(call rwildcard,common/$(SRCDIR)/,*$(ASMEXT))
SOURCES += $(call rwildcard,common/$(SRCDIR)/,*.c)
SOURCES += $(call rwildcard,common/$(SRCDIR)/,*$(ASMEXT))

# remove trailing and leading spaces.
SOURCES := $(strip $(SOURCES))
################################################
# PLATFORM SPECIFIC PATHS/SOURCES

define ADD_SOURCES
SOURCES += $(call rwildcard,$(CURRENT_PLATFORM)/$(1),*.c)
SOURCES += $(call rwildcard,$(CURRENT_PLATFORM)/$(1),*$(ASMEXT))
endef

define ADD_SRC_INC_DIRS
SRC_INC_DIRS += $(sort $(dir $(wildcard $(CURRENT_PLATFORM)/$(1)/*)))
endef

$(foreach path,$(PLATFORM_SPECIFIC_PATHS),$(eval $(call ADD_SOURCES,$(path))))
$(foreach path,$(PLATFORM_SPECIFIC_PATHS),$(eval $(call ADD_SRC_INC_DIRS,$(path))))

################################################
# GENERATE OBJECT LIST FROM ALL SOURCES

# convert from src/your/long/path/foo.[c|s] to obj/<target>/your/long/path/foo.o
# we need the target because compiling for previous target does not pick up potential macro changes
OBJ1 := $(SOURCES:.c=$(OBJEXT))
OBJECTS := $(OBJ1:$(ASMEXT)=$(OBJEXT))
OBJECTS_ORCA := $(OBJECTS) $(patsubst %.c,%.a,$(filter %.c,$(SOURCES)))

# this needs to undergo all substitutions too, this is the list of files that will be added to the archive (library)
OBJECTS_ARC := $(OBJECTS)

# add any additional archive objects before doing all the substitutions
-include ./makefiles/objects-$(CURRENT_TARGET).mk

OBJECTS := $(OBJECTS:$(PLATFORM_SRC_DIR)/%=$(OBJDIR)/$(CURRENT_TARGET)/%)
OBJECTS := $(OBJECTS:common/$(SRCDIR)/%=$(OBJDIR)/$(CURRENT_TARGET)/common/%)
OBJECTS_ORCA := $(OBJECTS_ORCA:$(PLATFORM_SRC_DIR)/%=$(OBJDIR)/$(CURRENT_TARGET)/%)
OBJECTS_ORCA := $(OBJECTS_ORCA:common/$(SRCDIR)/%=$(OBJDIR)/$(CURRENT_TARGET)/common/%)

OBJECTS_ARC := $(OBJECTS_ARC:$(PLATFORM_SRC_DIR)/%=$(OBJDIR)/$(CURRENT_TARGET)/%)
OBJECTS_ARC := $(OBJECTS_ARC:common/$(SRCDIR)/%=$(OBJDIR)/$(CURRENT_TARGET)/common/%)

################################################
# PLATFORM SPECIFIC OBJECTS

define SUBSTITUTE_OBJECTS
$($(1):$(CURRENT_PLATFORM)/$(2)/%=$(OBJDIR)/$(CURRENT_TARGET)/%)
endef

$(foreach path,$(PLATFORM_SPECIFIC_PATHS),$(eval OBJECTS := $(call SUBSTITUTE_OBJECTS,OBJECTS,$(path))))
$(foreach path,$(PLATFORM_SPECIFIC_PATHS),$(eval OBJECTS_ARC := $(call SUBSTITUTE_OBJECTS,OBJECTS_ARC,$(path))))

# remove trailing and leading spaces.
SOURCES := $(strip $(SOURCES))
OBJECTS := $(strip $(OBJECTS))
OBJECTS_ARC := $(strip $(OBJECTS_ARC))

# ensure the paths are unique
# SRC_INC_DIRS := $(sort $(filter-out %/, $(SRC_INC_DIRS)))

# Ensure make recompiles parts it needs to if src files change
DEPENDS := $(OBJECTS:$(OBJEXT)=.d)
Expand Down Expand Up @@ -75,6 +112,7 @@ CHANGELOG = Changelog.md

# allow for additional flags etc
-include ./makefiles/common.mk
# global PLATFORM custom settings
-include ./makefiles/custom-$(CURRENT_PLATFORM).mk

# allow for application specific config
Expand All @@ -87,18 +125,6 @@ all: $(ALL_TASKS) $(PROGRAM_TGT)

-include $(DEPENDS)

ifeq ($(BUILD_DIR),)
BUILD_DIR := build
endif

ifeq ($(OBJDIR),)
OBJDIR := obj
endif

ifeq ($(DIST_DIR),)
DIST_DIR := dist
endif

$(OBJDIR):
$(call MKDIR,$@)

Expand All @@ -111,12 +137,18 @@ $(BUILD_DIR):
$(DIST_DIR):
$(call MKDIR,$@)

SRC_INC_DIRS := \
# Add the default paths for the PLATFORM and common
SRC_INC_DIRS += \
$(sort $(dir $(wildcard $(PLATFORM_SRC_DIR)/*))) \
$(sort $(dir $(wildcard common/$(SRCDIR)/*)))


vpath %.c $(SRC_INC_DIRS)
vpath %$(ASMEXT) $(SRC_INC_DIRS)

# $(info SOURCES: $(SOURCES))
# $(info OBJECTS: $(OBJECTS))
# $(info OBJECTS_ARC: $(OBJECTS_ARC))
# $(info SRC_INC_DIRS: $(SRC_INC_DIRS))

$(OBJDIR)/$(CURRENT_TARGET)/common/%$(OBJEXT): %.c | $(TARGETOBJDIR)
@$(call MKDIR,$(dir $@))
Expand All @@ -138,8 +170,6 @@ else
$(CC) -c --deps $(CFLAGS) -o $@ $<
endif

vpath %$(ASMEXT) $(SRC_INC_DIRS)

## For now, no asm in common dirs... as it would be compiler specific
# $(OBJDIR)/$(CURRENT_TARGET)/common/%$(OBJEXT): %$(ASMEXT) | $(TARGETOBJDIR)
# @$(call MKDIR,$(dir $@))
Expand All @@ -160,9 +190,19 @@ endif

$(BUILD_DIR)/$(PROGRAM_TGT): $(OBJECTS) | $(BUILD_DIR)
ifeq ($(CC),cl65)
$(AR) a $@ $(OBJECTS)
$(AR) a $@ $(OBJECTS_ARC)
else ifeq ($(CC),iix compile)
$(AR) $@ $(addprefix +,$(OBJECTS_ORCA))

ifeq ($(detected_OS),$(filter $(detected_OS),MSYS MINGW))
rm -rf $(OBJDIR)/flat; \
FILE_LIST=$$(scripts/fix-makelib-path.sh $(OBJDIR)/$(CURRENT_TARGET) $(OBJDIR)/flat); \
cd $(OBJDIR)/flat; \
for f in $$(echo "$${FILE_LIST}" | tr ' ' '\n'); do $(AR) $(PROGRAM_TGT) $${f}; done; \
mv $(PROGRAM_TGT) ../../$(BUILD_DIR)/
else
$(AR) $@ $(addprefix +,$(OBJECTS_ARC))
endif

else
$(AR) $@ -a $(OBJECTS)
endif
Expand Down
4 changes: 4 additions & 0 deletions makefiles/objects-apple2gs.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# target (not platform) changes to OBJECTS/OBJECTS_ARC list

# this adds all the c files as a files to the archive, as the compiler creates .root and .a files for them.
OBJECTS_ARC += $(patsubst %.c,%.a,$(filter %.c,$(SOURCES)))
11 changes: 11 additions & 0 deletions makefiles/os.mk
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ CURRENT_PLATFORM_coco := coco

CURRENT_PLATFORM = $(CURRENT_PLATFORM_$(CURRENT_TARGET))

# platform specific src paths (PSP)
# These allow us to add additional directories (each entry can have space separated list) to a TARGET
# Used for apple2/enh vs apple2gs, but other platforms if they had different compiled code could use it.

PSP_apple2 := apple2-6502
PSP_apple2enh := apple2-6502
PSP_apple2gs := apple2gs

PLATFORM_SPECIFIC_PATHS := $(PSP_$(CURRENT_TARGET))


ifeq '$(findstring ;,$(PATH))' ';'
detected_OS := Windows
else
Expand Down
42 changes: 42 additions & 0 deletions scripts/fix-makelib-path.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

if [ $# -ne 2 ]; then
echo "Usage: $(basename $0) SOURCE_DIR DESTINATION_DIR"
echo " This script flattens every file in any directory under SOURCE_DIR into DESTINATION_DIR and then applies 0xb1 filetype for orca makefile"
echo " It will fail if the SOURCE_DIR does not exist"
exit 1
fi

SOURCE_DIR=$1
DEST_DIR=$2

if [ ! -d "${SOURCE_DIR}" ]; then
echo "ERROR: SOURCE_DIR '${SOURCE_DIR}' does not exist."
exit 1
fi

# Create destination directory if it does not exist
if [ ! -d "$DEST_DIR" ]; then
mkdir -p "$DEST_DIR"
fi

TEMP_ZIP=$(mktemp -u --tmpdir source_archive_XXXXX.zip)

# Ensure the temporary file is removed on script exit or interruption
trap 'rm -f "$TEMP_ZIP"' EXIT

# Create a zip file of the entire source directory (including subdirectories)
zip -r "$TEMP_ZIP" "$SOURCE_DIR"/* >/dev/null 2>&1

# Check if destination directory exists, if not create it
if [ ! -d "$DEST_DIR" ]; then
mkdir -p "$DEST_DIR"
fi

# Extract the zip file without preserving the directory structure
unzip -j "$TEMP_ZIP" -d "$DEST_DIR" > /dev/null 2>&1

cd $DEST_DIR
find . -type f -exec iix chtyp -t 0xb1 {} \;
FILE_LIST=$(find . -type f -exec basename {} \; | xargs -I {} echo -n "+{} " | sed 's/ $$//')
echo ${FILE_LIST}
2 changes: 1 addition & 1 deletion version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.7.0
4.7.1

0 comments on commit 52a2001

Please sign in to comment.