Added online impl

This commit is contained in:
Bill Chatfield 2018-09-25 01:13:19 -04:00
parent a63dc4abee
commit 9297b9687f
18 changed files with 1020 additions and 78 deletions

3
.gitignore vendored
View File

@ -1,3 +1,6 @@
# Vim swap files
*.swp
# Prerequisites
*.d

View File

@ -1,44 +1,30 @@
# Builds copy command
# Requirements:
# 1. Gmake must be used.
# 2. The cc65 compiler must be properly setup.
ifndef CC65_TARGET
CC65_TARGET:=apple2enh
# 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
endif
CC=cl65
CFLAGS=-O -t $(CC65_TARGET) -DTRACE
LDFLAGS=-t $(CC65_TARGET)
PGM=copy
DISK_VOL=$(PGM)
DISK=$(DISK_VOL).dsk
AC=java -jar AppleCommander-ac-1.4.0.jar
SYS_LOAD_ADDR=0x2000
BIN_LOAD_ADDR=0x0803
BASIC_AUX_TYPE=0x0801
READ_TIME_LOAD_ADDR=0x0260
MKDISK=$(AC) -pro140 $(DISK) $(DISK_VOL)
SRC=copy.s
PGM=copy
VOL=$(PGM)
DSK=$(PGM).dsk
########################################
$(DSK): $(PGM)
$(AC) -pro140 $(DSK) $(VOL)
$(AC) -p $(DSK) $(PGM) SYS < $(PGM)
all: $(DISK)
$(DISK): $(PGM)
$(RM) $(DISK)
$(AC) -pro140 $(DISK) $(DISK_VOL)
$(AC) -as $(DISK) $(PGM) BIN < $(PGM)
$(PGM): online.o $(PGM).o
$(CC) $(LDFLAGS) -o $@ $^
$(PGM).o: $(PGM).c
$(CC) $(CFLAGS) $^
online.o: online.c
$(CC) $(CFLAGS) $^
$(PGM): $(SRC)
$(MERLIN) $(MERLIN_LIB) $(SRC)
clean:
$(RM) *.o $(PGM) $(DISK)
$(RM) $(DSK) $(PGM)

42
Makefile.onl Normal file
View File

@ -0,0 +1,42 @@
# Builds online
# Requirements:
# 1. Gmake must be used.
# 2. The cc65 compiler must be properly setup.
ifndef CC65_TARGET
CC65_TARGET:=apple2enh
endif
CC=cl65
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) -u __EXEHDR__ --start-addr 0x6000
PGM=online
DISK_VOL=$(PGM)
DISK=$(DISK_VOL).dsk
BASIC_AUX_TYPE=0x0801
READ_TIME_LOAD_ADDR=0x0260
AC=java -jar AppleCommander-ac-1.4.0.jar
SYS_LOAD_ADDR=0x2000
BIN_LOAD_ADDR=0x0803
########################################
all: $(DISK)
$(DISK): $(PGM)
$(RM) $(DISK)
$(AC) -pro140 $(DISK) $(DISK_VOL)
$(AC) -as $(DISK) $(PGM) BIN < $(PGM)
$(PGM): $(PGM).o
$(CC) $(LDFLAGS) -o $@ $^
$(PGM).o: $(PGM).c
$(CC) $(CFLAGS) $(PGM).c
clean:
$(RM) *.o $(PGM) $(DISK)

170
copy.s Normal file
View File

