git: 0d3ad926cfcd - main - emulators/stonx: Build with free EmuTOS

From: Dirk Meyer <dinoex_at_FreeBSD.org>
Date: Sat, 12 Apr 2025 15:03:52 UTC
The branch main has been updated by dinoex:

URL: https://cgit.FreeBSD.org/ports/commit/?id=0d3ad926cfcd8bb9d4c66052368f7c929495bdd7

commit 0d3ad926cfcd8bb9d4c66052368f7c929495bdd7
Author:     Dirk Meyer <dinoex@FreeBSD.org>
AuthorDate: 2025-04-12 15:03:37 +0000
Commit:     Dirk Meyer <dinoex@FreeBSD.org>
CommitDate: 2025-04-12 15:03:37 +0000

    emulators/stonx: Build with free EmuTOS
    
    support localized ROMS
    add printer support
    preserve stonxrc on updates
    fix sound
---
 emulators/stonx/Makefile                      |  51 ++-
 emulators/stonx/distinfo                      |   3 +
 emulators/stonx/files/patch-AUTHORS           |   8 +
 emulators/stonx/files/patch-ChangeLog         |  27 ++
 emulators/stonx/files/patch-Makefile.in       |  36 +-
 emulators/stonx/files/patch-audio.c           |  20 +-
 emulators/stonx/files/patch-configure         |   6 +-
 emulators/stonx/files/patch-di_dis.c          |  51 +--
 emulators/stonx/files/patch-gemdos.c          | 566 ++++++++++++++++++++++++++
 emulators/stonx/files/patch-main.c            | 103 +++++
 emulators/stonx/files/patch-makefonts.sh      |   8 +-
 emulators/stonx/files/patch-mint_stonxfs_fs.c |   4 +-
 emulators/stonx/files/patch-options.h         |  19 +
 emulators/stonx/files/patch-x.c               |  12 +-
 emulators/stonx/pkg-plist                     |   2 +-
 15 files changed, 852 insertions(+), 64 deletions(-)

diff --git a/emulators/stonx/Makefile b/emulators/stonx/Makefile
index 5ea415c83443..e7b9dccbefa6 100644
--- a/emulators/stonx/Makefile
+++ b/emulators/stonx/Makefile
@@ -1,29 +1,28 @@
 PORTNAME=	stonx
 PORTVERSION=	0.6.7e.6
-PORTREVISION=	3
+PORTREVISION=	4
 CATEGORIES=	emulators
-MASTER_SITES=	SF/stonx/stonx/0.6.7.6
+MASTER_SITES=	SF/stonx/stonx/0.6.7.6 SF/emutos/emutos/1.3:tos
 DISTNAME=	STonX-0.6.7.6
+DISTFILES=	${DISTNAME}${EXTRACT_SUFX} emutos-512k-1.3.zip:tos
 
 MAINTAINER=	dinoex@FreeBSD.org
 COMMENT=	AtariST emulator
+WWW=		https://stonx.sourceforge.net/
 
-LICENSE=	GPLv2+ ROM
-LICENSE_COMB=	multi
-LICENSE_NAME_ROM=	Atari ROM
-LICENSE_TEXT_ROM=	Contains ROM (C) by Atari
-LICENSE_PERMS_ROM=	auto-accept
+LICENSE=	GPLv2+
 
 BUILD_DEPENDS=	bdftopcf:x11-fonts/bdftopcf \
 		gccmakedep:devel/gccmakedep \
 		mkfontscale:x11-fonts/mkfontscale \
 		${LOCALBASE}/share/fonts/misc/10x20-ISO8859-1.pcf.gz:x11-fonts/font-misc-misc
 
-TOSIMG?=	tos.img
 USES=		fonts xorg
 FONTNAME=	misc
 USE_XORG=	x11 sm ice xext xorgproto
-HAS_CONFIGURE=	yes
+GNU_CONFIGURE=	yes
+CONFIGURE_ENV+=	CC="${CC}" CFLAGS="${CFLAGS}"
+CONFIGURE_ENV+=	LDFLAGS="${LDFLAGS}"
 CONFIGURE_ARGS=	--x-includes=${LOCALBASE}/include \
 		--x-libraries=${LOCALBASE}/lib
 ALL_TARGET=	all fnttobdf tosfonts fonts
@@ -38,11 +37,36 @@ FONTS=	System0-iso.pcf System0.pcf System1-iso.pcf System1.pcf \
 	System2-iso.pcf System2.pcf
 
 OPTIONS_DEFINE=	DOCS EXAMPLES
+OPTIONS_DEFAULT=	UK
+OPTIONS_RADIO=  TOS
+OPTIONS_RADIO_TOS=	CZ DE ES FI FR GR HU IT NL NO RU SE SG TR UK US
+CZ_DESC=	Czech (PAL)
+DE_DESC=	German (PAL)
+ES_DESC=	Spanish (PAL)
+FI_DESC=	Finnish (PAL)
+FR_DESC=	French (PAL)
+GR_DESC=	Greek (PAL)
+HU_DESC=	Hungarian (PAL)
+IT_DESC=	Italian (PAL)
+NL_DESC=	Dutch (PAL)
+NO_DESC=	Norwegian (PAL)
+PL_DESC=	Polish (PAL)
+RO_DESC=	Romanian (PAL)
+RU_DESC=	Russian (PAL)
+SE_DESC=	Swedish (PAL)
+SG_DESC=	Swiss German (PAL)
+TR_DESC=	Turkish (PAL)
+UK_DESC=	English (PAL)
+US_DESC=	English (NTSC)
 
 .include <bsd.port.options.mk>
 
