From 72cc19c68088db903aff93094a20e000f0c299bd Mon Sep 17 00:00:00 2001
From: Oliver Schmidt
Date: Tue, 11 Oct 2016 11:18:23 +0200
Subject: [PATCH 1/5] Fixed ProDOS 800kB image.
The 800kB file claimed to be a 32MB image. Now the logical size and pysical size match.
---
tools/apple2enh/prodos.po | Bin 819200 -> 819200 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/tools/apple2enh/prodos.po b/tools/apple2enh/prodos.po
index ed32e7a381f05927a062794e1832e5b3cb58e267..af35b8c4590de2773965020fdd8cd871848172d8 100644
GIT binary patch
delta 140
zcmZo@FluNpTEMjVR{|5$WF{67bzMaR@%1Lb&WV^@Mq|m0o*rveLroh~$
iz|y9`+NQwProi5&z|p3_*`~nNrog>SfhS>6A|C*NdLJAB
delta 750
zcmcIg%TE(Q9G+bYEl?gEd=!v61))?Cq$gscK|@I@o31J9nS(EsdR0$tj589GdTBi9
zY1**ZJ#0h6!HYE{Mgk<5J$TTA+HSkMU_#mhdeK;C#o%AyOnx)@zWKi2W8(2ZJRYEY
zOt?d*#c6b26fYq(Iy{P+7#yAoM#4b>S<8BziiCyGh=_ubh!}Bz$&e64zJEF&3N!bl
zcsV@L4?^K9=Y-G%`kTVio(8}PJgpwv!o3gj-Nct#`p5I3_7!p1>UWEc`K#-wdUm~9b!4wn+9AA8xg{;i
ztQt!Ma7ik^)g)anExmF}x%)r)%Y=1!fsg
zfD;!K(1MGs`?Ng|JfFPODjD0WxzWBO18f?mHR7U~x8!+C&W5u|#cBhy36E25_z>?{Hm$$
zD&s3cB?b0Z@@HLFvYBt{=>u
Date: Tue, 11 Oct 2016 11:25:31 +0200
Subject: [PATCH 2/5] Improved dicarding of text in the HTML header.
Plain text in the HTML header (think of text) is collected as usual. The decision to discard it is triggered by the first withspace following. In the usual case of the no preceeded by any whitespace this means that by the point the first whitespace is encountered we're not in "discard mode" anymore and therefore incorrectly render the text.
Explicitly calling do_word() just before leaving "discard mode" discards all text collected so far.
---
apps/webbrowser/htmlparser.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/apps/webbrowser/htmlparser.c b/apps/webbrowser/htmlparser.c
index b0d8cfdc3..07653be8e 100644
--- a/apps/webbrowser/htmlparser.c
+++ b/apps/webbrowser/htmlparser.c
@@ -410,6 +410,7 @@ parse_tag(void)
switch_majorstate(s.lastmajorstate);
break;
case TAG_BODY:
+ do_word();
s.majorstate = s.lastmajorstate = MAJORSTATE_BODY;
break;
case TAG_IMG:
From c25e965b0cd507b7f2ed702fd419587e78f780f3 Mon Sep 17 00:00:00 2001
From: Oliver Schmidt
Date: Sat, 15 Oct 2016 15:27:42 +0200
Subject: [PATCH 3/5] Avoid unnecessary key presses.
The recently added doesclrscrafterexit() allows cc65 programs to determine if the screen will be cleared after exit(). If that isn't the case then there's no need to ask the user to press a key in order to allow him to read the final program output.
---
examples/wget/wget.c | 12 ++++++++++--
platform/apple2enh/lib/error.c | 7 +++++--
platform/atarixl/lib/error.c | 7 +++++--
3 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/examples/wget/wget.c b/examples/wget/wget.c
index bdba5b25d..bf1daf141 100644
--- a/examples/wget/wget.c
+++ b/examples/wget/wget.c
@@ -35,6 +35,10 @@
#include
#include
+#ifdef __CC65__
+#include
+#endif /* __CC65__ */
+
#include "contiki-net.h"
#include "webclient.h"
#include "cfs/cfs.h"
@@ -146,8 +150,12 @@ app_quit(void)
if(file != -1) {
cfs_close(file);
}
- puts("Press to continue...");
- getchar();
+#ifdef __CC65__
+ if(doesclrscrafterexit()) {
+ puts("Press to continue...");
+ getchar();
+ }
+#endif /* __CC65__ */
process_exit(&wget_process);
LOADER_UNLOAD();
}
diff --git a/platform/apple2enh/lib/error.c b/platform/apple2enh/lib/error.c
index b030d5877..39f3b0d7b 100644
--- a/platform/apple2enh/lib/error.c
+++ b/platform/apple2enh/lib/error.c
@@ -33,6 +33,7 @@
*/
#include
+#include
#include "sys/log.h"
@@ -43,8 +44,10 @@ void
error_exit(void)
{
#if LOG_CONF_ENABLED
- log_message("Press any key to continue ...", "");
- ctk_arch_getkey();
+ if(doesclrscrafterexit()) {
+ log_message("Press any key to continue ...", "");
+ ctk_arch_getkey();
+ }
#endif /* LOG_CONF_ENABLED */
exit(EXIT_FAILURE);
}
diff --git a/platform/atarixl/lib/error.c b/platform/atarixl/lib/error.c
index b030d5877..39f3b0d7b 100644
--- a/platform/atarixl/lib/error.c
+++ b/platform/atarixl/lib/error.c
@@ -33,6 +33,7 @@
*/
#include
+#include
#include "sys/log.h"
@@ -43,8 +44,10 @@ void
error_exit(void)
{
#if LOG_CONF_ENABLED
- log_message("Press any key to continue ...", "");
- ctk_arch_getkey();
+ if(doesclrscrafterexit()) {
+ log_message("Press any key to continue ...", "");
+ ctk_arch_getkey();
+ }
#endif /* LOG_CONF_ENABLED */
exit(EXIT_FAILURE);
}
From d864e7357978f598a386970f8dce94548d6b7179 Mon Sep 17 00:00:00 2001
From: Oliver Schmidt
Date: Sat, 15 Oct 2016 16:33:24 +0200
Subject: [PATCH 4/5] Added directory functions to the Commodore Platform File
System.
They reduce the Telnet server's run size by 1231 bytes.
---
core/cfs/cfs-posix-dir.c | 1 +
core/cfs/cfs-posix.c | 1 +
cpu/6502/lib/pfs.h | 7 +
examples/telnet-server/Makefile.c128.defines | 2 +-
platform/c128/Makefile.c128 | 3 +-
platform/c128/contiki-conf.h | 6 +
platform/c128/lib/pfs-dir-asm.S | 114 +++++++++++++
platform/c128/lib/pfs-dir.c | 171 +++++++++++++++++++
platform/c128/lib/pfs.S | 28 ++-
platform/c64/Makefile.c64 | 3 +-
platform/c64/contiki-conf.h | 6 +
platform/c64/lib/pfs-dir-asm.S | 114 +++++++++++++
platform/c64/lib/pfs-dir.c | 171 +++++++++++++++++++
platform/c64/lib/pfs.S | 28 ++-
14 files changed, 636 insertions(+), 19 deletions(-)
create mode 100644 platform/c128/lib/pfs-dir-asm.S
create mode 100644 platform/c128/lib/pfs-dir.c
create mode 100644 platform/c64/lib/pfs-dir-asm.S
create mode 100644 platform/c64/lib/pfs-dir.c
diff --git a/core/cfs/cfs-posix-dir.c b/core/cfs/cfs-posix-dir.c
index 0eb2ba9cb..623471b29 100644
--- a/core/cfs/cfs-posix-dir.c
+++ b/core/cfs/cfs-posix-dir.c
@@ -36,6 +36,7 @@
#include
#include
+#define CFS_IMPL 1
#include "cfs/cfs.h"
struct cfs_posix_dir {
diff --git a/core/cfs/cfs-posix.c b/core/cfs/cfs-posix.c
index 1ee1b99df..452ddbbbb 100644
--- a/core/cfs/cfs-posix.c
+++ b/core/cfs/cfs-posix.c
@@ -40,6 +40,7 @@
#include
#endif
+#define CFS_IMPL 1
#include "cfs/cfs.h"
/*---------------------------------------------------------------------------*/
diff --git a/cpu/6502/lib/pfs.h b/cpu/6502/lib/pfs.h
index 73102ce55..51fcd7c5b 100644
--- a/cpu/6502/lib/pfs.h
+++ b/cpu/6502/lib/pfs.h
@@ -29,6 +29,7 @@
* This file is part of the Contiki operating system.
*
* Author: Oliver Schmidt
+ * Author: Greg King
*
*/
@@ -37,11 +38,17 @@
#include
+struct cfs_dir;
+struct cfs_dirent;
+
int __fastcall__ pfs_open(const char *name, int flags);
void __fastcall__ pfs_close(int fd);
int __fastcall__ pfs_read(int fd, void *buf, unsigned int len);
int __fastcall__ pfs_write(int fd, const void *buf, unsigned int len);
off_t __fastcall__ pfs_seek(int fd, off_t offset, int whence);
int __fastcall__ pfs_remove(const char *name);
+int __fastcall__ pfs_opendir(struct cfs_dir *dirp, const char *name);
+void __fastcall__ pfs_closedir(struct cfs_dir *dirp);
+int __fastcall__ pfs_readdir(struct cfs_dir *dirp, struct cfs_dirent *dirent);
#endif /* PFS_H_ */
diff --git a/examples/telnet-server/Makefile.c128.defines b/examples/telnet-server/Makefile.c128.defines
index 062a12cd7..d8cd8baee 100644
--- a/examples/telnet-server/Makefile.c128.defines
+++ b/examples/telnet-server/Makefile.c128.defines
@@ -1 +1 @@
-DEFINES = WITH_LOGGING,WITH_80COL
+DEFINES = WITH_LOGGING,WITH_PFS,WITH_80COL
diff --git a/platform/c128/Makefile.c128 b/platform/c128/Makefile.c128
index 0c674ee38..dab80b1dc 100644
--- a/platform/c128/Makefile.c128
+++ b/platform/c128/Makefile.c128
@@ -31,7 +31,8 @@
# Author: Oliver Schmidt
#
-CONTIKI_TARGET_SOURCEFILES += exec.c lseek.c pfs.S pfs_remove.S pfs_seek.S pfs_write.S
+CONTIKI_TARGET_SOURCEFILES += exec.c lseek.c \
+ pfs.S pfs-dir.c pfs-dir-asm.S pfs_remove.S pfs_seek.S pfs_write.S
CONTIKI_CPU = $(CONTIKI)/cpu/6502
include $(CONTIKI_CPU)/Makefile.6502
diff --git a/platform/c128/contiki-conf.h b/platform/c128/contiki-conf.h
index 057d6473d..0e72f20c4 100644
--- a/platform/c128/contiki-conf.h
+++ b/platform/c128/contiki-conf.h
@@ -37,6 +37,12 @@
#include "6502def.h"
+#if (WITH_PFS && !CFS_IMPL)
+#define cfs_opendir pfs_opendir
+#define cfs_closedir pfs_closedir
+#define cfs_readdir pfs_readdir
+#endif
+
#define CTK_CONF_MENU_KEY CH_F1
#define CTK_CONF_WINDOWSWITCH_KEY CH_F3
#define CTK_CONF_WIDGETUP_KEY CH_F5
diff --git a/platform/c128/lib/pfs-dir-asm.S b/platform/c128/lib/pfs-dir-asm.S
new file mode 100644
index 000000000..dbc1c956f
--- /dev/null
+++ b/platform/c128/lib/pfs-dir-asm.S
@@ -0,0 +1,114 @@
+;
+; Helper functions for pfs_opendir() and pfs_readdir()
+;
+; Close a directory listing that had been openned by pfs_opendir().
+;
+; 2012-06-01, Ullrich von Bassewitz
+; 2016-04-10, Greg King
+;
+
+ .importzp sp, ptr1, tmp1
+ .import pushax, _pfs_read, _pfs_close
+ .export __pfs_dirread1, __pfs_dirread
+
+ .export _pfs_closedir
+
+;---------------------------------------------------------------------------
+; Data structure
+
+.struct DIR
+ fd .word
+.endstruct
+
+;---------------------------------------------------------------------------
+; /* Read one byte from the directory into the supplied buffer.
+; ** Return true if the read was successful, and false otherwise.
+; */
+; unsigned char __fastcall__ _pfs_dirread1(struct cfs_dir *dir, void *buf);
+
+__pfs_dirread1:
+ jsr pushax ; Push buf
+ lda #1 ; Load count = 1
+
+; Run directly into __dirread
+
+;---------------------------------------------------------------------------
+; /* Read characters from the directory into the supplied buffer.
+; ** Return true if the read was successful, and false otherwise.
+; */
+; unsigned char __fastcall__ _pfs_dirread(struct cfs_dir *dir, void *buf,
+
+__pfs_dirread:
+ pha ; Save count
+
+; Replace dir by ((DIR*)dir)->fd.
+
+ ldy #$02
+ lda (sp),y
+ sta ptr1
+ iny
+ lda (sp),y
+ sta ptr1+1
+ ldy #DIR::fd+1
+ lda (ptr1),y
+ pha
+ dey
+ lda (ptr1),y
+ ldy #$02
+ sta (sp),y
+ pla
+ iny
+ sta (sp),y
+
+; Get count, save it again, clear the high byte, and call pfs_read().
+; By the previous actions, the stack frame is as pfs_read() needs it;
+; and, pfs_read() also will drop it.
+
+ pla
+ pha
+ ldx #>$0000
+ jsr _pfs_read
+
+; Check for errors.
+
+ cpx #>-1
+ beq L3
+
+; pfs_read() was successful; check number of bytes read. We assume that
+; pfs_read() will not return more than count; so, .X is zero if we come here.
+
+ sta tmp1 ; Save returned count
+ pla ; Our count
+ cmp tmp1
+ beq L2 ; OK, return count
+
+; Didn't read enough bytes. That is an error for us.
+
+ bne L1 ; Branch always
+
+; pfs_read() returned an error.
+
+L3: pla ; Drop count
+ inx ; .X = 0
+L1: txa ; Return zero
+L2: rts
+
+;---------------------------------------------------------------------------
+; void __fastcall__ pfs_closedir(struct cfs_dir *dirp);
+
+.proc _pfs_closedir
+ sta ptr1
+ stx ptr1+1
+
+; Load ((DIR *)dirp)->fd.
+
+ ldy #DIR::fd+1
+ lda (ptr1),y
+ tax
+ dey
+ lda (ptr1),y
+
+; Close the directory file.
+
+ jmp _pfs_close
+.endproc
diff --git a/platform/c128/lib/pfs-dir.c b/platform/c128/lib/pfs-dir.c
new file mode 100644
index 000000000..2b9d959f9
--- /dev/null
+++ b/platform/c128/lib/pfs-dir.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2016, Greg King
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions, and the following
+ * disclaimer, in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS"; AND, ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is a part of the Contiki operating system.
+ */
+
+/*
+** Open a directory listing, so that it can be read by pfs_readdir().
+**
+** Read one file-name from a directory listing that was opened by pfs_opendir().
+**
+** 2012-05-30, Ullrich von Bassewitz
+** 2016-04-22, Greg King
+*/
+
+#include "cfs.h"
+
+typedef struct {
+ int fd; /* File descriptor for a directory */
+} DIR;
+
+/*---------------------------------------------------------------------------*/
+/*
+** Read characters from the directory into the supplied buffer.
+** Return true if the read was successful, and false otherwise.
+*/
+extern unsigned char __fastcall__ _pfs_dirread(struct cfs_dir *dir, void *buf,
+ unsigned char count);
+
+/*
+** Read one byte from the directory into the supplied buffer.
+** Return true if the read was successful, and false otherwise.
+*/
+extern unsigned char __fastcall__ _pfs_dirread1(struct cfs_dir *dir, void *buf);
+/*---------------------------------------------------------------------------*/
+int __fastcall__
+pfs_opendir(struct cfs_dir *dirp, register const char *name)
+{
+ static int fd;
+ static char buf[2 + 1] = "$";
+
+ /* Set up the actual file name that is sent to the DOS.
+ ** We accept "0:", "1:", "/", and "." as directory names.
+ */
+ if(name == NULL || name[0] == '\0' || (name[0] == '.' || name[0] == '/') && name[1] == '\0') {
+ buf[1] = '\0';
+ } else if((name[0] == '0' || name[0] == '1') && name[1] == ':' && name[2] == '\0') {
+ buf[1] = name[0];
+ buf[2] = '\0';
+ } else {
+ return -1;
+ }
+
+ /* Open the directory on a disk, for reading. */
+ fd = pfs_open(buf, CFS_READ);
+ if(fd >= 0) {
+ ((DIR *)dirp)->fd = fd;
+
+ /* Skip the load address. */
+ if(_pfs_dirread(dirp, buf + 1, 2)) {
+ return 0;
+ } else {
+ pfs_close(fd);
+ }
+ }
+
+ return -1;
+}
+/*---------------------------------------------------------------------------*/
+int __fastcall__
+pfs_readdir(struct cfs_dir *dirp, register struct cfs_dirent *dirent)
+{
+ register unsigned char *b;
+ register unsigned char i;
+ register unsigned char count;
+ unsigned char buffer[0x40];
+ static unsigned char s;
+ static unsigned char j;
+
+ /* Skip the BASIC line-link. */
+ if(!_pfs_dirread(dirp, buffer, 2)) {
+ return -1;
+ }
+
+ /* Read the number of blocks. It's a two-byte number; but, the size is
+ ** a four-byte number. Zero the size; then, put the block number in
+ ** the first two bytes. It works because the 6502 CPU's numbers are
+ ** little-endian.
+ */
+ dirent->size = 0;
+ if(!_pfs_dirread(dirp, &dirent->size, 2)) {
+ return -1;
+ }
+
+ /* Read the next file entry into a buffer. */
+ for(count = 0, b = buffer; count < sizeof(buffer); ++b) {
+ if(!_pfs_dirread1(dirp, b)) {
+ return -1;
+ }
+ ++count;
+ if(*b == '\0') {
+ break;
+ }
+ }
+
+ /* The end of the directory was reached if the buffer contains "blocks free."
+ ** It is sufficient here to check for the leading 'b'. The buffer will have
+ ** at least one byte if we come here.
+ */
+ if(buffer[0] == 'b') {
+ return -1;
+ }
+
+ /* Parse the buffer for the file-name. */
+ b = buffer;
+ j = 0;
+ s = 0;
+ i = 0;
+ while(i < count) {
+ switch(s) {
+ case 0:
+ /* Search for the start of the file-name. */
+ if(*b == '"') {
+ s = 1;
+ }
+ break;
+ case 1:
+ /* Within the file-name. */
+ if(*b == '"') {
+ /* The end of the file-name was found. */
+ dirent->name[j] = '\0';
+ return 0;
+ } else if(j < sizeof(dirent->name) - 1) {
+ dirent->name[j] = *b;
+ ++j;
+ }
+ break;
+ }
+ ++b;
+ ++i;
+ }
+
+ /* The file-name is too long for the buffer. Return what could be read. */
+ dirent->name[j] = '\0';
+ return 0;
+}
diff --git a/platform/c128/lib/pfs.S b/platform/c128/lib/pfs.S
index 7947b67d8..b835f613e 100644
--- a/platform/c128/lib/pfs.S
+++ b/platform/c128/lib/pfs.S
@@ -36,7 +36,7 @@
.constructor init_pfs
.destructor done_pfs
- .importzp sp, ptr1, ptr2, ptr3
+ .importzp sp, ptr1, ptr2, ptr3, tmp1
.import curunit, __filetype, popax, addysp, subysp
.export pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend
.if F_IDE64
@@ -46,6 +46,7 @@
.export pfs_makename, pfs_scratch
.export _pfs_open, _pfs_read, _pfs_close
+
;---------------------------------------------------------------------
MAXLEN = 80 ;maximum filename length
@@ -107,7 +108,14 @@ _pfs_open:
lda FNL
beq error ;must have a filename
- lda #2 - 1 ;file number
+ ; A directory listing needs a special secondary address
+ ldy tmp1
+ bne open1 ;branch if not directory
+ lda #2 - 1
+ dey ;.Y = 0 - 1
+ bne open2 ;branch always
+
+open1: lda #2 - 1 ;file number
tay ;secondary address
open2: sta ptr2
sty ptr2 + 1
@@ -118,10 +126,6 @@ next: inc ptr2 ;next file number
bcs error ;no more files
lda flags - 1,x
bne next ;already used
- lda ptr2 + 1
- bne nextsa
- inx
- stx ptr2 + 1
nextsa: inc ptr2 + 1 ;next channel
retr: lda ptr2 ;file number
ldx curunit
@@ -209,7 +213,7 @@ pfs_makename:
; Validate the name; and, find its length
ldy #<-1
- sty ptr3
+ sty ptr3 ;init. the count of retries
sty ptr1
@L10: iny
cpy #MAXLEN
@@ -227,9 +231,17 @@ pfs_makename:
bne @L10
cpy #0
beq badchr ;no name
+ sty FNL ;save original length
tay ;zero index reg.
- lda #'0' ;drive 0 or current partition
+ lda (FN),y
+ sta tmp1 ;preset not-directory flag to true
+ cmp #'$'
+ bne @L9
+ sty tmp1 ;set not-directory flag to false
+ rts
+
+@L9: lda #'0' ;drive 0 or current partition
sta (sp),y
iny
inc ptr1
diff --git a/platform/c64/Makefile.c64 b/platform/c64/Makefile.c64
index f78dcf717..96b54c287 100644
--- a/platform/c64/Makefile.c64
+++ b/platform/c64/Makefile.c64
@@ -31,7 +31,8 @@
# Author: Oliver Schmidt
#
-CONTIKI_TARGET_SOURCEFILES += exec.c lseek.c pfs.S pfs_remove.S pfs_seek.S pfs_write.S
+CONTIKI_TARGET_SOURCEFILES += exec.c lseek.c \
+ pfs.S pfs-dir.c pfs-dir-asm.S pfs_remove.S pfs_seek.S pfs_write.S
CONTIKI_CPU = $(CONTIKI)/cpu/6502
include $(CONTIKI_CPU)/Makefile.6502
diff --git a/platform/c64/contiki-conf.h b/platform/c64/contiki-conf.h
index 7d5a8d070..102d01a77 100644
--- a/platform/c64/contiki-conf.h
+++ b/platform/c64/contiki-conf.h
@@ -37,6 +37,12 @@
#include "6502def.h"
+#if (WITH_PFS && !CFS_IMPL)
+#define cfs_opendir pfs_opendir
+#define cfs_closedir pfs_closedir
+#define cfs_readdir pfs_readdir
+#endif
+
#define CTK_CONF_MENU_KEY CH_F1
#define CTK_CONF_WINDOWSWITCH_KEY CH_F3
#define CTK_CONF_WIDGETUP_KEY CH_F5
diff --git a/platform/c64/lib/pfs-dir-asm.S b/platform/c64/lib/pfs-dir-asm.S
new file mode 100644
index 000000000..dbc1c956f
--- /dev/null
+++ b/platform/c64/lib/pfs-dir-asm.S
@@ -0,0 +1,114 @@
+;
+; Helper functions for pfs_opendir() and pfs_readdir()
+;
+; Close a directory listing that had been openned by pfs_opendir().
+;
+; 2012-06-01, Ullrich von Bassewitz
+; 2016-04-10, Greg King
+;
+
+ .importzp sp, ptr1, tmp1
+ .import pushax, _pfs_read, _pfs_close
+ .export __pfs_dirread1, __pfs_dirread
+
+ .export _pfs_closedir
+
+;---------------------------------------------------------------------------
+; Data structure
+
+.struct DIR
+ fd .word
+.endstruct
+
+;---------------------------------------------------------------------------
+; /* Read one byte from the directory into the supplied buffer.
+; ** Return true if the read was successful, and false otherwise.
+; */
+; unsigned char __fastcall__ _pfs_dirread1(struct cfs_dir *dir, void *buf);
+
+__pfs_dirread1:
+ jsr pushax ; Push buf
+ lda #1 ; Load count = 1
+
+; Run directly into __dirread
+
+;---------------------------------------------------------------------------
+; /* Read characters from the directory into the supplied buffer.
+; ** Return true if the read was successful, and false otherwise.
+; */
+; unsigned char __fastcall__ _pfs_dirread(struct cfs_dir *dir, void *buf,
+
+__pfs_dirread:
+ pha ; Save count
+
+; Replace dir by ((DIR*)dir)->fd.
+
+ ldy #$02
+ lda (sp),y
+ sta ptr1
+ iny
+ lda (sp),y
+ sta ptr1+1
+ ldy #DIR::fd+1
+ lda (ptr1),y
+ pha
+ dey
+ lda (ptr1),y
+ ldy #$02
+ sta (sp),y
+ pla
+ iny
+ sta (sp),y
+
+; Get count, save it again, clear the high byte, and call pfs_read().
+; By the previous actions, the stack frame is as pfs_read() needs it;
+; and, pfs_read() also will drop it.
+
+ pla
+ pha
+ ldx #>$0000
+ jsr _pfs_read
+
+; Check for errors.
+
+ cpx #>-1
+ beq L3
+
+; pfs_read() was successful; check number of bytes read. We assume that
+; pfs_read() will not return more than count; so, .X is zero if we come here.
+
+ sta tmp1 ; Save returned count
+ pla ; Our count
+ cmp tmp1
+ beq L2 ; OK, return count
+
+; Didn't read enough bytes. That is an error for us.
+
+ bne L1 ; Branch always
+
+; pfs_read() returned an error.
+
+L3: pla ; Drop count
+ inx ; .X = 0
+L1: txa ; Return zero
+L2: rts
+
+;---------------------------------------------------------------------------
+; void __fastcall__ pfs_closedir(struct cfs_dir *dirp);
+
+.proc _pfs_closedir
+ sta ptr1
+ stx ptr1+1
+
+; Load ((DIR *)dirp)->fd.
+
+ ldy #DIR::fd+1
+ lda (ptr1),y
+ tax
+ dey
+ lda (ptr1),y
+
+; Close the directory file.
+
+ jmp _pfs_close
+.endproc
diff --git a/platform/c64/lib/pfs-dir.c b/platform/c64/lib/pfs-dir.c
new file mode 100644
index 000000000..2b9d959f9
--- /dev/null
+++ b/platform/c64/lib/pfs-dir.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2016, Greg King
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions, and the following
+ * disclaimer, in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS"; AND, ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is a part of the Contiki operating system.
+ */
+
+/*
+** Open a directory listing, so that it can be read by pfs_readdir().
+**
+** Read one file-name from a directory listing that was opened by pfs_opendir().
+**
+** 2012-05-30, Ullrich von Bassewitz
+** 2016-04-22, Greg King
+*/
+
+#include "cfs.h"
+
+typedef struct {
+ int fd; /* File descriptor for a directory */
+} DIR;
+
+/*---------------------------------------------------------------------------*/
+/*
+** Read characters from the directory into the supplied buffer.
+** Return true if the read was successful, and false otherwise.
+*/
+extern unsigned char __fastcall__ _pfs_dirread(struct cfs_dir *dir, void *buf,
+ unsigned char count);
+
+/*
+** Read one byte from the directory into the supplied buffer.
+** Return true if the read was successful, and false otherwise.
+*/
+extern unsigned char __fastcall__ _pfs_dirread1(struct cfs_dir *dir, void *buf);
+/*---------------------------------------------------------------------------*/
+int __fastcall__
+pfs_opendir(struct cfs_dir *dirp, register const char *name)
+{
+ static int fd;
+ static char buf[2 + 1] = "$";
+
+ /* Set up the actual file name that is sent to the DOS.
+ ** We accept "0:", "1:", "/", and "." as directory names.
+ */
+ if(name == NULL || name[0] == '\0' || (name[0] == '.' || name[0] == '/') && name[1] == '\0') {
+ buf[1] = '\0';
+ } else if((name[0] == '0' || name[0] == '1') && name[1] == ':' && name[2] == '\0') {
+ buf[1] = name[0];
+ buf[2] = '\0';
+ } else {
+ return -1;
+ }
+
+ /* Open the directory on a disk, for reading. */
+ fd = pfs_open(buf, CFS_READ);
+ if(fd >= 0) {
+ ((DIR *)dirp)->fd = fd;
+
+ /* Skip the load address. */
+ if(_pfs_dirread(dirp, buf + 1, 2)) {
+ return 0;
+ } else {
+ pfs_close(fd);
+ }
+ }
+
+ return -1;
+}
+/*---------------------------------------------------------------------------*/
+int __fastcall__
+pfs_readdir(struct cfs_dir *dirp, register struct cfs_dirent *dirent)
+{
+ register unsigned char *b;
+ register unsigned char i;
+ register unsigned char count;
+ unsigned char buffer[0x40];
+ static unsigned char s;
+ static unsigned char j;
+
+ /* Skip the BASIC line-link. */
+ if(!_pfs_dirread(dirp, buffer, 2)) {
+ return -1;
+ }
+
+ /* Read the number of blocks. It's a two-byte number; but, the size is
+ ** a four-byte number. Zero the size; then, put the block number in
+ ** the first two bytes. It works because the 6502 CPU's numbers are
+ ** little-endian.
+ */
+ dirent->size = 0;
+ if(!_pfs_dirread(dirp, &dirent->size, 2)) {
+ return -1;
+ }
+
+ /* Read the next file entry into a buffer. */
+ for(count = 0, b = buffer; count < sizeof(buffer); ++b) {
+ if(!_pfs_dirread1(dirp, b)) {
+ return -1;
+ }
+ ++count;
+ if(*b == '\0') {
+ break;
+ }
+ }
+
+ /* The end of the directory was reached if the buffer contains "blocks free."
+ ** It is sufficient here to check for the leading 'b'. The buffer will have
+ ** at least one byte if we come here.
+ */
+ if(buffer[0] == 'b') {
+ return -1;
+ }
+
+ /* Parse the buffer for the file-name. */
+ b = buffer;
+ j = 0;
+ s = 0;
+ i = 0;
+ while(i < count) {
+ switch(s) {
+ case 0:
+ /* Search for the start of the file-name. */
+ if(*b == '"') {
+ s = 1;
+ }
+ break;
+ case 1:
+ /* Within the file-name. */
+ if(*b == '"') {
+ /* The end of the file-name was found. */
+ dirent->name[j] = '\0';
+ return 0;
+ } else if(j < sizeof(dirent->name) - 1) {
+ dirent->name[j] = *b;
+ ++j;
+ }
+ break;
+ }
+ ++b;
+ ++i;
+ }
+
+ /* The file-name is too long for the buffer. Return what could be read. */
+ dirent->name[j] = '\0';
+ return 0;
+}
diff --git a/platform/c64/lib/pfs.S b/platform/c64/lib/pfs.S
index 49ef496ec..eae0838d4 100644
--- a/platform/c64/lib/pfs.S
+++ b/platform/c64/lib/pfs.S
@@ -36,7 +36,7 @@
.constructor init_pfs
.destructor done_pfs
- .importzp sp, ptr1, ptr2, ptr3
+ .importzp sp, ptr1, ptr2, ptr3, tmp1
.import curunit, __filetype, popax, addysp, subysp
.export pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend
.if F_IDE64
@@ -46,6 +46,7 @@
.export pfs_makename, pfs_scratch
.export _pfs_open, _pfs_read, _pfs_close
+
;---------------------------------------------------------------------
MAXLEN = 80 ;maximum filename length
@@ -107,7 +108,14 @@ _pfs_open:
lda FNL
beq error ;must have a filename
- lda #2 - 1 ;file number
+ ; A directory listing needs a special secondary address
+ ldy tmp1
+ bne open1 ;branch if not directory
+ lda #2 - 1
+ dey ;.Y = 0 - 1
+ bne open2 ;branch always
+
+open1: lda #2 - 1 ;file number
tay ;secondary address
open2: sta ptr2
sty ptr2 + 1
@@ -118,10 +126,6 @@ next: inc ptr2 ;next file number
bcs error ;no more files
lda flags - 1,x
bne next ;already used
- lda ptr2 + 1
- bne nextsa
- inx
- stx ptr2 + 1
nextsa: inc ptr2 + 1 ;next channel
retr: lda ptr2 ;file number
ldx curunit
@@ -209,7 +213,7 @@ pfs_makename:
; Validate the name; and, find its length
ldy #<-1
- sty ptr3
+ sty ptr3 ;init. the count of retries
sty ptr1
@L10: iny
cpy #MAXLEN
@@ -227,9 +231,17 @@ pfs_makename:
bne @L10
cpy #0
beq badchr ;no name
+ sty FNL ;save original length
tay ;zero index reg.
- lda #'0' ;drive 0 or current partition
+ lda (FN),y
+ sta tmp1 ;preset not-directory flag to true
+ cmp #'$'
+ bne @L9
+ sty tmp1 ;set not-directory flag to false
+ rts
+
+@L9: lda #'0' ;drive 0 or current partition
sta (sp),y
iny
inc ptr1
From fb4c42a3573af5806e960cba103cfc747b892a44 Mon Sep 17 00:00:00 2001
From: Oliver Schmidt
Date: Sat, 15 Oct 2016 23:36:53 +0200
Subject: [PATCH 5/5] Added custom log function for CBM machines.
The log function writes directly to the screen. Combined with the usage of PFS this means that the POSIX layer of the C library isn't referenced anymore thus reducing the memory requirements.
---
cpu/6502/6502def.h | 6 ++++++
cpu/6502/lib/log.c | 11 +++++------
platform/c128/Makefile.c128 | 2 +-
platform/c128/contiki-conf.h | 2 ++
platform/c128/lib/logscr.S | 5 +++++
platform/c64/Makefile.c64 | 2 +-
platform/c64/contiki-conf.h | 2 ++
platform/c64/lib/logscr.S | 38 ++++++++++++++++++++++++++++++++++++
8 files changed, 60 insertions(+), 8 deletions(-)
create mode 100644 platform/c128/lib/logscr.S
create mode 100644 platform/c64/lib/logscr.S
diff --git a/cpu/6502/6502def.h b/cpu/6502/6502def.h
index 2da81b02e..c0f5c999a 100644
--- a/cpu/6502/6502def.h
+++ b/cpu/6502/6502def.h
@@ -74,6 +74,12 @@ typedef unsigned short uip_stats_t;
#define LOADER_CONF_ARCH "lib/unload.h"
+#ifdef HAVE_LOGSCR
+void logscr(const void *msg, unsigned len);
+#else
+#define logscr(msg, len) write(STDERR_FILENO, msg, len)
+#endif
+
#if MTU_SIZE
#define UIP_CONF_BUFFER_SIZE (UIP_LLH_LEN + MTU_SIZE)
#else /* MTU_SIZE */
diff --git a/cpu/6502/lib/log.c b/cpu/6502/lib/log.c
index 93ed0eeda..a259c06d6 100644
--- a/cpu/6502/lib/log.c
+++ b/cpu/6502/lib/log.c
@@ -32,7 +32,6 @@
*
*/
-#include
#include
#include "net/ip/uip.h"
@@ -43,8 +42,8 @@
void
uip_log(char *message)
{
- write(STDERR_FILENO, message, strlen(message));
- write(STDERR_FILENO, "\n", 1);
+ logscr(message, strlen(message));
+ logscr("\n", 1);
}
#endif /* UIP_LOGGING */
/*-----------------------------------------------------------------------------------*/
@@ -52,9 +51,9 @@ uip_log(char *message)
void
log_message(const char *part1, const char *part2)
{
- write(STDERR_FILENO, part1, strlen(part1));
- write(STDERR_FILENO, part2, strlen(part2));
- write(STDERR_FILENO, "\n", 1);
+ logscr(part1, strlen(part1));
+ logscr(part2, strlen(part2));
+ logscr("\n", 1);
}
#endif /* LOG_CONF_ENABLED */
/*-----------------------------------------------------------------------------------*/
diff --git a/platform/c128/Makefile.c128 b/platform/c128/Makefile.c128
index dab80b1dc..c1adbaf08 100644
--- a/platform/c128/Makefile.c128
+++ b/platform/c128/Makefile.c128
@@ -31,7 +31,7 @@
# Author: Oliver Schmidt
#
-CONTIKI_TARGET_SOURCEFILES += exec.c lseek.c \
+CONTIKI_TARGET_SOURCEFILES += exec.c logscr.S lseek.c \
pfs.S pfs-dir.c pfs-dir-asm.S pfs_remove.S pfs_seek.S pfs_write.S
CONTIKI_CPU = $(CONTIKI)/cpu/6502
diff --git a/platform/c128/contiki-conf.h b/platform/c128/contiki-conf.h
index 0e72f20c4..9ee7cc2b7 100644
--- a/platform/c128/contiki-conf.h
+++ b/platform/c128/contiki-conf.h
@@ -35,6 +35,8 @@
#ifndef CONTIKI_CONF_H_
#define CONTIKI_CONF_H_
+#define HAVE_LOGSCR
+
#include "6502def.h"
#if (WITH_PFS && !CFS_IMPL)
diff --git a/platform/c128/lib/logscr.S b/platform/c128/lib/logscr.S
new file mode 100644
index 000000000..e87e2aa17
--- /dev/null
+++ b/platform/c128/lib/logscr.S
@@ -0,0 +1,5 @@
+; 2016-04-28, Greg King
+;
+; The C128 function is the same as the C64 function.
+
+ .include "../../c64/lib/logscr.S"
diff --git a/platform/c64/Makefile.c64 b/platform/c64/Makefile.c64
index 96b54c287..7fcb4d19f 100644
--- a/platform/c64/Makefile.c64
+++ b/platform/c64/Makefile.c64
@@ -31,7 +31,7 @@
# Author: Oliver Schmidt
#
-CONTIKI_TARGET_SOURCEFILES += exec.c lseek.c \
+CONTIKI_TARGET_SOURCEFILES += exec.c logscr.S lseek.c \
pfs.S pfs-dir.c pfs-dir-asm.S pfs_remove.S pfs_seek.S pfs_write.S
CONTIKI_CPU = $(CONTIKI)/cpu/6502
diff --git a/platform/c64/contiki-conf.h b/platform/c64/contiki-conf.h
index 102d01a77..21ea459bd 100644
--- a/platform/c64/contiki-conf.h
+++ b/platform/c64/contiki-conf.h
@@ -35,6 +35,8 @@
#ifndef CONTIKI_CONF_H_
#define CONTIKI_CONF_H_
+#define HAVE_LOGSCR
+
#include "6502def.h"
#if (WITH_PFS && !CFS_IMPL)
diff --git a/platform/c64/lib/logscr.S b/platform/c64/lib/logscr.S
new file mode 100644
index 000000000..e9f297be7
--- /dev/null
+++ b/platform/c64/lib/logscr.S
@@ -0,0 +1,38 @@
+; 2002-11-16, Ullrich von Bassewitz
+; 2016-04-28, Greg King
+;
+; void logscr(const void *msg, unsigned len);
+
+ .export _logscr
+
+ .import BSOUT
+ .import popax
+ .importzp ptr1, ptr2
+
+;--------------------------------------------------------------------------
+
+.proc _logscr
+ eor #$FF
+ sta ptr2
+ txa
+ eor #$FF
+ sta ptr2+1 ; remember -count-1
+
+ jsr popax ; get buf
+ sta ptr1
+ stx ptr1+1
+
+L1: inc ptr2 ; count the char that will be printed
+ bne L2
+ inc ptr2+1
+ beq L9
+L2: ldy #$00
+ lda (ptr1),y
+ jsr BSOUT
+ inc ptr1
+ bne L1
+ inc ptr1+1
+ bne L1 ; branch always
+
+L9: rts
+.endproc