From 332f067b2e60559953637bdce552a0e68434ba77 Mon Sep 17 00:00:00 2001 From: Bill Chatfield Date: Mon, 12 Nov 2018 21:27:27 -0500 Subject: [PATCH] Reorg --- Makefile | 32 +++++++++++++++++++-- copy.c | 53 ++++++++++++++++++---------------- cui.c | 38 +++++++++++++++++-------- cui.h | 3 +- fileinfo.c | 27 ------------------ fileinfo.h | 18 ------------ libgen.c | 23 +++++++++++++++ libgen.h | 9 ++++++ libgentest | Bin 0 -> 3433 bytes libgentest.c | 20 +++++++++++++ prodos.h | 33 ++++++++++++++++++---- prodos.s | 39 +++++++++++++++++--------- prodosext.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ prodosext.h | 10 +++++++ 14 files changed, 280 insertions(+), 103 deletions(-) delete mode 100644 fileinfo.c delete mode 100644 fileinfo.h create mode 100644 libgen.c create mode 100644 libgen.h create mode 100644 libgentest create mode 100644 libgentest.c create mode 100644 prodosext.c create mode 100644 prodosext.h diff --git a/Makefile b/Makefile index 96c529b..f3e8c7f 100644 --- a/Makefile +++ b/Makefile @@ -8,10 +8,28 @@ ifndef CC65_TARGET CC65_TARGET:=apple2enh endif +ifeq ($(OS),Windows_NT) + ifndef MERLIN_DIR + MERLIN_DIR=C:/opt/Merlin32_v1.0 + endif + MERLIN_LIB=$(MERLIN_DIR)/Library + MERLIN=$(MERLIN_DIR)/Windows/Merlin32 + COPY=copy + APPLEWIN="c:\opt\AppleWin1.26.2.3\applewin.exe" +else + ifndef MERLIN_DIR + MERLIN_DIR=$(HOME)/opt/Merlin32_v1.0 + endif + MERLIN_LIB=$(MERLIN_DIR)/Library + MERLIN=$(MERLIN_DIR)/Linux64/Merlin32 + COPY=cp + APPLEWIN=applewin +endif + CC=cl65 AS=ca65 -OBJS=copy.o cui.o fileinfo.o prodos.o -HDRS=fileinfo.h cui.h prodos.h +OBJS=copy.o cui.o prodos.o prodosext.o libgen.o +HDRS=cui.h prodos.h prodosext.h libgen.h CFLAGS=-O -t $(CC65_TARGET) -DTRACE # The -S $6000 makes the start address $6000 so that both hi-res # pages are available. @@ -31,14 +49,22 @@ BIN_LOAD_ADDR=0x0803 all: $(DISK) -$(DISK): $(PGM) +$(DISK): $(PGM) libgentest $(RM) $(DISK) $(AC) -pro140 $(DISK) $(DISK_VOL) $(AC) -as $(DISK) $(PGM) BIN < $(PGM) + $(AC) -as $(DISK) libgentest BIN < libgentest $(PGM): $(OBJS) $(CC) $(LDFLAGS) -o $@ $^ +libgentest: libgen.o libgentest.o + $(CC) $(LDFLAGS) -o $@ $^ + +test: $(DISK) + $(APPLEWIN) -d1 $(DISK) + #$(APPLEWIN) -s7 empty -d1 $(DISK) + clean: $(RM) *.o $(PGM) $(DISK) diff --git a/copy.c b/copy.c index 2462025..4214e04 100644 --- a/copy.c +++ b/copy.c @@ -1,54 +1,59 @@ #include /* fopen, fread, fwrite, fclose */ #include #include /* atexit */ +#include +#include "libgen.h" /* basename */ -#include "fileinfo.h" #include "prodos.h" +#include "prodosext.h" #include "cui.h" -#define BUFFER_SIZE 2048 +#define BF_SIZ 2048 void cleanup(void); FILE *openFile(const char *name, const char *mode); void closeFile(FILE *f, const char *name); void concatPath(char *dest, const char *src); -char sourceName[PRODOS_PATH_MAX + 1]; +char srcName[PRODOS_PATH_MAX + 1]; char destName[PRODOS_PATH_MAX + 1]; -FILE *sourceFile = NULL; -FILE *destFile = NULL; -struct FileInfo sourceInfo; -struct FileInfo destInfo; +FILE *src = NULL; +FILE *dest = NULL; +struct GetFileInfoParams srcInfo; +struct GetFileInfoParams destInfo; size_t n; -char buffer[BUFFER_SIZE]; +char buf[BF_SIZ]; size_t bytesRead; void main(void) { atexit(cleanup); - inputFileName("Source file or directory:", sourceName, sizeof(sourceName), &sourceInfo); - inputFileName("Destination file or directory:", destName, sizeof(destName), &destInfo); + if (! inputFileName("Source file or directory:", srcName, + sizeof(srcName), &srcInfo)) + return; - sourceFile = openFile(sourceName, "r"); + if (! inputFileName("Destination file or directory:", destName, + sizeof(destName), &destInfo)) + return; - if (isDir(&destInfo)) { - concatPath(destName, basename(sourceName)); - } + src = openFile(srcName, "r"); - destFile = openFile(destName, "w"); + if (isDirectory(&destInfo)) + concatPath(destName, basename(srcName)); - while ((bytesRead = fread(buffer, 1, sizeof(buffer), sourceFile)) == BUFFER_SIZE) { - if (fwrite(buffer, 1, bytesRead, destFile) < bytesRead) { + dest = openFile(destName, "w"); + + while ((bytesRead = fread(buf, 1, sizeof(buf), src)) == BF_SIZ) + if (fwrite(buf, 1, bytesRead, dest) < bytesRead) { perror(destName); break; } - } - if (bytesRead > 0 && !feof(destFile) && !ferror(destFile)) { - if (fwrite(buffer, 1, bytesRead, destFile) < bytesRead) { + + if (bytesRead > 0 && !feof(dest) && !ferror(dest)) + if (fwrite(buf, 1, bytesRead, dest) < bytesRead) perror(destName); - } - } + cleanup(); } @@ -83,7 +88,7 @@ void concatPath(char *dest, const char *src) void cleanup(void) { - closeFile(destFile, destName); - closeFile(sourceFile, sourceName); + closeFile(dest, destName); + closeFile(src, srcName); } diff --git a/cui.c b/cui.c index 516cf44..be36dd1 100644 --- a/cui.c +++ b/cui.c @@ -3,27 +3,44 @@ #include /* strlen */ #include "cui.h" -#include "fileinfo.h" +#include "prodos.h" +#include "prodosext.h" + +#define ESC '\x1b' static char *readLine(char *line, size_t capacity); static void chomp(char *line); static bool complete; +static uint8_t result; -void inputFileName(const char *prompt, char *name, size_t capacity, struct FileInfo *f) +bool inputFileName(const char *prompt, char *name, + size_t capacity, + struct GetFileInfoParams *params) { complete = false; while (! complete) { printf(prompt); readLine(name, capacity); - initFileInfo(f, name); - if (exists(f)) { + if (strlen(name) == 0) { + puts("Aborting"); + break; + } + else if (name[0] == ESC) { + puts("Escaping"); + break; + } + params->param_count = GET_FILE_INFO_PARAM_COUNT; + params->pathname = name; + printf("params address = %x\n", &(params->param_count)); + printf("params address = %x\n", params); + result = get_file_info(params); + if (result == PRODOS_E_NONE) complete = true; - } - else { - fprintf(stderr, "File '%s' does not exist\n", name); - } + else + fprintf(stderr, "%s: %s (code %d)\n", name, getMessage(result), result); } + return complete; } char *readLine(char *line, size_t capacity) @@ -32,9 +49,8 @@ char *readLine(char *line, size_t capacity) if ((result = fgets(line, capacity, stdin)) != NULL) chomp(line); - else - if (ferror(stdin)) - perror("stdin"); + else if (ferror(stdin)) + perror("stdin"); return result; } diff --git a/cui.h b/cui.h index bce173b..1c797ac 100644 --- a/cui.h +++ b/cui.h @@ -1,7 +1,8 @@ #ifndef CUI_H #define CUI_H -extern void inputFileName(const char *prompt, char *name, size_t capacity, struct FileInfo *f); +extern bool inputFileName(const char *prompt, char *name, size_t capacity, + struct GetFileInfoParams *params); #endif diff --git a/fileinfo.c b/fileinfo.c deleted file mode 100644 index da2a319..0000000 --- a/fileinfo.c +++ /dev/null @@ -1,27 +0,0 @@ -#include /* PRODOS_T_DIR */ -#include "fileinfo.h" -#include "prodos.h" - -static struct GetFileInfoParams *infoParams; - -void initFileInfo(struct FileInfo *f, const char *name) -{ - infoParams = &(f->infoParams); - infoParams->param_count = GET_FILE_INFO_PARAM_COUNT; - infoParams->pathname = name; - f->getFileInfoResult = get_file_info(infoParams); -} - -bool isDir(struct FileInfo *f) -{ - return f->infoParams.file_type == PRODOS_T_DIR; -} - -bool exists(struct FileInfo *f) -{ - if (f->getFileInfoResult == 0) - return true; - else - return false; -} - diff --git a/fileinfo.h b/fileinfo.h deleted file mode 100644 index 0db63d7..0000000 --- a/fileinfo.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef MY_FILE_H -#define MY_FILE_H - -#include -#include "prodos.h" - -struct FileInfo -{ - struct GetFileInfoParams infoParams; - uint8_t getFileInfoResult; -}; - -extern void initFileInfo(struct FileInfo *f, const char *name); -extern bool isDir(struct FileInfo *f); -extern bool exists(struct FileInfo *f); - -#endif - diff --git a/libgen.c b/libgen.c new file mode 100644 index 0000000..012b7ea --- /dev/null +++ b/libgen.c @@ -0,0 +1,23 @@ +#include + +char *basename(char *path) +{ + char *ptr; + + /* If path is NULL or the empty string, return "." */ + if (path == NULL || path[0] == '\0') + return "."; + + /* If path is "/", return "/" */ + if (path[0] == '/' && path[1] == '\0') + return path; + + /* If path does not contain a '/' then return path */ + if ((ptr = strrchr(path, '/')) == NULL) + return path; + + /* Path contains a slash so return the string following the last + slash. */ + return ++ptr; +} + diff --git a/libgen.h b/libgen.h new file mode 100644 index 0000000..81e49a9 --- /dev/null +++ b/libgen.h @@ -0,0 +1,9 @@ +#ifndef GUNGWALDS_LIBGEN_H +#define GUNGWALDS_LIBGEN_H + +/* Conforms to POSIX but does not modify path. A pointer into path + or a constant string value is returned. So don't attempt to + modify the return value. */ +char *basename(char *path); + +#endif diff --git a/libgentest b/libgentest new file mode 100644 index 0000000000000000000000000000000000000000..ba4edd650171eed5ff5c6ba6dcc9afa8ce4c783b GIT binary patch literal 3433 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 literal 0 HcmV?d00001 diff --git a/libgentest.c b/libgentest.c new file mode 100644 index 0000000..fbdb9f0 --- /dev/null +++ b/libgentest.c @@ -0,0 +1,20 @@ +#include +#include +#include "libgen.h" + +void assertStringEquals(char *s, char *t, char *name) +{ + if (strcmp(s, t) == 0) + printf("Success - %s\n", name); + else + printf("FAILURE - %s\n", name); +} + +void main(void) +{ + assertStringEquals(basename(NULL), ".", "NULL"); + assertStringEquals(basename(""), ".", "Empty"); + assertStringEquals(basename("/"), "/", "Slash"); + assertStringEquals(basename("/blah/"),"","Trailing slash"); + assertStringEquals(basename("/blah"), "blah", "Blah"); +} diff --git a/prodos.h b/prodos.h index 5f84bb9..93d8e30 100644 --- a/prodos.h +++ b/prodos.h @@ -4,20 +4,41 @@ #include /* PATH_MAX POSIX constant - ProDOS has a 64 char prefix that can be combined with partial - pathname of 64 characters. This is a total of 128 characters. */ + ProDOS has a 64 char prefix that can be combined + with partial pathname of 64 characters. This is + a total of 128 characters. */ #define PRODOS_PATH_MAX 128 - #define PRODOS_FILE_NAME_MAX 15 +#define PRODOS_E_NONE 0x00 +#define PRODOS_E_BAD_SYS_CALL_NUM 0x01 +#define PRODOS_E_BAD_SYS_PARAM_COUNT 0x04 +#define PRODOS_E_INTERRUPT_VECTOR_TABLE_FULL 0x25 #define PRODOS_E_IO_ERROR 0x27 +#define PRODOS_E_NO_DEVICE 0x28 +#define PRODOS_E_DISK_WRITE_PROTECTED 0x2b +#define PRODOS_E_DISK_SWITCHED 0x2e #define PRODOS_E_INVALID_PATH_SYNTAX 0x40 +#define PRODOS_E_FILE_CTRL_BLK_TABLE_FULL 0x42 +#define PRODOS_E_INVALID_REF_NUM 0x43 #define PRODOS_E_PATH_NOT_FOUND 0x44 #define PRODOS_E_VOLUME_DIR_NOT_FOUND 0x45 #define PRODOS_E_FILE_NOT_FOUND 0x46 -#define PRODOS_E_INCOMPAT_FILE_FORMAT 0x4A -#define PRODOS_E_UNSUP_STORAGE_TYPE 0x4B -#define PRODOS_E_INVALID_VALUE_IN_PARAM 0x53 +#define PRODOS_E_DUPLICATE_FILE_NAME 0x47 +#define PRODOS_E_OVERRUN_ERROR 0x48 +#define PRODOS_E_VOLUME_DIR_FULL 0x49 +#define PRODOS_E_INCOMPATIBLE_FILE_FORMAT 0x4A +#define PRODOS_E_UNSUPPORTED_STORAGE_TYPE 0x4B +#define PRODOS_E_END_OF_FILE 0x4C +#define PRODOS_E_POSITION_OUT_OF_RANGE 0x4D +#define PRODOS_E_ACCESS_ERROR 0x4E +#define PRODOS_E_FILE_IS_OPEN 0x50 +#define PRODOS_E_DIR_COUNT_ERROR 0x51 +#define PRODOS_E_NOT_PRODOS_DISK 0x52 +#define PRODOS_E_INVALID_PARAM 0x53 +#define PRODOS_E_VOLUME_CTRL_BLK_TABLE_FULL 0x55 +#define PRODOS_E_BAD_BUFFER_ADDR 0x56 +#define PRODOS_E_DUPLICATE_VOLUME 0x57 #define PRODOS_E_BITMAP_ADDR_IMPOSSIBLE 0x5A #define GET_FILE_INFO_PARAM_COUNT 0x0a diff --git a/prodos.s b/prodos.s index 55d156f..8a62d17 100644 --- a/prodos.s +++ b/prodos.s @@ -1,33 +1,46 @@ .export _get_file_info - MLI = $bf00 GET_FILE_INFO = $c4 +COUT = $FDED ;SUB TO OUTPUT A CHARACTER +PRBYTE = $FDDA ;SUB TO PRINT A BYTE +CROUT = $FD8E ;SUB TO OUTPUT CARRIAGE RETURN - - .bss - -_file_info_addr: .word $00 - - - - .code +.code ; This function is defined as "fastcall" which puts the right-most ; parameter into A/X and the return value in A/X. -_get_file_info: - sta _file_info_addr - stx _file_info_addr+1 +.proc _get_file_info + + sta params + stx params+1 + + ; Switch in ROM + bit $c082 + + lda params + jsr PRBYTE + jsr CROUT + + lda params+1 + jsr PRBYTE + jsr CROUT jsr MLI .byte GET_FILE_INFO - .word _file_info_addr +params: .word 0 ; The system call leaves the error status in the Accumulator. ; The "fastcall" calling convention returns the A register, ; which is what we want. rts +.endproc + + +.bss + +file_info_addr: .res 2 diff --git a/prodosext.c b/prodosext.c new file mode 100644 index 0000000..00e2a0f --- /dev/null +++ b/prodosext.c @@ -0,0 +1,78 @@ +#include +#include +#include "prodos.h" +#include "prodosext.h" + +bool isDirectory(struct GetFileInfoParams *params) +{ + return params->file_type == PRODOS_T_DIR; +} + +const char *getMessage(uint8_t errorCode) +{ + switch (errorCode) { + case PRODOS_E_NONE: + return "No error"; + case PRODOS_E_BAD_SYS_CALL_NUM: + return "Bad system call number"; + case PRODOS_E_BAD_SYS_PARAM_COUNT: + return "Bad system call parameter count"; + case PRODOS_E_INTERRUPT_VECTOR_TABLE_FULL: + return "Interrupt vector table full"; + case PRODOS_E_IO_ERROR: + return "I/O error"; + case PRODOS_E_NO_DEVICE: + return "No device detected/connected"; + case PRODOS_E_DISK_WRITE_PROTECTED: + return "Disk is write protected"; + case PRODOS_E_DISK_SWITCHED: + return "Disk switched"; + case PRODOS_E_INVALID_PATH_SYNTAX: + return "Invalid path syntax"; + case PRODOS_E_FILE_CTRL_BLK_TABLE_FULL: + return "File control block table full"; + case PRODOS_E_INVALID_REF_NUM: + return "Invalid reference number"; + case PRODOS_E_PATH_NOT_FOUND: + return "Path not found"; + case PRODOS_E_VOLUME_DIR_NOT_FOUND: + return "Volume directory not found"; + case PRODOS_E_FILE_NOT_FOUND: + return "File not found"; + case PRODOS_E_DUPLICATE_FILE_NAME: + return "Duplicate file name"; + case PRODOS_E_OVERRUN_ERROR: + return "No space left on device"; + case PRODOS_E_VOLUME_DIR_FULL: + return "No entries left in volume directory"; + case PRODOS_E_INCOMPATIBLE_FILE_FORMAT: + return "Incompatible file format"; + case PRODOS_E_UNSUPPORTED_STORAGE_TYPE: + return "Unsupported storage type"; + case PRODOS_E_END_OF_FILE: + return "End of file reached"; + case PRODOS_E_POSITION_OUT_OF_RANGE: + return "File position out of range"; + case PRODOS_E_ACCESS_ERROR: + return "File attribute forbids operation"; + case PRODOS_E_FILE_IS_OPEN: + return "File is open"; + case PRODOS_E_DIR_COUNT_ERROR: + return "Directory header / file entry mismatch"; + case PRODOS_E_NOT_PRODOS_DISK: + "Not a ProDOS disk"; + case PRODOS_E_INVALID_PARAM: + return "Invalid value in parameter"; + case PRODOS_E_VOLUME_CTRL_BLK_TABLE_FULL: + return "Volume control block table full"; + case PRODOS_E_BAD_BUFFER_ADDR: + return "Bad buffer address"; + case PRODOS_E_DUPLICATE_VOLUME: + return "Duplicate volume"; + case PRODOS_E_BITMAP_ADDR_IMPOSSIBLE: + return "Bitmap address impossible"; + default: + return "Unknown error"; + } +} + diff --git a/prodosext.h b/prodosext.h new file mode 100644 index 0000000..b877053 --- /dev/null +++ b/prodosext.h @@ -0,0 +1,10 @@ +#ifndef PRODOSEXT_H +#define PRODOSEXT_H + +#include +#include + +extern bool isDirectory(struct GetFileInfoParams *params); +extern const char *getMessage(uint8_t errorCode); + +#endif