mirror of https://github.com/gungwald/copy.git
Implemented input
This commit is contained in:
parent
9297b9687f
commit
f06be7c8bc
58
Makefile
58
Makefile
|
@ -1,30 +1,44 @@
|
|||
# Compiles with https://www.brutaldeluxe.fr/products/crossdevtools/merlin/
|
||||
#
|
||||
ifeq ($(OS),Windows_NT)
|
||||
MERLIN_DIR=C:/opt/Merlin32_v1.0
|
||||
MERLIN_LIB=$(MERLIN_DIR)/Library
|
||||
MERLIN=$(MERLIN_DIR)/Windows/Merlin32
|
||||
RM=del /s
|
||||
else
|
||||
MERLIN_DIR=$(HOME)/opt/Merlin32_v1.0
|
||||
MERLIN_LIB=$(MERLIN_DIR)/Library
|
||||
MERLIN=$(MERLIN_DIR)/Linux64/Merlin32
|
||||
RM=rm -f
|
||||
# Builds copy command
|
||||
|
||||
# Requirements:
|
||||
# 1. Gmake must be used.
|
||||
# 2. The cc65 compiler must be properly setup.
|
||||
|
||||
ifndef CC65_TARGET
|
||||
CC65_TARGET:=apple2enh
|
||||
endif
|
||||
|
||||
AC=java -jar AppleCommander-ac-1.4.0.jar
|
||||
SRC=copy.s
|
||||
CC=cl65
|
||||
AS=ca65
|
||||
OBJS=copy.o cui.o fileinfo.o prodos.o
|
||||
HDRS=fileinfo.h cui.h prodos.h
|
||||
CFLAGS=-O -t $(CC65_TARGET) -DTRACE
|
||||
# The -S $6000 makes the start address $6000 so that both hi-res
|
||||
# pages are available.
|
||||
LDFLAGS=-t $(CC65_TARGET)
|
||||
PGM=copy
|
||||
VOL=$(PGM)
|
||||
DSK=$(PGM).dsk
|
||||
DISK_VOL=$(PGM)
|
||||
DISK=$(PGM).dsk
|
||||
AC=java -jar AppleCommander-ac-1.4.0.jar
|
||||
|
||||
$(DSK): $(PGM)
|
||||
$(AC) -pro140 $(DSK) $(VOL)
|
||||
$(AC) -p $(DSK) $(PGM) SYS < $(PGM)
|
||||
# Extra stuff
|
||||
BASIC_AUX_TYPE=0x0801
|
||||
READ_TIME_LOAD_ADDR=0x0260
|
||||
SYS_LOAD_ADDR=0x2000
|
||||
BIN_LOAD_ADDR=0x0803
|
||||
|
||||
$(PGM): $(SRC)
|
||||
$(MERLIN) $(MERLIN_LIB) $(SRC)
|
||||
########################################
|
||||
|
||||
all: $(DISK)
|
||||
|
||||
$(DISK): $(PGM)
|
||||
$(RM) $(DISK)
|
||||
$(AC) -pro140 $(DISK) $(DISK_VOL)
|
||||
$(AC) -as $(DISK) $(PGM) BIN < $(PGM)
|
||||
|
||||
$(PGM): $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $@ $^
|
||||
|
||||
clean:
|
||||
$(RM) $(DSK) $(PGM)
|
||||
$(RM) *.o $(PGM) $(DISK)
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "fileinfo.h"
|
||||
#include "prodos.h"
|
||||
#include "cui.h"
|
||||
|
||||
char sourceName[PRODOS_PATH_MAX + 1];
|
||||
char destName[PRODOS_PATH_MAX + 1];
|
||||
FILE *sourceFile;
|
||||
FILE *destFile;
|
||||
struct FileInfo sourceInfo;
|
||||
struct FileInfo destInfo;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
inputFileName("Source file or directory:", sourceName, sizeof(sourceName), &sourceInfo);
|
||||
inputFileName("Destination file or directory:", destName, sizeof(destName), &destInfo);
|
||||
|
||||
sourceFile = fopen(sourceName, "r");
|
||||
destFile = fopen(destName, "r");
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h> /* strlen */
|
||||
|
||||
#include "cui.h"
|
||||
#include "fileinfo.h"
|
||||
|
||||
static char *readLine(char *line, size_t capacity);
|
||||
static void chomp(char *line);
|
||||
static bool complete;
|
||||
|
||||
void inputFileName(const char *prompt, char *name, size_t capacity, struct FileInfo *f)
|
||||
{
|
||||
complete = false;
|
||||
|
||||
while (! complete) {
|
||||
printf(prompt);
|
||||
readLine(name, capacity);
|
||||
initFileInfo(f, name);
|
||||
if (exists(f)) {
|
||||
complete = true;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "File '%s' does not exist\n", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *readLine(char *line, size_t capacity)
|
||||
{
|
||||
char *result;
|
||||
|
||||
if ((result = fgets(line, capacity, stdin)) != NULL)
|
||||
chomp(line);
|
||||
else
|
||||
if (ferror(stdin))
|
||||
perror("stdin");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void chomp(char *line)
|
||||
{
|
||||
size_t i;
|
||||
char c;
|
||||
|
||||
for (i = strlen(line); i > 0; ) {
|
||||
c = line[--i];
|
||||
if (c == '\r' || c == '\n')
|
||||
line[i] = '\0';
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef CUI_H
|
||||
#define CUI_H
|
||||
|
||||
extern void inputFileName(const char *prompt, char *name, size_t capacity, struct FileInfo *f);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#include <apple2_filetype.h> /* 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef MY_FILE_H
|
||||
#define MY_FILE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#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
|
||||
|
|
@ -22,6 +22,7 @@ void online(void)
|
|||
arguments.unitNumber = 0; // All units
|
||||
arguments.volumes = volumes;
|
||||
|
||||
__asm__(".byte 1");
|
||||
__asm__("lda #%b", ON_LINE);
|
||||
__asm__("sta %g", l1);
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef PRODOS_MLI_H
|
||||
#define PRODOS_MLI_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* 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. */
|
||||
#define PRODOS_PATH_MAX 128
|
||||
|
||||
#define PRODOS_FILE_NAME_MAX 15
|
||||
|
||||
#define PRODOS_E_IO_ERROR 0x27
|
||||
#define PRODOS_E_INVALID_PATH_SYNTAX 0x40
|
||||
#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_BITMAP_ADDR_IMPOSSIBLE 0x5A
|
||||
|
||||
#define GET_FILE_INFO_PARAM_COUNT 0x0a
|
||||
#define ON_LINE_PARAM_COUNT 0x02
|
||||
#define ON_LINE_VOLUME_SIZE 256
|
||||
|
||||
struct GetFileInfoParams
|
||||
{
|
||||
uint8_t param_count; /* in */
|
||||
const char *pathname; /* in */
|
||||
uint8_t access; /* out */
|
||||
uint8_t file_type; /* out */
|
||||
uint16_t aux_type; /* out */
|
||||
uint8_t storage_type; /* out */
|
||||
uint16_t blocks_used; /* out */
|
||||
uint16_t mod_date; /* out */
|
||||
uint16_t mod_time; /* out */
|
||||
uint16_t create_date; /* out */
|
||||
uint16_t create_time; /* out */
|
||||
};
|
||||
|
||||
struct OnLineParams
|
||||
{
|
||||
uint8_t param_count;
|
||||
uint8_t unit_num;
|
||||
char data_buffer[ON_LINE_VOLUME_SIZE];
|
||||
};
|
||||
|
||||
uint8_t on_line(struct OnLineParams *params);
|
||||
uint8_t get_file_info(struct GetFileInfoParams *params);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
.export _get_file_info
|
||||
|
||||
|
||||
|
||||
MLI = $bf00
|
||||
GET_FILE_INFO = $c4
|
||||
|
||||
|
||||
|
||||
.bss
|
||||
|
||||
_file_info_addr: .word $00
|
||||
|
||||
|
||||
|
||||
.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
|
||||
|
||||
jsr MLI
|
||||
.byte GET_FILE_INFO
|
||||
.word _file_info_addr
|
||||
|
||||
; The system call leaves the error status in the Accumulator.
|
||||
; The "fastcall" calling convention returns the A register,
|
||||
; which is what we want.
|
||||
rts
|
||||
|
Loading…
Reference in New Issue