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/
|
# Builds copy command
|
||||||
#
|
|
||||||
ifeq ($(OS),Windows_NT)
|
# Requirements:
|
||||||
MERLIN_DIR=C:/opt/Merlin32_v1.0
|
# 1. Gmake must be used.
|
||||||
MERLIN_LIB=$(MERLIN_DIR)/Library
|
# 2. The cc65 compiler must be properly setup.
|
||||||
MERLIN=$(MERLIN_DIR)/Windows/Merlin32
|
|
||||||
RM=del /s
|
ifndef CC65_TARGET
|
||||||
else
|
CC65_TARGET:=apple2enh
|
||||||
MERLIN_DIR=$(HOME)/opt/Merlin32_v1.0
|
|
||||||
MERLIN_LIB=$(MERLIN_DIR)/Library
|
|
||||||
MERLIN=$(MERLIN_DIR)/Linux64/Merlin32
|
|
||||||
RM=rm -f
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
AC=java -jar AppleCommander-ac-1.4.0.jar
|
CC=cl65
|
||||||
SRC=copy.s
|
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
|
PGM=copy
|
||||||
VOL=$(PGM)
|
DISK_VOL=$(PGM)
|
||||||
DSK=$(PGM).dsk
|
DISK=$(PGM).dsk
|
||||||
|
AC=java -jar AppleCommander-ac-1.4.0.jar
|
||||||
|
|
||||||
$(DSK): $(PGM)
|
# Extra stuff
|
||||||
$(AC) -pro140 $(DSK) $(VOL)
|
BASIC_AUX_TYPE=0x0801
|
||||||
$(AC) -p $(DSK) $(PGM) SYS < $(PGM)
|
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:
|
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.unitNumber = 0; // All units
|
||||||
arguments.volumes = volumes;
|
arguments.volumes = volumes;
|
||||||
|
|
||||||
|
__asm__(".byte 1");
|
||||||
__asm__("lda #%b", ON_LINE);
|
__asm__("lda #%b", ON_LINE);
|
||||||
__asm__("sta %g", l1);
|
__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