-pre-build:
-	${CP} ${DISTDIR}/${TOSIMG} ${WRKSRC}/tos.img
+pre-configure:
+.for l in ${OPTIONS_RADIO_TOS}
+.if ${PORT_OPTIONS:M${l}}
+	${CP} -v ${WRKDIR}/emutos-512k-1.3/etos512${l:tl}.img ${WRKSRC}/tos.img
+.endif
+.endfor
 
 post-install:
 .for f in ${ETCFILES}
@@ -63,9 +87,4 @@ post-install-EXAMPLES-on:
 	${MKDIR} ${STAGEDIR}${EXAMPLESDIR}
 	${INSTALL_DATA} ${DATA:S,^,${WRKSRC}/,} ${STAGEDIR}${EXAMPLESDIR}/
 
-.if !exists(${DISTDIR}/${TOSIMG})
-IGNORE=	please get a ROM dump from your AtariST and save it as\
-"${TOSIMG}" in "${DISTDIR}" manually, and then make again
-.endif
-
 .include <bsd.port.mk>
diff --git a/emulators/stonx/distinfo b/emulators/stonx/distinfo
index ae29881a8254..b90bb15f80e0 100644
--- a/emulators/stonx/distinfo
+++ b/emulators/stonx/distinfo
@@ -1,2 +1,5 @@
+TIMESTAMP = 1744129426
 SHA256 (STonX-0.6.7.6.tar.gz) = 664df47df3be34be852dff24d4a43f507bf0a1d4d137e8016128a23486aafbd8
 SIZE (STonX-0.6.7.6.tar.gz) = 379738
+SHA256 (emutos-512k-1.3.zip) = 65fcee085560745aaa8d9938bd35f7b2fe6277b035cc8146c349dcad4a5bc4c5
+SIZE (emutos-512k-1.3.zip) = 3441410
diff --git a/emulators/stonx/files/patch-AUTHORS b/emulators/stonx/files/patch-AUTHORS
new file mode 100644
index 000000000000..a53a755fd0e6
--- /dev/null
+++ b/emulators/stonx/files/patch-AUTHORS
@@ -0,0 +1,8 @@
+--- docs/AUTHORS.orig	2003-01-31 22:21:18 UTC
++++ docs/AUTHORS
+@@ -5,3 +5,5 @@ Alex Bennee <alex@bennee.com>
+ Till Harbaum <t.harbaum@tu-bs.de> (TH)
+ Thomas Huth <thothy@users.sourceforge.net> (Thothy)
+ Alex Bennee <alex@bennee.com>
++Hans-Peter Jansen <hpj@urpla.net> (hpj)
++Andreas Alich
diff --git a/emulators/stonx/files/patch-ChangeLog b/emulators/stonx/files/patch-ChangeLog
new file mode 100644
index 000000000000..0489524bbd04
--- /dev/null
+++ b/emulators/stonx/files/patch-ChangeLog
@@ -0,0 +1,27 @@
+--- ChangeLog.orig	2004-08-15 14:10:06 UTC
++++ ChangeLog
+@@ -1,3 +1,24 @@
++
++2004-12-25  Andreas Alich
++	* di_dis.c
++	  Fixes a number of bugs of the disassembler
++	  (which led to wrong output and also to crashes).
++	  The disassembler still disassembles lots of invalid instructions
++	  (opcode/adressing modes) without any hint that they are invalid.
++	  But at least valid instructions should be disassembled correctly now.
++
++2004-12-25  Andreas Alich
++	* gemdos.c
++	  Increases compatibility of STonx with real GEMDOS:
++	  Fdatime did not return correct date/time (conversion missing).
++	  Setting date/time was not implemented (now needs /proc-based OS).
++	  Reading in files opened with Fcreate was not possible.
++	  Fopen allowed opening directories.
++	  Fopen/Fcreate did not return error in case of invalid path.
++
++2001-09-01 Hans-Peter Jansen
++	* LPPIPES and quoted arguments in rc files added
++
+ 2004-08-15  Thomas Huth,  STonX-0.6.7.6
+ 
+ 	* audio.c, di_dis.c, di_dis.h, x.c, xlib_vdi.c, mint/mint_stonxfs_fs.c:
diff --git a/emulators/stonx/files/patch-Makefile.in b/emulators/stonx/files/patch-Makefile.in
index bac91f146e06..3097f7b50408 100644
--- a/emulators/stonx/files/patch-Makefile.in
+++ b/emulators/stonx/files/patch-Makefile.in
@@ -1,6 +1,6 @@
---- Makefile.in.orig	2004-08-15 16:35:04.000000000 +0200
-+++ Makefile.in	2014-04-11 20:36:37.000000000 +0200
-@@ -19,7 +19,7 @@
+--- Makefile.in.orig	2004-08-15 14:35:04 UTC
++++ Makefile.in
+@@ -19,7 +19,7 @@ STONXDIR=@datadir@/stonx
  exec_prefix = @exec_prefix@
  SYSCONFDIR = @sysconfdir@/stonx
  STONXDIR=@datadir@/stonx
@@ -9,7 +9,25 @@
  DISTDIR=STonX-@version@
  
  