@ -0,0 +1,170 @@
********************************
* *
* COPY - COPIES FILES *
* *
* AUTHOR: BILL CHATFIELD *
* LICENSE: GPL2 *
* *
********************************
org $2000
dsk copy
typ $ff ;System type
********************************
* *
* CONSTANTS *
* *
********************************
IN equ $0200
RDKEY equ $FD0C ;Reads 1 character
GETLN equ $fd6a
GETLN1 equ $fd6f ;Get line, no prompt
CROUT equ $FD8E ;Output carriage return
COUT equ $FDED ;Output a character
PRBYTE equ $FDDA ;Print error message
BELL equ $FF3A ;Subroutine to beep
PRODOS_MLI equ $bf00 ;Address for MLI subroutine entry point
SET_FILE_INFO equ $c3 ;Code for system call
GET_FILE_INFO equ $c4 ;Code for system call
ON_LINE equ $c5 ;Id for ON_LINE MLI system call
********************************
* *
* puts *
* *
********************************
puts mac
tya ;Preserve y
pha
ldy #0 ;Prepare loop index
]nextchar lda ]1,y ;Load a character
cmp #0 ;Check for end of string
beq finish
jsr COUT
iny
jmp ]nextchar
finish pla ;Restore y
tay
<<<
********************************
* *
* movb - Move byte *
* *
********************************
movb mac
lda ]2
sta ]1
<<<
********************************
* *
* mova - Move addrs *
* *
********************************
mova mac
lda src
sta dest
lda src+1
sta dest+1
<<<
********************************
* *
* Main *
* *
********************************
main
; Read in source file name and store it in srcFile
getSource puts srcPrompt
jsr GETLN1
cpx #64
bpl getSource
stx srcFileLength
ldx #0
srcChar lda IN,x
sta srcFileChars,x
inx
cpx srcFileLength
bmi srcChar
; Set fiParamCount parameter
lda #$a
sta fiParamCount
; Set fiPathName parameter
lda #<srcFile
sta fiPathName
lda #>srcFile
sta fiPathName+1
jsr PRODOS_MLI ;Call MLI subroutine
db GET_FILE_INFO ;Identify the system call
da fileInfo ;Address of system call args
beq cont1 ;Returns 0 on success
jsr handleError
cont1
; Read in destination file name and store it in dstFile
getDest puts dstPrompt
jsr GETLN1
cpx #64
bpl getDest
stx dstFileLength
ldx #0
dstChar lda IN,x
sta dstFileChars,x
inx
cpx dstFileLength
bmi dstChar
rts
********************************
* *
* Data *
* *
********************************
srcPrompt asc "File to copy: ",00
srcFile
srcFileLength db 0 ;Length byte
srcFileChars ds 64 ;Characters of srcFile
dstFile
dstFileLength db 0 ;Length byte
dstFileChars ds 64 ;Characters of dstFile
onlineVols ds 256 ;Space for 16 disk vol records
onlineArgs
olParamCount db 2 ;Parameter count
olUnitNumber db 0 ;Unit number, 0=all
olBufferAddr da onlineVols ;Address of output buffer
fileInfo
fiParamCount db 0
fiPathName da 0
fiAccess db 0
fiFileType db 0
fiAuxType dw 0
fiStorageType db 0
fiBlocksUsed dw 0
fiModDate dw 0
fiModTime dw 0
fiCreateDate dw 0
fiCreateTime dw 0

160
errorhandler.s Normal file
View File

