diff --git a/libsrc/apple2/closedir.c b/libsrc/apple2/closedir.c deleted file mode 100644 index d37d15bba7..0000000000 --- a/libsrc/apple2/closedir.c +++ /dev/null @@ -1,57 +0,0 @@ -/*****************************************************************************/ -/* */ -/* 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 "dir.h" - - - -/*****************************************************************************/ -/* 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/closedir.s b/libsrc/apple2/closedir.s new file mode 100644 index 0000000000..1f176092b9 --- /dev/null +++ b/libsrc/apple2/closedir.s @@ -0,0 +1,35 @@ +; +; Colin Leroy-Mira , 2024 +; +; int __fastcall__ closedir (DIR *dir) +; + + .export _closedir, closedir_ptr1 + + .import _close + .import _free + .import pushax, popax, pushptr1, swapstk + + .importzp ptr1 + + .include "apple2.inc" + .include "dir.inc" + .include "errno.inc" + .include "fcntl.inc" + .include "zeropage.inc" + +_closedir: + sta ptr1 + stx ptr1+1 +closedir_ptr1: + ; Close fd + jsr pushptr1 ; Backup ptr1 + ldy #$00 + lda (ptr1),y ; Get fd + ldx #$00 + jsr _close + jsr swapstk ; Store result, pop ptr1 + + ; Free dir structure + jsr _free + jmp popax ; Return result diff --git a/libsrc/apple2/opendir.s b/libsrc/apple2/opendir.s index 38110b6809..317be2755a 100644 --- a/libsrc/apple2/opendir.s +++ b/libsrc/apple2/opendir.s @@ -4,16 +4,18 @@ ; DIR* __fastcall__ opendir (register const char* name) ; - .export _opendir + .export _opendir, read_dir_block_ptr1 + .import closedir_ptr1 .import _open, _read, _close - .import _malloc, _free + .import _malloc .import ___directerrno .import ___oserror, __cwd .import pushptr1, popptr1 .import pushax, pusha0 + .import return0, returnFFFF .importzp ptr1 @@ -37,7 +39,7 @@ sta ptr1 stx ptr1+1 -: ; open directory +: ; Open directory jsr pushptr1 lda #O_RDONLY jsr pusha0 @@ -58,23 +60,17 @@ ; We failed to allocate pla ; Get fd back ldx #$00 - jsr _close ; close it + jsr _close ; Close it lda #ENOMEM ; Set error jsr ___directerrno - @return_null: - lda #$00 - tax - rts + jmp return0 : ; Store dir struct to pointer sta ptr1 stx ptr1+1 - ; Push ptr1, read will destroy it - jsr pushptr1 - ; Save fd to dir struct lda #$00 ldy #DIR::FD + 1 @@ -84,49 +80,15 @@ pla ; Get fd back sta (ptr1),y - jsr pusha0 ; push fd for read - lda #DIR::BYTES - adc ptr1+1 - tax - pla - jsr pushax ; Push dir->block.bytes for read - - lda #<.sizeof(DIR::BYTES) - ldx #>.sizeof(DIR::BYTES) - - jsr _read ; Read directory block - cpx #>.sizeof(DIR::BYTES) - bne @err_read - cmp #<.sizeof(DIR::BYTES) - beq @read_ok - -@err_read: - ; Read failed, exit - lda ___oserror - bne :+ - lda #EINVAL - jsr ___directerrno - -: ; Close fd - jsr popptr1 ; Restore our dir pointer - ldy #$00 - lda (ptr1),y ; Get fd - ldx #$00 - jsr _close + jsr read_dir_block_ptr1 + bcc @read_ok - ; Free dir structure - lda ptr1 - ldx ptr1+1 - jsr _free - jmp @return_null + ; Close directory, free it + jsr closedir_ptr1 + jmp return0 ; Return NULL @read_ok: ; Read succeeded, populate dir struct - jsr popptr1 ; Restore our dir pointer ; Get file_count to entry_length from block ldy #$26 + DIR::BYTES @@ -153,3 +115,45 @@ ldx ptr1+1 rts .endproc + +; Read a directory for the DIR* pointer in ptr1 +; Return with carry clear on success +read_dir_block_ptr1: + ; Push ptr1, read will destroy it + jsr pushptr1 + + ldy #DIR::FD + lda (ptr1),y + + jsr pusha0 ; Push fd for read + lda #DIR::BYTES + adc ptr1+1 + tax + pla + jsr pushax ; Push dir->block.bytes for read + + lda #<.sizeof(DIR::BYTES) + ldx #>.sizeof(DIR::BYTES) + + jsr _read ; Read directory block + cpx #>.sizeof(DIR::BYTES) + bne @read_err + cmp #<.sizeof(DIR::BYTES) + beq @read_ok + +@read_err: + ; Read failed, exit + lda ___oserror + bne :+ + lda #EINVAL + jsr ___directerrno +: sec + bcs @out +@read_ok: + clc +@out: + jmp popptr1 diff --git a/libsrc/apple2/readdir.c b/libsrc/apple2/readdir.c deleted file mode 100644 index 8acfbbe8b7..0000000000 --- a/libsrc/apple2/readdir.c +++ /dev/null @@ -1,90 +0,0 @@ -/*****************************************************************************/ -/* */ -/* 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 "dir.h" - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -struct dirent* __fastcall__ readdir (register DIR* dir) -{ - register unsigned 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[0x00] == 0); - - /* Move creation date/time to allow for next step below */ - *(unsigned long*)&entry[0x1A] = *(unsigned long*)&entry[0x18]; - - /* Feature unsigned long access to EOF by extension from 3 to 4 bytes */ - entry[0x18] = 0; - - /* Move file type to allow for next step below */ - entry[0x19] = entry[0x10]; - - /* Zero-terminate file name */ - entry[0x01 + (entry[0x00] & 0x0F)] = 0; - - /* Return success */ - return (struct dirent*)&entry[0x01]; -} diff --git a/libsrc/apple2/readdir.s b/libsrc/apple2/readdir.s new file mode 100644 index 0000000000..e748055e15 --- /dev/null +++ b/libsrc/apple2/readdir.s @@ -0,0 +1,113 @@ +; +; Colin Leroy-Mira , 2024 +; +; struct dirent * __fastcall__ readdir (DIR *dir) +; + .export _readdir + .import read_dir_block_ptr1 + + .import incax1, return0 + .import tosaddax, tosumula0, incaxy + .import pushax, pusha0, pushptr1, popptr1 + .importzp ptr1, ptr4 + + .include "dir.inc" + +.proc _readdir + sta ptr1 + stx ptr1+1 + +@next_entry: + ; Do we need to read the next directory block? + ldy #DIR::CURRENT_ENTRY + lda (ptr1),y + ldy #DIR::ENTRIES_PER_BLOCK + cmp (ptr1),y + bne @read_entry ; We don't + + jsr read_dir_block_ptr1 + bcc @read_ok + + ; We had a read error + jmp return0 + +@read_ok: + ldy #DIR::CURRENT_ENTRY + lda #$00 + sta (ptr1),y + +@read_entry: + ; Compute pointer to current entry: + ; entry = dir->block.content.entries + + ; dir->current_entry * dir->entry_length + + jsr pushptr1 ; Backup ptr1 + lda ptr1 + ldx ptr1+1 + ldy #DIR::BYTES + DIR::CONTENT::ENTRIES + jsr incaxy + jsr pushax + ldy #DIR::CURRENT_ENTRY + lda (ptr1),y + jsr pusha0 + ldy #DIR::ENTRY_LENGTH + lda (ptr1),y + jsr tosumula0 + jsr tosaddax + ; Store pointer to current entry + sta ptr4 + stx ptr4+1 + jsr popptr1 + + ; Switch to next entry + ldy #DIR::CURRENT_ENTRY + lda (ptr1),y + clc + adc #1 + sta (ptr1),y + + ; Check if entry[0] == 0 + ldy #$00 + lda (ptr4),y + beq @next_entry ; Yes, skip entry + + ; Move creation date/time to allow for next step below + ; 18-19-1A-1B => 1A-1B-1C-1D + ldy #$1B +: lda (ptr4),y + iny + iny + sta (ptr4),y + dey + dey + dey + cpy #$17 + bne :- + + ; Feature unsigned long access to EOF by extension from 3 to 4 bytes + ; entry[0x18] = 0 + iny + lda #$00 + sta (ptr4),y + + ; Move file type to allow for next step below + ; entry[0x19] = entry[0x10] + ldy #$10 + lda (ptr4),y + ldy #$19 + sta (ptr4),y + + ; Zero-terminate file name + ldy #$00 + lda (ptr4),y + and #$0F + tay + iny + lda #$00 + sta (ptr4),y + + ; Return pointer to entry+1 + lda ptr4 + ldx ptr4+1 + jmp incax1 +.endproc