diff --git a/include/dirent.h b/include/dirent.h new file mode 100644 index 000000000..012ee82e9 --- /dev/null +++ b/include/dirent.h @@ -0,0 +1,69 @@ +/*****************************************************************************/ +/* */ +/* dirent.h */ +/* */ +/* Directory entries for cc65 */ +/* */ +/* */ +/* */ +/* (C) 2005 Oliver Schmidt, */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef _DIRENT_H +#define _DIRENT_H + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +typedef struct DIR DIR; + +struct dirent { + char d_name[1]; +}; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +DIR* __fastcall__ opendir (const char* name); + +struct dirent* __fastcall__ readdir (DIR* dir); + +int __fastcall__ closedir (DIR* dir); + +void __fastcall__ rewinddir (DIR* dir); + + + +/* End of dirent.h */ +#endif diff --git a/libsrc/apple2/.cvsignore b/libsrc/apple2/.cvsignore index 58093ab1b..a4181471b 100644 --- a/libsrc/apple2/.cvsignore +++ b/libsrc/apple2/.cvsignore @@ -1,3 +1,7 @@ *.emd *.joy *.tgi +closedir.s +opendir.s +readdir.s +rewinddir.s diff --git a/libsrc/apple2/Makefile b/libsrc/apple2/Makefile index 49add99ba..2030c0797 100644 --- a/libsrc/apple2/Makefile +++ b/libsrc/apple2/Makefile @@ -38,7 +38,12 @@ CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include #-------------------------------------------------------------------------- # Object files -OBJS= _scrsize.o \ +C_OBJS= closedir.o \ + opendir.o \ + readdir.o \ + rewinddir.o + +S_OBJS= _scrsize.o \ break.o \ cclear.o \ cgetc.o \ @@ -82,6 +87,11 @@ OBJS= _scrsize.o \ rrdkey.o \ rvtabz.o \ rwcommon.o \ + syschdir.o \ + sysmkdir.o \ + sysremove.o \ + sysrename.o \ + sysrmdir.o \ systime.o \ sysuname.o \ tgi_mode_table.o\ @@ -105,13 +115,13 @@ TGIS = apple2-40-40-16.tgi apple2-280-192-6.tgi .PHONY: all clean zap -all: $(OBJS) $(EMDS) $(JOYS) $(SERS) $(TGIS) +all: $(C_OBJS) $(S_OBJS) $(EMDS) $(JOYS) $(SERS) $(TGIS) ../runtime/zeropage.o: $(MAKE) -C $(dir $@) $(notdir $@) clean: - @$(RM) $(OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(SERS:.ser=.o) $(TGIS:.tgi=.o) + @$(RM) $(C_OBJS:.o=.s) $(C_OBJS) $(S_OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(SERS:.ser=.o) $(TGIS:.tgi=.o) zap: clean @$(RM) $(EMDS) $(JOYS) $(SERS) $(TGIS) diff --git a/libsrc/apple2/closedir.c b/libsrc/apple2/closedir.c new file mode 100644 index 000000000..55df68ca9 --- /dev/null +++ b/libsrc/apple2/closedir.c @@ -0,0 +1,57 @@ +/*****************************************************************************/ +/* */ +/* closedir.c */ +/* */ +/* Close a directory */ +/* */ +/* */ +/* */ +/* (C) 2005 Oliver Schmidt, */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include +#include +#include +#include + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +int __fastcall__ closedir (DIR* dir) +{ + int result; + + /* Cleanup directory file */ + result = close (dir->fd); + + /* Cleanup DIR */ + free (dir); + + return result; +} diff --git a/libsrc/apple2/dir.h b/libsrc/apple2/dir.h new file mode 100644 index 000000000..997e63bcd --- /dev/null +++ b/libsrc/apple2/dir.h @@ -0,0 +1,62 @@ +/*****************************************************************************/ +/* */ +/* dir.h */ +/* */ +/* Apple ][ system specific DIR */ +/* */ +/* */ +/* */ +/* (C) 2005 Oliver Schmidt, */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef _DIR_H +#define _DIR_H + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +struct DIR { + int fd; + unsigned char entry_length; + unsigned char entries_per_block; + unsigned char current_entry; + union { + unsigned char bytes[512]; + struct { + unsigned prev_block; + unsigned next_block; + char entries[1]; + } content; + } block; +}; + + + +/* End of dir.h */ +#endif diff --git a/libsrc/apple2/opendir.c b/libsrc/apple2/opendir.c new file mode 100644 index 000000000..5879f7448 --- /dev/null +++ b/libsrc/apple2/opendir.c @@ -0,0 +1,112 @@ +/*****************************************************************************/ +/* */ +/* opendir.h */ +/* */ +/* Open a directory */ +/* */ +/* */ +/* */ +/* (C) 2005 Oliver Schmidt, */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include +#include +#include +#include +#include +#include +#include +#include + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +extern char _cwd[FILENAME_MAX]; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +DIR* __fastcall__ opendir (const char* name) +{ + DIR* dir; + + /* Alloc DIR */ + if ((dir = malloc (sizeof (*dir))) == NULL) { + + /* May not have been done by malloc() */ + errno = ENOMEM; + + /* Return failure */ + return NULL; + } + + /* Interpret dot as current working directory */ + if (*name == '.') { + name = _cwd; + } + + /* Open directory file */ + if ((dir->fd = open (name, O_RDONLY)) != -1) { + + /* Read directory key block */ + if (read (dir->fd, + dir->block.bytes, + sizeof (dir->block)) == sizeof (dir->block)) { + + /* Get directory entry infos from directory header */ + dir->entry_length = dir->block.bytes[0x23]; + dir->entries_per_block = dir->block.bytes[0x24]; + + /* Skip directory header entry */ + dir->current_entry = 1; + + /* Return success */ + return dir; + } + + /* EOF: Most probably no directory file at all */ + if (errno == 0) { + errno = EINVAL; + } + + /* Cleanup directory file */ + close (dir->fd); + } + + /* Cleanup DIR */ + free (dir); + + /* Return failure */ + return NULL; +} diff --git a/libsrc/apple2/readdir.c b/libsrc/apple2/readdir.c new file mode 100644 index 000000000..f4653cfae --- /dev/null +++ b/libsrc/apple2/readdir.c @@ -0,0 +1,81 @@ +/*****************************************************************************/ +/* */ +/* readdir.c */ +/* */ +/* Read directory entry */ +/* */ +/* */ +/* */ +/* (C) 2005 Oliver Schmidt, */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include +#include +#include +#include + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +struct dirent* __fastcall__ readdir (DIR* dir) +{ + char* entry; + + /* Search for the next active directory entry */ + do { + + /* Read next directory block if necessary */ + if (dir->current_entry == dir->entries_per_block) { + if (read (dir->fd, + dir->block.bytes, + sizeof (dir->block)) != sizeof (dir->block)) { + + /* Just return failure as read() has */ + /* set errno if (and only if) no EOF */ + return NULL; + } + + /* Start with first entry in next block */ + dir->current_entry = 0; + } + + /* Compute pointer to current entry */ + entry = dir->block.content.entries + + dir->current_entry * dir->entry_length; + + /* Switch to next entry */ + ++dir->current_entry; + } while (entry[0] == 0); + + /* Zero-terminate name */ + entry[1 + (entry[0] & 15)] = '\0'; + + /* Return success */ + return (struct dirent*)&entry[1]; +} diff --git a/libsrc/apple2/rewinddir.c b/libsrc/apple2/rewinddir.c new file mode 100644 index 000000000..b1099a86a --- /dev/null +++ b/libsrc/apple2/rewinddir.c @@ -0,0 +1,69 @@ +/*****************************************************************************/ +/* */ +/* rewinddir.c */ +/* */ +/* Reset directory stream */ +/* */ +/* */ +/* */ +/* (C) 2005 Oliver Schmidt, */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include +#include +#include +#include +#include + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void __fastcall__ rewinddir (DIR* dir) +{ + /* Rewind directory file */ + if (lseek (dir->fd, 0, SEEK_SET)) { + + /* Read directory key block */ + if (read (dir->fd, + dir->block.bytes, + sizeof (dir->block)) == sizeof (dir->block)) { + + /* Skip directory header entry */ + dir->current_entry = 1; + + /* Return success */ + return; + } + } + + /* Assert that no subsequent readdir() finds an active entry */ + memset (dir->block.bytes, 0, sizeof (dir->block)); + + /* Return failure */ +} diff --git a/libsrc/apple2/syschdir.s b/libsrc/apple2/syschdir.s new file mode 100644 index 000000000..48bbc2eed --- /dev/null +++ b/libsrc/apple2/syschdir.s @@ -0,0 +1,41 @@ +; +; Oliver Schmidt, 17.04.2005 +; +; unsigned char __fastcall__ _syschdir (const char* name); +; + + .export __syschdir + .import pushname, popname + .import __cwd + + .include "zeropage.inc" + .include "mli.inc" + +__syschdir: + ; Push name + jsr pushname + bne oserr + + ; Set pushed name + lda sp + ldx sp+1 + sta mliparam + MLI::PREFIX::PATHNAME + stx mliparam + MLI::PREFIX::PATHNAME+1 + + ; Change directory + lda #SET_PREFIX_CALL + ldx #PREFIX_COUNT + jsr callmli + bcs cleanup + + ldy #$01 +: lda (sp),y + sta __cwd-1,y + beq cleanup + iny + bne :- ; Branch always + + ; Cleanup name +cleanup:jsr popname ; Preserves A + +oserr: rts diff --git a/libsrc/apple2/sysmkdir.s b/libsrc/apple2/sysmkdir.s new file mode 100644 index 000000000..1281fc5ae --- /dev/null +++ b/libsrc/apple2/sysmkdir.s @@ -0,0 +1,55 @@ +; +; Oliver Schmidt, 15.04.2005 +; +; unsigned char _sysmkdir (const char* name, ...); +; + + .export __sysmkdir + .import pushname, popname + .import addysp, popax + + .include "zeropage.inc" + .include "mli.inc" + +__sysmkdir: + ; Throw away all parameters except the name + dey + dey + jsr addysp + + ; Get and push name + jsr popax + jsr pushname + bne oserr + + ; Set pushed name + lda sp + ldx sp+1 + sta mliparam + MLI::CREATE::PATHNAME + stx mliparam + MLI::CREATE::PATHNAME+1 + + ; Set all other parameters from template + ldx #(MLI::CREATE::CREATE_TIME+1) - (MLI::CREATE::PATHNAME+1) - 1 +: lda CREATE,x + sta mliparam + MLI::CREATE::ACCESS,x + dex + bpl :- + + ; Make directory + lda #CREATE_CALL + ldx #CREATE_COUNT + jsr callmli + + ; Cleanup name + jsr popname ; Preserves A + +oserr: rts + + .rodata + +CREATE: .byte %11000011 ; ACCESS: Standard full access + .byte $0F ; FILE_TYPE: Directory file + .word $0000 ; AUX_TYPE: N/A + .byte $0D ; STORAGE_TYPE: Linked directory file + .word $0000 ; CREATE_DATE: Current date + .word $0000 ; CREATE_TIME: Current time diff --git a/libsrc/apple2/sysremove.s b/libsrc/apple2/sysremove.s new file mode 100644 index 000000000..7483b9320 --- /dev/null +++ b/libsrc/apple2/sysremove.s @@ -0,0 +1,32 @@ +; +; Oliver Schmidt, 15.04.2005 +; +; unsigned char __fastcall__ _sysremove (const char* name); +; + + .export __sysremove + .import pushname, popname + + .include "zeropage.inc" + .include "mli.inc" + +__sysremove: + ; Push name + jsr pushname + bne oserr + + ; Set pushed name + lda sp + ldx sp+1 + sta mliparam + MLI::DESTROY::PATHNAME + stx mliparam + MLI::DESTROY::PATHNAME+1 + + ; Remove file + lda #DESTROY_CALL + ldx #DESTROY_COUNT + jsr callmli + + ; Cleanup name + jsr popname ; Preserves A + +oserr: rts diff --git a/libsrc/apple2/sysrename.s b/libsrc/apple2/sysrename.s new file mode 100644 index 000000000..125a216a4 --- /dev/null +++ b/libsrc/apple2/sysrename.s @@ -0,0 +1,59 @@ +; +; Oliver Schmidt, 15.04.2005 +; +; unsigned char __fastcall__ _sysrename (const char* oldname, const char* newname); +; + + .export __sysrename + .import pushname, popname + .import popax + + .include "zeropage.inc" + .include "mli.inc" + +__sysrename: + ; Save newname + sta ptr2 + stx ptr2+1 + + ; Get and push oldname + jsr popax + jsr pushname + bne oserr1 + + ; Save pushed oldname + lda sp + ldx sp+1 + sta ptr3 + stx ptr3+1 + + ; Restore and push newname + lda ptr2 + ldx ptr2+1 + jsr pushname + bne oserr2 + + ; Restore and set pushed oldname + lda ptr3 + ldx ptr3+1 + sta mliparam + MLI::RENAME::PATHNAME + stx mliparam + MLI::RENAME::PATHNAME+1 + + ; Set pushed newname + lda sp + ldx sp+1 + sta mliparam + MLI::RENAME::NEW_PATHNAME + stx mliparam + MLI::RENAME::NEW_PATHNAME+1 + + ; Rename file + lda #RENAME_CALL + ldx #RENAME_COUNT + jsr callmli + + ; Cleanup newname + jsr popname ; Preserves A + + ; Cleanup oldname +oserr2: jsr popname ; Preserves A + +oserr1: rts diff --git a/libsrc/apple2/sysrmdir.s b/libsrc/apple2/sysrmdir.s new file mode 100644 index 000000000..668be1208 --- /dev/null +++ b/libsrc/apple2/sysrmdir.s @@ -0,0 +1,10 @@ +; +; Oliver Schmidt, 15.04.2005 +; +; unsigned char __fastcall__ _sysrmdir (const char* name); +; + + .export __sysrmdir + .import __sysremove + +__sysrmdir := __sysremove diff --git a/libsrc/apple2enh/Makefile b/libsrc/apple2enh/Makefile index 23407c79d..4cadba893 100644 --- a/libsrc/apple2enh/Makefile +++ b/libsrc/apple2enh/Makefile @@ -38,7 +38,12 @@ CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I ../apple2 -I ../../include #-------------------------------------------------------------------------- # Object files -OBJS= _scrsize.o \ +C_OBJS= closedir.o \ + opendir.o \ + readdir.o \ + rewinddir.o + +S_OBJS= _scrsize.o \ break.o \ cclear.o \ cgetc.o \ @@ -82,6 +87,11 @@ OBJS= _scrsize.o \ rrdkey.o \ rvtabz.o \ rwcommon.o \ + syschdir.o \ + sysmkdir.o \ + sysremove.o \ + sysrename.o \ + sysrmdir.o \ systime.o \ sysuname.o \ textframe.o \ @@ -106,13 +116,13 @@ TGIS = apple2-40-40-16.tgi apple2-280-192-6.tgi .PHONY: all clean zap -all: $(OBJS) $(EMDS) $(JOYS) $(SERS) $(TGIS) +all: $(C_OBJS) $(S_OBJS) $(EMDS) $(JOYS) $(SERS) $(TGIS) ../runtime/zeropage.o: $(MAKE) -C $(dir $@) $(notdir $@) clean: - @$(RM) $(OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(SERS:.ser=.o) $(TGIS:.tgi=.o) + @$(RM) $(C_OBJS:.o=.s) $(C_OBJS) $(S_OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(SERS:.ser=.o) $(TGIS:.tgi=.o) zap: clean @$(RM) $(EMDS) $(JOYS) $(SERS) $(TGIS) diff --git a/libsrc/common/Makefile b/libsrc/common/Makefile index 464124192..6a810301a 100644 --- a/libsrc/common/Makefile +++ b/libsrc/common/Makefile @@ -137,6 +137,7 @@ S_OBJS = _cwd.o \ memcpy.o \ memmove.o \ memset.o \ + mkdir.o \ modfree.o \ modload.o \ oserrcheck.o \ @@ -147,6 +148,7 @@ S_OBJS = _cwd.o \ raise.o \ remove.o \ rename.o \ + rmdir.o \ scanf.o \ searchenv.o \ setjmp.o \ diff --git a/libsrc/common/mkdir.s b/libsrc/common/mkdir.s new file mode 100644 index 000000000..c65f6d197 --- /dev/null +++ b/libsrc/common/mkdir.s @@ -0,0 +1,20 @@ +; +; Oliver Schmidt, 2005-08-30 +; +; int mkdir (const char* name, ...); /* May take a mode argument */ +; + + .export _mkdir + + .import __sysmkdir + .import oserrcheck + + +;-------------------------------------------------------------------------- + +.proc _mkdir + + jsr __sysmkdir ; Call the machine specific function + jmp oserrcheck ; Store into _oserror, set errno, return 0/-1 + +.endproc diff --git a/libsrc/common/rmdir.s b/libsrc/common/rmdir.s new file mode 100644 index 000000000..100f1a3fb --- /dev/null +++ b/libsrc/common/rmdir.s @@ -0,0 +1,20 @@ +; +; Oliver Schmidt, 2005-08-30 +; +; int __fastcall__ rmdir (const char* name); +; + + .export _rmdir + + .import __sysrmdir + .import oserrcheck + + +;-------------------------------------------------------------------------- + +.proc _rmdir + + jsr __sysrmdir ; Call the machine specific function + jmp oserrcheck ; Store into _oserror, set errno, return 0/-1 + +.endproc