@ -0,0 +1,160 @@
ENOERR equ $00
EBADCALLNUM equ $01
EBADPARMCNT equ $04
EINTRTBLFULL equ $25
EIO equ $27
ENODEV equ $28
EROFS equ $b2
EDISKSWITCHED equ $2e
EINVALIDPATH equ $40
EMAXFILES equ $42
EINVALIDREF equ $43
EDIRNOTFOUND equ $44
EVOLNOTFOUND equ $45
ENOENT equ $46
EDUPFILENAME equ $47
EVOLFULL equ $48
EVOLDIRFULL equ $49
EFILEFORMAT equ $4a
ESTRGTYPE equ $4b
EEOF equ $4c
EOUTOFRANGE equ $4d
EFILELOCKED equ $4e
EFILEISOPEN equ $50
EDAMAGEDDIR equ $51
ENOTPRODOS equ $52
EBADPARAM equ $53
EVCBTBLFULL equ $55
EBADADDR equ $56
EDUPVOL equ $57
EDAMAGEDFILE equ $5a
handleError
sta errorCode
ldx #0
ldy #0
nextCode
lda errorCodes,x
cmp errorCode
beq foundCode
inx
iny
iny
cpy errorCodeCount
bmi nextCode
unknownCode
puts errorLabel
lda errorCode
jsr PRBYTE
jsr CROUT
rts
foundCode
lda errorMessages,y
sta errorMessage
iny
lda errorMessage,y
sta errorMessage+1
puts (errorMessage)
rts
errorCode db 0
errorMessage da 0
errorLabel asc "Error ",00
EMNOERR ASC "No error",00 ;$00
EMBADCALLNUM ASC "Bad system call number",00 ;$01
EMBADPARMCNT ASC "Bad system call parameter count",00 ;$04
EMINTRTBLFULL ASC "Interrupt table full",00 ;$25
EMIO ASC "I/O error",00 ;$27
EMNODEV ASC "No device connected",00 ;$28
EMROFS ASC "Disk write protected",00 ;$b2
EMDISKSWITCHED ASC "Disk switched",00 ;$2e
EMINVALIDPATH ASC "Invalid pathname",00 ;$40
EMMAXFILES ASC "Maximum number of files open",00 ;$42
EMINVALIDREF ASC "Invalid reference number",00 ;$43
EMDIRNOTFOUND ASC "Directory not found",00 ;$44
EMVOLNOTFOUND ASC "Volume not found",00 ;$45
EMNOENT ASC "File not found",00 ;$46
EMDUPFILENAME ASC "Duplicate filename",00 ;$47
EMVOLFULL ASC "Volume full",00 ;$48
EMVOLDIRFULL ASC "Volume directory full",00 ;$49
EMFILEFORMAT ASC "Incompatible file format",00 ;$4a
EMSTRGTYPE ASC "Unsupported storage_type",00 ;$4b
EMEOF ASC "End of file encountered",00 ;$4c
EMOUTOFRANGE ASC "Position out of range",00 ;$4d
EMFILELOCKED ASC "File access error or file locked",00 ;$4e
EMFILEISOPEN ASC "File is open",00 ;$50
EMDAMAGEDDIR ASC "Directory structure damaged",00 ;$51
EMNOTPRODOS ASC "Not a ProDOS volume",00 ;$52
EMBADPARAM ASC "Invalid system call parameter",00 ;$53
EMVCBTBLFULL ASC "Volume Control Block table full",00 ;$55
EMBADADDR ASC "Bad buffer address",00 ;$56
EMDUPVOL ASC "Duplicate volume",00 ;$57
EMDAMAGEDFILE ASC "File structure damaged",00 ;$5a
errorCodes
DB ENOERR
DB EBADCALLNUM
db EBADPARMCNT
db EINTRTBLFULL
db EIO
db ENODEV
db EROFS
db EDISKSWITCHED
db EINVALIDPATH
db EMAXFILES
db EINVALIDREF
db EDIRNOTFOUND
db EVOLNOTFOUND
db ENOENT
db EDUPFILENAME
db EVOLFULL
db EVOLDIRFULL
db EFILEFORMAT
db ESTRGTYPE
db EEOF
db EOUTOFRANGE
db EFILELOCKED
db EFILEISOPEN
db EDAMAGEDDIR
db ENOTPRODOS
db EBADPARAM
db EVCBTBLFULL
db EBADADDR
db EDUPVOL
db EDAMAGEDFILE
errorCodeCount
db errorCodeCount - errorCodes
errorMessages
DA EMNOERR
DA EMBADCALLNUM
da EMBADPARMCNT
da EMINTRTBLFULL
da EMIO
da EMNODEV
da EMROFS
da EMDISKSWITCHED
da EMINVALIDPATH
da EMMAXFILES
da EMINVALIDREF
da EMDIRNOTFOUND
da EMVOLNOTFOUND
da EMNOENT
da EMDUPFILENAME
da EMVOLFULL
da EMVOLDIRFULL
da EMFILEFORMAT
da EMSTRGTYPE
da EMEOF
da EMOUTOFRANGE
da EMFILELOCKED
da EMFILEISOPEN
da EMDAMAGEDDIR
da EMNOTPRODOS
da EMBADPARAM
da EMVCBTBLFULL
da EMBADADDR
da EMDUPVOL
da EMDAMAGEDFILE

52
old/Makefile Normal file
View File