-@@ -199,32 +199,32 @@
+@@ -41,7 +41,7 @@ XLIBS=@X_LIBS@ @X_PRE_LIBS@ -lXext -lX11 @X_EXTRA_LIBS
+ 
+ # X11 library path - I'm sure not everything here is X related?
+ XLIBS=@X_LIBS@ @X_PRE_LIBS@ -lXext -lX11 @X_EXTRA_LIBS@ @xtra@
+-SFLAGS=
++SFLAGS=@CFLAGS@
+ 
+ # Monitor support, call configure with --enable-monitor
+ MON_OBJS = @mon_objs@
+@@ -160,7 +160,7 @@ stonx:	$(OBJ) $(XOBJ) $(MOREOBJ)
+ cpu.o:	code.c
+ 
+ stonx:	$(OBJ) $(XOBJ) $(MOREOBJ)
+-	$(SCC) @static@ -o $@ $(OBJ) $(XOBJ) $(MOREOBJ) $(LIBS) $(XLIBS)
++	$(SCC) @static@ @LDFLAGS@ -o $@ $(OBJ) $(XOBJ) $(MOREOBJ) $(LIBS) $(XLIBS)
+ 
+ stonvga: $(OBJ) $(SVGAOBJ) $(MOREOBJ)
+ 	$(SCC) @static@ -o $@ $(OBJ) $(SVGAOBJ) $(MOREOBJ) $(SVGALIBS)
+@@ -199,32 +199,32 @@ install:
  
  install:
  	install -d -m 755 $(INSTBIN)
@@ -47,11 +65,11 @@
 -	echo "vbl 2 refresh 2 chunky" >> $(SYSCONFDIR)/stonxrc ; \
 -	echo "boot c" >> $(SYSCONFDIR)/stonxrc ; \
 +	echo "Creating ${DESTDIR}$(SYSCONFDIR)/stonxrc" >&2; \
-+	echo "cartridge $(STONXDIR)/cartridge.img" > ${DESTDIR}$(SYSCONFDIR)/stonxrc ; \
-+	echo "tos $(STONXDIR)/tos.img" >> ${DESTDIR}$(SYSCONFDIR)/stonxrc ; \
-+	echo "fs C:$(STONXDIR)/gemdos_c" >> ${DESTDIR}$(SYSCONFDIR)/stonxrc ; \
-+	echo "vbl 2 refresh 2 chunky" >> ${DESTDIR}$(SYSCONFDIR)/stonxrc ; \
-+	echo "boot c" >> ${DESTDIR}$(SYSCONFDIR)/stonxrc ; \
++	echo "cartridge $(STONXDIR)/cartridge.img" > ${DESTDIR}$(SYSCONFDIR)/stonxrc.sample ; \
++	echo "tos $(STONXDIR)/tos.img" >> ${DESTDIR}$(SYSCONFDIR)/stonxrc.sample ; \
++	echo "fs C:$(STONXDIR)/gemdos_c" >> ${DESTDIR}$(SYSCONFDIR)/stonxrc.sample ; \
++	echo "vbl 2 refresh 2 chunky" >> ${DESTDIR}$(SYSCONFDIR)/stonxrc.sample ; \
++	echo "boot c" >> ${DESTDIR}$(SYSCONFDIR)/stonxrc.sample ; \
  	fi
  	@if test -f data/tos.img ; then \
 -	  echo "install -c -m 0644  data/tos.img" $(STONXDIR)/tos.img ; \
diff --git a/emulators/stonx/files/patch-audio.c b/emulators/stonx/files/patch-audio.c
index 76d948065c5f..a79cdd02a8ba 100644
--- a/emulators/stonx/files/patch-audio.c
+++ b/emulators/stonx/files/patch-audio.c
@@ -1,6 +1,6 @@
---- audio.c.orig	2004-08-15 16:07:55.000000000 +0200
-+++ audio.c	2010-04-03 09:44:58.000000000 +0200
-@@ -45,6 +45,9 @@
+--- audio.c.orig	2004-08-15 14:07:55 UTC
++++ audio.c
+@@ -45,6 +45,9 @@ extern int snd_porta;
  #include <linux/sched.h>
  #include <linux/unistd.h>
  #endif
@@ -10,3 +10,17 @@
  #elif defined(__NetBSD__) || defined(__OpenBSD__)
  /* NetBSD's Linux API emulation, require -lossaudio too */
  #include <soundcard.h>
