1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-21 05:29:52 +00:00

Apple2: Rewrite rewinddir() in assembly

This commit is contained in:
Colin Leroy-Mira 2024-11-16 22:01:11 +01:00 committed by Oliver Schmidt
parent f663ee428d
commit 21030c22a0
3 changed files with 70 additions and 132 deletions

View File

@ -1,63 +0,0 @@
/*****************************************************************************/
/* */
/* dir.h */
/* */
/* Apple ][ system specific DIR */
/* */
/* */
/* */
/* (C) 2005 Oliver Schmidt, <ol.sc@web.de> */
/* */
/* */
/* 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 int file_count;
unsigned char current_entry;
union {
unsigned char bytes[512];
struct {
unsigned prev_block;
unsigned next_block;
unsigned char entries[1];
} content;
} block;
};
/* End of dir.h */
#endif

View File

@ -1,69 +0,0 @@
/*****************************************************************************/
/* */
/* rewinddir.c */
/* */
/* Reset directory stream */
/* */
/* */
/* */
/* (C) 2005 Oliver Schmidt, <ol.sc@web.de> */
/* */
/* */
/* 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 <stdio.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include "dir.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void __fastcall__ rewinddir (register 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 */
}

70
libsrc/apple2/rewinddir.s Normal file
View File

@ -0,0 +1,70 @@
;
; Colin Leroy-Mira <colin@colino.net>, 2024
;
; void __fastcall__ rewinddir (DIR* dir)
;
.export _rewinddir
.import read_dir_block_ptr1
.import pusha, pusha0, pushax
.import pushptr1, popptr1
.import incaxy
.import _lseek, _memset
.importzp ptr1, sreg
.include "dir.inc"
.include "stdio.inc"
.proc _rewinddir
sta ptr1
stx ptr1+1
jsr pushptr1 ; Backup ptr1, destroyed by _lseek
; Rewind directory file
ldy #DIR::FD
lda (ptr1),y
jsr pusha0 ; Push dir->fd
tya ; Y = 0 here
jsr pusha0
jsr pusha0 ; Push 0L
lda #SEEK_SET ; X = 0 here
jsr _lseek
ora sreg ; Check lseek returned 0L
ora sreg+1
bne @rewind_err
txa
bne @rewind_err
jsr popptr1 ; Restore ptr1
; Read directory key block
jsr read_dir_block_ptr1
bcs @rewind_err
; Skip directory header entry
lda #$01
ldy #DIR::CURRENT_ENTRY
sta (ptr1),y
rts
@rewind_err:
jsr popptr1 ; Restore ptr1
; Assert that no subsequent readdir() finds an active entry
lda ptr1
ldx ptr1+1
ldy #DIR::BYTES + DIR::CONTENT::ENTRIES
jsr incaxy
jsr pushax
lda #$00
jsr pusha
lda #<.sizeof(DIR::BYTES)
ldx #>.sizeof(DIR::BYTES)
jmp _memset
.endproc