@ -0,0 +1,52 @@
# Builds copy command
# Requirements:
# 1. Gmake must be used.
# 2. The cc65 compiler must be properly setup.
ifndef CC65_TARGET
CC65_TARGET:=apple2enh
endif
CC=cl65
CFLAGS=-O -t $(CC65_TARGET) -DTRACE
LDFLAGS=-t $(CC65_TARGET)
PGM=copy
DISK_VOL=$(PGM)
DISK=$(DISK_VOL).dsk
AC=java -jar AppleCommander-ac-1.4.0.jar
SYS_LOAD_ADDR=0x2000
BIN_LOAD_ADDR=0x0803
BASIC_AUX_TYPE=0x0801
READ_TIME_LOAD_ADDR=0x0260
MKDISK=$(AC) -pro140 $(DISK) $(DISK_VOL)
OBJS=copy.o online.o prodos.o prodos-util.o
SRCS=copy.c online.c prodos-util.c
########################################
all: $(DISK)
$(DISK): $(PGM)
$(RM) $(DISK)
$(AC) -pro140 $(DISK) $(DISK_VOL)
$(AC) -as $(DISK) $(PGM) BIN < $(PGM)
$(PGM): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $^
copy.o: copy.c prodos.h
$(CC) -c $(CFLAGS) $<
online.o: online.c prodos.h
$(CC) -c $(CFLAGS) $<
prodos-util.o: prodos-util.c prodos.h
$(CC) -c $(CFLAGS) $<
prodos.o: prodos.s prodos.h
ca65 -t $(CC65_TARGET) $<
clean:
$(RM) $(OBJS) $(PGM) $(DISK)

114
old/copy-ca65.s Normal file
View File

@ -0,0 +1,114 @@
********************************
* *
* COPY - COPIES FILES *
* *
* AUTHOR: BILL CHATFIELD *
* LICENSE: GPL2 *
* *
********************************
********************************
* *
* CONSTANTS *
* *
********************************
RDKEY EQU $FD0C ;READS 1 CHAR
CROUT EQU $FD8E ;SUB TO OUTPUT CARRIAGE RETURN
COUT EQU $FDED ;SUB TO OUTPUT A CHARACTER
PRBYTE EQU $FDDA ;SUB TO PRINT ERROR MESSAGE
BELL EQU $FF3A ;SUBROUTINE TO BEEP
PRODOS_MLI = $bf00 ;Address for MLI subroutine entry point
SET_FILE_INFO = $c3 ;Code for system call
GET_FILE_INFO = $c4 ;Code for system call
ON_LINE = $c5 ;ID FOR ON_LINE MLI SYSTEM CALL
********************************
* *
* puts *
* *
********************************
.macro puts s
.local nextchar
.local finish
tya ;Preserve y
pha
ldy #0 ;Prepare loop index
nextchar: lda s,y ;Load a character
cmp #0 ;Check for end of string
beq finish
jsr cout
iny
jmp nextchar
finish: pla ;Restore y
tay
.endmacro
.macro movb dest,src
lda src
sta dest
.endmacro
.macro mova dest,src
lda src
sta dest
lda src+1
sta dest+1
.endmacro
.proc handleError
rts
.endproc
********************************
* *
* Main *
* *
********************************
main:
movb fileInfo+FileInfo::paramCount,$a
mova fileInfo+FileInfo::pathName,srcFile
jsr PRODOS_MLI ;Call MLI subroutine
.byte GET_FILE_INFO ;Identify the system call
.addr fileInfo ;Address of system call args
beq cont1 ;Returns 0 on success
jsr handleError
rts
; BSS is Block Started by Symbol for zero-initialized read/write data
; Constructed by loader and zeroed out based on required size
.bss
onlineVols: .res 256 ;SPACE FOR 16 DISK VOL RECORDS
srcFile .byte ;Length byte
.res 64 ;Characters of srcFile
; DATA contains initialized read/write data - encoded into binary
.data
onlineArgs: .byte 2 ;PARAMETER COUNT
.byte 0 ;UNIT NUMBER, 0=ALL
.addr _onlineVols ;ADDRESS OF OUTPUT BUFFER
.struct FileInfo
paramCount .byte
pathName .addr
access .byte
fileType .byte
auxType .word
storageType .byte
blocksUsed .word
modDate .word
modTime .word
createDate .word
createTime .word
.endstruct
fileInfo: .tag FileInfo

63
old/copy.c Normal file
View File