+@@ -1558,11 +1561,12 @@ void audio_open(void) 
+ #if 0
+ 	child_pid = clone(0,SIGCLD);
+ #else
+-	child_pid = fork();
++	child_pid = _Fork();
+ #endif
+ 	switch (child_pid)
+ 	{	case 0: 
+ 			audio_server();	
++			_exit(0);
+ 		case -1:
+ 			fprintf(stderr,"Failed to fork() Audio server\n");
+ 			break;
diff --git a/emulators/stonx/files/patch-configure b/emulators/stonx/files/patch-configure
index 7cee9c4f6c6d..38c2066894c8 100644
--- a/emulators/stonx/files/patch-configure
+++ b/emulators/stonx/files/patch-configure
@@ -1,6 +1,6 @@
---- configure.orig	2004-08-15 15:36:21.000000000 +0200
-+++ configure	2010-04-03 09:57:44.000000000 +0200
-@@ -3989,6 +3990,30 @@
+--- configure.orig	2004-08-15 13:36:21 UTC
++++ configure
+@@ -3989,6 +3989,30 @@ _ACEOF
  	esac
  	copt="$copt -funroll-loops"
  	;;
diff --git a/emulators/stonx/files/patch-di_dis.c b/emulators/stonx/files/patch-di_dis.c
index 727e1121dca3..8094f856f612 100644
--- a/emulators/stonx/files/patch-di_dis.c
+++ b/emulators/stonx/files/patch-di_dis.c
@@ -1,6 +1,6 @@
---- STonX-0.6.7.6.orig/di_dis.c	2004-08-15 14:33:40.000000000 +0200
-+++ di_dis.c	2004-12-25 15:21:15.000000000 +0100
-@@ -76,7 +76,6 @@
+--- di_dis.c.orig	2004-08-15 12:33:40 UTC
++++ di_dis.c
+@@ -76,7 +76,6 @@ static const OP_DEF table[] = {
  
  static const OP_DEF table[] = {
  	"ABCD",0xc100,0xf1f0,type_14,
@@ -8,7 +8,7 @@
  
  	"RESET",0x4e70,0xffff,type_10,
  	"RTE",0x4e73,0xffff,type_10,
-@@ -105,12 +104,12 @@
+@@ -105,12 +104,12 @@ static const OP_DEF table[] = {
  	"NBCD",0x4800,0xffc0,type_15,
  	"PEA",0x4840,0xffc0,type_5,
  
@@ -23,7 +23,7 @@
  
  	"TST",0x4a00,0xff00,type_7,
  	"CLR",0x4200,0xff00,type_15,
-@@ -152,13 +151,13 @@
+@@ -152,13 +151,13 @@ static const OP_DEF table[] = {
  	"SVC",0x58c0,0xffc0,type_5,
  	"SVS",0x59c0,0xffc0,type_5,
  	"ADDQ",0x5000,0xf100,type_6,
@@ -41,7 +41,7 @@
  	"BCC",0x6400,0xff00,type_8,
  	"BCS",0x6500,0xff00,type_8,
  	"BEQ",0x6700,0xff00,type_8,
-@@ -175,15 +174,14 @@
+@@ -175,15 +174,14 @@ static const OP_DEF table[] = {
  	"BVS",0x6900,0xff00,type_8,
  	"BRA",0x6000,0xff00,type_8,
  	"BSR",0x6100,0xff00,type_8,
@@ -61,7 +61,7 @@
  	"MOVE.B",0x1000,0xf000,type_4,
  	"MOVE.W",0x3000,0xf000,type_4,
  	"MOVE.L",0x2000,0xf000,type_4,
-@@ -196,10 +194,10 @@
+@@ -196,10 +194,10 @@ static const OP_DEF table[] = {
  	"%6lx   EORI   #$%x,SR",0x0a7c,0xffff,type_27,
  	"%6lx   ANDI   #$%x,CCR",0x023c,0xffff,type_27,	/*	ANDI #<data>,CCR	*/
  	"%6lx   ANDI   #$%x,SR",0x027c,0xffff,type_27,	/*	ANDI #data,SR		*/
@@ -76,7 +76,7 @@
  	"BTST",0x0800,0xffc0,type_20,
  	"BSET",0x08c0,0xffc0,type_20,
  	"BCHG",0x0840,0xffc0,type_20,
-@@ -216,14 +214,23 @@
+@@ -216,14 +214,23 @@ static const OP_DEF table[] = {
  	"BCHG",0x0140,0xf1c0,type_21,
  	"BCLR",0x0180,0xf1c0,type_21,
  
@@ -104,18 +104,19 @@
  	"SUBQ",0x5100,0xf100,type_6,
  	"SUBA",0x90c0,0xf0c0,type_3,   /* SUBA can look like a SUBX! */
  	"SUBX",0x9100,0xf130,type_14,
-@@ -237,7 +244,9 @@
+@@ -237,8 +244,10 @@ static const char *data_regs[] = {
  static const char *data_regs[] = {
  	"D0","D1","D2","D3","D4","D5","D6","D7"};
  
 -static const char *sizes[] = {".B",".W",".L"};
 +static const char *sizes[] = {".B",".W",".L",".?"};
-+
-+static const char *unknown = "??";
  
++static const char *unknown = "??";
++
  void *dis(void *c,char *s)
  {
-@@ -309,7 +318,7 @@
+ 	/*
+@@ -309,7 +318,7 @@ static UWORD *type_27(UWORD *c,char *s,WORD index)
  	ULONG adr;
  /*	WORD data;	*/
  
@@ -124,7 +125,7 @@
          c++;
  	sprintf(s,table[index].op,adr,LM_UW(MEM(c)));
  	return(++c);
-@@ -524,7 +533,14 @@
+@@ -524,7 +533,14 @@ static UWORD *type_21(UWORD *c,char *s,WORD index)
  	adr = (long)c;
  	dest_reg = (LM_UW(MEM(c)) & 0x0e00) >> 9;	/*	get destination reg	*/
  	source = LM_UW(MEM(c)) & 0x3f;				/*	this is an effective address	*/
@@ -140,7 +141,7 @@
  	sprintf(s,"%6lx   %s  %s,%s",adr,table[index].op,data_regs[dest_reg],e_a);
  	++c;
  	return(c);
-@@ -575,7 +591,7 @@
+@@ -575,7 +591,7 @@ static UWORD *type_18(UWORD *c,char *s,WORD index)
  	const char *rx,*ry;
  
  	adr = (long)c;
@@ -149,7 +150,7 @@
  	source = (LM_UW(MEM(c)) & 0x0e00) >> 9;
  	op_mode = (LM_UW(MEM(c)) & 0xf8) >> 3;
  	if(op_mode == 0x08)
-@@ -593,6 +609,11 @@
+@@ -593,6 +609,11 @@ static UWORD *type_18(UWORD *c,char *s,WORD index)
  		rx = data_regs[source];
  		ry = adr_regs[dest];
  	}
@@ -161,7 +162,7 @@
  	sprintf(s,"%6lx   %s  %s,%s",adr,table[index].op,rx,ry);
  	++c;
  	return(c);
-@@ -693,7 +714,7 @@
+@@ -693,7 +714,7 @@ static UWORD *type_13(UWORD *c,char *s,WORD index)
  	}
  	else
  	{
@@ -170,7 +171,7 @@
  	}
  	c = effective_address(c,e_a,dest,index,0);
  	sprintf(s,"%6lx   %s%s  #$%lx,%s",adr,table[index].op,sizes[size],il_data,e_a);
-@@ -731,7 +752,7 @@
+@@ -731,7 +752,7 @@ static UWORD *type_11(UWORD *c,char *s,WORD index)
  	size = (LM_UW(MEM(c)) & 0x0c0) >> 6;
  	if(size < 3)	/*	register shifts	*/
  	{
@@ -179,7 +180,7 @@
  		dest = (LM_UW(MEM(c)) & 0x07);
  		count = (LM_UW(MEM(c)) & 0x0e00)>>9;
  		if(type)
-@@ -796,9 +817,9 @@
+@@ -796,9 +817,9 @@ static UWORD *type_8(UWORD *c,char *s,WORD index)
  	else
  	{
  		size = ".S";
@@ -191,7 +192,7 @@
  	sprintf(s,"%6lx   %s%s  $%lx",adr,table[index].op,size,dest);
  	++c;
  	return(c);
-@@ -952,7 +973,7 @@
+@@ -952,7 +973,7 @@ static UWORD *type_1(UWORD *c,char *s,WORD index)
  	adr = (long)c;
  	the_reg = LM_UW(MEM(c)) & 0x07;	/*	get register number	*/
  	++c;	                /*	point to word displacement	*/
@@ -200,7 +201,7 @@
  	++c;
  	return(c);
  }
-@@ -1043,7 +1064,7 @@
+@@ -1043,7 +1064,7 @@ static UWORD *effective_address(UWORD *a,char *s,UWORD
  			displacement = LM_UW(MEM(a)) & 0xff;
  			index_reg = (LM_UW(MEM(a)) & 0x7000) >> 12;
  			index_reg_ind = (LM_UW(MEM(a)) & 0x8000)>> 15;
@@ -209,7 +210,7 @@
  			if(index_size)
  			{
  				s1 = ".L";
-@@ -1082,15 +1103,15 @@
+@@ -1082,15 +1103,15 @@ static UWORD *effective_address(UWORD *a,char *s,UWORD
  				case 2:	/*	program counter with displacement	*/
  					++a;
  					displacement = LM_UW(MEM(a));
@@ -228,15 +229,15 @@
  					a1 += (long)a;
  					if(index_size)
  					{
-@@ -1134,6 +1155,11 @@
+@@ -1133,6 +1154,11 @@ static UWORD *effective_address(UWORD *a,char *s,UWORD
+ 						else if (op_mode == BYTE_SIZE)
  							sprintf(s,"#$%x.B",displacement);
  					}
- 					break;
++					break;
 +				case 5:
 +				case 6:
 +				case 7:
 +					sprintf (s, "%s", unknown);
-+					break;
+ 					break;
  			default:
  			  {
- 			    fprintf(stderr,"Overun decode!\n");
diff --git a/emulators/stonx/files/patch-gemdos.c b/emulators/stonx/files/patch-gemdos.c
new file mode 100644
index 000000000000..c0d8b8796bed
--- /dev/null
+++ b/emulators/stonx/files/patch-gemdos.c
@@ -0,0 +1,566 @@
+--- gemdos.c.orig	2003-12-19 20:56:06 UTC
++++ gemdos.c
+@@ -10,6 +10,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <time.h>
++#include <utime.h>
+ #include <unistd.h>
+ #include <ctype.h>
+ #include <errno.h>
+@@ -83,6 +84,9 @@ typedef struct
+ {
+     UL bp;
+     int f,redirected;
++#if LPPIPES
++    FILE *lpp;	/* special pipe descriptor for PRN:/AUX: device handling */
++#endif
+ } FINFO;
+ 
+ #define MAXDRIVES 26
+@@ -93,13 +97,24 @@ char curpath[MAXDRIVES][500];
+ UL gemdos_drives = 0;
+ UW curdrv=0;
+ char curpath[MAXDRIVES][500];
++#if LPPIPES
++char *prnpipe = NULL;
++char *auxpipe = NULL;
++#define MAXFILES 128	/* try to conform with default GEMDOS limits */
++#define H_OFFSET 6	/* and behaviour */
++#define MAXDIRS  256	/* At least, _I_ need this */
++#else
++/* FIXME: don't no the intension of those strange values
++ * stonx used here. These parameters need further discussion.
++ * see above attempt to fix them */
+ #define MAXFILES 100
+ #define H_OFFSET 80 /* < 100 because of problems with PC/TC's assembler */
++#define MAXDIRS  40
++#endif
+ 	/* FIXME: There should be one handle-pool only!  */
+ static FINFO file[MAXFILES];
+ static int redirect_stdh[6][MAXFILES];
+ void *act_pd;
+-#define MAXDIRS 40
+ 
+ DIR *fsdir[MAXDIRS];
+ char curspath[MAXDIRS][500];
+@@ -282,8 +297,9 @@ void Dsetdrv (UW drv)
+ 
+ void Dsetdrv (UW drv)
+ {
++    DBG("Dsetdrv(%c), db: 0x%x = ",'A'+drv, drive_bits);
+     curdrv = drv;
+-#if 0
++#if 1
+     if (BIT(drv,drive_bits) == 0)
+     {
+ 	DREG(0) = TOS_EDRIVE;
+@@ -296,17 +312,20 @@ void Dsetdrv (UW drv)
+ 	SET_Z();
+     }
+ #endif
++    DBG("%d (curdrv: %d)\n", DREG(1), curdrv);
+ }
+ 
+ void Dgetdrv (void)
+ {
+     DREG(0) = curdrv;
++    DBG("Dgetdrv() = %d\n", curdrv);
+     SET_Z();
+ }
+ 
+ void Fsetdta (UL dtaptr)
+ {
+     UL bp = LM_UL(act_pd);
++    DBG("Process %lx DTA = %lx\n", (long)bp, (long)dtaptr);
+ #if 0
+     SM_UL(MEM(bp+32),dtaptr);
+     SET_Z();
+@@ -333,6 +352,7 @@ void fname2unix (char *stpath, char *unixpath)
+ 	n++;
+     }
+     *unixpath=0;
++    DBG("Converted <%s> to <%s>\n", a, b);
+ }
+ 
+ static char lastpath[500];
+@@ -344,6 +364,7 @@ int st2unixpath (char *stpath, char *unixpath)
+     drv = (stpath[1] == ':' ? toupper(stpath[0])-'A' : curdrv);
+     if (((gemdos_drives>>drv)&1) == 0)
+     {
++	DBG("ERROR in st2unixpath <%s>\n", stpath);
+ 	*unixpath=0;
+ 	return 0;
+     }
+@@ -359,6 +380,7 @@ int st2unixpath (char *stpath, char *unixpath)
+     }
+     fname2unix(lastpath,path);
+     sprintf(unixpath,"%s%s",root[drv],path);
++    DBG("st2unixpath(%s) = <%s>\n", stpath, unixpath);
+     return 1;
+ }
+ 
+@@ -382,27 +404,50 @@ int unix2fname (char *unixname, char *stname)
+ 	p++;
+     }
+     *stname=0;
++    DBG("ufile: <%s> stfile: <%s>\n", unixname, q);
+     return 1;
+ }
+ 
+ static int match (char *pat, char *name)
+ {
+-    if (strcmp(pat,"*.*")==0) return 1;
+-    else if (strcasecmp(pat,name)==0) return 1;
++    DBG("Match(<%s>, <%s>) ", pat, name);
++    if (strcmp(pat,"*.*")==0)
++    {
++		DBG("OK\n");
++		return 1;
++    }
++    else if (strcasecmp(pat,name)==0)
++    {
++		DBG("OK\n");
++		return 1;
++    }
+     else
+     {
+ 	char *p=pat,*n=name;
+ 	for(;*n;)
+ 	{
+-	    if (*p=='*') {while (*n && *n != '.') n++;p++;}
+-	    else if (*p=='?' && *n) {n++;p++;}
+-	    else if (*p++ != *n++) return 0;
++	    if (*p=='*') {
++			while (*n && *n != '.')
++				n++;	/* skip to extension */
++			p++;		/* step over '*' */
++		}
++	    else if (*p=='?' && *n) {
++			n++; p++;	/* single match */
++		}
++	    else if (toupper(*p++) != *n++) {
++			/* FIXME: TOS always uses uppercase letters */
++			/* does mint behave different? hpj */
++			DBG("Failed\n");
++			return 0;
++		}
+ 	}
+ 	if (*p==0)
+ 	{
++		DBG("OK\n");
+ 	    return 1;
+ 	}
+     }
++    DBG("Failed\n");
+     return 0;
+ }
+ 
+@@ -411,6 +456,7 @@ void compress_path (char *path)
+     char *lastdir=NULL, lastchar=0, *d, *p=path;
+     char *dirstack[MAXDIRS];
+     int a=0, i;
++    DBG("Before path compression: <%s>\n", p);
+     d = path;
+     while (*p)
+     {
+@@ -441,6 +487,7 @@ void compress_path (char *path)
+     }
+     if (d != path && *(d-1) == '\\') d--;
+     *d=0;
++    DBG("Result of path compression: %s\n", path);
+ }
+ 
+ int xopendir (char *p, int doopen)
+@@ -496,7 +543,19 @@ UW date2dos (time_t t)
+     return x->tm_mday|((x->tm_mon+1)<<5)|(MAX(x->tm_year-80,0)<<9);
+ }
+ 
++time_t dos2time (UW time, UW date)
++{
++    struct tm brokentime;
+ 
++    brokentime.tm_sec = (time & 0x001f) << 1;
++    brokentime.tm_min = (time & 0x07e0) >> 5;
++    brokentime.tm_hour = (time & 0xf800) >> 11;
++    brokentime.tm_mday = (date & 0x001f);
++    brokentime.tm_mon = (date & 0x01e0) >> 5;
++    brokentime.tm_year = ((date & 0xfe00) >> 9) + 80;
++    return mktime(&brokentime);
++}
++
+ void Fsnext (void)
+ {
+     UL bp;
+@@ -522,6 +581,7 @@ void Fsnext (void)
+     bp = LM_UL(act_pd);
+     dta = (DTA *)MEM(LM_UL(MEM(bp+32)));
+     attribs = LM_UB(&(dta->dta_sattrib));
++    DBG("Fsnext(%s)\n", dta->dta_pat);
+ 
+  repeat:
+     SM_UL((UL *)&(dta -> magic),EVALID);
+@@ -530,6 +590,7 @@ void Fsnext (void)
+ 	rr = (LM_W((W *)&(dta->index)));
+ 	if (rr < 0) {
+ 	    if (rr == -1) {
++		DBG("(no more files)\n");
+ 		DREG(0) = TOS_ENMFIL;
+ 		SET_Z();
+ 		return;
+@@ -548,6 +609,7 @@ void Fsnext (void)
+ 	    e = xreaddir (rr);
+ 	    if (e == NULL)
+ 	    {	
++		DBG("(no more files)\n");
+ 		DREG(0) = TOS_ENMFIL;
+ 		SET_Z();
+ 		xclosedir(LM_UW((UW *)&(dta->index)));
+@@ -558,6 +620,7 @@ void Fsnext (void)
+     SM_UL((UL *)&(dta->magic),SVALID);
+     strcpy(dta->dta_name, stname);
+     sprintf (uname, "%s/%s", curspath[rr], e->d_name);
++    DBG("stat(%s)\n", uname);
+     if (STATFUNC (uname, &s) < 0)
+ 	goto repeat;
+     da = (s.st_mode & S_IFDIR)?0x10:0; 	/* FIXME */
+@@ -600,7 +663,7 @@ void Dsetpath (char *pname)
+ 	return;
+     }
+     if (pname[1] == ':') strcpy(pname,&pname[2]); /* for Dsetdrv(C:\FOO) */
+-    if (pname[0] == '\\') strcpy(curpath[drv],pname);
++    if (!pname[0] || (pname[0] == '\\')) strcpy(curpath[drv],pname);
+     else
+     {
+ 	strcat(curpath[drv],"\\");
+@@ -609,6 +672,8 @@ void Dsetpath (char *pname)
+ #if 1
+     compress_path(curpath[drv]);
+ #endif
++    DBG("Dsetpath(%s) -> %s on drive %d <%s>\n",
++				pname, curpath[drv], curdrv, upath);
+     /* FIXME */
+     DREG(0)=0;
+     SET_Z();
+@@ -626,6 +691,7 @@ void Fsfirst (char *fspec, UW attribs)
+ 	cursdrv=999;
+ 	return;
+     }
++	DBG("Fsfirst(%s,%x) on drive %d\n", fspec, attribs, curdrv);
+     if (fspec[1]==':') cursdrv=toupper(fspec[0])-'A';
+     else cursdrv=curdrv;
+     bp = LM_UL(act_pd);
+@@ -657,6 +723,7 @@ void Fsfirst (char *fspec, UW attribs)
+ 	!strchr (dta -> dta_pat, '*')) {
+ 	r = xopendir (upath, 0);
+     } else {
++	DBG("Opendir(%s)\n", upath);
+ 	r = xopendir (upath, 1);
+ 	if (r < 0)
+ 	{
+@@ -690,13 +757,17 @@ void Fopen (char *fname, UW mode)
+     UL bp;
+     int f;
+     char upath[500];
++    struct stat s;
++
+     if (!st2unixpath(fname, upath))
+     {
+ 	DBG("Fopen(%s,%x) drive %d not done\n",fname,mode,curdrv);
++	DREG(0) = TOS_EFILNF;
++	SET_Z();
+ 	return;
+     }
+     bp = LM_UL(act_pd);
+-    DBG("Fopen(%s,%x) on drive %d -> %s\n",fname,mode,curdrv,upath);
++    DBG("Fopen(\"%s\",%x) on drive %d -> %s\n",fname,mode,curdrv,upath);
+     for (i=0; i<MAXFILES && file[i].bp != 0; i++)
+ 	if (i >= MAXFILES)
+ 	{
+@@ -713,6 +784,13 @@ void Fopen (char *fname, UW mode)
+ 	SET_Z();
+ 	return;
+     }
++    fstat(f,&s);
++    if (S_ISDIR(s.st_mode)) {
++	DBG("Fopen: %s is a directory\n",fname);
++	DREG(0) = TOS_EFILNF;
++	SET_Z();
++	return;
++    }
+     file[i].bp = bp;
+     file[i].f = f;
+     file[i].redirected = 0;
+@@ -738,6 +816,15 @@ void Fread (W handle, UL count, char *buf)
+ 	SET_Z();
+ 	return;
+     }
++#if LPPIPES
++    /* ignore reading on a lppipe */
++    if (file[i].lpp)
++    {
++	DREG(0) = 0;
++	SET_Z();
++	return;
++    }
++#endif
+     if (count > 0x1fffffff) count = 0x1fffffff;
+     rd = FREAD_CHUNK;
+     for(;count > 0;)
+@@ -775,7 +862,16 @@ void Fclose (W handle)
+ 	SET_Z();
+ 	return;
+     }
+-    close(file[i].f);
++#if LPPIPES
++    /* close lp pipe */
++    if (file[i].lpp)
++    {
++	pclose(file[i].lpp);
++	file[i].lpp = NULL;
++    }
++    else
++#endif
++	close(file[i].f);
+     file[i].bp = 0;
+     file[i].f = -1;
+     /* handle end of redirection (see Fforce) */
+@@ -787,16 +883,66 @@ void Fcreate (char *fname, UW attribs)
+ 
+ void Fcreate (char *fname, UW attribs)
+ {
+-    int i;
+-    UL bp;
+-    int f;
++    int i=0;
++    int f=0;
++    UL bp=LM_UL(act_pd);
+     char upath[500];
++
++#if LPPIPES
++    /* check for a pipe command */
++    if (prnpipe && !strcasecmp(fname, "PRN:"))
++	f = 'p';
++
++    if (auxpipe && !strcasecmp(fname, "AUX:"))
++	f = 'a';
++
++    if (f)
++    {
++	/* create new pipe */
++	for (i=0; i<MAXFILES && file[i].bp != 0; i++)
++	    ;
++	if (i >= MAXFILES)
++	{
++	    DREG(0) = TOS_ENMFIL;
++	    SET_Z();
++	    return;
++	}
++
++	if (f == 'a')
++	{
++	    file[i].lpp = popen(auxpipe, "w");
++	    DBG("Fcreate(%s) -> %s = %d ", fname, auxpipe, i+H_OFFSET);
++	} else if (f == 'p') {
++	    file[i].lpp = popen(prnpipe, "w");
++	    DBG("Fcreate(%s) -> %s = %d ", fname, prnpipe, i+H_OFFSET);
++	}
++
++	if (file[i].lpp)
++	{
++	    file[i].bp = bp;
++	    file[i].f = i;
++	    file[i].redirected = 0;
++	    DREG(0) = i+H_OFFSET;
++	    SET_Z();
++	    DBG("OK\n");
++	}
++	else
++	{
++	    DREG(0) = TOS_EACCDN;
++	    SET_Z();
++	    DBG("Failed\n");
++	}
++	return;
++    }
++#endif
++
+     if (!st2unixpath(fname, upath))
+     {
+ 	DBG("Fcreate(%s,%x) drive %d not done\n",fname,attribs,curdrv);
++	DREG(0) = TOS_EPTHNF;
++	SET_Z();
+ 	return;
+     }
+-    bp = LM_UL(act_pd);
+     DBG("Fcreate(%s,%x) on drive %d -> %s\n",fname,attribs,curdrv,upath);
+     if (attribs == FA_LABEL) {
+ 	DBG("\tDrivelabels cannot be created!\n");
+@@ -813,7 +959,7 @@ void Fcreate (char *fname, UW attribs)
+ 	    return;
+ 	}
+     
+-    f = creat(upath,DEFAULT_MODE);
++    f = open(upath,O_CREAT|O_RDWR|O_TRUNC,DEFAULT_MODE);
+     if (f < 0)
+     {
+ 	DBG("creat(): %s\n",strerror(errno));
+@@ -843,7 +989,12 @@ void Fwrite (W handle, UL count, char *buf)
+ 	SET_Z();
+ 	return;
+     }
+-    r = write (file[i].f, buf, (size_t) count);
++#if LPPIPES
++    if (file[i].lpp)
++	r = fwrite(buf, 1, (size_t) count, file[i].lpp);
++    else
++#endif
++	r = write (file[i].f, buf, (size_t) count);
+     if ( r < 0 )
+ 	r = unix2toserrno( errno, TOS_EACCDN );
+     DBG("\tReturnvalue for handle %d = %d\n",i+H_OFFSET,r);
+@@ -856,6 +1007,7 @@ void Fdelete (char *fname)
+ {
+     char upath[500];
+     if (!st2unixpath(fname,upath)) return;
++    DBG("Fdelete(%s) on drive %d <%s> = ",fname,curdrv,upath);
+     if (unlink(upath) < 0)
+     {
+ 	DREG(0) = unix2toserrno( errno, TOS_EACCDN );
+@@ -864,13 +1016,14 @@ void Fdelete (char *fname)
+     }
+     DREG(0)=0;
+     SET_Z();
+-    return;
++    DBG("%d\n", DREG(0));
+ }
+ 
+ void Dcreate (char *pname)
+ {
+     char upath[500];
+     if (!st2unixpath(pname,upath)) return;
++	DBG("Dcreate(%s) on drive %d <%s> = ",pname,curdrv,upath);
+     if (mkdir(upath,DEFAULT_DIRMODE) < 0)
+     {
+ 	DREG(0) = unix2toserrno(errno,TOS_EACCDN);
+@@ -879,12 +1032,14 @@ void Dcreate (char *pname)
+     }
+     DREG(0)=0;
+     SET_Z();
++    DBG("%d\n", DREG(0));
+ }
+ 
+ void Ddelete (char *pname)
+ {
+     char upath[500];
+     if (!st2unixpath(pname,upath)) return;
++    DBG("Ddelete(%s) on drive %d <%s> = ",pname,curdrv,upath);
+     if (rmdir(upath) < 0)
+     {
+ 	DREG(0) = unix2toserrno(errno,TOS_EACCDN);
+@@ -893,22 +1048,26 @@ void Ddelete (char *pname)
+     }
+     DREG(0)=0;
+     SET_Z();
++    DBG("%d\n", DREG(0));
+ }
+ 
+ void Dgetpath (char *buf, UW drv)
+ {
+     /* FIXME */
++    DBG("Dgetpath(%d) = ",drv);
+     if (drv == 0)
+ 	drv=curdrv;
+     else
+ 	--drv;
+     if (!((gemdos_drives >> drv)&1))
+     {
++	DBG("(tos)\n");
+ 	return;
+     }
+     DREG(0) = 0;
+     sprintf(buf,"%s",curpath[drv]);
+     SET_Z();
++    DBG("%s\n",curpath[drv]);
+ }
+ 
+ void Pexec (UW mode, char *file, char *cmdlin, char *env)
+@@ -957,13 +1116,25 @@ void Fseek (L offset, W handle, UW mode)
+ 	SET_Z();
+ 	return;
+     }
++#if LPPIPES
++    /* do not allow seeking on lp pipe */ 
++    if (file[i].lpp)
++    {
++	DREG(0) = TOS_EACCDN;
++	SET_Z();
++	return;
++    }
++#endif
++
+     dpos=lseek(file[i].f,0,SEEK_CUR);
+     dlen=lseek(file[i].f,0,SEEK_END);
++    DBG("Fseek: file length is %ld\n",dlen);
+     (void)lseek(file[i].f,dpos,SEEK_SET);
+     dpos=lseek(file[i].f,offset,mode);
+     if (dpos > dlen) DREG(0)=-64;	/* ERANGE */
+     else DREG(0)=dpos;
+     SET_Z();
++    DBG("Fseek(%d,%d,%d) = %d\n", offset, handle, mode, DREG(0));
*** 258 LINES SKIPPED ***