@ -0,0 +1,63 @@
#include <stdio.h> /* FILENAME_MAX */
#include <string.h> /* strerror */
#include <errno.h> /* errno */
#include "prodos.h" /* prodosGetFileInfo, prodosSetFileInfo */
void copy(const char *srcName, const char *dstName);
#define BUFFER_SIZE 2048
char src[FILENAME_MAX];
char dst[FILENAME_MAX];
char buf[BUFFER_SIZE];
struct ProdosFileInfo fileAttributes;
struct ProdosPathName srcPathName;
struct ProdosPathName dstPathName;
void main(void)
{
printf("Source file:");
fgets(src, FILENAME_MAX, stdin);
printf("Destination file:");
fgets(dst, FILENAME_MAX, stdin);
copy(src, dst);
}
void copy(const char *srcName, const char *dstName)
{
FILE *src, *dst;
size_t readCount;
int errorCode;
fileAttributes.paramCount = PRODOS_GET_FILE_INFO_PARAM_COUNT;
fileAttributes.pathName = prodosAssignPathName(&srcPathName, srcName);
errorCode = prodosGetFileInfo(&fileAttributes);
if (errorCode > 0) {
fprintf(stderr, "%s: %s\n", srcName, prodosGetMessage(errorCode));
return;
}
src = fopen(srcName, "r");
dst = fopen(dstName, "w");
while ((readCount = fread(buf,1,BUFFER_SIZE,src)) == BUFFER_SIZE) {
fwrite(buf,1,BUFFER_SIZE,dst);
}
if (feof(src) && readCount > 0) {
fwrite(buf,1,readCount,dst);
} else if (ferror(src)) {
fprintf(stderr, "%s: %s\n", srcName, strerror(errno));
}
fclose(dst);
fclose(src);
fileAttributes.paramCount = PRODOS_SET_FILE_INFO_PARAM_COUNT;
fileAttributes.pathName = prodosAssignPathName(&dstPathName, dstName);
errorCode = prodosSetFileInfo(&fileAttributes);
if (errorCode > 0) {
fprintf(stderr, "%s: %s\n", dstName, prodosGetMessage(errorCode));
return;
}
}

32
old/online-mli.s Normal file
View File

@ -0,0 +1,32 @@
.export _onlineSysCall
.export _onlineVols
ON_LINE = $c5 ;ID FOR ON_LINE MLI SYSTEM CALL
PRODOS_MLI = $bf00 ;ADDRESS OF MLI ENTRY POINT
.proc _onlineSysCall
jsr PRODOS_MLI ;CALL MACHINE LANGUAGE INTERFACE
.byte ON_LINE ;SPECIFY THE ON_LINE SYSTEM CALL
.addr onlineArgs ;SPECIFY ADDRESS OF ARGUMENTS
; sta retCode ;Store the return code
; lda #<retCode ;PUT LOW BYTE INTO ACCUMULATOR
; ldx #>retCode ;PUT HIGH BYTE INTO X
rts
.endproc
; BSS is Block Started by Symbol for zero-initialized read/write data
; Constructed by loader and zeroed out based on required size
.bss
retCode: .byte 0
_onlineVols:.res 256 ;SPACE FOR 16 DISK VOL RECORDS
; DATA contains initialized read/write data - encoded into binary
.data
onlineArgs: .byte 2 ;PARAMETER COUNT
.byte 0 ;UNIT NUMBER, 0=ALL
.addr _onlineVols ;ADDRESS OF OUTPUT BUFFER

33
old/online-old.c Normal file
View File

@ -0,0 +1,33 @@
#include <stdint.h>
#define PRODOS_MLI 0xbf00
#define ON_LINE_SYSTEM_CALL 0xc5
#define PRODOS_FILE_NAME_MAX_LEN 15
typedef char ProdosFileName[PRODOS_FILE_NAME_MAX_LEN + 1];
typedef ProdosFileName ProdosFileNameArray16[16];
typedef struct OnlineSystemCallArguments {
uint8_t argumentCount;
uint8_t unitNumber;
ProdosFileNameArray16 *volumesOutputBuffer;
} OnlineSystemCallArguments;
static ProdosFileNameArray16 volumes;
static OnlineSystemCallArguments arguments;
ProdosFileNameArray16 *online(uint8_t *errorCode)
{
arguments.argumentCount = 2;
arguments.unitNumber = 0; // All units
arguments.volumesOutputBuffer = &volumes;
__asm__("jsr %w", PRODOS_MLI);
__asm__("db %b", ON_LINE_SYSTEM_CALL);
__asm__("da %v", &arguments);
__asm__("bne %g", errorHandler);
return &volumes;
errorHandler:
return errorCode;
}

69
old/online.c Normal file
View File

@ -0,0 +1,69 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <device.h>
#include "prodos.h"
extern uint8_t onlineVols[];
extern uint8_t onlineSysCall();
enum ProdosErrorCode online(struct ProdosVolumes *vols)
{
uint8_t byte;
uint8_t i;
uint8_t nameLength;
enum ProdosErrorCode errorCode;
struct ProdosVolume *volume;
errorCode = onlineSysCall();
if (errorCode != PRODOS_ERR_NO_ERROR) {
return NULL;
}
for (i = 0; i < PRODOS_MAX_VOLUME_COUNT; ++i) {
byte = onlineVols[i*16];
if (byte == 0) {
vols->count = i;
break;
}
volume = &(vols->volumes[i]);
volume->drive = ((byte & 0x80) >> 7) + 1;
volume->slot = (byte & 0x70) >> 4;
nameLength = byte & 0x0f;
strncpy(volume->name, &(onlineVols[i*16+1]), nameLength);
volume->name[nameLength] = '\0';
}
return errorCode;
}
struct ProdosVolume volume;
struct ProdosVolumes volumes;
enum ProdosErrorCode errorCode;
void printOnline(void)
{
uint8_t i, dev;
char volName[FILENAME_MAX];
errorCode = online(&volumes);
if (errorCode > 0) {
printf("Error: %d\n", errorCode);
exit(1);
}
for (i = 0; i < volumes.count; ++i) {
volume = volumes.volumes[i];
if (strlen(volume.name)>0) {
printf("S%d,D%d /%s\n", volume.slot, volume.drive, volume.name);
}
}
dev = getfirstdevice();
while (dev != INVALID_DEVICE) {
getdevicedir(dev, volName, sizeof(volName));
printf("device=%d volume=%s\n", dev, volName);
dev = getnextdevice(dev);
}
}

42
old/prodos-util.c Normal file
View File

@ -0,0 +1,42 @@
#include <string.h> /* size_t */
#include "prodos.h"
struct ProdosPathName *
prodosAssignPathName(struct ProdosPathName *dest, const char *src)
{
size_t i;
char c;
char *name;
name = dest->name;
for (i = 0; i < PRODOS_MAX_PATHNAME_LENGTH && (c = src[i]) != '\0'; ++i) {
name[i] = c;
}
dest->length = i;
return dest;
}
char *
prodosGetMessage(enum ProdosErrorCode code)
{
char *message;
switch (code) {
case PRODOS_ERR_NO_ERROR:
message = "No error";
break;
case PRODOS_ERR_BAD_SYS_CALL_NUM:
message = "Bad system call number";
break;
case PRODOS_ERR_BAD_PARAM_COUNT:
message = "Bad parameter count";
break;
case PRODOS_ERR_INTR_VECT_TBL_FULL:
message = "Interrupt vector table full";
break;
default:
message = "Unknown error";
}
return message;
}

66
old/prodos.h Normal file
View File

@ -0,0 +1,66 @@
#ifndef PRODOS
#define PRODOS
#include <stdint.h> /* uint8_t, uint16_t */
#define PRODOS_GET_FILE_INFO_PARAM_COUNT 0x0a
#define PRODOS_SET_FILE_INFO_PARAM_COUNT 0x07
#define PRODOS_MAX_PATHNAME_LENGTH 64
#define PRODOS_MAX_VOLUME_NAME_LEN 15
#define PRODOS_MAX_VOLUME_COUNT 16
enum ProdosErrorCode {
PRODOS_ERR_NO_ERROR = 0,
PRODOS_ERR_BAD_SYS_CALL_NUM = 1,
PRODOS_ERR_BAD_PARAM_COUNT = 4,
PRODOS_ERR_INTR_VECT_TBL_FULL = 25,
};
struct ProdosVolume {
uint8_t drive;
uint8_t slot;
uint8_t nameLength;
char name[PRODOS_MAX_VOLUME_NAME_LEN+1];
};
struct ProdosVolumes {
uint8_t count;
struct ProdosVolume volumes[PRODOS_MAX_VOLUME_COUNT];
};
struct ProdosPathName
{
uint8_t length;
char name[PRODOS_MAX_PATHNAME_LENGTH];
};
struct ProdosFileInfo
{
uint8_t paramCount;
struct ProdosPathName *pathName;
uint8_t access;
uint8_t fileType;
uint16_t auxType;
uint8_t storageType;
uint16_t blocksUsed;
uint16_t modDate;
uint16_t modTime;
uint16_t createDate;
uint16_t createTime;
};
extern int __fastcall__
prodosGetFileInfo(struct ProdosFileInfo *fileInfo);
extern int __fastcall__
prodosSetFileInfo(struct ProdosFileInfo *fileInfo);
extern struct ProdosPathName *
prodosAssignPathName(struct ProdosPathName *dest, const char *src);
extern char *
prodosGetMessage(enum ProdosErrorCode code);
#endif

57
old/prodos.s Normal file
View File

@ -0,0 +1,57 @@
.export _prodosGetFileInfo
.export _prodosSetFileInfo
.export _onlineSysCall
.export _onlineVols
PRODOS_MLI = $bf00 ;Address for MLI subroutine entry point
SET_FILE_INFO = $c3 ;Code for system call
GET_FILE_INFO = $c4 ;Code for system call
ON_LINE = $c5 ;ID FOR ON_LINE MLI SYSTEM CALL
.proc _prodosGetFileInfo
sta fileInfo ;Store low-byte of C address param
stx fileInfo+1 ;Store high-byte of C address param
jsr PRODOS_MLI ;Call MLI subroutine
.byte GET_FILE_INFO ;Identify the system call
fileInfo: .addr $0000 ;Address of system call args
ldx #0 ;Zero high byte of int return value
rts ;Accum has error code, low byte of int
.endproc
.proc _prodosSetFileInfo
sta fileInfo ;Store low-byte of C address param
stx fileInfo+1 ;Store high-byte of C address param
jsr PRODOS_MLI ;Call MLI subroutine
.byte SET_FILE_INFO ;Identify the system call
fileInfo: .addr $0000 ;Address of system call args
ldx #0 ;Zero high byte of int return value
rts ;Accumulator has error code
.endproc
.proc _onlineSysCall
jsr PRODOS_MLI ;CALL MACHINE LANGUAGE INTERFACE
.byte ON_LINE ;SPECIFY THE ON_LINE SYSTEM CALL
.addr onlineArgs ;SPECIFY ADDRESS OF ARGUMENTS
; sta retCode ;Store the return code
; lda #<retCode ;PUT LOW BYTE INTO ACCUMULATOR
; ldx #>retCode ;PUT HIGH BYTE INTO X
rts
.endproc
; BSS is Block Started by Symbol for zero-initialized read/write data
; Constructed by loader and zeroed out based on required size
.bss
retCode: .byte 0
_onlineVols:.res 256 ;SPACE FOR 16 DISK VOL RECORDS
; DATA contains initialized read/write data - encoded into binary
.data
onlineArgs: .byte 2 ;PARAMETER COUNT
.byte 0 ;UNIT NUMBER, 0=ALL
.addr _onlineVols ;ADDRESS OF OUTPUT BUFFER

36
old/prodos.s.bak Normal file
View File

@ -0,0 +1,36 @@
.export _mliGetFileInfo
.export _mliSetFileInfo
SET_FILE_INFO = $c3 ;Code for system call
GET_FILE_INFO = $c4 ;Code for system call
PRODOS_MLI = $bf00 ;Address for MLI subroutine entry point
.proc _mliGetFileInfo
sta fileInfo ;Store low-byte of C address param
stx fileInfo+1 ;Store high-byte of C address param
jsr PRODOS_MLI ;Call MLI subroutine
.byte GET_FILE_INFO ;Identify the system call
fileInfo: .addr $0000 ;Address of system call args
ldx #0 ;Zero high byte of int return value
rts ;Accum has error code, low byte of int
.endproc
.proc _mliSetFileInfo
sta fileInfo ;Store low-byte of C address param
stx fileInfo+1 ;Store high-byte of C address param
jsr PRODOS_MLI ;Call MLI subroutine
.byte SET_FILE_INFO ;Identify the system call
fileInfo: .addr $0000 ;Address of system call args
ldx #0 ;Zero high byte of int return value
rts ;Accumulator has error code
.endproc
; BSS is Block Started by Symbol for zero-initialized read/write data
; Constructed by loader and zeroed out based on required size
.bss
; DATA segment contains initialized read/write data - encoded into binary
.data

View File

@ -1,33 +1,55 @@
#include <stdio.h>
#include <stdint.h>
#define PRODOS_MLI 0xbf00
#define ON_LINE_SYSTEM_CALL 0xc5
#define PRODOS_FILE_NAME_MAX_LEN 15
typedef char ProdosFileName[PRODOS_FILE_NAME_MAX_LEN + 1];
typedef ProdosFileName ProdosFileNameArray16[16];
typedef struct OnlineSystemCallArguments {
#define ON_LINE (uint8_t) 0xc5
#define PRODOS_NAME_CAPACITY 16
struct OnlineArguments {
uint8_t argumentCount;
uint8_t unitNumber;
ProdosFileNameArray16 *volumesOutputBuffer;
} OnlineSystemCallArguments;
char **volumes;
};
static ProdosFileNameArray16 volumes;
static OnlineSystemCallArguments arguments;
struct OnlineArguments arguments;
char volumes[16][PRODOS_NAME_CAPACITY];
uint8_t argumentsAddrLowByte;
uint8_t argumentsAddrHighByte;
ProdosFileNameArray16 *online(uint8_t *errorCode)
void online(void)
{
arguments.argumentCount = 2;
arguments.unitNumber = 0; // All units
arguments.volumesOutputBuffer = &volumes;
arguments.volumes = volumes;
__asm__("lda #%b", ON_LINE);
__asm__("sta %g", l1);
argumentsAddrLowByte = (uint8_t) &arguments;
argumentsAddrLowByte = (uint8_t) &arguments >> 4;
__asm__("lda %v", argumentsAddrLowByte);
__asm__("sta %g", l2);
__asm__("lda %v", argumentsAddrHighByte);
__asm__("sta %g", l3);
__asm__("jsr %w", PRODOS_MLI);
__asm__("db %b", ON_LINE_SYSTEM_CALL);
__asm__("da %v", &arguments);
l1:
__asm__("nop");
l2:
__asm__("nop");
l3:
__asm__("nop");
__asm__("bne %g", errorHandler);
return &volumes;
errorHandler:
return errorCode;
fprintf(stderr, "Online system call failed\n");
}
void main(void)
{
online();
puts(volumes[0]);
}

View File

@ -1,26 +0,0 @@
.export _onLineSysCall
.export _onLineVols
ON_LINE = $c5 ;ID FOR ON_LINE MLI SYSTEM CALL
PRODOS_MLI = $bf00 ;ADDRESS OF MLI ENTRY POINT
.proc _onLineSysCall
jsr PRODOS_MLI ;CALL MACHINE LANGUAGE INTERFACE
.byte ON_LINE ;SPECIFY THE ON_LINE SYSTEM CALL
.addr onlineArgs ;SPECIFY ADDRESS OF ARGUMENTS
sta retCode ;Store the return code
lda #<retCode ;PUT LOW BYTE INTO ACCUMULATOR
ldx #>retCode ;PUT HIGH BYTE INTO X
rts
.endproc
.bss
retCode: .byte 0
_onLineVols:.res 256 ;SPACE FOR 16 DISK VOL RECORDS
onlineArgs: .byte 2 ;PARAMETER COUNT
.byte 0 ;UNIT NUMBER, 0=ALL
.addr _onLineVols ;ADDRESS OF OUTPUT BUFFER

21
onlinesys.s Normal file
View File

@ -0,0 +1,21 @@
.export _online
.export _olerr
.include "mli.inc"
.bss
_olerr: .byte $00
.code
_open:
lda #ON_LINE_CALL
ldx #ON_LINE_COUNT
jsr callmli
bcc done
sta _olerr
done:
rts