From 8c9ce2184e77ad961fe2b164a541748e20de7141 Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Thu, 10 Feb 2022 16:51:33 -0800 Subject: [PATCH] ZXCC Sync - Attempting to sync ZXCC with latest source in repository by Tony Nicholson. Generally a failure, but it is closer. --- Source/Apps/Build.cmd | 12 +- Source/Apps/Test/Build.cmd | 6 +- Source/Apps/XM/Build.cmd | 20 +- Source/Apps/XM/Makefile | 6 +- Source/Apps/ZMD/Build.cmd | 38 +- Source/Apps/ZMD/Makefile | 4 +- Source/Apps/ZMP/Build.cmd | 10 +- Source/Apps/ZMP/Makefile | 2 +- Source/BPBIOS/Build.cmd | 14 +- Source/BPBIOS/Makefile | 2 +- Source/BPBIOS/ZCPR33/Build.cmd | 8 +- Source/BPBIOS/ZCPR33/Makefile | 4 +- Source/CBIOS/Build.cmd | 6 +- Source/CPM22/Build.cmd | 30 +- Source/CPM3/Build.cmd | 80 +- Source/CPM3/Makefile | 16 +- Source/Forth/Build.cmd | 10 +- Source/HBIOS/Build.cmd | 6 +- Source/HDIAG/Build.cmd | 4 - Source/RomDsk/Build.cmd | 6 +- Source/ZCPR-DJ/Build.cmd | 10 +- Source/ZCPR-DJ/Makefile | 2 +- Source/ZCPR/Build.cmd | 14 +- Source/ZCPR/Makefile | 4 +- Source/ZPM3/Build.cmd | 22 +- Source/ZPM3/Makefile | 4 +- Source/ZSDOS/Build.cmd | 10 +- Source/ZSDOS/Clock/Build.cmd | 8 +- Source/ZSDOS/Makefile | 4 +- Tools/Makefile.inc | 5 +- Tools/cpm/{bin => bin80}/ARCV.COM | Bin Tools/cpm/{bin => bin80}/AS.COM | Bin Tools/cpm/{bin => bin80}/BASCOM.COM | Bin Tools/cpm/{bin => bin80}/CC.COM | Bin Tools/cpm/{bin => bin80}/CNM.COM | Bin Tools/cpm/{bin => bin80}/CRC.COM | Bin Tools/cpm/{bin => bin80}/CREF80.COM | Bin Tools/cpm/{bin => bin80}/CZ.COM | Bin Tools/cpm/{bin => bin80}/DIRX.COM | Bin Tools/cpm/{bin => bin80}/DISKINFO.COM | Bin Tools/cpm/{bin => bin80}/GENCPM.COM | Bin Tools/cpm/{bin => bin80}/HEX80.COM | Bin Tools/cpm/{bin => bin80}/HEXCOM.COM | Bin Tools/cpm/{bin => bin80}/L80.COM | Bin Tools/cpm/{bin => bin80}/LBREXT.COM | Bin Tools/cpm/{bin => bin80}/LIB.COM | Bin Tools/cpm/{bin => bin80}/LIB80.COM | Bin Tools/cpm/{bin => bin80}/LIBUTIL.COM | Bin Tools/cpm/{bin => bin80}/LINK.COM | Bin Tools/cpm/{bin => bin80}/LN.COM | Bin Tools/cpm/{bin => bin80}/M80.COM | Bin Tools/cpm/{bin => bin80}/MAC.COM | Bin Tools/cpm/{bin => bin80}/MLOAD25.COM | Bin Tools/cpm/{bin => bin80}/NULU.COM | Bin Tools/cpm/{bin => bin80}/RMAC.COM | Bin Tools/cpm/{bin => bin80}/SIDSYM.COM | Bin Tools/cpm/{bin => bin80}/SLR180.COM | Bin Tools/cpm/{bin => bin80}/SLRMAC.COM | Bin Tools/cpm/{bin => bin80}/SLRNK.COM | Bin Tools/cpm/{bin => bin80}/SQZ.COM | Bin Tools/cpm/{bin => bin80}/TEX21.COM | Bin Tools/cpm/{bin => bin80}/TEX21A.COM | Bin Tools/cpm/{bin => bin80}/TEX21B.COM | Bin Tools/cpm/{bin => bin80}/UCRLZH.COM | Bin Tools/cpm/{bin => bin80}/UNARC.COM | Bin Tools/cpm/{bin => bin80}/UNCR.COM | Bin Tools/cpm/{bin => bin80}/UNZIP.COM | Bin Tools/cpm/{bin => bin80}/UNZIP154.COM | Bin Tools/cpm/{bin => bin80}/UNZIP186.COM | Bin Tools/cpm/{bin => bin80}/USQ.COM | Bin Tools/cpm/{bin => bin80}/Z80ASM.COM | Bin Tools/cpm/{bin => bin80}/ZMAC.COM | Bin Tools/cpm/{bin => bin80}/ZML.COM | Bin Tools/cpm/{bin => bin80}/ZMLIB.COM | Bin Tools/cpm/{bin => bin80}/ZSM.COM | Bin Tools/cpm/{include => include80}/CTYPE.H | 0 Tools/cpm/{include => include80}/ERRNO.H | 0 Tools/cpm/{include => include80}/FCNTL.H | 0 Tools/cpm/{include => include80}/IO.H | 0 Tools/cpm/{include => include80}/LIBC.H | 0 Tools/cpm/{include => include80}/MATH.H | 0 Tools/cpm/{include => include80}/SETJMP.H | 0 Tools/cpm/{include => include80}/SGTTY.H | 0 Tools/cpm/{include => include80}/STDIO.H | 0 Tools/cpm/{lib => lib80}/C.LIB | Bin Tools/cpm/{lib => lib80}/M.LIB | Bin Tools/cpm/{lib => lib80}/ROM.LIB | Bin Tools/cpm/{lib => lib80}/T.LIB | Bin Tools/unix/Makefile | 2 +- Tools/unix/zx/Makefile | 37 - Tools/unix/zx/config.h.darwin | 16 - Tools/unix/zx/config.h.linux | 17 - Tools/unix/zx/config.h.windows | 9 - Tools/unix/zx/cpmparse.c | 126 - Tools/unix/zx/readme.txt | 72 - Tools/unix/zx/xlt.c | 191 -- Tools/unix/zx/zx.html | 132 - Tools/unix/zxcc/Build-OW.cmd | 21 + Tools/unix/zxcc/Build-VC.cmd | 25 + Tools/unix/{zx => zxcc}/COPYING | 0 Tools/unix/zxcc/Clean.cmd | 11 + Tools/unix/zxcc/Makefile | 40 + Tools/unix/{zx => zxcc}/cbops.h | 344 +-- Tools/unix/zxcc/config.h.darwin | 6 + Tools/unix/zxcc/config.h.linux | 9 + Tools/unix/zxcc/config.h.windows | 5 + Tools/unix/{zx => zxcc/cpm}/bios.bin | Bin Tools/unix/{zx => zxcc}/cpm/bios.com | Bin Tools/unix/{zx => zxcc}/cpm/bios.lst | 0 Tools/unix/{zx => zxcc}/cpm/bios.z80 | 0 Tools/unix/{zx => zxcc}/cpmdrv.c | 14 +- Tools/unix/{zx => zxcc}/cpmglob.c | 37 +- Tools/unix/{zx => zxcc}/cpmint.h | 99 +- Tools/unix/zxcc/cpmparse.c | 126 + Tools/unix/{zx => zxcc}/cpmredir.c | 154 +- Tools/unix/{zx => zxcc}/cpmredir.h | 0 Tools/unix/{zx => zxcc}/dirent.c | 0 Tools/unix/{zx => zxcc}/dirent.h | 0 Tools/unix/{zx => zxcc}/drdos.c | 472 ++-- Tools/unix/{zx => zxcc}/edops.h | 0 Tools/unix/zxcc/readme.txt | 86 + Tools/unix/zxcc/track.c | 150 ++ Tools/unix/{zx => zxcc}/util.c | 99 +- Tools/unix/zxcc/xlt.c | 241 ++ Tools/unix/{zx => zxcc}/z80.c | 542 ++--- Tools/unix/{zx => zxcc}/z80.h | 172 +- Tools/unix/{zx => zxcc}/z80ops.h | 2664 ++++++++++----------- Tools/unix/{zx => zxcc}/zxbdos.c | 30 +- Tools/unix/{zx => zxcc}/zxbdos.h | 0 Tools/unix/{zx => zxcc}/zxcbdos.c | 32 +- Tools/unix/{zx => zxcc}/zxcbdos.h | 0 Tools/unix/{zx/zx.c => zxcc/zxcc.c} | 261 +- Tools/unix/zxcc/zxcc.doc | 207 ++ Tools/unix/{zx/zx.h => zxcc/zxcc.h} | 89 +- Tools/unix/zxcc/zxcc.html | 200 ++ Tools/unix/{zx => zxcc}/zxdbdos.c | 185 +- Tools/unix/{zx => zxcc}/zxdbdos.h | 0 Tools/zx/ReadMe.txt | 12 - Tools/zx/bios.bin | Bin 384 -> 0 bytes Tools/zx/zx-src.zip | Bin 58984 -> 0 bytes Tools/zx/zx.exe | Bin 94720 -> 0 bytes Tools/zx/zx.html | 132 - Tools/zx/zxdbg.exe | Bin 102400 -> 0 bytes Tools/{zx => zxcc}/COPYING | 0 Tools/zxcc/ReadMe.txt | 86 + Tools/{unix/zx/cpm => zxcc}/bios.bin | Bin Tools/zxcc/zxcc-src.zip | Bin 0 -> 69549 bytes Tools/zxcc/zxcc.exe | Bin 0 -> 95744 bytes Tools/zxcc/zxcc.html | 200 ++ Tools/zxcc/zxccdbg.exe | Bin 0 -> 104448 bytes 150 files changed, 4289 insertions(+), 3431 deletions(-) rename Tools/cpm/{bin => bin80}/ARCV.COM (100%) rename Tools/cpm/{bin => bin80}/AS.COM (100%) rename Tools/cpm/{bin => bin80}/BASCOM.COM (100%) rename Tools/cpm/{bin => bin80}/CC.COM (100%) rename Tools/cpm/{bin => bin80}/CNM.COM (100%) rename Tools/cpm/{bin => bin80}/CRC.COM (100%) rename Tools/cpm/{bin => bin80}/CREF80.COM (100%) rename Tools/cpm/{bin => bin80}/CZ.COM (100%) rename Tools/cpm/{bin => bin80}/DIRX.COM (100%) rename Tools/cpm/{bin => bin80}/DISKINFO.COM (100%) rename Tools/cpm/{bin => bin80}/GENCPM.COM (100%) rename Tools/cpm/{bin => bin80}/HEX80.COM (100%) rename Tools/cpm/{bin => bin80}/HEXCOM.COM (100%) rename Tools/cpm/{bin => bin80}/L80.COM (100%) rename Tools/cpm/{bin => bin80}/LBREXT.COM (100%) rename Tools/cpm/{bin => bin80}/LIB.COM (100%) rename Tools/cpm/{bin => bin80}/LIB80.COM (100%) rename Tools/cpm/{bin => bin80}/LIBUTIL.COM (100%) rename Tools/cpm/{bin => bin80}/LINK.COM (100%) rename Tools/cpm/{bin => bin80}/LN.COM (100%) rename Tools/cpm/{bin => bin80}/M80.COM (100%) rename Tools/cpm/{bin => bin80}/MAC.COM (100%) rename Tools/cpm/{bin => bin80}/MLOAD25.COM (100%) rename Tools/cpm/{bin => bin80}/NULU.COM (100%) rename Tools/cpm/{bin => bin80}/RMAC.COM (100%) rename Tools/cpm/{bin => bin80}/SIDSYM.COM (100%) rename Tools/cpm/{bin => bin80}/SLR180.COM (100%) rename Tools/cpm/{bin => bin80}/SLRMAC.COM (100%) rename Tools/cpm/{bin => bin80}/SLRNK.COM (100%) rename Tools/cpm/{bin => bin80}/SQZ.COM (100%) rename Tools/cpm/{bin => bin80}/TEX21.COM (100%) rename Tools/cpm/{bin => bin80}/TEX21A.COM (100%) rename Tools/cpm/{bin => bin80}/TEX21B.COM (100%) rename Tools/cpm/{bin => bin80}/UCRLZH.COM (100%) rename Tools/cpm/{bin => bin80}/UNARC.COM (100%) rename Tools/cpm/{bin => bin80}/UNCR.COM (100%) rename Tools/cpm/{bin => bin80}/UNZIP.COM (100%) rename Tools/cpm/{bin => bin80}/UNZIP154.COM (100%) rename Tools/cpm/{bin => bin80}/UNZIP186.COM (100%) rename Tools/cpm/{bin => bin80}/USQ.COM (100%) rename Tools/cpm/{bin => bin80}/Z80ASM.COM (100%) rename Tools/cpm/{bin => bin80}/ZMAC.COM (100%) rename Tools/cpm/{bin => bin80}/ZML.COM (100%) rename Tools/cpm/{bin => bin80}/ZMLIB.COM (100%) rename Tools/cpm/{bin => bin80}/ZSM.COM (100%) rename Tools/cpm/{include => include80}/CTYPE.H (100%) rename Tools/cpm/{include => include80}/ERRNO.H (100%) rename Tools/cpm/{include => include80}/FCNTL.H (100%) rename Tools/cpm/{include => include80}/IO.H (100%) rename Tools/cpm/{include => include80}/LIBC.H (100%) rename Tools/cpm/{include => include80}/MATH.H (100%) rename Tools/cpm/{include => include80}/SETJMP.H (100%) rename Tools/cpm/{include => include80}/SGTTY.H (100%) rename Tools/cpm/{include => include80}/STDIO.H (100%) rename Tools/cpm/{lib => lib80}/C.LIB (100%) rename Tools/cpm/{lib => lib80}/M.LIB (100%) rename Tools/cpm/{lib => lib80}/ROM.LIB (100%) rename Tools/cpm/{lib => lib80}/T.LIB (100%) delete mode 100644 Tools/unix/zx/Makefile delete mode 100644 Tools/unix/zx/config.h.darwin delete mode 100644 Tools/unix/zx/config.h.linux delete mode 100644 Tools/unix/zx/config.h.windows delete mode 100644 Tools/unix/zx/cpmparse.c delete mode 100644 Tools/unix/zx/readme.txt delete mode 100644 Tools/unix/zx/xlt.c delete mode 100644 Tools/unix/zx/zx.html create mode 100644 Tools/unix/zxcc/Build-OW.cmd create mode 100644 Tools/unix/zxcc/Build-VC.cmd rename Tools/unix/{zx => zxcc}/COPYING (100%) create mode 100644 Tools/unix/zxcc/Clean.cmd create mode 100644 Tools/unix/zxcc/Makefile rename Tools/unix/{zx => zxcc}/cbops.h (96%) create mode 100644 Tools/unix/zxcc/config.h.darwin create mode 100644 Tools/unix/zxcc/config.h.linux create mode 100644 Tools/unix/zxcc/config.h.windows rename Tools/unix/{zx => zxcc/cpm}/bios.bin (100%) rename Tools/unix/{zx => zxcc}/cpm/bios.com (100%) rename Tools/unix/{zx => zxcc}/cpm/bios.lst (100%) rename Tools/unix/{zx => zxcc}/cpm/bios.z80 (100%) rename Tools/unix/{zx => zxcc}/cpmdrv.c (96%) rename Tools/unix/{zx => zxcc}/cpmglob.c (94%) rename Tools/unix/{zx => zxcc}/cpmint.h (76%) create mode 100644 Tools/unix/zxcc/cpmparse.c rename Tools/unix/{zx => zxcc}/cpmredir.c (87%) rename Tools/unix/{zx => zxcc}/cpmredir.h (100%) rename Tools/unix/{zx => zxcc}/dirent.c (100%) rename Tools/unix/{zx => zxcc}/dirent.h (100%) rename Tools/unix/{zx => zxcc}/drdos.c (95%) rename Tools/unix/{zx => zxcc}/edops.h (100%) create mode 100644 Tools/unix/zxcc/readme.txt create mode 100644 Tools/unix/zxcc/track.c rename Tools/unix/{zx => zxcc}/util.c (83%) create mode 100644 Tools/unix/zxcc/xlt.c rename Tools/unix/{zx => zxcc}/z80.c (93%) rename Tools/unix/{zx => zxcc}/z80.h (96%) rename Tools/unix/{zx => zxcc}/z80ops.h (93%) rename Tools/unix/{zx => zxcc}/zxbdos.c (95%) rename Tools/unix/{zx => zxcc}/zxbdos.h (100%) rename Tools/unix/{zx => zxcc}/zxcbdos.c (77%) rename Tools/unix/{zx => zxcc}/zxcbdos.h (100%) rename Tools/unix/{zx/zx.c => zxcc/zxcc.c} (61%) create mode 100644 Tools/unix/zxcc/zxcc.doc rename Tools/unix/{zx/zx.h => zxcc/zxcc.h} (51%) create mode 100644 Tools/unix/zxcc/zxcc.html rename Tools/unix/{zx => zxcc}/zxdbdos.c (64%) rename Tools/unix/{zx => zxcc}/zxdbdos.h (100%) delete mode 100644 Tools/zx/ReadMe.txt delete mode 100644 Tools/zx/bios.bin delete mode 100644 Tools/zx/zx-src.zip delete mode 100644 Tools/zx/zx.exe delete mode 100644 Tools/zx/zx.html delete mode 100644 Tools/zx/zxdbg.exe rename Tools/{zx => zxcc}/COPYING (100%) create mode 100644 Tools/zxcc/ReadMe.txt rename Tools/{unix/zx/cpm => zxcc}/bios.bin (100%) create mode 100644 Tools/zxcc/zxcc-src.zip create mode 100644 Tools/zxcc/zxcc.exe create mode 100644 Tools/zxcc/zxcc.html create mode 100644 Tools/zxcc/zxccdbg.exe diff --git a/Source/Apps/Build.cmd b/Source/Apps/Build.cmd index cbcf8a01..675d1f44 100644 --- a/Source/Apps/Build.cmd +++ b/Source/Apps/Build.cmd @@ -4,13 +4,11 @@ setlocal set TOOLS=../../Tools set APPBIN=..\..\Binary\Apps -set PATH=%TOOLS%\tasm32;%TOOLS%\zx;%PATH% +set PATH=%TOOLS%\tasm32;%TOOLS%\zxcc;%PATH% set TASMTABS=%TOOLS%\tasm32 -set ZXBINDIR=%TOOLS%/cpm/bin/ -set ZXLIBDIR=%TOOLS%/cpm/lib/ -set ZXINCDIR=%TOOLS%/cpm/include/ +set CPMDIR80=%TOOLS%/cpm/ call :asm syscopy || exit /b call :asm assign || exit /b @@ -21,10 +19,10 @@ call :asm rtc || exit /b call :asm timer || exit /b call :asm rtchb || exit /b -zx Z80ASM -SYSGEN/F || exit /b +zxcc Z80ASM -SYSGEN/F || exit /b -zx MAC SURVEY.ASM -$PO || exit /b -zx MLOAD25 -SURVEY.COM=SURVEY.HEX || exit /b +zxcc MAC SURVEY.ASM -$PO || exit /b +zxcc MLOAD25 -SURVEY.COM=SURVEY.HEX || exit /b pushd XM && call Build || exit /b & popd pushd FDU && call Build || exit /b & popd diff --git a/Source/Apps/Test/Build.cmd b/Source/Apps/Test/Build.cmd index fb322d6b..ac6e0c2b 100644 --- a/Source/Apps/Test/Build.cmd +++ b/Source/Apps/Test/Build.cmd @@ -4,13 +4,11 @@ setlocal set TOOLS=../../../Tools set APPBIN=..\..\Binary\Apps -set PATH=%TOOLS%\tasm32;%TOOLS%\zx;%PATH% +set PATH=%TOOLS%\tasm32;%TOOLS%\zxcc;%PATH% set TASMTABS=%TOOLS%\tasm32 -set ZXBINDIR=%TOOLS%/cpm/bin/ -set ZXLIBDIR=%TOOLS%/cpm/lib/ -set ZXINCDIR=%TOOLS%/cpm/include/ +set CPMDIR80=%TOOLS%/cpm/ pushd DMAmon && call Build || exit /b & popd pushd tstdskng && call Build || exit /b & popd diff --git a/Source/Apps/XM/Build.cmd b/Source/Apps/XM/Build.cmd index fef70f92..cf07e3cd 100644 --- a/Source/Apps/XM/Build.cmd +++ b/Source/Apps/XM/Build.cmd @@ -3,22 +3,20 @@ setlocal set TOOLS=..\..\..\Tools -set PATH=%TOOLS%\zx;%PATH% +set PATH=%TOOLS%\zxcc;%PATH% -set ZXBINDIR=%TOOLS%\cpm\bin\ -set ZXLIBDIR=%TOOLS%\cpm\lib\ -set ZXINCDIR=%TOOLS%\cpm\include\ +set CPMDIR80=%TOOLS%/cpm/ -zx mac xmdm125.asm $PO || exit /b +zxcc mac xmdm125.asm $PO || exit /b -zx slr180 -xmhb/HF || exit /b -zx mload25 XM=xmdm125,xmhb || exit /b +zxcc slr180 -xmhb/HF || exit /b +zxcc mload25 XM=xmdm125,xmhb || exit /b -rem zx slr180 -xmuf/HF || exit /b -rem zx mload25 XMUF=xmdm125,xmuf || exit /b +rem zxcc slr180 -xmuf/HF || exit /b +rem zxcc mload25 XMUF=xmdm125,xmuf || exit /b -zx slr180 -xmhb_old/HF || exit /b -zx mload25 XMOLD=xmdm125,xmhb_old || exit /b +zxcc slr180 -xmhb_old/HF || exit /b +zxcc mload25 XMOLD=xmdm125,xmhb_old || exit /b rem set PROMPT=[Build] %PROMPT% rem %comspec% diff --git a/Source/Apps/XM/Makefile b/Source/Apps/XM/Makefile index 62c4f1e8..fc9a62e6 100644 --- a/Source/Apps/XM/Makefile +++ b/Source/Apps/XM/Makefile @@ -7,10 +7,10 @@ OTHERS = *.hex include $(TOOLS)/Makefile.inc xm.com: xmdm125.hex xmhb.hex - $(ZXCC) $(CPM)/MLOAD25 XM=xmdm125,xmhb + $(ZXCC) MLOAD25 XM=xmdm125,xmhb xmuf.com: xmdm125.hex xmuf.hex - $(ZXCC) $(CPM)/MLOAD25 XMUF=xmdm125,xmuf + $(ZXCC) MLOAD25 XMUF=xmdm125,xmuf xmold.com: xmdm125.hex xmhb_old.hex - $(ZXCC) $(CPM)/MLOAD25 XMOLD=xmdm125,xmhb_old + $(ZXCC) MLOAD25 XMOLD=xmdm125,xmhb_old diff --git a/Source/Apps/ZMD/Build.cmd b/Source/Apps/ZMD/Build.cmd index cc8d63d5..5d8d700d 100644 --- a/Source/Apps/ZMD/Build.cmd +++ b/Source/Apps/ZMD/Build.cmd @@ -3,35 +3,33 @@ setlocal set TOOLS=..\..\..\Tools -set PATH=%TOOLS%\zx;%PATH% +set PATH=%TOOLS%\zxcc;%PATH% -set ZXBINDIR=%TOOLS%\cpm\bin\ -set ZXLIBDIR=%TOOLS%\cpm\lib\ -set ZXINCDIR=%TOOLS%\cpm\include\ +set CPMDIR80=%TOOLS%/cpm/ -zx z80asm -zmd/fm -zx l80 -zmd,zmd/n/e +zxcc z80asm -zmd/fm +zxcc l80 -zmd,zmd/n/e -zx z80asm -zmap/fm -zx l80 -zmap,zmap/n/e +zxcc z80asm -zmap/fm +zxcc l80 -zmap,zmap/n/e -zx z80asm -znews/fm -zx l80 -znews,znews/n/e +zxcc z80asm -znews/fm +zxcc l80 -znews,znews/n/e -zx z80asm -znewp/fm -zx l80 -znewp,znewp/n/e +zxcc z80asm -znewp/fm +zxcc l80 -znewp,znewp/n/e -zx z80asm -zfors/fm -zx l80 -zfors,zfors/n/e +zxcc z80asm -zfors/fm +zxcc l80 -zfors,zfors/n/e -zx z80asm -zforp/fm -zx l80 -zforp,zforp/n/e +zxcc z80asm -zforp/fm +zxcc l80 -zforp,zforp/n/e -zx z80asm -zmdel/fm -zx l80 -zmdel,zmdel/n/e +zxcc z80asm -zmdel/fm +zxcc l80 -zmdel,zmdel/n/e -zx z80asm -zmdhb/fh -zx mload25 -zmd=zmd.com,zmdhb +zxcc z80asm -zmdhb/fh +zxcc mload25 -zmd=zmd.com,zmdhb copy /Y zmd.com ..\..\..\Binary\Apps\ || exit /b diff --git a/Source/Apps/ZMD/Makefile b/Source/Apps/ZMD/Makefile index 997b4997..70350198 100644 --- a/Source/Apps/ZMD/Makefile +++ b/Source/Apps/ZMD/Makefile @@ -6,5 +6,5 @@ OTHERS = *.hex zmd.rel include $(TOOLS)/Makefile.inc zmd.com: zmd.rel zmdhb.hex - $(ZXCC) $(CPM)/L80 -zmd,zmd/n/e - $(ZXCC) $(CPM)/MLOAD25 -zmd=zmd.com,zmdhb + $(ZXCC) L80 -zmd,zmd/n/e + $(ZXCC) MLOAD25 -zmd=zmd.com,zmdhb diff --git a/Source/Apps/ZMP/Build.cmd b/Source/Apps/ZMP/Build.cmd index 71f79633..8df63e1a 100644 --- a/Source/Apps/ZMP/Build.cmd +++ b/Source/Apps/ZMP/Build.cmd @@ -3,14 +3,12 @@ setlocal set TOOLS=..\..\..\Tools -set PATH=%TOOLS%\zx;%PATH% +set PATH=%TOOLS%\zxcc;%PATH% -set ZXBINDIR=%TOOLS%\cpm\bin\ -set ZXLIBDIR=%TOOLS%\cpm\lib\ -set ZXINCDIR=%TOOLS%\cpm\include\ +set CPMDIR80=%TOOLS%/cpm/ -zx Z80ASM -ZMO-RW01/H || exit /b -zx MLOAD25 -ZMP.COM=ZMPX.COM,ZMO-RW01 || exit /b +zxcc Z80ASM -ZMO-RW01/H || exit /b +zxcc MLOAD25 -ZMP.COM=ZMPX.COM,ZMO-RW01 || exit /b copy /Y zmp.com ..\..\..\Binary\Apps\ || exit /b copy /Y *.ovr ..\..\..\Binary\Apps\ || exit /b diff --git a/Source/Apps/ZMP/Makefile b/Source/Apps/ZMP/Makefile index 09abd053..11574dd6 100644 --- a/Source/Apps/ZMP/Makefile +++ b/Source/Apps/ZMP/Makefile @@ -7,4 +7,4 @@ NODELETE = *.ovr zmp.doc *.hlp include $(TOOLS)/Makefile.inc zmp.com: zmo-rw01.hex - $(ZXCC) $(CPM)/MLOAD25 -ZMP.COM=ZMPX.COM,ZMO-RW01 + $(ZXCC) MLOAD25 -ZMP.COM=ZMPX.COM,ZMO-RW01 diff --git a/Source/BPBIOS/Build.cmd b/Source/BPBIOS/Build.cmd index 90aa684f..184aafec 100644 --- a/Source/BPBIOS/Build.cmd +++ b/Source/BPBIOS/Build.cmd @@ -3,11 +3,9 @@ setlocal pushd ZCPR33 && call Build || exit /b & popd -set PATH=%PATH%;..\..\Tools\zx;..\..\Tools\cpmtools; +set PATH=%PATH%;..\..\Tools\zxcc;..\..\Tools\cpmtools; -set ZXBINDIR=../../tools/cpm/bin/ -set ZXLIBDIR=../../tools/cpm/lib/ -set ZXINCDIR=../../tools/cpm/include/ +set CPMDIR80=%TOOLS%/cpm/ call :makebp 33 call :makebp 33bnk @@ -45,7 +43,7 @@ echo. copy def-ww-z%VER%.lib def-ww.lib || exit /b rem if exist bpbio-ww.rel del bpbio-ww.rel || exit /b -zx ZMAC -BPBIO-WW -/P || exit /b +zxcc ZMAC -BPBIO-WW -/P || exit /b if exist bp%VER%.prn del bp%VER%.prn || exit /b ren bpbio-ww.prn bp%VER%.prn || exit /b if exist bp%VER%.err del bp%VER%.err || exit /b @@ -56,18 +54,18 @@ rem pause rem BPBUILD attempts to rename bpsys.img -> bpsys.bak rem while is is still open. Real CP/M does not care, -rem but zx fails due to host OS. Below, a temp file +rem but zxcc fails due to host OS. Below, a temp file rem is used to avoid the problematic rename. if exist bpsys.img del bpsys.img || exit /b if exist bpsys.tmp del bpsys.tmp || exit /b copy bp%VER%.dat bpsys.tmp || exit /b rem bpsys.tmp -> bpsys.img -zx bpbuild -bpsys.tmp bpsys.img -zx bpbuild -bpsys.tmp $@ diff --git a/Tools/Makefile.inc b/Tools/Makefile.inc index 70820679..59b7e6d5 100644 --- a/Tools/Makefile.inc +++ b/Tools/Makefile.inc @@ -37,7 +37,8 @@ CASEFN = $(TOOLS)/unix/casefn.sh # # compiler/assembler locations and flags # -ZXCC=$(BINDIR)/zx +ZXCC=$(BINDIR)/zxcc +export CPMDIR80=$(TOOLS)/cpm/ TASM=$(BINDIR)/uz80as -t z80 TASMFLAGS= OPENSPIN=$(BINDIR)/openspin @@ -48,7 +49,7 @@ CPMCHATTR=$(BINDIR)/cpmchattr # # directory containing cpm binaries # -CPM=$(TOOLS)/cpm/bin +CPM=$(TOOLS)/cpm/bin80/ # # .ONESHELL uses a single shell instance for all shell scripts. diff --git a/Tools/cpm/bin/ARCV.COM b/Tools/cpm/bin80/ARCV.COM similarity index 100% rename from Tools/cpm/bin/ARCV.COM rename to Tools/cpm/bin80/ARCV.COM diff --git a/Tools/cpm/bin/AS.COM b/Tools/cpm/bin80/AS.COM similarity index 100% rename from Tools/cpm/bin/AS.COM rename to Tools/cpm/bin80/AS.COM diff --git a/Tools/cpm/bin/BASCOM.COM b/Tools/cpm/bin80/BASCOM.COM similarity index 100% rename from Tools/cpm/bin/BASCOM.COM rename to Tools/cpm/bin80/BASCOM.COM diff --git a/Tools/cpm/bin/CC.COM b/Tools/cpm/bin80/CC.COM similarity index 100% rename from Tools/cpm/bin/CC.COM rename to Tools/cpm/bin80/CC.COM diff --git a/Tools/cpm/bin/CNM.COM b/Tools/cpm/bin80/CNM.COM similarity index 100% rename from Tools/cpm/bin/CNM.COM rename to Tools/cpm/bin80/CNM.COM diff --git a/Tools/cpm/bin/CRC.COM b/Tools/cpm/bin80/CRC.COM similarity index 100% rename from Tools/cpm/bin/CRC.COM rename to Tools/cpm/bin80/CRC.COM diff --git a/Tools/cpm/bin/CREF80.COM b/Tools/cpm/bin80/CREF80.COM similarity index 100% rename from Tools/cpm/bin/CREF80.COM rename to Tools/cpm/bin80/CREF80.COM diff --git a/Tools/cpm/bin/CZ.COM b/Tools/cpm/bin80/CZ.COM similarity index 100% rename from Tools/cpm/bin/CZ.COM rename to Tools/cpm/bin80/CZ.COM diff --git a/Tools/cpm/bin/DIRX.COM b/Tools/cpm/bin80/DIRX.COM similarity index 100% rename from Tools/cpm/bin/DIRX.COM rename to Tools/cpm/bin80/DIRX.COM diff --git a/Tools/cpm/bin/DISKINFO.COM b/Tools/cpm/bin80/DISKINFO.COM similarity index 100% rename from Tools/cpm/bin/DISKINFO.COM rename to Tools/cpm/bin80/DISKINFO.COM diff --git a/Tools/cpm/bin/GENCPM.COM b/Tools/cpm/bin80/GENCPM.COM similarity index 100% rename from Tools/cpm/bin/GENCPM.COM rename to Tools/cpm/bin80/GENCPM.COM diff --git a/Tools/cpm/bin/HEX80.COM b/Tools/cpm/bin80/HEX80.COM similarity index 100% rename from Tools/cpm/bin/HEX80.COM rename to Tools/cpm/bin80/HEX80.COM diff --git a/Tools/cpm/bin/HEXCOM.COM b/Tools/cpm/bin80/HEXCOM.COM similarity index 100% rename from Tools/cpm/bin/HEXCOM.COM rename to Tools/cpm/bin80/HEXCOM.COM diff --git a/Tools/cpm/bin/L80.COM b/Tools/cpm/bin80/L80.COM similarity index 100% rename from Tools/cpm/bin/L80.COM rename to Tools/cpm/bin80/L80.COM diff --git a/Tools/cpm/bin/LBREXT.COM b/Tools/cpm/bin80/LBREXT.COM similarity index 100% rename from Tools/cpm/bin/LBREXT.COM rename to Tools/cpm/bin80/LBREXT.COM diff --git a/Tools/cpm/bin/LIB.COM b/Tools/cpm/bin80/LIB.COM similarity index 100% rename from Tools/cpm/bin/LIB.COM rename to Tools/cpm/bin80/LIB.COM diff --git a/Tools/cpm/bin/LIB80.COM b/Tools/cpm/bin80/LIB80.COM similarity index 100% rename from Tools/cpm/bin/LIB80.COM rename to Tools/cpm/bin80/LIB80.COM diff --git a/Tools/cpm/bin/LIBUTIL.COM b/Tools/cpm/bin80/LIBUTIL.COM similarity index 100% rename from Tools/cpm/bin/LIBUTIL.COM rename to Tools/cpm/bin80/LIBUTIL.COM diff --git a/Tools/cpm/bin/LINK.COM b/Tools/cpm/bin80/LINK.COM similarity index 100% rename from Tools/cpm/bin/LINK.COM rename to Tools/cpm/bin80/LINK.COM diff --git a/Tools/cpm/bin/LN.COM b/Tools/cpm/bin80/LN.COM similarity index 100% rename from Tools/cpm/bin/LN.COM rename to Tools/cpm/bin80/LN.COM diff --git a/Tools/cpm/bin/M80.COM b/Tools/cpm/bin80/M80.COM similarity index 100% rename from Tools/cpm/bin/M80.COM rename to Tools/cpm/bin80/M80.COM diff --git a/Tools/cpm/bin/MAC.COM b/Tools/cpm/bin80/MAC.COM similarity index 100% rename from Tools/cpm/bin/MAC.COM rename to Tools/cpm/bin80/MAC.COM diff --git a/Tools/cpm/bin/MLOAD25.COM b/Tools/cpm/bin80/MLOAD25.COM similarity index 100% rename from Tools/cpm/bin/MLOAD25.COM rename to Tools/cpm/bin80/MLOAD25.COM diff --git a/Tools/cpm/bin/NULU.COM b/Tools/cpm/bin80/NULU.COM similarity index 100% rename from Tools/cpm/bin/NULU.COM rename to Tools/cpm/bin80/NULU.COM diff --git a/Tools/cpm/bin/RMAC.COM b/Tools/cpm/bin80/RMAC.COM similarity index 100% rename from Tools/cpm/bin/RMAC.COM rename to Tools/cpm/bin80/RMAC.COM diff --git a/Tools/cpm/bin/SIDSYM.COM b/Tools/cpm/bin80/SIDSYM.COM similarity index 100% rename from Tools/cpm/bin/SIDSYM.COM rename to Tools/cpm/bin80/SIDSYM.COM diff --git a/Tools/cpm/bin/SLR180.COM b/Tools/cpm/bin80/SLR180.COM similarity index 100% rename from Tools/cpm/bin/SLR180.COM rename to Tools/cpm/bin80/SLR180.COM diff --git a/Tools/cpm/bin/SLRMAC.COM b/Tools/cpm/bin80/SLRMAC.COM similarity index 100% rename from Tools/cpm/bin/SLRMAC.COM rename to Tools/cpm/bin80/SLRMAC.COM diff --git a/Tools/cpm/bin/SLRNK.COM b/Tools/cpm/bin80/SLRNK.COM similarity index 100% rename from Tools/cpm/bin/SLRNK.COM rename to Tools/cpm/bin80/SLRNK.COM diff --git a/Tools/cpm/bin/SQZ.COM b/Tools/cpm/bin80/SQZ.COM similarity index 100% rename from Tools/cpm/bin/SQZ.COM rename to Tools/cpm/bin80/SQZ.COM diff --git a/Tools/cpm/bin/TEX21.COM b/Tools/cpm/bin80/TEX21.COM similarity index 100% rename from Tools/cpm/bin/TEX21.COM rename to Tools/cpm/bin80/TEX21.COM diff --git a/Tools/cpm/bin/TEX21A.COM b/Tools/cpm/bin80/TEX21A.COM similarity index 100% rename from Tools/cpm/bin/TEX21A.COM rename to Tools/cpm/bin80/TEX21A.COM diff --git a/Tools/cpm/bin/TEX21B.COM b/Tools/cpm/bin80/TEX21B.COM similarity index 100% rename from Tools/cpm/bin/TEX21B.COM rename to Tools/cpm/bin80/TEX21B.COM diff --git a/Tools/cpm/bin/UCRLZH.COM b/Tools/cpm/bin80/UCRLZH.COM similarity index 100% rename from Tools/cpm/bin/UCRLZH.COM rename to Tools/cpm/bin80/UCRLZH.COM diff --git a/Tools/cpm/bin/UNARC.COM b/Tools/cpm/bin80/UNARC.COM similarity index 100% rename from Tools/cpm/bin/UNARC.COM rename to Tools/cpm/bin80/UNARC.COM diff --git a/Tools/cpm/bin/UNCR.COM b/Tools/cpm/bin80/UNCR.COM similarity index 100% rename from Tools/cpm/bin/UNCR.COM rename to Tools/cpm/bin80/UNCR.COM diff --git a/Tools/cpm/bin/UNZIP.COM b/Tools/cpm/bin80/UNZIP.COM similarity index 100% rename from Tools/cpm/bin/UNZIP.COM rename to Tools/cpm/bin80/UNZIP.COM diff --git a/Tools/cpm/bin/UNZIP154.COM b/Tools/cpm/bin80/UNZIP154.COM similarity index 100% rename from Tools/cpm/bin/UNZIP154.COM rename to Tools/cpm/bin80/UNZIP154.COM diff --git a/Tools/cpm/bin/UNZIP186.COM b/Tools/cpm/bin80/UNZIP186.COM similarity index 100% rename from Tools/cpm/bin/UNZIP186.COM rename to Tools/cpm/bin80/UNZIP186.COM diff --git a/Tools/cpm/bin/USQ.COM b/Tools/cpm/bin80/USQ.COM similarity index 100% rename from Tools/cpm/bin/USQ.COM rename to Tools/cpm/bin80/USQ.COM diff --git a/Tools/cpm/bin/Z80ASM.COM b/Tools/cpm/bin80/Z80ASM.COM similarity index 100% rename from Tools/cpm/bin/Z80ASM.COM rename to Tools/cpm/bin80/Z80ASM.COM diff --git a/Tools/cpm/bin/ZMAC.COM b/Tools/cpm/bin80/ZMAC.COM similarity index 100% rename from Tools/cpm/bin/ZMAC.COM rename to Tools/cpm/bin80/ZMAC.COM diff --git a/Tools/cpm/bin/ZML.COM b/Tools/cpm/bin80/ZML.COM similarity index 100% rename from Tools/cpm/bin/ZML.COM rename to Tools/cpm/bin80/ZML.COM diff --git a/Tools/cpm/bin/ZMLIB.COM b/Tools/cpm/bin80/ZMLIB.COM similarity index 100% rename from Tools/cpm/bin/ZMLIB.COM rename to Tools/cpm/bin80/ZMLIB.COM diff --git a/Tools/cpm/bin/ZSM.COM b/Tools/cpm/bin80/ZSM.COM similarity index 100% rename from Tools/cpm/bin/ZSM.COM rename to Tools/cpm/bin80/ZSM.COM diff --git a/Tools/cpm/include/CTYPE.H b/Tools/cpm/include80/CTYPE.H similarity index 100% rename from Tools/cpm/include/CTYPE.H rename to Tools/cpm/include80/CTYPE.H diff --git a/Tools/cpm/include/ERRNO.H b/Tools/cpm/include80/ERRNO.H similarity index 100% rename from Tools/cpm/include/ERRNO.H rename to Tools/cpm/include80/ERRNO.H diff --git a/Tools/cpm/include/FCNTL.H b/Tools/cpm/include80/FCNTL.H similarity index 100% rename from Tools/cpm/include/FCNTL.H rename to Tools/cpm/include80/FCNTL.H diff --git a/Tools/cpm/include/IO.H b/Tools/cpm/include80/IO.H similarity index 100% rename from Tools/cpm/include/IO.H rename to Tools/cpm/include80/IO.H diff --git a/Tools/cpm/include/LIBC.H b/Tools/cpm/include80/LIBC.H similarity index 100% rename from Tools/cpm/include/LIBC.H rename to Tools/cpm/include80/LIBC.H diff --git a/Tools/cpm/include/MATH.H b/Tools/cpm/include80/MATH.H similarity index 100% rename from Tools/cpm/include/MATH.H rename to Tools/cpm/include80/MATH.H diff --git a/Tools/cpm/include/SETJMP.H b/Tools/cpm/include80/SETJMP.H similarity index 100% rename from Tools/cpm/include/SETJMP.H rename to Tools/cpm/include80/SETJMP.H diff --git a/Tools/cpm/include/SGTTY.H b/Tools/cpm/include80/SGTTY.H similarity index 100% rename from Tools/cpm/include/SGTTY.H rename to Tools/cpm/include80/SGTTY.H diff --git a/Tools/cpm/include/STDIO.H b/Tools/cpm/include80/STDIO.H similarity index 100% rename from Tools/cpm/include/STDIO.H rename to Tools/cpm/include80/STDIO.H diff --git a/Tools/cpm/lib/C.LIB b/Tools/cpm/lib80/C.LIB similarity index 100% rename from Tools/cpm/lib/C.LIB rename to Tools/cpm/lib80/C.LIB diff --git a/Tools/cpm/lib/M.LIB b/Tools/cpm/lib80/M.LIB similarity index 100% rename from Tools/cpm/lib/M.LIB rename to Tools/cpm/lib80/M.LIB diff --git a/Tools/cpm/lib/ROM.LIB b/Tools/cpm/lib80/ROM.LIB similarity index 100% rename from Tools/cpm/lib/ROM.LIB rename to Tools/cpm/lib80/ROM.LIB diff --git a/Tools/cpm/lib/T.LIB b/Tools/cpm/lib80/T.LIB similarity index 100% rename from Tools/cpm/lib/T.LIB rename to Tools/cpm/lib80/T.LIB diff --git a/Tools/unix/Makefile b/Tools/unix/Makefile index cba1782e..571e876d 100644 --- a/Tools/unix/Makefile +++ b/Tools/unix/Makefile @@ -9,7 +9,7 @@ ifeq ($(UNAME), Darwin) SUFFIX=osx endif -SUBDIRS = bst uz80as zx cpmtools bin2asm lzsa +SUBDIRS = bst uz80as zxcc cpmtools bin2asm lzsa all: @chmod +x casefn.sh diff --git a/Tools/unix/zx/Makefile b/Tools/unix/zx/Makefile deleted file mode 100644 index 862ec7a3..00000000 --- a/Tools/unix/zx/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# -# hacked up brute force makefile for linux and osx -# -UNAME := $(shell uname) -ifeq ($(UNAME), Linux) - SUFFIX=linux -endif -ifeq ($(UNAME), Darwin) - SUFFIX=darwin -endif - -DEST = ../../$(UNAME) -CFLAGS = -g # -DDEBUG - -OBJECTS = zx.o cpmdrv.o cpmglob.o cpmparse.o cpmredir.o \ - drdos.o util.o xlt.o zxbdos.o zxcbdos.o zxdbdos.o z80.o -UNUSED = dirent.o - -all: zx $(DEST) - cp -p bios.bin zx $(DEST) - -$(DEST): - mkdir -p $(DEST) - -clean: - -rm -f $(OBJECTS) config.h zx - -clobber: clean - -rm -f $(DEST)/zx $(DEST)/bios.bin zx - -$(OBJECTS): config.h - -zx: $(OBJECTS) - $(CC) -o zx $(OBJECTS) - -config.h: config.h.$(SUFFIX) - cp config.h.$(SUFFIX) config.h diff --git a/Tools/unix/zx/config.h.darwin b/Tools/unix/zx/config.h.darwin deleted file mode 100644 index cc4b425c..00000000 --- a/Tools/unix/zx/config.h.darwin +++ /dev/null @@ -1,16 +0,0 @@ -//#define HAVE_WINDOWS_H -#define HAVE_DIRENT_H -#define HAVE_UTIME_H -#define HAVE_FCNTL_H -#define HAVE_UNISTD_H -#define BINDIR80 getenv("ZXBINDIR") -#define LIBDIR80 getenv("ZXLIBDIR") -#define INCDIR80 getenv("ZXINCDIR") -#define DARWIN -#include -#include -#define _S_IFDIR S_IFDIR -#define strcmpi(a,b) strcasecmp(a,b) -//#define WIN32 -//#define WINVER 0x0501 // target Windows XP -//#define _WIN32_WINNNT 0x0501 // target Windows XP diff --git a/Tools/unix/zx/config.h.linux b/Tools/unix/zx/config.h.linux deleted file mode 100644 index a015591c..00000000 --- a/Tools/unix/zx/config.h.linux +++ /dev/null @@ -1,17 +0,0 @@ -//#define HAVE_WINDOWS_H -#define HAVE_DIRENT_H -#define HAVE_UTIME_H -#define HAVE_FCNTL_H -#define HAVE_SYS_VFS_H -#define HAVE_UNISTD_H -#define BINDIR80 getenv("ZXBINDIR") -#define LIBDIR80 getenv("ZXLIBDIR") -#define INCDIR80 getenv("ZXINCDIR") -#define LINUX -#include -#include -#define _S_IFDIR S_IFDIR -#define strcmpi(a,b) strcasecmp(a,b) -//#define WIN32 -//#define WINVER 0x0501 // target Windows XP -//#define _WIN32_WINNNT 0x0501 // target Windows XP diff --git a/Tools/unix/zx/config.h.windows b/Tools/unix/zx/config.h.windows deleted file mode 100644 index 8186c485..00000000 --- a/Tools/unix/zx/config.h.windows +++ /dev/null @@ -1,9 +0,0 @@ -#define HAVE_WINDOWS_H -//#define HAVE_DIRENT_H -#define HAVE_FCNTL_H -#define BINDIR80 getenv("ZXBINDIR") -#define LIBDIR80 getenv("ZXLIBDIR") -#define INCDIR80 getenv("ZXINCDIR") -#define WIN32 -#define WINVER 0x0501 // target Windows XP -#define _WIN32_WINNNT 0x0501 // target Windows XP diff --git a/Tools/unix/zx/cpmparse.c b/Tools/unix/zx/cpmparse.c deleted file mode 100644 index 4c709ec1..00000000 --- a/Tools/unix/zx/cpmparse.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - - CPMREDIR: CP/M filesystem redirector - Copyright (C) 1998, John Elliott - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - This file parses filenames to FCBs. -*/ - -#include "cpmint.h" - -#define is_num(c) ((c >= '0') && (c <= '9')) - -static int parse_drive_user(char *txt, cpm_byte *fcb) -{ - char uid[4], drvid[4]; - int up, dp; - - for (up = dp = 0; *txt != ':'; ++txt) - { - if (is_num (*txt)) uid [up++] = *txt; - if (isalpha(*txt)) drvid[dp++] = *txt; - if (!is_num(*txt) && !isalpha(*txt)) return -1; - } - uid[up] = 0; drvid[dp] = 0; - - if (dp > 1) return -1; /* Invalid driveletter */ - if (up > 2) return -1; /* Invalid uid */ - - fcb[0x0d] = atoi(uid) + 1; if (fcb[0x0d] > 16) return -1; - - if (islower(drvid[0])) drvid[0] = toupper(drvid[0]); - - if (drvid[0] < 'A' || drvid[0] > 'P') return -1; - - fcb[0] = drvid[0] - '@'; - return 0; -} - - - -cpm_word fcb_parse(char *txt, cpm_byte *fcb) -{ - int nl = 0, tl = 0, pl = 0, phase = 0; - char *ntxt, ch; - - memset(fcb, 0, 0x24); - - if (txt[1] == ':' || txt[2] == ':' || txt[3] == ':') - { - if (parse_drive_user(txt, fcb)) return 0xFFFF; - /* Move past the colon */ - ntxt = strchr(txt, ':') + 1; - } - else ntxt = txt; - while (phase < 3) - { - ch = *ntxt; - if (islower(ch)) ch = toupper(ch); - - switch(ch) - { - case 0: - case '\r': /* EOL */ - phase = 4; - break; - - case '.': /* file.typ */ - if (!phase) ++phase; - else phase = 3; - break; - - case ';': /* Password */ - if (phase < 2) phase = 2; - else phase = 3; - break; - - case '[': case ']': case '=': case 9: case ' ': - case '>': case '<': case ':': case ',': case '/': - case '|': /* Terminator */ - phase = 3; - - default: - switch(phase) - { - case 0: - if (nl >= 8) return 0xFFFF; - fcb[++nl] = ch; - break; - - case 1: - if (tl >= 3) return 0xFFFF; - fcb[tl + 9] = ch; - ++tl; - break; - - case 2: - if (pl >= 8) return 0xFFFF; - fcb[pl + 0x10] = ch; - ++pl; - break; - } - break; - } - } - if (!nl) return 0xFFFF; - - fcb[0x1A] = pl; - - if (phase == 4) return 0; - - return ntxt - txt; -} diff --git a/Tools/unix/zx/readme.txt b/Tools/unix/zx/readme.txt deleted file mode 100644 index 15feb3e8..00000000 --- a/Tools/unix/zx/readme.txt +++ /dev/null @@ -1,72 +0,0 @@ -ZX Command - -An adaptation of zxcc-0.5.6 by Wayne Warthen - -This directory contains the source files used to build the "zx" tool. This tool -is essentially just John Elliott's zxcc package version zxcc-0.5.6 modified to -build for Windows and simplified down to just a single command (zx) -which is essentially just the zxcc command. - -Please see http://www.seasip.info/Unix/Zxcc/ for more information on zxcc. - -Note that this is a Win32 build. The code has not been updated to build as a 64-bit -binary. However, Win32 binaries run very nicely under 64 bit Windows. - -To build under Open Watcom or Microsoft Visual C++, use the following command: - - cl /Fe"zx.exe" zx.c cpmdrv.c cpmglob.c cpmparse.c cpmredir.c drdos.c util.c xlt.c zxbdos.c zxcbdos.c zxdbdos.c z80.c dirent.c - -To build a debug version, use the following command: - - cl /DDEBUG /Fe"zxdbg.exe" zx.c cpmdrv.c cpmglob.c cpmparse.c cpmredir.c drdos.c util.c xlt.c zxbdos.c zxcbdos.c zxdbdos.c z80.c dirent.c - -WARNING: There seems to be a rare scenario that breaks zx under the Open Watcom build. -CP/M allows a file to be accessed under multiple FCB's without an error. Open Watcom -will see this as an error. At present, the only tool I know of that does this is M80. - -December 5, 2014 - -After struggling to get the entire zxcc package to build nicely using autoconf, -I finally gave up and took a much more direct approach. I have extracted just -the source files needed and created a simple batch file to build the tool. I -realize this could be done much better, but I cheated in the interest of time. - -The one "real" change I made in the source code was that I modified the tool -to look for bios.bin in the same directory as the executable is in. This -just makes it much easier to set up (for me, anyway). - -The GPL status of everything remains in place and carries forward. - -Wayne Warthen -wwarthen@gmail.com - -March 15, 2017 - -- Updated to compile under Open Watcom. -- Implemented BDOS console status function. -- Set stdin and stdout to binary mode at startup. - -August 21, 2021 - -- Incorporated filename case insensitivity changes from Curt Mayer -- Incorporated fixes from Tony Nicholson at https://github.com/agn453/ZXCC - - Emulation of CP/M BDOS function 60 (call resident system extension) - should be disabled and return 0xFF in both the A and L registers. - - Change cpm_bdos_10() to return an unsigned result to avoid buffer - size being interpreted as negative. - - Fix the emulation of Z80 opcodes for IN (HL),(C) and - OUT (C),(HL) - opcodes 0xED,0x70 and 0xED,0x71 respectively. - This is noted in Fred Weigel's AM9511 arithmetic processing unit - emulation from https://github.com/ratboy666/am9511 in the howto.txt - description. NB: I have not included Fred's am9511 support at this - time into ZXCC. -- Fixed parse_to_fcb function in zx.c to handle parsing second automatic - FCB from command line -- I have not been able to reproduce the multiple FCBs referring to a - single file issue with Watcom documented above. Perhaps I fixed it - and don't remember or I found a bug-fixed version of M80. Not sure. - -Wayne Warthen -wwarthen@gmail.com - ---WBW 4:09 PM 8/21/2021 \ No newline at end of file diff --git a/Tools/unix/zx/xlt.c b/Tools/unix/zx/xlt.c deleted file mode 100644 index f0ba1da5..00000000 --- a/Tools/unix/zx/xlt.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - - CPMREDIR: CP/M filesystem redirector - Copyright (C) 1998, John Elliott - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - This file holds functions dealing with name translation; also the - initialisation code. -*/ - -#include "cpmint.h" - -/* Detect DRDOS */ - -#ifdef __MSDOS__ -static void drdos_init(void) -{ - -/* The DJGPP DOS extender won't detect DRDOS using intdos(), so we have - to use __dpmi_int() instead. */ - -#ifdef __GO32__ - __dpmi_regs ir; - - ir.x.ax = 0x4452; /* "DR" */ - - __dpmi_int(0x21, &ir); - if (ir.x.flags & 1) return; /* Not DRDOS */ - - redir_Msg("DRDOS detected.\r\n"); - - redir_drdos = 1; - -#else /* __GO32__ */ - - union REGS ir, or; - - ir.w.ax = 0x4452; /* "DR" */ - - intdos(&ir, &or); - if (or.w.cflag) return; /* Not DRDOS */ - - redir_Msg("DRDOS detected.\r\n"); - - redir_drdos = 1; -#endif /* __GO32__ */ -} -#endif /* __MSDOS__ */ - - - -int fcb_init(void) -{ - int n; - - /* A: to O: free */ - for (n = 0; n < 15; n++) redir_drive_prefix[n][0] = 0; - - strcpy(redir_drive_prefix[15], "./"); /* P: is current directory */ - - /* Log on to P:. It is the only drive at this point which we - * know works. */ - redir_cpmdrive = 15; -#ifdef __MSDOS__ - drdos_init(); -#endif - - return 1; -} - -/* Deinitialise the library. */ - -void fcb_deinit(void) -{ - /* Nothing */ -} - -/* Translate a name from the host FS to a CP/M name. This will (if necessary) - * create a mapping between a CP/M drive and a host directory path. - * - * CP/M drives A: to O: can be mapped in this way. P: is always the current - * drive. - * - */ - -void xlt_name(char *localname, char *cpmname) -{ - char ibuf[CPM_MAXPATH + 1]; - char nbuf[CPM_MAXPATH + 1]; - char *pname; - int n; - - sprintf(ibuf, "%-.*s", CPM_MAXPATH, localname); - pname = strrchr(ibuf, '/'); -#ifdef __MSDOS__ - if (!pname) pname = strrchr(ibuf,'\\'); - if (!pname) pname = strrchr(ibuf,':'); -#endif - if (!pname) /* No path separators in the name. It is therefore a - local filename, so map it to drive P: */ - { - strcpy(cpmname, "p:"); - strcat(cpmname, ibuf); - return; - } - ++pname; - strcpy(nbuf, pname); /* nbuf holds filename component */ - *pname = 0; /* ibuf holds path component */ - - /* See if the path is one of those already mapped to drives */ - - for (n = 0; n < 15; n++) - { - if (redir_drive_prefix[n][0] && !strcmp(ibuf, redir_drive_prefix[n])) - { - sprintf(cpmname,"%c:%s", n + 'a', nbuf); - return; - } - } - - /* It is not, see if another drive can be allocated */ - - for (n = 0; n < 15; n++) if (!redir_drive_prefix[n][0]) - { - strcpy(redir_drive_prefix[n], ibuf); - sprintf(cpmname,"%c:%s", n + 'a', nbuf); - return; - } - - /* No other drive can be allocated */ - - strcpy(cpmname,"p:"); - strcat(cpmname, nbuf); -} - -/* It is sometimes convenient to set some fixed mappings. This will create - * a mapping for a given directory. - * Pass drive = -1 for "first available", or 0-15 for A: to P: - */ - -int xlt_map(int drive, char *localdir) -{ - int n; - - if (drive == -1) - { - for (n = 0; n < 15; n++) if (!redir_drive_prefix[n][0]) - { - drive = n; - break; - } - if (drive == -1) return 0; /* No space for mappings */ - } - if (redir_drive_prefix[drive][0]) return 0; /* Drive taken */ - - sprintf(redir_drive_prefix[drive], "%-.*s", CPM_MAXPATH, localdir); - return 1; -} - - -/* Unmap a drive - */ - -int xlt_umap(int drive) -{ - if (!redir_drive_prefix[drive][0]) return 0; /* Drive not taken */ - redir_drive_prefix[drive][0] = 0; - return 1; -} - - -char *xlt_getcwd(int drive) -{ - if (drive < 0 || drive > 16) return ""; - - return redir_drive_prefix[drive]; -} - diff --git a/Tools/unix/zx/zx.html b/Tools/unix/zx/zx.html deleted file mode 100644 index ff2da790..00000000 --- a/Tools/unix/zx/zx.html +++ /dev/null @@ -1,132 +0,0 @@ -zx CP/M Command Line Emulator - -

zx CP/M Command Line Emulator

- -

zx allows execution of CP/M 2.2 and 3.X application from a -Windows command line. It is compatible with Windows XP and greater (both -32 and 64 bit).

- -

zx is basically a port of a subset of the zxcc program by John Elliott. -The GPLv2 licensing carries forward. Please refer to the - -zxcc web page for more information.

- -

While the original zxcc package was generally intended to allow -execution of the Hi-Tech C CP/M compiler under Unix, zx is slightly -more general and intended to allow running most CP/M tools. Specific -changes were incorporated to improve interactice console operation of -CP/M applications. Additionally, Curt Mayer added case insensitivity -for filenames under Unix variants.

- -

Setup

- -

The zx application (zx.exe) may be copied to any directory for execution. -The bios.bin file must be copied to the same directory. For ease of use, -you will probably want the directory to part of your PATH environment -variable so that you can run the tool from any location.

- -

You will also need the CP/M applications that you want to run. -zx will load files fromthe current directory or one of the following -directories based on file type. Any of the following environment -variables may be defined to determine where zx searches for the -respective file types:

- -
    -
  • ZXBINDIR may contain a single path which will -be searched for executable files (usually *.com)
  • -
  • ZXLIBDIR may contain a single path which will -be search for library files (usually *.lib)
  • -
  • ZXINCDIR may contain a single path which will -be searched for include files (usually *.inc)
  • -
- -

Usage

- -

In general CP/M applications are executed by prefixing the CP/M command -line with "zx". So for example, you could assemble a test.asm using -rmac with a command line like:

- -
zx rmac hello
- -

In this case, rmac.com would need to be in the directory specified by -environment variable ZXBINDIR or in the current directory. Also, -hello.asm would need to be in the current directory.

- -

Filenames

- -

Where you would normally enter a CP/M filename you instead enter -a Windows filename. Note that you will need to use a forward slash -instead of the traditional backslash as a directory separator. The -filename itself (as opposed to any directories in -its path) must obey CP/M 8.3 naming conventions.

- -

Where the documentation requires a CP/M drive letter/user number -you should enter a path complete with trailing slash, for example:

-
-I/usr/src/linux-80/include/
- -

Technical

- -

zx emulates a subset of CP/M 3; hopefully enough to run the -most CP/M tools. It can be used as a limited general-purpose CP/M 3 -emulator provided the emulated program only uses a common subset of -system calls.

- -

Syntax for zx is:

- -
-zx comfile.com arg1 arg2 ... -
- -

The comfile is the program to run; zx searches the current -directory and ZXBINDIR for it.

- -

The arguments are parsed in this way:

- -
    -
  • Any argument starting with a - sign is passed to the CP/M program as-is, -minus the leading - sign. -
  • Any argument starting with a + sign is parsed as a filename (see below) -and then concatenated to the previous argument. -
  • Any argument starting "+-" is concatenated without being parsed. -
  • All other arguments are parsed as filenames. The path is -converted to a CP/M driveletter. -
- -

For example: -

-zx foo.com --Q -A /src/main --I +/src/sub +-, +/foo/bar -
- -

would pass these arguments to foo.com:

- -
--Q A d:main -Id:sub,e:bar -
- -

The other programs are merely wrappers that convert their command lines -into the form required by zx.

- -

Errors

- -

Any errors raised by the zx runtime system will be prefixed -with zx:. Some errors you may encounter are:

- -
-
Unsupported BDOS call
-
Part of CP/M 3 that the program uses has not been emulated. Add the -required functionality to zxbdos.c and recompile.
-
Z80 encountered invalid trap
-
The CP/M program being run attempted to call the zx runtime -system with an unknown call number.
-
- -

Acknowledgements

- -
    -
  • zxcc was written by John Elliott
  • -
  • Hi-Tech C was written by Hi-Tech Software.
  • -
  • The Z80 emulation engine was written by Ian Collier.
  • -
  • Thanks to Jacob Nevins, Andy Parkins and others for bug fix suggestions.
  • -
- - diff --git a/Tools/unix/zxcc/Build-OW.cmd b/Tools/unix/zxcc/Build-OW.cmd new file mode 100644 index 00000000..3be3cdaa --- /dev/null +++ b/Tools/unix/zxcc/Build-OW.cmd @@ -0,0 +1,21 @@ +@echo off +setlocal + +:: +:: Edit WATCOM variable below as needed for your environment +:: +set WATCOM=..\..\Tools\WATCOM2 + +set PATH=%WATCOM%\BINNT;%WATCOM%\BINW;%PATH% +set EDPATH=%WATCOM%\EDDAT +set INCLUDE=%WATCOM%\H;%WATCOM%\H\NT + +copy config.h.windows config.h + +cl /Fe"zxcc.exe" zxcc.c cpmdrv.c cpmglob.c cpmparse.c cpmredir.c drdos.c util.c track.c xlt.c zxbdos.c zxcbdos.c zxdbdos.c z80.c +if errorlevel 1 exit /b 255 + +cl /Fe"zxccdbg.exe" /DDEBUG zxcc.c cpmdrv.c cpmglob.c cpmparse.c cpmredir.c drdos.c util.c track.c xlt.c zxbdos.c zxcbdos.c zxdbdos.c z80.c +if errorlevel 1 exit /b 255 + +copy cpm\bios.bin . \ No newline at end of file diff --git a/Tools/unix/zxcc/Build-VC.cmd b/Tools/unix/zxcc/Build-VC.cmd new file mode 100644 index 00000000..2d199c6d --- /dev/null +++ b/Tools/unix/zxcc/Build-VC.cmd @@ -0,0 +1,25 @@ +@echo off +setlocal + +:: +:: Visual Studio x86 Native Tools Command Prompt is assumed +:: + +:: Below configures VS2012 to target Windows XP and beyond +:: Not sure if it will work in later versions of VS, but seems +:: to do no harm. +set INCLUDE=%ProgramFiles(x86)%\Microsoft SDKs\Windows\7.1A\Include;%INCLUDE% +set PATH=%ProgramFiles(x86)%\Microsoft SDKs\Windows\7.1A\Bin;%PATH% +set LIB=%ProgramFiles(x86)%\Microsoft SDKs\Windows\7.1A\Lib;%LIB% +set CL=/D_USING_V110_SDK71_;%CL% +set LINK=/SUBSYSTEM:CONSOLE,5.01 %LINK% + +copy config.h.windows config.h + +cl zxcc.c cpmdrv.c cpmglob.c cpmparse.c cpmredir.c drdos.c util.c xlt.c zxbdos.c zxcbdos.c zxdbdos.c z80.c dirent.c track.c +if errorlevel 1 exit /b 255 + +cl /DDEBUG /Fe"zxccdbg.exe" zxcc.c cpmdrv.c cpmglob.c cpmparse.c cpmredir.c drdos.c util.c xlt.c zxbdos.c zxcbdos.c zxdbdos.c z80.c dirent.c track.c +if errorlevel 1 exit /b 255 + +copy cpm\bios.bin . \ No newline at end of file diff --git a/Tools/unix/zx/COPYING b/Tools/unix/zxcc/COPYING similarity index 100% rename from Tools/unix/zx/COPYING rename to Tools/unix/zxcc/COPYING diff --git a/Tools/unix/zxcc/Clean.cmd b/Tools/unix/zxcc/Clean.cmd new file mode 100644 index 00000000..eb7fc764 --- /dev/null +++ b/Tools/unix/zxcc/Clean.cmd @@ -0,0 +1,11 @@ +@echo off +setlocal + +if exist *.exe del *.exe +if exist *.obj del *.obj +if exist *.err del *.err +if exist *.o del *.o +if exist *.bin del *.bin +if exist zxcc del zxcc +if exist zxccdbg del zxccdbg +if exist config.h del config.h diff --git a/Tools/unix/zxcc/Makefile b/Tools/unix/zxcc/Makefile new file mode 100644 index 00000000..70420378 --- /dev/null +++ b/Tools/unix/zxcc/Makefile @@ -0,0 +1,40 @@ +# +# hacked up brute force makefile for linux and osx +# +UNAME := $(shell uname) +ifeq ($(UNAME), Linux) + SUFFIX=linux +endif +ifeq ($(UNAME), Darwin) + SUFFIX=darwin +endif + +DEST = ../../$(UNAME) +CFLAGS = -g # -DDEBUG + +OBJECTS = zxcc.o cpmdrv.o cpmglob.o cpmparse.o cpmredir.o \ + drdos.o util.o xlt.o zxbdos.o zxcbdos.o zxdbdos.o z80.o track.o +UNUSED = dirent.o + +all: zxcc $(DEST) + cp -p bios.bin zxcc $(DEST) + +$(DEST): + mkdir -p $(DEST) + +clean: + -rm -f $(OBJECTS) config.h zxcc bios.bin + +clobber: clean + -rm -f $(DEST)/zxcc $(DEST)/bios.bin zxcc + +$(OBJECTS): config.h bios.bin + +zxcc: $(OBJECTS) + $(CC) -o zxcc $(OBJECTS) + +config.h: config.h.$(SUFFIX) + cp config.h.$(SUFFIX) config.h + +bios.bin: cpm/bios.bin + cp cpm/bios.bin . diff --git a/Tools/unix/zx/cbops.h b/Tools/unix/zxcc/cbops.h similarity index 96% rename from Tools/unix/zx/cbops.h rename to Tools/unix/zxcc/cbops.h index 47b69da0..f583e3a8 100644 --- a/Tools/unix/zx/cbops.h +++ b/Tools/unix/zxcc/cbops.h @@ -1,172 +1,172 @@ -/* Emulations of the CB operations of the Z80 instruction set. - * Copyright (C) 1994 Ian Collier. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define var_t unsigned char t -#define rlc(x) (x=(x<<1)|(x>>7),rflags(x,x&1)) -#define rrc(x) do{var_t=x&1;x=(x>>1)|(t<<7);rflags(x,t);}while(0) -#define rl(x) do{var_t=x>>7;x=(x<<1)|(f&1);rflags(x,t);}while(0) -#define rr(x) do{var_t=x&1;x=(x>>1)|(f<<7);rflags(x,t);}while(0) -#define sla(x) do{var_t=x>>7;x<<=1;rflags(x,t);}while(0) -#define sra(x) do{var_t=x&1;x=((signed char)x)>>1;rflags(x,t);}while(0) -#define sll(x) do{var_t=x>>7;x=(x<<1)|1;rflags(x,t);}while(0) -#define srl(x) do{var_t=x&1;x>>=1;rflags(x,t);}while(0) - -#define rflags(x,c) (f=(c)|(x&0xa8)|((!x)<<6)|parity(x)) - -#define bit(n,x) (f=(f&1)|((x&(1<>3)&7; - switch(op&0xc7){ - case 0x40: bit(n,b); break; - case 0x41: bit(n,c); break; - case 0x42: bit(n,d); break; - case 0x43: bit(n,e); break; - case 0x44: bit(n,h); break; - case 0x45: bit(n,l); break; - case 0x46: tstates+=4;val=fetch(addr);bit(n,val);store(addr,val);break; - case 0x47: bit(n,a); break; - case 0x80: res(n,b); break; - case 0x81: res(n,c); break; - case 0x82: res(n,d); break; - case 0x83: res(n,e); break; - case 0x84: res(n,h); break; - case 0x85: res(n,l); break; - case 0x86: tstates+=4;val=fetch(addr);res(n,val);store(addr,val);break; - case 0x87: res(n,a); break; - case 0xc0: set(n,b); break; - case 0xc1: set(n,c); break; - case 0xc2: set(n,d); break; - case 0xc3: set(n,e); break; - case 0xc4: set(n,h); break; - case 0xc5: set(n,l); break; - case 0xc6: tstates+=4;val=fetch(addr);set(n,val);store(addr,val);break; - case 0xc7: set(n,a); break; - } - } - if(ixoriy)switch(reg){ - case 0:b=val; break; - case 1:c=val; break; - case 2:d=val; break; - case 3:e=val; break; - case 4:h=val; break; - case 5:l=val; break; - case 7:a=val; break; - } -} - -#undef var_t -#undef rlc -#undef rrc -#undef rl -#undef rr -#undef sla -#undef sra -#undef sll -#undef srl -#undef rflags -#undef bit -#undef set -#undef res +/* Emulations of the CB operations of the Z80 instruction set. + * Copyright (C) 1994 Ian Collier. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define var_t unsigned char t +#define rlc(x) (x=(x<<1)|(x>>7),rflags(x,x&1)) +#define rrc(x) do{var_t=x&1;x=(x>>1)|(t<<7);rflags(x,t);}while(0) +#define rl(x) do{var_t=x>>7;x=(x<<1)|(f&1);rflags(x,t);}while(0) +#define rr(x) do{var_t=x&1;x=(x>>1)|(f<<7);rflags(x,t);}while(0) +#define sla(x) do{var_t=x>>7;x<<=1;rflags(x,t);}while(0) +#define sra(x) do{var_t=x&1;x=((signed char)x)>>1;rflags(x,t);}while(0) +#define sll(x) do{var_t=x>>7;x=(x<<1)|1;rflags(x,t);}while(0) +#define srl(x) do{var_t=x&1;x>>=1;rflags(x,t);}while(0) + +#define rflags(x,c) (f=(c)|(x&0xa8)|((!x)<<6)|parity(x)) + +#define bit(n,x) (f=(f&1)|((x&(1<>3)&7; + switch(op&0xc7){ + case 0x40: bit(n,b); break; + case 0x41: bit(n,c); break; + case 0x42: bit(n,d); break; + case 0x43: bit(n,e); break; + case 0x44: bit(n,h); break; + case 0x45: bit(n,l); break; + case 0x46: tstates+=4;val=fetch(addr);bit(n,val);store(addr,val);break; + case 0x47: bit(n,a); break; + case 0x80: res(n,b); break; + case 0x81: res(n,c); break; + case 0x82: res(n,d); break; + case 0x83: res(n,e); break; + case 0x84: res(n,h); break; + case 0x85: res(n,l); break; + case 0x86: tstates+=4;val=fetch(addr);res(n,val);store(addr,val);break; + case 0x87: res(n,a); break; + case 0xc0: set(n,b); break; + case 0xc1: set(n,c); break; + case 0xc2: set(n,d); break; + case 0xc3: set(n,e); break; + case 0xc4: set(n,h); break; + case 0xc5: set(n,l); break; + case 0xc6: tstates+=4;val=fetch(addr);set(n,val);store(addr,val);break; + case 0xc7: set(n,a); break; + } + } + if(ixoriy)switch(reg){ + case 0:b=val; break; + case 1:c=val; break; + case 2:d=val; break; + case 3:e=val; break; + case 4:h=val; break; + case 5:l=val; break; + case 7:a=val; break; + } +} + +#undef var_t +#undef rlc +#undef rrc +#undef rl +#undef rr +#undef sla +#undef sra +#undef sll +#undef srl +#undef rflags +#undef bit +#undef set +#undef res diff --git a/Tools/unix/zxcc/config.h.darwin b/Tools/unix/zxcc/config.h.darwin new file mode 100644 index 00000000..b3df1720 --- /dev/null +++ b/Tools/unix/zxcc/config.h.darwin @@ -0,0 +1,6 @@ +#define HAVE_DIRENT_H +#define HAVE_UTIME_H +#define HAVE_FCNTL_H +#define HAVE_UNISTD_H +#define DARWIN +//#define FILETRACKER 1 diff --git a/Tools/unix/zxcc/config.h.linux b/Tools/unix/zxcc/config.h.linux new file mode 100644 index 00000000..86925d43 --- /dev/null +++ b/Tools/unix/zxcc/config.h.linux @@ -0,0 +1,9 @@ +#define HAVE_DIRENT_H +#define HAVE_UTIME_H +#define HAVE_FCNTL_H +#define HAVE_SYS_VFS_H +#define HAVE_UNISTD_H +#define HAVE_STRING_H +#define HAVE_STDLIB_H +#define LINUX +//#define FILETRACKER 1 diff --git a/Tools/unix/zxcc/config.h.windows b/Tools/unix/zxcc/config.h.windows new file mode 100644 index 00000000..1b838310 --- /dev/null +++ b/Tools/unix/zxcc/config.h.windows @@ -0,0 +1,5 @@ +#define HAVE_WINDOWS_H +#define HAVE_FCNTL_H +#define WINVER _WIN32_WINNT_WINXP // target Windows XP +#define _WIN32_WINNT _WIN32_WINNT_WINXP // target Windows XP +//#define FILETRACKER 1 diff --git a/Tools/unix/zx/bios.bin b/Tools/unix/zxcc/cpm/bios.bin similarity index 100% rename from Tools/unix/zx/bios.bin rename to Tools/unix/zxcc/cpm/bios.bin diff --git a/Tools/unix/zx/cpm/bios.com b/Tools/unix/zxcc/cpm/bios.com similarity index 100% rename from Tools/unix/zx/cpm/bios.com rename to Tools/unix/zxcc/cpm/bios.com diff --git a/Tools/unix/zx/cpm/bios.lst b/Tools/unix/zxcc/cpm/bios.lst similarity index 100% rename from Tools/unix/zx/cpm/bios.lst rename to Tools/unix/zxcc/cpm/bios.lst diff --git a/Tools/unix/zx/cpm/bios.z80 b/Tools/unix/zxcc/cpm/bios.z80 similarity index 100% rename from Tools/unix/zx/cpm/bios.z80 rename to Tools/unix/zxcc/cpm/bios.z80 diff --git a/Tools/unix/zx/cpmdrv.c b/Tools/unix/zxcc/cpmdrv.c similarity index 96% rename from Tools/unix/zx/cpmdrv.c rename to Tools/unix/zxcc/cpmdrv.c index 24042e5b..8dcd8889 100644 --- a/Tools/unix/zx/cpmdrv.c +++ b/Tools/unix/zxcc/cpmdrv.c @@ -22,13 +22,12 @@ #include "cpmint.h" -#ifdef WIN32 - +#ifdef _WIN32 static char *drive_to_hostdrive(int cpm_drive) { static char prefix[CPM_MAXPATH]; char *lpfp; - DWORD dw; + dword dw; if (!redir_drive_prefix[cpm_drive]) return NULL; dw = GetFullPathName(redir_drive_prefix[cpm_drive], sizeof(prefix), @@ -37,7 +36,7 @@ static char *drive_to_hostdrive(int cpm_drive) if (!dw) return NULL; if (prefix[1] == ':') /* If path starts with a drive, limit it */ { /* to just that drive */ - prefix[2] = '/'; + prefix[2] = '\\'; /* GetDiskFreeSpace should have trailing backslash */ prefix[3] = 0; } return prefix; @@ -122,7 +121,7 @@ cpm_word fcb_resro(cpm_word bitmap) cpm_word fcb_sync(cpm_byte flag) { -#ifdef WIN32 +#ifdef _WIN32 return 0; #else sync(); return 0; /* Apparently some sync()s are void not int */ @@ -132,7 +131,7 @@ cpm_word fcb_sync(cpm_byte flag) cpm_word fcb_purge() { -#ifdef WIN32 +#ifdef _WIN32 return 0; #else sync(); return 0; /* Apparently some sync()s are void not int */ @@ -182,3 +181,6 @@ cpm_word fcb_dfree (cpm_byte drive, cpm_byte *dma) redir_wr24(dma, 0x8000L); /* 8MB / 128 / 2 */ return 0; } + + + diff --git a/Tools/unix/zx/cpmglob.c b/Tools/unix/zxcc/cpmglob.c similarity index 94% rename from Tools/unix/zx/cpmglob.c rename to Tools/unix/zxcc/cpmglob.c index 5566d8a4..dadae255 100644 --- a/Tools/unix/zx/cpmglob.c +++ b/Tools/unix/zxcc/cpmglob.c @@ -21,6 +21,10 @@ */ #include "cpmint.h" +#ifdef _MSC_VER +#define S_ISDIR(mode) (((mode) & _S_IFDIR) != 0) +#endif + static cpm_byte *find_fcb; static int find_n; @@ -50,7 +54,8 @@ static char upper(char c) static int cpm_match(char *s, cpm_byte *fcb, cpm_byte *pattern) { - int n, m; + int n; + size_t m; char *dotpos; m = strlen(s); @@ -98,10 +103,11 @@ static int cpm_match(char *s, cpm_byte *fcb, cpm_byte *pattern) if (((fcb[0] & 0x7F) == '?') || (fcb[0] & 0x80)) { return 1; } - - for (n = 0; n < 11; n++) { + for (n = 0; n < 11; n++) + { if (fcb[n+1] == '?') continue; - if ((pattern[n] & 0x7F) != (fcb[n+1] & 0x7F)) { + if ((pattern[n] & 0x7F) != (fcb[n+1] & 0x7F)) + { return 0; } } @@ -147,8 +153,7 @@ static struct dirent * next_entry(DIR *dir, cpm_byte *fcb, cpm_byte *pattern, redir_Msg("Can't stat %s so omitting it.\n", target_name); continue; /* Can't stat */ } - //if (S_ISDIR(st->st_mode)) - if ((st->st_mode) & _S_IFDIR) + if (S_ISDIR(st->st_mode)) { /* Searching for files only */ if (fcb[0] != '?' && fcb[0] < 0x80) @@ -291,17 +296,17 @@ cpm_word redir_find(int n, cpm_byte *fcb, cpm_byte *dma) dma[0x0d] = st.st_size & 0x7F; /* Last record byte count */ dma[0x0e] = 0; /* Extent counter, high */ -#ifdef __MSDOS__ - _dos_getfileattr(target_name, (unsigned int *)&attrib); +#ifdef _WIN32 + attrib = GetFileAttributesA(target_name); rights = redir_drdos_get_rights(target_name); if (rights && ((fcb[0] & 0x7F) == '?')) find_xfcb = 1; #else attrib = 0; rights = 0; #endif - if (attrib & 1) dma[9] |= 0x80; - if (attrib & 4) dma[10] |= 0x80; - if (!(attrib & 0x20)) dma[11] |= 0x80; + if (attrib & 1) dma[9] |= 0x80; /* read only */ + if (attrib & 4) dma[10] |= 0x80; /* system */ + if (!(attrib & 0x20)) dma[11] |= 0x80; /* archive */ @@ -310,14 +315,13 @@ cpm_word redir_find(int n, cpm_byte *fcb, cpm_byte *dma) recs = (st.st_size + 127) / 128; dma[0x0f] = (recs > 127) ? 0x80 : (recs & 0x7F); dma[0x10] = 0x80; - //if (S_ISDIR(st.st_mode)) dma[0x10] |= 0x40; - if ((st.st_mode) & _S_IFDIR) {dma[0x10] |= 0x40;} + if (S_ISDIR(st.st_mode)) dma[0x10] |= 0x40; if (attrib & 2) dma[0x10] |= 0x20; dma[0x10] |= ((entryno & 0x1FFF) >> 8); dma[0x11] = dma[0x10]; dma[0x12] = entryno & 0xFF; - redir_wr32(dma + 0x16, st.st_mtime); /* Modification time. */ + redir_wr32(dma + 0x16, (dword)st.st_mtime); /* Modification time. */ /* TODO: It should be in DOS */ /* format */ /* TODO: At 0x1A, 1st cluster */ @@ -483,10 +487,12 @@ cpm_word fcb_unlink(cpm_byte *fcb, cpm_byte *dma) } else { + releaseFile(target_name); handle = unlink(target_name); if (handle && redir_password_error()) { redir_password_append(target_name, dma); + releaseFile(target_name); handle = unlink(target_name); } } @@ -559,7 +565,8 @@ cpm_word redir_get_label(cpm_byte drv, char *pattern) cpm_word redir_get_label(cpm_byte drv, char *pattern) { char *dname; - int l, n; + size_t l; + int n; memset(pattern, ' ', 11); diff --git a/Tools/unix/zx/cpmint.h b/Tools/unix/zxcc/cpmint.h similarity index 76% rename from Tools/unix/zx/cpmint.h rename to Tools/unix/zxcc/cpmint.h index e6878174..65879654 100644 --- a/Tools/unix/zx/cpmint.h +++ b/Tools/unix/zxcc/cpmint.h @@ -20,82 +20,100 @@ This file holds internal declarations for the library. */ -#include "config.h" +#ifndef _WIN32 + #include "config.h" + #define DIRSEP "/" +#else + #include "config.h" + #define DIRSEP "/\\:" +#endif #include -#include +#ifdef HAVE_STDLIB_H + #include +#endif #include -#include +#ifdef HAVE_STRING_H + #include +#endif #include #include -#include +#ifdef _WIN32 + #include +#endif +#ifdef HAVE_SYS_TYPES_H + #include +#endif #include #include #ifdef HAVE_DIRENT_H -# include -#else -#ifdef __WATCOMC__ -# include -# include + #include + #ifdef HAVE_DIRECT_H + #include + #endif #else -# include "dirent.h" -#endif + #ifdef __WATCOMC__ + #include + #include + #else + #include "dirent.h" + #endif #endif #ifdef HAVE_NDIR_H -# include + #include #endif #ifdef HAVE_SYS_DIR_H -# include + #include #endif #ifdef HAVE_SYS_NDIR_H -# include + #include #endif #ifdef HAVE_WINDOWS_H -# include + #include #endif #ifdef HAVE_WINNT_H -# include + #include #endif #ifdef HAVE_SYS_VFS_H -# include + #include #endif #ifdef HAVE_UTIME_H -# include + #include #endif #ifdef HAVE_FCNTL_H -# include + #include #endif #ifdef HAVE_UNISTD_H -# include + #include #endif -#ifdef WIN32 -# define strcasecmp _stricmp +#ifndef _WIN32 + #include + #include + #define _S_IFDIR S_IFDIR #endif +/* MSDOS includes removed */ -#ifdef __MSDOS__ - #include - #include - #include - #ifdef __GO32__ - #include - #include - #include - #endif +#ifdef _WIN32 + #define mkdir(dir, mode) _mkdir(dir) + #define strcasecmp _stricmp + int truncate(const char* path, off_t length); /* see util.c */ + #define ftruncate _chsize + /* note Windows build assumes Windows is configured as a non case sensitive filesystem */ +#else + #define CASE_SENSITIVE_FILESYSTEM 1 #endif -#define CASE_SENSITIVE_FILESYSTEM 0 - - #include "cpmredir.h" typedef unsigned long dword; /* Must be at least 32 bits, and >= sizeof(int) */ + #ifdef CPMDEF - #define EXT - #define INIT(x) =x + #define EXT + #define INIT(x) =x #else - #define EXT extern - #define INIT(x) + #define EXT extern + #define INIT(x) #endif /* The 16 directories to which the 16 CP/M drives are mapped */ @@ -149,9 +167,11 @@ int redir_verify_fcb(cpm_byte *fcb); long zxlseek(int fd, long offset, int wh); #ifdef DEBUG + // long zxlseek(int fd, long offset, int wh); void redir_Msg(char *s, ...); void redir_showfcb(cpm_byte *fcb); #else + // #define zxlseek lseek /* Warning: This is a GCC extension */ #define redir_Msg(x, ...) #define redir_showfcb(x) @@ -224,3 +244,6 @@ cpm_word redir_password_error(void); /* Append password to filename (FILE.TYP -> FILE.TYP;PASSWORD) */ void redir_password_append(char *s, cpm_byte *dma); +void releaseFile(char *fname); +int trackFile(char *fname, void *fcb, int fd); +#define releaseFCB(fcb) trackFile(NULL, fcb, -1) diff --git a/Tools/unix/zxcc/cpmparse.c b/Tools/unix/zxcc/cpmparse.c new file mode 100644 index 00000000..ea0949ed --- /dev/null +++ b/Tools/unix/zxcc/cpmparse.c @@ -0,0 +1,126 @@ +/* + + CPMREDIR: CP/M filesystem redirector + Copyright (C) 1998, John Elliott + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file parses filenames to FCBs. +*/ + +#include "cpmint.h" + +#define is_num(c) ((c >= '0') && (c <= '9')) + +static int parse_drive_user(char *txt, cpm_byte *fcb) +{ + char uid[4], drvid[4]; + int up, dp; + + for (up = dp = 0; *txt != ':'; ++txt) + { + if (is_num (*txt)) uid [up++] = *txt; + if (isalpha(*txt)) drvid[dp++] = *txt; + if (!is_num(*txt) && !isalpha(*txt)) return -1; + } + uid[up] = 0; drvid[dp] = 0; + + if (dp > 1) return -1; /* Invalid driveletter */ + if (up > 2) return -1; /* Invalid uid */ + + fcb[0x0d] = atoi(uid) + 1; if (fcb[0x0d] > 16) return -1; + + if (islower(drvid[0])) drvid[0] = toupper(drvid[0]); + + if (drvid[0] < 'A' || drvid[0] > 'P') return -1; + + fcb[0] = drvid[0] - '@'; + return 0; +} + + + +cpm_word fcb_parse(char *txt, cpm_byte *fcb) +{ + int nl = 0, tl = 0, pl = 0, phase = 0; + char *ntxt, ch; + + memset(fcb, 0, 0x24); + + if (txt[1] == ':' || txt[2] == ':' || txt[3] == ':') + { + if (parse_drive_user(txt, fcb)) return 0xFFFF; + /* Move past the colon */ + ntxt = strchr(txt, ':') + 1; + } + else ntxt = txt; + while (phase < 3) + { + ch = *ntxt; + if (islower(ch)) ch = toupper(ch); + + switch(ch) + { + case 0: + case '\r': /* EOL */ + phase = 4; + break; + + case '.': /* file.typ */ + if (!phase) ++phase; + else phase = 3; + break; + + case ';': /* Password */ + if (phase < 2) phase = 2; + else phase = 3; + break; + + case '[': case ']': case '=': case 9: case ' ': + case '>': case '<': case ':': case ',': case '/': + case '|': /* Terminator */ + phase = 3; + + default: + switch(phase) + { + case 0: + if (nl >= 8) return 0xFFFF; + fcb[++nl] = ch; + break; + + case 1: + if (tl >= 3) return 0xFFFF; + fcb[tl + 9] = ch; + ++tl; + break; + + case 2: + if (pl >= 8) return 0xFFFF; + fcb[pl + 0x10] = ch; + ++pl; + break; + } + break; + } + } + if (!nl) return 0xFFFF; + + fcb[0x1A] = pl; + + if (phase == 4) return 0; + + return (cpm_word)(ntxt - txt); +} diff --git a/Tools/unix/zx/cpmredir.c b/Tools/unix/zxcc/cpmredir.c similarity index 87% rename from Tools/unix/zx/cpmredir.c rename to Tools/unix/zxcc/cpmredir.c index d8a5e337..6484608e 100644 --- a/Tools/unix/zx/cpmredir.c +++ b/Tools/unix/zxcc/cpmredir.c @@ -71,7 +71,8 @@ cpm_word fcb_open(cpm_byte *fcb, cpm_byte *dma) { char fname[CPM_MAXPATH]; int handle; - int drv, l; + int drv; + size_t l; char *s; DIR *dir; @@ -95,23 +96,13 @@ cpm_word fcb_open(cpm_byte *fcb, cpm_byte *dma) { l = strlen(redir_drive_prefix[drv]) - 1; s = redir_drive_prefix[drv]; + while (--l > 0 && !strchr(DIRSEP, s[l])) --l; - while (l > 0) - { - if (s[l] == '/') break; -#ifdef __MSDOS__ - if (s[l] == '\\') break; - if (s[l] == ':') break; -#endif - --l; - } -#ifdef __MSDOS__ - if (l < 2) return 0; /* "C:" */ -#else - if (l <= 0) return 0; /* "/" */ + if (l == 0) return 0; /* "/" or "\" */ +#ifdef _WIN32 + if (s[l] == ':' && l < 2) return 0; /* "C:" */ #endif - ++l; - s[l] = 0; + s[l + 1] = 0; return 0; } /* Opening some other directory */ @@ -160,11 +151,11 @@ cpm_word fcb_open(cpm_byte *fcb, cpm_byte *dma) */ /* Get the file length */ - redir_wr32(fcb + 0x1C, zxlseek(handle, 0, SEEK_END)); + redir_wr32(fcb + LENGTH_OFFSET, zxlseek(handle, 0, SEEK_CUR)); zxlseek(handle, 0, SEEK_SET); /* Set the last record byte count */ - if (fcb[0x20] == 0xFF) fcb[0x20] = fcb[0x1C] & 0x7F; + if (fcb[0x20] == 0xFF) fcb[0x20] = fcb[LENGTH_OFFSET] & 0x7F; redir_Msg("Ret: 0\n"); @@ -179,7 +170,7 @@ cpm_word fcb_close(cpm_byte *fcb) SHOWNAME("fcb_close") if ((handle = redir_verify_fcb(fcb)) < 0) return -1; - redir_Msg(" (at %lx)\n", zxlseek(handle, 0, SEEK_CUR)); + redir_Msg(" (at %lx)\n", zxlseek(handle, 0, SEEK_END)); if (fcb[0] & 0x80) /* Close directory */ { @@ -195,13 +186,13 @@ cpm_word fcb_close(cpm_byte *fcb) if (fcb[5] & 0x80) /* CP/M 3: Flush rather than close */ { -#ifndef WIN32 +#ifndef _WIN32 sync(); #endif return 0; } -#ifdef WIN32 +#ifdef _WIN32 { BOOL b; redir_Msg(">CloseHandle() Handle=%lu\n", handle); @@ -290,7 +281,7 @@ cpm_word fcb_read(cpm_byte *fcb, cpm_byte *dma) memset(dma, 0x00, redir_rec_len); -#ifdef WIN32 +#ifdef _WIN32 { BOOL b; redir_Msg(">ReadFile() Handle=%lu, DMA=%lu, Len=%lu\n", handle, dma, redir_rec_len); @@ -324,6 +315,9 @@ cpm_word fcb_read(cpm_byte *fcb, cpm_byte *dma) return redir_xlt_err(); /* unwritten extent */ } + /* if not multiple of 128 bytes, pad sector with 0x1A */ + for (n = rv; n < rd_len; n++) dma[n] = 0x1A; + /* Less was read in than asked for. Report the number of 128-byte * records that _were_ read in. */ @@ -332,16 +326,11 @@ cpm_word fcb_read(cpm_byte *fcb, cpm_byte *dma) { /* Pack from the size actually read up to the size we claim * to have read */ - for (n = rv; n < rd_len; n++) dma[n] = 0x1A; - rd_len = ((rv + 127) / 128) << 8; /* High byte */ + rd_len = rd_len * 2; /* rd_len already sector * 128, so * 2 to move to High byte */ redir_Msg("Ret: 0x%x\n", rd_len | 1); return rd_len | 1; /* eof */ } - /* We have reported that all records were read in. But the last - * record might be less than 128 bytes, so pack it with 0x1A bytes */ - - for (n = rv; n < rd_len; n++) dma[n] = 0x1A; redir_Msg("Ret: 0 (bytes read=%d)\n", rv); return 0; } @@ -366,7 +355,7 @@ cpm_word fcb_write(cpm_byte *fcb, cpm_byte *dma) redir_Msg(" (to %lx)\n", zxlseek(handle, 0, SEEK_CUR)); -#ifdef WIN32 +#ifdef _WIN32 { BOOL b; redir_Msg(">WriteFile() Handle=%lu, DMA=%lu, Len=%lu\n", handle, dma, redir_rec_len); @@ -382,8 +371,8 @@ cpm_word fcb_write(cpm_byte *fcb, cpm_byte *dma) redir_put_fcb_pos(fcb, npos); /* Update the file length */ - len = redir_rd32(fcb + 0x1C); - if (len < npos) redir_wr32(fcb + 0x1C, npos); + len = redir_rd32(fcb + LENGTH_OFFSET); + if (len < npos) redir_wr32(fcb + LENGTH_OFFSET, npos); if (rv < 0) return redir_xlt_err(); /* error */ if (rv < redir_rec_len) return 1; /* disk full */ @@ -397,6 +386,8 @@ cpm_word fcb_creat(cpm_byte *fcb, cpm_byte *dma) char fname[CPM_MAXPATH]; int handle; + releaseFCB(fcb); /* release existing fcb usage */ + /* Don't support ambiguous filenames */ if (redir_fcb2unix(fcb, fname)) return 0x09FF; redir_Msg("fcb_creat(\"%s\")\n", fname); @@ -408,16 +399,13 @@ cpm_word fcb_creat(cpm_byte *fcb, cpm_byte *dma) if (fcb[0] & 0x80) { -#ifdef WIN32 - handle = mkdir(fname); -#else handle = mkdir(fname, 0x777); -#endif if (handle) return redir_xlt_err(); return 0; } + releaseFile(fname); /* purge any open handles for this file */ -#ifdef WIN32 +#ifdef _WIN32 redir_Msg(">CreateFile([CREATE_ALWAYS]) Name='%s'\n", fname); handle = (int)CreateFile(fname, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); redir_Msg("ReadFile() Handle=%lu, DMA=%lu, Len=%lu\n", handle, dma, redir_rec_len); @@ -526,16 +519,20 @@ cpm_word fcb_randrd(cpm_byte *fcb, cpm_byte *dma) redir_put_fcb_pos(fcb, offs); + if (rv < 0) return redir_xlt_err(); /* Error */ + rd_len = ((rv + 127) / 128) * 128; - if (rv < 0) return redir_xlt_err(); /* Error */ + /* PMO: pad partial sector to 128 bytes, even if EOF reached in multi sector read */ + for (n = rv; n < rd_len; n++) dma[n] = 0x1A; /* pad last read to 128 boundary with 0x1A*/ + if (rd_len < redir_rec_len) /* eof */ { - rd_len = ((rv + 127) / 128) << 8; /* High byte */ + rd_len = rd_len * 2; /* rd_len already sector * 128, so * 2 to move to High byte */ redir_Msg("Ret: 0x%x\n", rd_len | 1); return rd_len | 1; /* eof */ } - for (n = rv; n < rd_len; n++) dma[n] = 0x1A; + return 0; } @@ -546,7 +543,7 @@ cpm_word fcb_randwr(cpm_byte *fcb, cpm_byte *dma) int handle; int rv; dword offs = redir_rd24(fcb + 0x21) * 128; - long len; + dword len; SHOWNAME("fcb_randwr") @@ -555,7 +552,8 @@ cpm_word fcb_randwr(cpm_byte *fcb, cpm_byte *dma) if (redir_ro_fcb(fcb)) return 0x02FF; if (zxlseek(handle, offs, SEEK_SET) < 0) return 6; /* bad record no. */ -#ifdef WIN32 + +#ifdef _WIN32 { BOOL b; redir_Msg(">WriteFile() Handle=%lu, DMA=%lu, Len=%lu\n", handle, dma, redir_rec_len); @@ -569,15 +567,38 @@ cpm_word fcb_randwr(cpm_byte *fcb, cpm_byte *dma) zxlseek(handle, offs, SEEK_SET); redir_put_fcb_pos(fcb, offs); + if (rv < 0) return redir_xlt_err(); /* Error */ /* Update the file length */ - len = redir_rd32(fcb + 0x1C); - if (len < offs) redir_wr32(fcb + LENGTH_OFFSET, offs); + len = redir_rd32(fcb + LENGTH_OFFSET); + /* PMO: Bug fix, account for the data just written */ + if (len < offs + rv) { + redir_wr32(fcb + LENGTH_OFFSET, offs + rv); + // fcb[0x20] = (offs + rv) % 256; + } - if (rv < 0) return redir_xlt_err(); /* Error */ if (rv < redir_rec_len) return 1; /* disk full */ return 0; } +#ifndef OLD_RANDWZ +/* PMO: + * Under CP/M for random write with zero fill, the zero fill is only done for a newly allocated + * block and not fill from previous end of file + * to implement this fully would require tracking sparse files and filling to block + * boundaries. + * As the default for POSIX/Windows lseek is to effectively zero fill and for modern hard disks + * the additional space used is small compared to capacity, fcb_randwz is the same as fcb_randwr + * Note zero padding to the end of the block will be done automatically as required when data is + * written to later offsets + */ +/* Write random with 0 fill */ +cpm_word fcb_randwz(cpm_byte* fcb, cpm_byte* dma) +{ + SHOWNAME("fcb_randwz"); + return fcb_randwr(fcb, dma); +} + +#else /* Write random with 0 fill */ cpm_word fcb_randwz(cpm_byte *fcb, cpm_byte *dma) { @@ -588,8 +609,11 @@ cpm_word fcb_randwz(cpm_byte *fcb, cpm_byte *dma) SHOWNAME("fcb_randwz") if ((handle = redir_verify_fcb(fcb)) < 0) return 9; /* Invalid FCB */ + /* Software write-protection */ + if (redir_ro_fcb(fcb)) return 0x02FF; + offs = redir_rd24(fcb + 0x21) * 128; - len = redir_rd32(fcb + 0x1C); + len = redir_rd32(fcb + LENGTH_OFFSET); redir_wr32(fcb + LENGTH_OFFSET, offs); @@ -601,7 +625,7 @@ cpm_word fcb_randwz(cpm_byte *fcb, cpm_byte *dma) rl = sizeof(zerorec); if ((offs - len) < sizeof(zerorec)) rl = offs - len; -#ifdef WIN32 +#ifdef _WIN32 { BOOL b; redir_Msg(">WriteFile() Handle=%lu, DMA=%lu, Len=%lu\n", handle, zerorec, rl); @@ -623,6 +647,8 @@ cpm_word fcb_randwz(cpm_byte *fcb, cpm_byte *dma) return fcb_randwr(fcb, dma); } +#endif + cpm_word fcb_tell(cpm_byte *fcb) { @@ -656,7 +682,7 @@ cpm_word fcb_stat(cpm_byte *fcb) rv = stat(fname, &st); - redir_Msg("fcb_stat(\"%s\") fcb=%x\n", fname, (int)fcb); + redir_Msg("fcb_stat(\"%s\") fcb=%p\n", fname, fcb); if (rv < 0) { redir_Msg("ret: -1\n"); @@ -687,6 +713,10 @@ cpm_word fcb_date(cpm_byte *fcb) struct stat st; int rv; + /* as this function will overwrite the fcb info used by ZXCC + * release any file associated with it + */ + releaseFCB(fcb); /* Don't support ambiguous filenames */ if (redir_fcb2unix(fcb, fname)) return 0x09FF; @@ -703,23 +733,20 @@ cpm_word fcb_date(cpm_byte *fcb) } - cpm_word fcb_trunc(cpm_byte *fcb, cpm_byte *dma) { char fname[CPM_MAXPATH]; dword offs = redir_rd24(fcb + 0x21) * 128; + releaseFCB(fcb); /* CP/M requires truncated files be closed */ /* Don't support ambiguous filenames */ if (redir_fcb2unix(fcb, fname)) return 0x09FF; /* Software write-protection */ if (redir_ro_fcb(fcb)) return 0x02FF; + releaseFile(fname); /* after truncate open files are invalid */ redir_log_fcb(fcb); -#ifdef WIN32 - (void)offs; - return 0x06FF; /* Simply not implemented */ -#else if (truncate(fname, offs)) { if (redir_password_error()) @@ -730,24 +757,13 @@ cpm_word fcb_trunc(cpm_byte *fcb, cpm_byte *dma) return redir_xlt_err(); } return 0; -#endif } cpm_word fcb_sdate(cpm_byte *fcb, cpm_byte *dma) { char fname[CPM_MAXPATH]; -#ifdef WIN32 - /* TODO: Use SetFileTime() here */ - - /* Don't support ambiguous filenames */ - if (redir_fcb2unix(fcb, fname)) return 0x09FF; - - /* Software write-protection */ - if (redir_ro_fcb(fcb)) return 0x02FF; - redir_log_fcb(fcb); -#else struct utimbuf buf; buf.actime = redir_unixtime(dma); @@ -770,7 +786,6 @@ cpm_word fcb_sdate(cpm_byte *fcb, cpm_byte *dma) } return redir_xlt_err(); } -#endif return 0; } @@ -809,7 +824,7 @@ cpm_word fcb_chmod(cpm_byte *fcb, cpm_byte *dma) } return redir_xlt_err(); } -#elif defined (WIN32) +#elif defined (_WIN32) omode = 0; if (fcb[9] & 0x80) omode |= FILE_ATTRIBUTE_READONLY; @@ -838,13 +853,16 @@ cpm_word fcb_chmod(cpm_byte *fcb, cpm_byte *dma) { if (stat(fname, &st)) return redir_xlt_err(); + releaseFCB(fcb); /* cpm required file to be closed so release FCB */ + releaseFile(fname); /* also make sure no other handles open to file */ handle = open(fname, O_RDWR | O_BINARY); if (handle < 0) return redir_xlt_err(); newoffs = offs = ((st.st_size + 127) / 128) * 128; if (fcb[0x20] & 0x7F) { - newoffs -= (0x80 - (fcb[0x20] & 0x7F)); + newoffs -= fcb[0x20] & 0x7f; + //newoffs -= (0x80 - (fcb[0x20] & 0x7F)); } if (newoffs == st.st_size) { @@ -852,13 +870,11 @@ cpm_word fcb_chmod(cpm_byte *fcb, cpm_byte *dma) } else if (newoffs < st.st_size) { -#ifndef WIN32 /* XXX Do this somehow in Win32 */ if (ftruncate(handle, newoffs)) { close(handle); return redir_xlt_err(); } -#endif } else while (newoffs > st.st_size) { diff --git a/Tools/unix/zx/cpmredir.h b/Tools/unix/zxcc/cpmredir.h similarity index 100% rename from Tools/unix/zx/cpmredir.h rename to Tools/unix/zxcc/cpmredir.h diff --git a/Tools/unix/zx/dirent.c b/Tools/unix/zxcc/dirent.c similarity index 100% rename from Tools/unix/zx/dirent.c rename to Tools/unix/zxcc/dirent.c diff --git a/Tools/unix/zx/dirent.h b/Tools/unix/zxcc/dirent.h similarity index 100% rename from Tools/unix/zx/dirent.h rename to Tools/unix/zxcc/dirent.h diff --git a/Tools/unix/zx/drdos.c b/Tools/unix/zxcc/drdos.c similarity index 95% rename from Tools/unix/zx/drdos.c rename to Tools/unix/zxcc/drdos.c index 97bd583c..baf7a00b 100644 --- a/Tools/unix/zx/drdos.c +++ b/Tools/unix/zxcc/drdos.c @@ -1,236 +1,236 @@ -/* - - CPMREDIR: CP/M filesystem redirector - Copyright (C) 1998, John Elliott - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - This file holds DRDOS-specific password code. -*/ - -#include "cpmint.h" - -cpm_word redir_drdos_pwmode(cpm_byte b) -{ - cpm_word mode = 0; - - if (b & 0x80) mode |= 0xddd; - if (b & 0x40) mode |= 0x555; - if (b & 0x20) mode |= 0x111; - - return mode; -} - -cpm_byte redir_cpm_pwmode(cpm_word w) -{ - cpm_byte mode = 0; - - if (w & 0x8) mode |= 0x80; - if (w & 0x4) mode |= 0x40; - if (w & 0x1) mode |= 0x20; - - return mode; -} - -#ifdef __MSDOS__ -#ifdef __GO32__ /* The GO32 extender doesn't understand DRDOS password - * functions, so these are done with __dpmi_int() rather - * than intdos() */ - -cpm_word redir_drdos_get_rights(char *path) -{ - __dpmi_regs r; - - if (!redir_drdos) return 0; - - redir_Msg("Rights for file %s: \n\r", path); - - dosmemput(path, strlen(path) + 1, __tb); - r.x.ax = 0x4302; - r.x.dx = __tb & 0x0F; - r.x.ds = (__tb) >> 4; - - __dpmi_int(0x21, &r); - - redir_Msg(" %04x \n\r", r.x.cx); - - if (r.x.flags & 1) return 0; - return r.x.cx; -} - - -cpm_word redir_drdos_put_rights(char *path, cpm_byte *dma, cpm_word rights) -{ - __dpmi_regs r; - - if (!redir_drdos) return 0; - - redir_Msg("Put rights for file %s: %04x %-8.8s %-8.8s\n\r", path, rights, dma, dma + 8); - - dosmemput(dma+8, 8, __tb); /* Point DTA at password */ - r.x.ax = 0x1A00; - r.x.dx = (__tb & 0x0F); - r.x.ds = (__tb) >> 4; - __dpmi_int(0x21, &r); - - dosmemput(path, strlen(path) + 1, __tb + 0x10); - r.x.ax = 0x4303; /* Set rights */ - r.x.cx = rights; - r.x.dx = (__tb & 0x0F) + 0x10; - r.x.ds = (__tb) >> 4; - - __dpmi_int(0x21, &r); - - if (r.x.flags & 1) - { - redir_Msg(" Try 1 failed. Error %04x\n\r", r.x.ax); - if (redir_password_error()) - { - redir_password_append(path, dma); - - dosmemput(path, strlen(path) + 1, __tb + 0x10); - r.x.ax = 0x4303; /* Set rights */ - r.x.cx = rights; - r.x.dx = (__tb & 0x0F) + 0x10; - r.x.ds = (__tb) >> 4; - - __dpmi_int(0x21, &r); - if (!r.x.flags & 1) return 0; - if (redir_password_error()) return 0x7FF; - } - return 0xFF; - } - return 0; -} - -#else /* __GO32__ */ - -cpm_word redir_drdos_get_rights(char *path) -{ - union REGS r; - struct SREGS s; - - if (!redir_drdos) return 0; - - redir_Msg("Rights for file %s: \n\r", path); - - dosmemput(path, strlen(path) + 1, __tb); - r.w.ax = 0x4302; - r.w.dx = __tb & 0x0F; - s.ds = (__tb) >> 4; - - intdosx(&r, &r, &s); - - redir_Msg(" %04x \n\r", r.w.cx); - - if (r.w.cflag) return 0; - return r.w.cx; -} - - -cpm_word redir_drdos_put_rights(char *path, cpm_byte *dma, cpm_word rights) -{ - union REGS r; - struct SREGS s; - - if (!redir_drdos) return 0; - - redir_Msg("Put rights for file %s: %04x\n\r", path, rights); - - dosmemput(dma, 8, __tb); /* Point DTA at password */ - r.w.ax = 0x1A00; - r.w.dx = (__tb & 0x0F); - s.ds = (__tb) >> 4; - intdosx(&r, &r, &s); - - dosmemput(path, strlen(path) + 1, __tb + 0x10); - r.w.ax = 0x4303; /* Set rights */ - r.w.cx = rights; - r.w.dx = (__tb & 0x0F) + 0x10; - s.ds = (__tb) >> 4; - - intdosx(&r, &r, &s); - - if (r.w.cflag) - { - redir_Msg(" Try 1 failed. Error %04x \n\r", r.w.ax); - if (redir_password_error()) - { - redir_password_append(path, dma); - - dosmemput(path, strlen(path) + 1, __tb + 0x10); - r.w.ax = 0x4303; /* Set rights */ - r.w.cx = rights; - r.w.dx = (__tb & 0x0F) + 0x10; - s.ds = (__tb) >> 4; - - intdosx(&r, &r, &s); - if (!r.w.cflag) return 0; - } - return 0xFF; - } - return 0; -} - -#endif /* __GO32__ */ - - -cpm_word redir_password_error(void) -{ - union REGS r; - - if (!redir_drdos) return 0; - - r.w.ax = 0x5900; - r.w.bx = 0x0000; - - intdos(&r, &r); - - redir_Msg("Last error was: %04x\r\n", r.w.ax); - - if (r.w.ax == 0x56) return 1; /* Bad password */ - return 0; -} - - -void redir_password_append(char *s, cpm_byte *dma) -{ - int n, m; - - if (!redir_drdos) return; - - if (dma[0] == 0 || dma[0] == 0x20) return; - - strcat(s, ";"); - m = strlen(s); - - for (n = 0; n < 8; n++) - { - if (dma[n] == ' ') s[m] = 0; - else s[m] = dma[n]; - ++m; - } - s[m] = 0; - -} -#else /* __MSDOS__ */ -void redir_password_append(char *s, cpm_byte *dma) {} -cpm_word redir_password_error(void) { return 0; } -cpm_word redir_drdos_put_rights(char *path, cpm_byte *dma, cpm_word rights) -{ return 0; } -cpm_word redir_drdos_get_rights(char *path) { return 0; } -#endif /* __MSDOS__ */ - - +/* + + CPMREDIR: CP/M filesystem redirector + Copyright (C) 1998, John Elliott + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file holds DRDOS-specific password code. +*/ + +#include "cpmint.h" + +cpm_word redir_drdos_pwmode(cpm_byte b) +{ + cpm_word mode = 0; + + if (b & 0x80) mode |= 0xddd; + if (b & 0x40) mode |= 0x555; + if (b & 0x20) mode |= 0x111; + + return mode; +} + +cpm_byte redir_cpm_pwmode(cpm_word w) +{ + cpm_byte mode = 0; + + if (w & 0x8) mode |= 0x80; + if (w & 0x4) mode |= 0x40; + if (w & 0x1) mode |= 0x20; + + return mode; +} + +#ifdef __MSDOS__ +#ifdef __GO32__ /* The GO32 extender doesn't understand DRDOS password + * functions, so these are done with __dpmi_int() rather + * than intdos() */ + +cpm_word redir_drdos_get_rights(char *path) +{ + __dpmi_regs r; + + if (!redir_drdos) return 0; + + redir_Msg("Rights for file %s: \n\r", path); + + dosmemput(path, strlen(path) + 1, __tb); + r.x.ax = 0x4302; + r.x.dx = __tb & 0x0F; + r.x.ds = (__tb) >> 4; + + __dpmi_int(0x21, &r); + + redir_Msg(" %04x \n\r", r.x.cx); + + if (r.x.flags & 1) return 0; + return r.x.cx; +} + + +cpm_word redir_drdos_put_rights(char *path, cpm_byte *dma, cpm_word rights) +{ + __dpmi_regs r; + + if (!redir_drdos) return 0; + + redir_Msg("Put rights for file %s: %04x %-8.8s %-8.8s\n\r", path, rights, dma, dma + 8); + + dosmemput(dma+8, 8, __tb); /* Point DTA at password */ + r.x.ax = 0x1A00; + r.x.dx = (__tb & 0x0F); + r.x.ds = (__tb) >> 4; + __dpmi_int(0x21, &r); + + dosmemput(path, strlen(path) + 1, __tb + 0x10); + r.x.ax = 0x4303; /* Set rights */ + r.x.cx = rights; + r.x.dx = (__tb & 0x0F) + 0x10; + r.x.ds = (__tb) >> 4; + + __dpmi_int(0x21, &r); + + if (r.x.flags & 1) + { + redir_Msg(" Try 1 failed. Error %04x\n\r", r.x.ax); + if (redir_password_error()) + { + redir_password_append(path, dma); + + dosmemput(path, strlen(path) + 1, __tb + 0x10); + r.x.ax = 0x4303; /* Set rights */ + r.x.cx = rights; + r.x.dx = (__tb & 0x0F) + 0x10; + r.x.ds = (__tb) >> 4; + + __dpmi_int(0x21, &r); + if (!r.x.flags & 1) return 0; + if (redir_password_error()) return 0x7FF; + } + return 0xFF; + } + return 0; +} + +#else /* __GO32__ */ + +cpm_word redir_drdos_get_rights(char *path) +{ + union REGS r; + struct SREGS s; + + if (!redir_drdos) return 0; + + redir_Msg("Rights for file %s: \n\r", path); + + dosmemput(path, strlen(path) + 1, __tb); + r.w.ax = 0x4302; + r.w.dx = __tb & 0x0F; + s.ds = (__tb) >> 4; + + intdosx(&r, &r, &s); + + redir_Msg(" %04x \n\r", r.w.cx); + + if (r.w.cflag) return 0; + return r.w.cx; +} + + +cpm_word redir_drdos_put_rights(char *path, cpm_byte *dma, cpm_word rights) +{ + union REGS r; + struct SREGS s; + + if (!redir_drdos) return 0; + + redir_Msg("Put rights for file %s: %04x\n\r", path, rights); + + dosmemput(dma, 8, __tb); /* Point DTA at password */ + r.w.ax = 0x1A00; + r.w.dx = (__tb & 0x0F); + s.ds = (__tb) >> 4; + intdosx(&r, &r, &s); + + dosmemput(path, strlen(path) + 1, __tb + 0x10); + r.w.ax = 0x4303; /* Set rights */ + r.w.cx = rights; + r.w.dx = (__tb & 0x0F) + 0x10; + s.ds = (__tb) >> 4; + + intdosx(&r, &r, &s); + + if (r.w.cflag) + { + redir_Msg(" Try 1 failed. Error %04x \n\r", r.w.ax); + if (redir_password_error()) + { + redir_password_append(path, dma); + + dosmemput(path, strlen(path) + 1, __tb + 0x10); + r.w.ax = 0x4303; /* Set rights */ + r.w.cx = rights; + r.w.dx = (__tb & 0x0F) + 0x10; + s.ds = (__tb) >> 4; + + intdosx(&r, &r, &s); + if (!r.w.cflag) return 0; + } + return 0xFF; + } + return 0; +} + +#endif /* __GO32__ */ + + +cpm_word redir_password_error(void) +{ + union REGS r; + + if (!redir_drdos) return 0; + + r.w.ax = 0x5900; + r.w.bx = 0x0000; + + intdos(&r, &r); + + redir_Msg("Last error was: %04x\r\n", r.w.ax); + + if (r.w.ax == 0x56) return 1; /* Bad password */ + return 0; +} + + +void redir_password_append(char *s, cpm_byte *dma) +{ + int n, m; + + if (!redir_drdos) return; + + if (dma[0] == 0 || dma[0] == 0x20) return; + + strcat(s, ";"); + m = strlen(s); + + for (n = 0; n < 8; n++) + { + if (dma[n] == ' ') s[m] = 0; + else s[m] = dma[n]; + ++m; + } + s[m] = 0; + +} +#else /* __MSDOS__ */ +void redir_password_append(char *s, cpm_byte *dma) {} +cpm_word redir_password_error(void) { return 0; } +cpm_word redir_drdos_put_rights(char *path, cpm_byte *dma, cpm_word rights) +{ return 0; } +cpm_word redir_drdos_get_rights(char *path) { return 0; } +#endif /* __MSDOS__ */ + + diff --git a/Tools/unix/zx/edops.h b/Tools/unix/zxcc/edops.h similarity index 100% rename from Tools/unix/zx/edops.h rename to Tools/unix/zxcc/edops.h diff --git a/Tools/unix/zxcc/readme.txt b/Tools/unix/zxcc/readme.txt new file mode 100644 index 00000000..ba94bf5d --- /dev/null +++ b/Tools/unix/zxcc/readme.txt @@ -0,0 +1,86 @@ +This is an adaptation of zxcc-0.5.7 for RomWBW by Wayne Warthen. + +In general, this is a stripped down variant of John Elliott's zxcc package that +runs under a Windows command line (32 or 64 bit Windows), Linux, or MacOS. +This adaptation implements only the main "zxcc" command. The other programs +(zxc, zxas, zxlink, and zslibr) are not inluded here because they are fairly +specific to Hi-Tech C. + +Please see http://www.seasip.info/Unix/Zxcc/ for more information on the original +version of zxcc. Also, refer to https://github.com/agn453/ZXCC which has an +updated version of the code. + +The included zxcc.html documentation is from the original version, so it does not +reflect the changes made here. + +To build under Open Watcom, use Build-OW.cmd. To build under Microsoft Visual C, +use Build-VC.cmd. To build under Linux or MacOS, use the Makefile. + +The GPL status of everything remains in place and carries forward. + +December 5, 2014 + +After struggling to get the entire zxcc package to build nicely using autoconf, +I finally gave up and took a much more direct approach. I have extracted just +the source files needed and created a simple batch file to build the tool. I +realize this could be done much better, but I cheated in the interest of time. + +The one "real" change I made in the source code was that I modified the tool +to look for bios.bin in the same directory as the executable is in. This +just makes it much easier to set up (for me, anyway). + +Wayne Warthen +wwarthen@gmail.com + +March 15, 2017 + +- Updated to compile under Open Watcom. +- Implemented BDOS console status function. +- Set stdin and stdout to binary mode at startup. + +August 21, 2021 + +- Incorporated filename case insensitivity changes from Curt Mayer +- Incorporated fixes from Tony Nicholson at https://github.com/agn453/ZXCC + - Emulation of CP/M BDOS function 60 (call resident system extension) + should be disabled and return 0xFF in both the A and L registers. + - Change cpm_bdos_10() to return an unsigned result to avoid buffer + size being interpreted as negative. + - Fix the emulation of Z80 opcodes for IN (HL),(C) and + OUT (C),(HL) - opcodes 0xED,0x70 and 0xED,0x71 respectively. + This is noted in Fred Weigel's AM9511 arithmetic processing unit + emulation from https://github.com/ratboy666/am9511 in the howto.txt + description. NB: I have not included Fred's am9511 support at this + time into ZXCC. +- Fixed parse_to_fcb function in zxcc.c to handle parsing second automatic + FCB from command line + +Wayne Warthen +wwarthen@gmail.com + +--WBW 4:09 PM 8/21/2021 + +January 9, 2022 + +- Running zxcc under WSL (Windows Subsystem for Linux) was gererating output + that was correct but did not match standard Windows or Linux runs. This + turned out to be an assumption in a few places in the code that reading + into a buffer would not modify the area of the buffer that was beyond + the space required by the data being read. Under WSL, this "slack" space + was mangled. I made changes in these locations to clean up the slack + space after such reads. This fixed WSL runs to produce binary identical + output. Although only required by WSL, the changes cause no problems for + other environments and are actually correct per POSIX. + +--WBW 11:56 AM 1/9/2022 + +- I have attempted to sync my code up with the latest code found in Tony + Nicholson's GitHub repo at https://github.com/agn453/ZXCC. The most + significant difference in my code is that I am using the WIN32 API + for all disk I/O. Although the file tracking code is retained, I have + found this mechanism to fail insome scenarios. By using the WIN32 API + I can achieve the same file sharing attributes as Unix which makes the + file tracking mechanism optional. + +--WBW 9:34 AM 2/10/2022 + diff --git a/Tools/unix/zxcc/track.c b/Tools/unix/zxcc/track.c new file mode 100644 index 00000000..20770a8a --- /dev/null +++ b/Tools/unix/zxcc/track.c @@ -0,0 +1,150 @@ +/* + + CPMREDIR: CP/M filesystem redirector + Optional Open file tracker + Copyright (C) 2021, Mark Ogden + + This is an addition to the CPMREDIR + Copyright (C) 1998, John Elliott + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +//#include "cpmint.h" +#include "zxcc.h" + +/* CP/M does not require that files opened for reading need to be closed, + * this has two impacts + * 1) a lot of file handles can remain opened even when the file is no + * longer used. For modern OS builds this isn't a major problem as + * the system limits are quite high. It is however wasteful + * 2) for windows it can lead to issues when trying to delete / rename a file + * as normally windows will not allow files to be deleted/renamed if the + * file is currently open. Unix variants don't have this restriction. + * + * As an example the build of cgen.com using my decompiled sources + * the linq phase without tracking left 42 open files + * with tracking this was reduced to 2 + * + * This code keeps track of files that are opened until they are explicitly + * closed or the FCB used to open the file is reused, or the file needs to be + * renamed or deleted. + * To do this it keeps track of the expanded filename, fcb location and allocated + * file handle + * + * Two public functions are used to manage the file list, and are called from + * within the bdos emulation + * + * trackFile(char *fname, void *fcb, int fd) + * removes existing tracking with matchin fcb or fd and + * if (fname != NULL) - add the info to the head of the open files list + * it returns fd + * + * the function is called in the following circumstances + * 1) before closing a file (fname is NULL) + * 2) just after the file has been opened/created. + * 3) to remove association with a given fcb trackFile(NULL, fcb, -1) + * + * note a helper macro releaseFCB(fcb) can be used for (3) above + * + * releaseFile(char *fname) + * this scans through the list of open files and for each open file + * with a matching fname, the file is closed + * + * the function is called before deleting a file or renaming a file + * + * + * there is a helper function that removes the info from the list + * + * Notes: + * For most applications the tracker could in principle automatically + * close existing open files at the start of a new executable invocation. + * Unfortunately this does not support the case where there is a scripting + * engine intercepting the warm reboots, as it may need to keep the script + * source file open. + * + * Note in theory it would be possible for a CP/M program to open a file + * with a given fcb, move the fcb internally and then open another file + * with the original fcb. If this happens the FCB tracking could cause + * a problem. I am not aware of any real programs that do this. + * Please let me know if the situation arises. +*/ +/* windows needs to use file tracking, for unix/linux it is optional */ +#ifdef FILETRACKER +typedef struct _track { + struct _track* next; + int handle; + void* fcb; + char* fname; +} track_t; + +track_t* openFiles; + +static track_t* rmHandle(track_t* s) { + track_t* next = s->next; + free(s->fname); + free(s); + return next; +} + +void releaseFile(char* fname) { + track_t* s = (track_t*)&openFiles; + while (s->next) + if (strcmp(s->next->fname, fname) == 0) { + close(s->next->handle); + Msg("releaseFile closed file \"%s\"\n", s->next->fname); + s->next = rmHandle(s->next); + } + else + s = s->next; +} + + +int trackFile(char* fname, void* fcb, int fd) { + track_t* s = (track_t*)&openFiles; + Msg("trackFile: \"%s\", FCB=0x%X, Handle=%i\n", fname, (byte *)fcb - RAM, fd); + while (s->next) { /* find any existing fcb or fd */ + if (s->next->fcb == fcb || s->next->handle == fd) { + if (s->next->handle != fd) { + close(s->next->handle); + Msg(" closed file \"%s\", Handle=%i\n", s->next->fname, s->next->handle); + } + Msg(" released file \"%s\", Handle=%i\n", s->next->fname, s->next->handle); + s->next = rmHandle(s->next); /* release the tracker */ + } + else + s = s->next; + } + if (fname && fd >= 0) { + if ((s = malloc(sizeof(track_t))) == NULL) { + fprintf(stderr, "out of memory\n"); + exit(1); + } + s->next = openFiles; + s->fname = strdup(fname); + s->fcb = fcb; + s->handle = fd; + openFiles = s; + } + return fd; +} + +#else + +void releaseFile(char* fname) {} +int trackFile(char* fname, void* fcb, int fd) { return fd; } + +#endif + diff --git a/Tools/unix/zx/util.c b/Tools/unix/zxcc/util.c similarity index 83% rename from Tools/unix/zx/util.c rename to Tools/unix/zxcc/util.c index cb22e18b..bc3dbb6e 100644 --- a/Tools/unix/zx/util.c +++ b/Tools/unix/zxcc/util.c @@ -22,13 +22,18 @@ #include "cpmint.h" + + + + + /* In debug mode, lseek()s can be traced. */ #ifdef DEBUG long zxlseek(int fd, long offset, int wh) { -#ifdef WIN32 +#ifdef _WIN32 long v; redir_Msg(">SetFilePointer() Handle=%lu, Offset=%lu, Method=%lu\n", fd, offset, wh); v = SetFilePointer((HANDLE)fd, offset, NULL, wh); @@ -49,6 +54,22 @@ long zxlseek(int fd, long offset, int wh) #endif } +#else + +long zxlseek(int fd, long offset, int wh) +{ + #ifdef _WIN32 + return SetFilePointer((HANDLE)fd, offset, NULL, wh); + #else + return lseek(fd, offset, wh); + #endif +} + + +#endif + +#ifdef DEBUG + void redir_showfcb(cpm_byte *fd) { int n; @@ -61,18 +82,6 @@ void redir_showfcb(cpm_byte *fd) printf("\r\n"); } -#else - -long zxlseek(int fd, long offset, int wh) -{ -#ifdef WIN32 - return SetFilePointer((HANDLE)fd, offset, NULL, wh); -#else - return lseek(fd, offset, wh); -#endif -} - - #endif /* Get the "sequential access" file pointer out of an FCB */ @@ -90,9 +99,9 @@ long redir_get_fcb_pos(cpm_byte *fcb) void redir_put_fcb_pos(cpm_byte *fcb, long npos) { - fcb[0x20] = (npos / 128) % 128; - fcb[0x0C] = (npos / 16384) % 32; - fcb[0x0E] = (npos / 524288L) % 64; + fcb[0x20] = (npos / 128) % 128; /* Record */ + fcb[0x0C] = (npos / 16384) % 32; /* Extent */ + fcb[0x0E] = (npos / 524288L) % 64; /* S2 */ } @@ -132,10 +141,8 @@ swizzle(char *fullpath) closedir(dirp); } -/* - * Passed a CP/M FCB, convert it to a unix filename. Turn its drive back into - * a path. - */ +/* Passed a CP/M FCB, convert it to a unix filename. Turn its drive back into + * a path. */ int redir_fcb2unix(cpm_byte *fcb, char *fname) { @@ -178,10 +185,10 @@ int redir_fcb2unix(cpm_byte *fcb, char *fname) int redir_ofile(cpm_byte *fcb, char *s) { - int h, rv; + int h; /* Software write-protection */ -#ifdef WIN32 +#ifdef _WIN32 redir_Msg(">CreateFile([OPEN_EXISTING]) Name='%s'\n", s); h = (int)CreateFile(s, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); redir_Msg("= 0 || (errno != EACCES && errno != EROFS)) return h; + if (h >= 0 || (errno != EACCES && errno != EROFS)) + return trackFile(s, fcb, h); } - redir_Msg("**2**"); h = open(s, O_RDONLY | O_BINARY); if (h < 0) return -1; fcb[9] |= 0x80; #endif #endif - - return h; + return trackFile(s, fcb, h); } @@ -250,10 +257,10 @@ void redir_Msg(char *s, ...) va_list ap; va_start(ap, s); - printf("cpmredir trace: "); - vprintf(s, ap); + fprintf(stderr, "cpmredir trace: "); + vfprintf(stderr, s, ap); va_end(ap); - fflush(stdout); + fflush(stderr); } #endif @@ -263,9 +270,16 @@ void redir_Msg(char *s, ...) /* Convert time_t to CP/M day count/hours/minutes */ dword redir_cpmtime(time_t t) { - long d = (t / 86400) - 2921; /* CP/M day 0 is unix day 2921 */ - long h = (t % 86400) / 3600; /* Hour, 0-23 */ - long m = (t % 3600) / 60; /* Minute, 0-59 */ +/* Microsoft compiler warned around the conversion from time_t to long + * as to support dates beyond 2038 time_t is set as a long long + * and for the Microsoft compiler sizeof(long) == 4 and sizeof(long long) == 8 + * for other compilers both have size 8 + * As the result is a dword (unsigned long), the code below is modified to reflect this + */ + + dword d = (dword)((t / 86400) - 2921); /* CP/M day 0 is unix day 2921 */ + dword h = (t % 86400) / 3600; /* Hour, 0-23 */ + dword m = (t % 3600) / 60; /* Minute, 0-59 */ return (d | (BCD(h) << 16) | (BCD(m) << 24)); } @@ -375,3 +389,20 @@ cpm_word redir_xlt_err(void) } } + +#ifdef _WIN32 +/* minimal implementation of truncate */ +int truncate(const char* path, off_t length) +{ + int result; + int fd = open(path, O_BINARY | O_RDWR); + + if (fd < 0) + return -1; + result = ftruncate(fd, length); + return close(fd) == 0 && result == 0 ? 0 : -1; + +} + + +#endif diff --git a/Tools/unix/zxcc/xlt.c b/Tools/unix/zxcc/xlt.c new file mode 100644 index 00000000..84b76952 --- /dev/null +++ b/Tools/unix/zxcc/xlt.c @@ -0,0 +1,241 @@ +/* + + CPMREDIR: CP/M filesystem redirector + Copyright (C) 1998, John Elliott + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file holds functions dealing with name translation; also the + initialisation code. +*/ + +#include "cpmint.h" +static char* skipUser(char* localname); +/* Detect DRDOS */ + +#ifdef __MSDOS__ +static void drdos_init(void) +{ + +/* The DJGPP DOS extender won't detect DRDOS using intdos(), so we have + to use __dpmi_int() instead. */ + +#ifdef __GO32__ + __dpmi_regs ir; + + ir.x.ax = 0x4452; /* "DR" */ + + __dpmi_int(0x21, &ir); + if (ir.x.flags & 1) return; /* Not DRDOS */ + + redir_Msg("DRDOS detected.\r\n"); + + redir_drdos = 1; + +#else /* __GO32__ */ + + union REGS ir, or; + + ir.w.ax = 0x4452; /* "DR" */ + + intdos(&ir, &or); + if (or.w.cflag) return; /* Not DRDOS */ + + redir_Msg("DRDOS detected.\r\n"); + + redir_drdos = 1; +#endif /* __GO32__ */ +} +#endif /* __MSDOS__ */ + + + +int fcb_init(void) +{ + int n; + + /* A: to O: free */ + for (n = 0; n < 15; n++) redir_drive_prefix[n][0] = 0; + + strcpy(redir_drive_prefix[15], "./"); /* P: is current directory */ + + /* Log on to P:. It is the only drive at this point which we + * know works. */ + redir_cpmdrive = 15; +#ifdef __MSDOS__ + drdos_init(); +#endif + + return 1; +} + +/* Deinitialise the library. */ + +void fcb_deinit(void) +{ + /* Nothing */ +} + +/* Translate a name from the host FS to a CP/M name. This will (if necessary) + * create a mapping between a CP/M drive and a host directory path. + * + * CP/M drives A: to O: can be mapped in this way. P: is always the current + * drive. + * + */ + +void xlt_name(char *localname, char *cpmname) +{ + char ibuf[CPM_MAXPATH + 1]; + char nbuf[CPM_MAXPATH + 1]; + char *pname = ibuf; + char *s; + int n; + + sprintf(ibuf, "%-.*s", CPM_MAXPATH, skipUser(localname)); + + while ((s = strpbrk(pname, DIRSEP))) { /* find the last directory separator allows mixed \ and / in windows */ +#ifdef _WIN32 + if (*s == '\\') /* convert separators to common format so directory tracking works more efficiently */ + *s = '/'; +#endif + pname = s + 1; + } + + if (pname == ibuf) { /* No path separators in the name. It is therefore a + local filename, so map it to drive P: */ + strcpy(cpmname, "p:"); + strcat(cpmname, ibuf); + return; + } + + /* catch user specified current drive a,b,c,p or A,B,C,P only, which map to predefined directories */ + if (pname == ibuf + 2 && ibuf[1] == ':' && (s = strchr("aAbBcCpP", ibuf[0]))) { + cpmname[0] = tolower(*s); /* make sure it's lower case */ + strcpy(cpmname + 1, ibuf + 1); + return; + } + + strcpy(nbuf, pname); /* nbuf holds filename component */ + *pname = 0; /* ibuf holds path component */ + + /* See if the path is one of those already mapped to drives */ + + for (n = 0; n < 15; n++) + { + if (redir_drive_prefix[n][0] && !strcmp(ibuf, redir_drive_prefix[n])) + { + sprintf(cpmname,"%c:%s", n + 'a', nbuf); + return; + } + } + + /* It is not, see if another drive can be allocated */ + + for (n = 0; n < 15; n++) if (!redir_drive_prefix[n][0]) + { + strcpy(redir_drive_prefix[n], ibuf); + sprintf(cpmname,"%c:%s", n + 'a', nbuf); + return; + } + + /* No other drive can be allocated */ + + strcpy(cpmname,"p:"); + strcat(cpmname, nbuf); +} + +/* It is sometimes convenient to set some fixed mappings. This will create + * a mapping for a given directory. + * Pass drive = -1 for "first available", or 0-15 for A: to P: + */ + +int xlt_map(int drive, char *localdir) +{ + int n; + + if (drive == -1) + { + for (n = 0; n < 15; n++) if (!redir_drive_prefix[n][0]) + { + drive = n; + break; + } + if (drive == -1) return 0; /* No space for mappings */ + } + if (redir_drive_prefix[drive][0]) return 0; /* Drive taken */ + + sprintf(redir_drive_prefix[drive], "%-.*s", CPM_MAXPATH, localdir); + return 1; +} + + +/* Unmap a drive + */ + +int xlt_umap(int drive) +{ + if (!redir_drive_prefix[drive][0]) return 0; /* Drive not taken */ + redir_drive_prefix[drive][0] = 0; + return 1; +} + + +char *xlt_getcwd(int drive) +{ + if (drive < 0 || drive > 16) return ""; + + return redir_drive_prefix[drive]; +} + +/* as zxcc doesn't really support user spaces, remove any user specification + *hitech c supports + * [[0-9]+[:]][[a-pA-P]:]name[.ext] | [[a-pA-p][[0-9]+]:]name[.ext] + * this function also checks that user is no more than 2 digits and user # <= 31 + * the hitech fcb checks for : as char 2, 3, or 4 which aligns to this + */ +static char* skipUser(char* localname) { + char* s; + int user; + int drive; + + if (!localname || !(s = strchr(localname, ':')) || s > localname + 3) + return localname; + s = localname; + if (isdigit(*s)) { + user = *s++ - '0'; + if (isdigit(*s)) { + user = user * 10 + *s++ - '0'; + if (user > 31) /* check sensible user id */ + return localname; + } + if (*s == ':') /* just strip the user id assume rest is a filename */ + return s + 1; + if ('a' <= (drive = tolower(*s)) && drive <= 'p' && s[1] == ':') + return s; /* was form [0-9]+[a-pA-P] so strip user id */ + else + return localname; /* not vaild so don't change */ + } + if ((drive = tolower(*s++)) < 'a' || 'p' < drive || !isdigit(*s)) + return localname; /* not a valid drive prefix or simple drive spec */ + + user = *s++ - '0'; + if (isdigit(*s)) + user = user * 10 + *s++ - '0'; + if (*s != ':' || user > 31) + return localname; + *--s = drive; /* reinsert the drive just before the : */ + return s; +} diff --git a/Tools/unix/zx/z80.c b/Tools/unix/zxcc/z80.c similarity index 93% rename from Tools/unix/zx/z80.c rename to Tools/unix/zxcc/z80.c index d1d99cd5..1b62994c 100644 --- a/Tools/unix/zx/z80.c +++ b/Tools/unix/zxcc/z80.c @@ -1,270 +1,272 @@ -/* Emulation of the Z80 CPU with hooks into the other parts of xz80. - * Copyright (C) 1994 Ian Collier. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include "zx.h" - -#define parity(a) (partable[a]) - -unsigned char partable[256]={ - 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, - 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, - 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, - 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, - 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, - 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, - 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, - 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, - 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, - 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, - 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, - 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, - 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, - 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, - 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, - 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4 - }; - -#ifdef DEBUG -static unsigned short breakpoint=0; -static unsigned int breaks=0; - -//static void inline log(fp,name,val) -static void log(fp,name,val) -FILE *fp; -char *name; -unsigned short val; -{ - int i; - fprintf(fp,"%s=%04X ",name,val); - for(i=0;i<8;i++,val++)fprintf(fp," %02X",fetch(val)); - putc('\n',fp); -} -#endif - -void mainloop(word spc, word ssp){ - register unsigned char a, f, b, c, d, e, h, l; - unsigned char r, a1, f1, b1, c1, d1, e1, h1, l1, i, iff1, iff2, im; - register unsigned short pc; - unsigned short ix, iy, sp; - register unsigned long tstates; - register unsigned int radjust; - register unsigned char ixoriy, new_ixoriy; - unsigned char intsample; - register unsigned char op; -#ifdef DEBUG - char flags[9]; - int bit; - FILE *fp=0; - register unsigned short af2=0,bc2=0,de2=0,hl2=0,ix2=0,iy2=0,sp2=0; - register unsigned char i2=0; - //unsigned char *memory=memptr[0]; - struct _next {unsigned char bytes[8];} *next; - unsigned short BC, DE, HL, AF; - - fputs("Press F11 to log\n",stderr); -#endif - a=f=b=c=d=e=h=l=a1=f1=b1=c1=d1=e1=h1=l1=i=r=iff1=iff2=im=0; - ixoriy=new_ixoriy=0; - ix=iy=0; - pc=spc; - sp=ssp; - tstates=radjust=0; - while(1){ - ixoriy=new_ixoriy; - new_ixoriy=0; -#ifdef DEBUG - next=(struct _next *)&fetch(pc); - BC=bc;DE=de;HL=hl;AF=(a<<8)|f; - if(fp && !ixoriy){ - log(fp,"pc",pc); - if(sp!=sp2)log(fp,"sp",sp2=sp); - if(iy!=iy2)log(fp,"iy",iy2=iy); - if(ix!=ix2)log(fp,"ix",ix2=ix); - if(hl!=hl2)log(fp,"hl",hl2=hl); - if(de!=de2)log(fp,"de",de2=de); - if(bc!=bc2)log(fp,"bc",bc2=bc); - if(((a<<8)|f)!=af2){ - af2=(a<<8)|f; - strcpy(flags,"SZ H VNC"); - for(bit=0;bit<8;bit++)if(!(f&(1<<(7-bit))))flags[bit]=' '; - fprintf(fp,"af=%04X %s\n",af2,flags); - } - if(i!=i2)fprintf(fp,"ir=%02X%02X\n",i2=i,r); - putc('\n',fp); - } - if(pc==breakpoint && pc) - breaks++; /* some code at which to set a breakpoint */ - a=AF>>8; f=AF; h=HL>>8; l=HL; d=DE>>8; e=DE; b=BC>>8; c=BC; -#endif -/* -{ - static int tr = 0; - static int id = 0; -// static byte b = 0; -// - if (pc == 0x1177) tr = 1; - if (pc == 0x1185) tr = 0; - if (tr >= 1) ++id; - if (tr >= 1) printf("%d: PC=%04x %02x AF=%02x:%02x BC=%04x DE=%04x HL=%04x IX=%04x IY=%04x\r\n", - id, pc, fetch(pc), a,f, bc, de, hl, ix, iy); -} -*/ - intsample=1; - op=fetch(pc); - pc++; - radjust++; - switch(op){ -#include "z80ops.h" - } -/*** - * ZXCC doesn't do interrupts at all, so all this is commented out - if(tstates>=int_cycles && intsample){ - tstates-=int_cycles; - frames++; - // Carry out X-related tasks (including waiting for timer - // signal if necessary) - switch(interrupt()){ - case Z80_quit: -#ifdef DEBUG - if(fp)fclose(fp); -#endif - return; - case Z80_NMI: - if(fetch(pc)==0x76)pc++; - iff2=iff1; - iff1=0; - // The Z80 performs a machine fetch cycle for 5 Tstates - // but ignores the result. It takes a further 10 Tstates - // to jump to the NMI routine at 0x66. - tstates+=15; - push2(pc); - pc=0x66; - break; - case Z80_reset: - a=f=b=c=d=e=h=l=a1=f1=b1=c1=d1=e1= - h1=l1=i=r=iff1=iff2=im=0; - ix=iy=sp=pc=0; - radjust=0; - break; -#ifdef DEBUG - case Z80_log: - if(fp){ - fclose(fp); - fp=0; - fputs("Logging turned off\n",stderr); - } else { - fp=fopen(config.log,"a"); - if(fp)fprintf(stderr,"Logging to file %s\n",config.log); - else perror(config.log); - } - break; -#endif - - case Z80_load: - stopwatch(); - if(snapload()){ - a=snapa; - f=snapf; - b=snapb; - c=snapc; - d=snapd; - e=snape; - h=snaph; - l=snapl; - a1=snapa1; - f1=snapf1; - b1=snapb1; - c1=snapc1; - d1=snapd1; - e1=snape1; - h1=snaph1; - l1=snapl1; - iff1=snapiff1; - iff2=snapiff2; - i=snapi; - r=snapr; - radjust=r; - im=snapim; - ix=snapix; - iy=snapiy; - sp=snapsp; - pc=snappc; - } - startwatch(1); - break; - case Z80_save: - r=(r&0x80)|(radjust&0x7f); - snapa=a; - snapf=f; - snapb=b; - snapc=c; - snapd=d; - snape=e; - snaph=h; - snapl=l; - snapa1=a1; - snapf1=f1; - snapb1=b1; - snapc1=c1; - snapd1=d1; - snape1=e1; - snaph1=h1; - snapl1=l1; - snapiff1=iff1; - snapiff2=iff2; - snapi=i; - snapr=r; - snapim=im; - snapix=ix; - snapiy=iy; - snapsp=sp; - snappc=pc; - snapsave(); - startwatch(1); - break; - - } - if(iff1){ -#ifdef DEBUG - if(fp)fprintf(fp,"Interrupt (im=%d)\n\n",im); -#endif - if(fetch(pc)==0x76)pc++; - iff1=iff2=0; - tstates+=5; // accompanied by an input from the data bus // - switch(im){ - case 0: // IM 0 // - case 1: // undocumented // - case 2: // IM 1 // - // there is little to distinguish between these cases // - tstates+=8; - push2(pc); - pc=0x38; - break; - case 3: // IM 2 // - tstates+=14; - { - int addr=fetch2((i<<8)|0xff); - push2(pc); - pc=addr; - } - } - } - }*/ - } -} +/* Emulation of the Z80 CPU with hooks into the other parts of xz80. + * Copyright (C) 1994 Ian Collier. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include "zxcc.h" + +#define parity(a) (partable[a]) + +unsigned char partable[256]={ + 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, + 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, + 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, + 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, + 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, + 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, + 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, + 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, + 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, + 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, + 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, + 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, + 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, + 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, + 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, + 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4 + }; + +#ifdef DEBUG +// Avoid name conflict with built-in log math function +#define log z80_log + +static unsigned short breakpoint=0; +static unsigned int breaks=0; + +static void inline log(fp,name,val) +FILE *fp; +char *name; +unsigned short val; +{ + int i; + fprintf(fp,"%s=%04X ",name,val); + for(i=0;i<8;i++,val++)fprintf(fp," %02X",fetch(val)); + putc('\n',fp); +} +#endif + +void mainloop(word spc, word ssp){ + register unsigned char a, f, b, c, d, e, h, l; + unsigned char r, a1, f1, b1, c1, d1, e1, h1, l1, i, iff1, iff2, im; + register unsigned short pc; + unsigned short ix, iy, sp; + register unsigned long tstates; + register unsigned int radjust; + register unsigned char ixoriy, new_ixoriy; + unsigned char intsample; + register unsigned char op; +#ifdef DEBUG + char flags[9]; + int bit; + FILE *fp=0; + register unsigned short af2=0,bc2=0,de2=0,hl2=0,ix2=0,iy2=0,sp2=0; + register unsigned char i2=0; + /*unsigned char *memory=memptr[0];*/ + struct _next {unsigned char bytes[8];} *next; + unsigned short BC, DE, HL, AF; + + fputs("Press F11 to log\n",stderr); +#endif + a=f=b=c=d=e=h=l=a1=f1=b1=c1=d1=e1=h1=l1=i=r=iff1=iff2=im=0; + ixoriy=new_ixoriy=0; + ix=iy=0; + pc=spc; + sp=ssp; + tstates=radjust=0; + while(1){ + ixoriy=new_ixoriy; + new_ixoriy=0; +#ifdef DEBUG + next=(struct _next *)&fetch(pc); + BC=bc;DE=de;HL=hl;AF=(a<<8)|f; + if(fp && !ixoriy){ + log(fp,"pc",pc); + if(sp!=sp2)log(fp,"sp",sp2=sp); + if(iy!=iy2)log(fp,"iy",iy2=iy); + if(ix!=ix2)log(fp,"ix",ix2=ix); + if(hl!=hl2)log(fp,"hl",hl2=hl); + if(de!=de2)log(fp,"de",de2=de); + if(bc!=bc2)log(fp,"bc",bc2=bc); + if(((a<<8)|f)!=af2){ + af2=(a<<8)|f; + strcpy(flags,"SZ H VNC"); + for(bit=0;bit<8;bit++)if(!(f&(1<<(7-bit))))flags[bit]=' '; + fprintf(fp,"af=%04X %s\n",af2,flags); + } + if(i!=i2)fprintf(fp,"ir=%02X%02X\n",i2=i,r); + putc('\n',fp); + } + if(pc==breakpoint && pc) + breaks++; /* some code at which to set a breakpoint */ + a=AF>>8; f=AF; h=HL>>8; l=HL; d=DE>>8; e=DE; b=BC>>8; c=BC; +#endif +/* +{ + static int tr = 1; + static int id = 0; +// static byte b = 0; +// +// if (pc == 0x1177) tr = 1; + // if (pc == 0x1185) tr = 0; + if (tr >= 1) ++id; + if (tr >= 1) printf("%d: PC=%04x %02x AF=%02x:%02x BC=%04x DE=%04x HL=%04x IX=%04x IY=%04x\r\n", + id, pc, fetch(pc), a,f, bc, de, hl, ix, iy); +} +*/ + intsample=1; + op=fetch(pc); + pc++; + radjust++; + switch(op){ +#include "z80ops.h" + } +/*** + * ZXCC doesn't do interrupts at all, so all this is commented out + if(tstates>=int_cycles && intsample){ + tstates-=int_cycles; + frames++; + // Carry out X-related tasks (including waiting for timer + // signal if necessary) + switch(interrupt()){ + case Z80_quit: +#ifdef DEBUG + if(fp)fclose(fp); +#endif + return; + case Z80_NMI: + if(fetch(pc)==0x76)pc++; + iff2=iff1; + iff1=0; + // The Z80 performs a machine fetch cycle for 5 Tstates + // but ignores the result. It takes a further 10 Tstates + // to jump to the NMI routine at 0x66. + tstates+=15; + push2(pc); + pc=0x66; + break; + case Z80_reset: + a=f=b=c=d=e=h=l=a1=f1=b1=c1=d1=e1= + h1=l1=i=r=iff1=iff2=im=0; + ix=iy=sp=pc=0; + radjust=0; + break; +#ifdef DEBUG + case Z80_log: + if(fp){ + fclose(fp); + fp=0; + fputs("Logging turned off\n",stderr); + } else { + fp=fopen(config.log,"a"); + if(fp)fprintf(stderr,"Logging to file %s\n",config.log); + else perror(config.log); + } + break; +#endif + + case Z80_load: + stopwatch(); + if(snapload()){ + a=snapa; + f=snapf; + b=snapb; + c=snapc; + d=snapd; + e=snape; + h=snaph; + l=snapl; + a1=snapa1; + f1=snapf1; + b1=snapb1; + c1=snapc1; + d1=snapd1; + e1=snape1; + h1=snaph1; + l1=snapl1; + iff1=snapiff1; + iff2=snapiff2; + i=snapi; + r=snapr; + radjust=r; + im=snapim; + ix=snapix; + iy=snapiy; + sp=snapsp; + pc=snappc; + } + startwatch(1); + break; + case Z80_save: + r=(r&0x80)|(radjust&0x7f); + snapa=a; + snapf=f; + snapb=b; + snapc=c; + snapd=d; + snape=e; + snaph=h; + snapl=l; + snapa1=a1; + snapf1=f1; + snapb1=b1; + snapc1=c1; + snapd1=d1; + snape1=e1; + snaph1=h1; + snapl1=l1; + snapiff1=iff1; + snapiff2=iff2; + snapi=i; + snapr=r; + snapim=im; + snapix=ix; + snapiy=iy; + snapsp=sp; + snappc=pc; + snapsave(); + startwatch(1); + break; + + } + if(iff1){ +#ifdef DEBUG + if(fp)fprintf(fp,"Interrupt (im=%d)\n\n",im); +#endif + if(fetch(pc)==0x76)pc++; + iff1=iff2=0; + tstates+=5; // accompanied by an input from the data bus // + switch(im){ + case 0: // IM 0 // + case 1: // undocumented // + case 2: // IM 1 // + // there is little to distinguish between these cases // + tstates+=8; + push2(pc); + pc=0x38; + break; + case 3: // IM 2 // + tstates+=14; + { + int addr=fetch2((i<<8)|0xff); + push2(pc); + pc=addr; + } + } + } + }*/ + } +} diff --git a/Tools/unix/zx/z80.h b/Tools/unix/zxcc/z80.h similarity index 96% rename from Tools/unix/zx/z80.h rename to Tools/unix/zxcc/z80.h index 89e12a84..d9e3a547 100644 --- a/Tools/unix/zx/z80.h +++ b/Tools/unix/zxcc/z80.h @@ -1,86 +1,86 @@ -/* Miscellaneous definitions for xz80, copyright (C) 1994 Ian Collier. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* [John Elliott, 15 July 2001] - * Copied this file into ZXCC, a CP/M emulator. - * Since ZXCC's memory is a flat 64k space and will never be bank-switched, - * the bank-switching code is removed. - * Since ZXCC has no memory-mapped screen, all the screen management code - * goes as well. - * Since ZXCC doesn't need its speed regulated, all the speed regulation - * code goes as well. - * Since ZXCC doesn't save or load snapshots... OK, you get the idea. - */ - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#define Z80_quit 1 -#define Z80_NMI 2 -#define Z80_reset 3 -#define Z80_load 4 -#define Z80_save 5 -#define Z80_log 6 - -unsigned int in(); -unsigned int out(); -//int interrupt(); -int snapload(); -void snapsave(); -void mainloop(word xpc, word xsp); -void eachframe(); -void itimeron(); -void itimeroff(); -void startwatch(); -unsigned long stopwatch(); -void requester(); -int loader(); -int saver(); -void multiloader(); -void usage(); -void version(); -void drawborder(); - -#define fetch(x) (RAM[x]) -#define fetch2(x) ((fetch((x)+1)<<8)|fetch(x)) - -#define store(x,y) do { RAM[(x)] = (y); } while(0) - -#define store2b(x,hi,lo) do {\ - RAM[(x)]=(lo); \ - RAM[((x+1) & 0xFFFF)]=(hi); } while(0) - -#define store2(x,y) store2b(x,(y)>>8,y) - -#ifdef __GNUC__ -static void inline storefunc(unsigned short ad,unsigned char b){ - store(ad,b); -} -#undef store -#define store(x,y) storefunc(x,y) - -static void inline store2func(unsigned short ad,unsigned char b1,unsigned char b2){ - store2b(ad,b1,b2); -} -#undef store2b -#define store2b(x,hi,lo) store2func(x,hi,lo) -#endif - -#define bc ((b<<8)|c) -#define de ((d<<8)|e) -#define hl ((h<<8)|l) +/* Miscellaneous definitions for xz80, copyright (C) 1994 Ian Collier. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* [John Elliott, 15 July 2001] + * Copied this file into ZXCC, a CP/M emulator. + * Since ZXCC's memory is a flat 64k space and will never be bank-switched, + * the bank-switching code is removed. + * Since ZXCC has no memory-mapped screen, all the screen management code + * goes as well. + * Since ZXCC doesn't need its speed regulated, all the speed regulation + * code goes as well. + * Since ZXCC doesn't save or load snapshots... OK, you get the idea. + */ + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#define Z80_quit 1 +#define Z80_NMI 2 +#define Z80_reset 3 +#define Z80_load 4 +#define Z80_save 5 +#define Z80_log 6 + +unsigned int in(); +unsigned int out(); +//int interrupt(); +int snapload(); +void snapsave(); +void mainloop(word xpc, word xsp); +void eachframe(); +void itimeron(); +void itimeroff(); +void startwatch(); +unsigned long stopwatch(); +void requester(); +int loader(); +int saver(); +void multiloader(); +void usage(); +void version(); +void drawborder(); + +#define fetch(x) (RAM[x]) +#define fetch2(x) ((fetch((x)+1)<<8)|fetch(x)) + +#define store(x,y) do { RAM[(x)] = (y); } while(0) + +#define store2b(x,hi,lo) do {\ + RAM[(x)]=(lo); \ + RAM[((x+1) & 0xFFFF)]=(hi); } while(0) + +#define store2(x,y) store2b(x,(y)>>8,y) + +#ifdef __GNUC__ +static void inline storefunc(unsigned short ad,unsigned char b){ + store(ad,b); +} +#undef store +#define store(x,y) storefunc(x,y) + +static void inline store2func(unsigned short ad,unsigned char b1,unsigned char b2){ + store2b(ad,b1,b2); +} +#undef store2b +#define store2b(x,hi,lo) store2func(x,hi,lo) +#endif + +#define bc ((b<<8)|c) +#define de ((d<<8)|e) +#define hl ((h<<8)|l) diff --git a/Tools/unix/zx/z80ops.h b/Tools/unix/zxcc/z80ops.h similarity index 93% rename from Tools/unix/zx/z80ops.h rename to Tools/unix/zxcc/z80ops.h index aac5d548..a07cfe5e 100644 --- a/Tools/unix/zx/z80ops.h +++ b/Tools/unix/zxcc/z80ops.h @@ -1,1332 +1,1332 @@ -/* Emulations of the Z80 CPU instruction set - part of xz80. - * Copyright (C) 1994 Ian Collier. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define instr(opcode,cycles) case opcode: {tstates+=cycles -#define HLinstr(opcode,cycles,morecycles) \ - case opcode: {unsigned short addr; \ - tstates+=cycles; \ - if(ixoriy==0)addr=hl; \ - else tstates+=morecycles, \ - addr=(ixoriy==1?ix:iy)+ \ - (signed char)fetch(pc),\ - pc++ -#define endinstr }; break - -#define cy (f&1) - -#define xh (ixoriy==0?h:ixoriy==1?(ix>>8):(iy>>8)) -#define xl (ixoriy==0?l:ixoriy==1?(ix&0xff):(iy&0xff)) - -#define setxh(x) (ixoriy==0?(h=(x)):ixoriy==1?(ix=(ix&0xff)|((x)<<8)):\ - (iy=(iy&0xff)|((x)<<8))) -#define setxl(x) (ixoriy==0?(l=(x)):ixoriy==1?(ix=(ix&0xff00)|(x)):\ - (iy=(iy&0xff00)|(x))) - -#define inc(var) /* 8-bit increment */ ( var++,\ - f=(f&1)|(var&0xa8)|\ - ((!(var&15))<<4)|((!var)<<6)|\ - ((var==128)<<2)\ - ) -#define dec(var) /* 8-bit decrement */ ( f=(f&1)|((!(var&15))<<4)|2,\ - --var,\ - f|=(var&0xa8)|((var==127)<<2)|\ - ((!var)<<6)\ - ) -#define swap(x,y) {unsigned char t=x; x=y; y=t;} -#define addhl(hi,lo) /* 16-bit add */ if(!ixoriy){\ - unsigned short t;\ - l=t=l+(lo);\ - f=(f&0xc4)|(((t>>=8)+(h&0x0f)+((hi)&0x0f)>15)<<4);\ - h=t+=h+(hi);\ - f|=(h&0x28)|(t>>8);\ - }\ - else do{unsigned long t=(ixoriy==1?ix:iy);\ - f=(f&0xc4)|(((t&0xfff)+((hi<<8)|lo)>0xfff)<<4);\ - t+=(hi<<8)|lo;\ - if(ixoriy==1)ix=t; else iy=t;\ - f|=((t>>8)&0x28)|(t>>16);\ - } while(0) -#define adda(x,c) /* 8-bit add */ do{unsigned short y;\ - unsigned char z=(x);\ - y=a+z+(c);\ - f=(y&0xa8)|(y>>8)|(((a&0x0f)+(z&0x0f)+(c)>15)<<4)|\ - (((~a^z)&0x80&(y^a))>>5);\ - f|=(!(a=y))<<6;\ - } while(0) -#define suba(x,c) /* 8-bit subtract */ do{unsigned short y;\ - unsigned char z=(x);\ - y=(a-z-(c))&0x1ff;\ - f=(y&0xa8)|(y>>8)|(((a&0x0f)<(z&0x0f)+(c))<<4)|\ - (((a^z)&0x80&(y^a))>>5)|2;\ - f|=(!(a=y))<<6;\ - } while(0) -#define cpa(x) /* 8-bit compare */ do{unsigned short y;\ - unsigned char z=(x);\ - y=(a-z)&0x1ff;\ - f=(y&0xa8)|(y>>8)|(((a&0x0f)<(z&0x0f))<<4)|\ - (((a^z)&0x80&(y^a))>>5)|2|((!y)<<6);\ - } while(0) -#define anda(x) /* logical and */ do{\ - a&=(x);\ - f=(a&0xa8)|((!a)<<6)|0x10|parity(a);\ - } while(0) -#define xora(x) /* logical xor */ do{\ - a^=(x);\ - f=(a&0xa8)|((!a)<<6)|parity(a);\ - } while(0) -#define ora(x) /* logical or */ do{\ - a|=(x);\ - f=(a&0xa8)|((!a)<<6)|parity(a);\ - } while(0) - -#define jr /* execute relative jump */ do{int j=(signed char)fetch(pc);\ - pc+=j+1;\ - tstates+=5;\ - } while(0) -#define jp /* execute jump */ (pc=fetch2(pc)) -#define call /* execute call */ do{\ - tstates+=7;\ - push2(pc+2);\ - jp;\ - } while(0) -#define ret /* execute return */ do{\ - tstates+=6;\ - pop2(pc);\ - } while(0) -#define pop2(var) /* pop 16-bit register */ (var=fetch2(sp),sp+=2) -#define pop1(v1,v2) /* pop register pair */ (v2=fetch(sp),\ - v1=fetch(sp+1),sp+=2) -#define push2(val) /* push 16-bit register */ do{sp-=2;store2(sp,(val));}\ - while(0) -#define push1(v1,v2) /* push register pair */ do{sp-=2;\ - store2b(sp,v1,v2);\ - }while(0) - -instr(0,4); - /* nop */ -endinstr; - -instr(1,10); - c=fetch(pc),pc++; - b=fetch(pc),pc++; -endinstr; - -instr(2,7); - store(bc,a); -endinstr; - -instr(3,6); - if(!++c)b++; -endinstr; - -instr(4,4); - inc(b); -endinstr; - -instr(5,4); - dec(b); -endinstr; - -instr(6,7); - b=fetch(pc),pc++; -endinstr; - -instr(7,4); - a=(a<<1)|(a>>7); - f=(f&0xc4)|(a&0x29); -endinstr; - -instr(8,4); - swap(a,a1); - swap(f,f1); -endinstr; - -instr(9,11); - addhl(b,c); -endinstr; - -instr(10,7); - a=fetch(bc); -endinstr; - -instr(11,6); - if(!c--)b--; -endinstr; - -instr(12,4); - inc(c); -endinstr; - -instr(13,4); - dec(c); -endinstr; - -instr(14,7); - c=fetch(pc),pc++; -endinstr; - -instr(15,4); - f=(f&0xc4)|(a&1); - a=(a>>1)|(a<<7); - f|=a&0x28; -endinstr; - -instr(16,8); - if(!--b)pc++; - else jr; -endinstr; - -instr(17,10); - e=fetch(pc),pc++; - d=fetch(pc),pc++; -endinstr; - -instr(18,7); - store(de,a); -endinstr; - -instr(19,6); - if(!++e)d++; -endinstr; - -instr(20,4); - inc(d); -endinstr; - -instr(21,4); - dec(d); -endinstr; - -instr(22,7); - d=fetch(pc),pc++; -endinstr; - -instr(23,4); - {int t=a>>7; - a=(a<<1)|(f&1); - f=(f&0xc4)|(a&0x28)|t; - } -endinstr; - -instr(24,7); - jr; -endinstr; - -instr(25,11); - addhl(d,e); -endinstr; - -instr(26,7); - a=fetch(de); -endinstr; - -instr(27,6); - if(!e--)d--; -endinstr; - -instr(28,4); - inc(e); -endinstr; - -instr(29,4); - dec(e); -endinstr; - -instr(30,7); - e=fetch(pc),pc++; -endinstr; - -instr(31,4); - {int t=a&1; - a=(a>>1)|(f<<7); - f=(f&0xc4)|(a&0x28)|t; - } -endinstr; - -instr(32,7); - if(f&0x40)pc++; - else jr; -endinstr; - -instr(33,10); - if(!ixoriy){ - l=fetch(pc),pc++; - h=fetch(pc),pc++; - } - else { - if(ixoriy==1)ix=fetch2(pc); - else iy=fetch2(pc); - pc+=2; - } -endinstr; - -instr(34,16); - {unsigned short addr=fetch2(pc); - pc+=2; - if(!ixoriy)store2b(addr,h,l); - else if(ixoriy==1)store2(addr,ix); - else store2(addr,iy); - } -endinstr; - -instr(35,6); - if(!ixoriy){if(!++l)h++;} - else if(ixoriy==1)ix++; - else iy++; -endinstr; - -instr(36,4); - if(ixoriy==0)inc(h); - else{unsigned char t; - t=(ixoriy==1?ix:iy)>>8; - inc(t); - if(ixoriy==1)ix=(ix&0xff)|(t<<8); - else iy=(iy&0xff)|(t<<8); - } -endinstr; - -instr(37,4); - if(ixoriy==0)dec(h); - else{unsigned char t; - t=(ixoriy==1?ix:iy)>>8; - dec(t); - if(ixoriy==1)ix=(ix&0xff)|(t<<8); - else iy=(iy&0xff)|(t<<8); - } -endinstr; - -instr(38,7); - setxh(fetch(pc)); - pc++; -endinstr; - -instr(39,4); - { - /* Frank D. Cringle's DAA implementation, converted from yaze 1.10 */ - unsigned int acu,temp,cbits; - - acu=a; - temp=(acu&15); - cbits=(f&1); - if(f&2) /* if N */ - { - /* last operation was a subtract */ - int hd=(cbits || (acu>0x99)); - if((f&16) || (temp>9)) - { /* adjust low digit */ - if(temp>5) f&=~16; - acu-=6; - acu&=0xff; - } - /* adjust high digit */ - if(hd) - acu-=0x160; - } - else - { - /* last operation was an add */ - if((f&16) || (temp>9)) - { - /* adjust low digit */ - if(temp>9) f|=16; else f&=~16; - acu+=6; - } - /* adjust high digit */ - if(cbits || ((acu&0x1f0)>0x90)) - acu+=0x60; - } - cbits|=((acu>>8)&1); - acu&=0xff; - a=acu; - f=((acu&0xa8)|((acu==0)<<6)|(f&0x12)|parity(a)|cbits); - } -endinstr; - -instr(40,7); - if(f&0x40)jr; - else pc++; -endinstr; - -instr(41,11); - if(!ixoriy)addhl(h,l); - else if(ixoriy==1)addhl((ix>>8),(ix&0xff)); - else addhl((iy>>8),(iy&0xff)); -endinstr; - -instr(42,16); - {unsigned short addr=fetch2(pc); - pc+=2; - if(!ixoriy){ - l=fetch(addr); - h=fetch(addr+1); - } - else if(ixoriy==1)ix=fetch2(addr); - else iy=fetch2(addr); - } -endinstr; - -instr(43,6); - if(!ixoriy){if(!l--)h--;} - else if(ixoriy==1)ix--; - else iy--; -endinstr; - -instr(44,4); - if(!ixoriy)inc(l); - else {unsigned char t; - t=(ixoriy==1?ix:iy); - inc(t); - if(ixoriy==1)ix=(ix&0xff00)|t; - else iy=(iy&0xff00)|t; - } -endinstr; - -instr(45,4); - if(!ixoriy)dec(l); - else {unsigned char t; - t=(ixoriy==1?ix:iy); - dec(t); - if(ixoriy==1)ix=(ix&0xff00)|t; - else iy=(iy&0xff00)|t; - } -endinstr; - -instr(46,7); - setxl(fetch(pc)); - pc++; -endinstr; - -instr(47,4); - a=~a; - f=(f&0xc5)|(a&0x28)|0x12; -endinstr; - -instr(48,7); - if(f&1)pc++; - else jr; -endinstr; - -instr(49,10); - sp=fetch2(pc); - pc+=2; -endinstr; - -instr(50,13); - {unsigned short addr=fetch2(pc); - pc+=2; - store(addr,a); - } -endinstr; - -instr(51,6); - sp++; -endinstr; - -HLinstr(52,11,8); - {unsigned char t=fetch(addr); - inc(t); - store(addr,t); - } -endinstr; - -HLinstr(53,11,8); - {unsigned char t=fetch(addr); - dec(t); - store(addr,t); - } -endinstr; - -HLinstr(54,10,5); - store(addr,fetch(pc)); - pc++; -endinstr; - -instr(55,4); - f=(f&0xc4)|1|(a&0x28); -endinstr; - -instr(56,7); - if(f&1)jr; - else pc++; -endinstr; - -instr(57,11); - addhl((sp>>8),(sp&0xff)); -endinstr; - -instr(58,13); - {unsigned short addr=fetch2(pc); - pc+=2; - a=fetch(addr); - } -endinstr; - -instr(59,6); - sp--; -endinstr; - -instr(60,4); - inc(a); -endinstr; - -instr(61,4); - dec(a); -endinstr; - -instr(62,7); - a=fetch(pc),pc++; -endinstr; - -instr(63,4); - f=(f&0xc4)|(cy^1)|(cy<<4)|(a&0x28); -endinstr; - -instr(0x40,4); - /* ld b,b */ -endinstr; - -instr(0x41,4); - b=c; -endinstr; - -instr(0x42,4); - b=d; -endinstr; - -instr(0x43,4); - b=e; -endinstr; - -instr(0x44,4); - b=xh; -endinstr; - -instr(0x45,4); - b=xl; -endinstr; - -HLinstr(0x46,7,8); - b=fetch(addr); -endinstr; - -instr(0x47,4); - b=a; -endinstr; - -instr(0x48,4); - c=b; -endinstr; - -instr(0x49,4); - /* ld c,c */ -endinstr; - -instr(0x4a,4); - c=d; -endinstr; - -instr(0x4b,4); - c=e; -endinstr; - -instr(0x4c,4); - c=xh; -endinstr; - -instr(0x4d,4); - c=xl; -endinstr; - -HLinstr(0x4e,7,8); - c=fetch(addr); -endinstr; - -instr(0x4f,4); - c=a; -endinstr; - -instr(0x50,4); - d=b; -endinstr; - -instr(0x51,4); - d=c; -endinstr; - -instr(0x52,4); - /* ld d,d */ -endinstr; - -instr(0x53,4); - d=e; -endinstr; - -instr(0x54,4); - d=xh; -endinstr; - -instr(0x55,4); - d=xl; -endinstr; - -HLinstr(0x56,7,8); - d=fetch(addr); -endinstr; - -instr(0x57,4); - d=a; -endinstr; - -instr(0x58,4); - e=b; -endinstr; - -instr(0x59,4); - e=c; -endinstr; - -instr(0x5a,4); - e=d; -endinstr; - -instr(0x5b,4); - /* ld e,e */ -endinstr; - -instr(0x5c,4); - e=xh; -endinstr; - -instr(0x5d,4); - e=xl; -endinstr; - -HLinstr(0x5e,7,8); - e=fetch(addr); -endinstr; - -instr(0x5f,4); - e=a; -endinstr; - -instr(0x60,4); - setxh(b); -endinstr; - -instr(0x61,4); - setxh(c); -endinstr; - -instr(0x62,4); - setxh(d); -endinstr; - -instr(0x63,4); - setxh(e); -endinstr; - -instr(0x64,4); - /* ld h,h */ -endinstr; - -instr(0x65,4); - setxh(xl); -endinstr; - -HLinstr(0x66,7,8); - h=fetch(addr); -endinstr; - -instr(0x67,4); - setxh(a); -endinstr; - -instr(0x68,4); - setxl(b); -endinstr; - -instr(0x69,4); - setxl(c); -endinstr; - -instr(0x6a,4); - setxl(d); -endinstr; - -instr(0x6b,4); - setxl(e); -endinstr; - -instr(0x6c,4); - setxl(xh); -endinstr; - -instr(0x6d,4); - /* ld l,l */ -endinstr; - -HLinstr(0x6e,7,8); - l=fetch(addr); -endinstr; - -instr(0x6f,4); - setxl(a); -endinstr; - -HLinstr(0x70,7,8); - store(addr,b); -endinstr; - -HLinstr(0x71,7,8); - store(addr,c); -endinstr; - -HLinstr(0x72,7,8); - store(addr,d); -endinstr; - -HLinstr(0x73,7,8); - store(addr,e); -endinstr; - -HLinstr(0x74,7,8); - store(addr,h); -endinstr; - -HLinstr(0x75,7,8); - store(addr,l); -endinstr; - -instr(0x76,4); - /* Was HALT - ZXCC ignores HALT */ -endinstr; - -HLinstr(0x77,7,8); - store(addr,a); -endinstr; - -instr(0x78,4); - a=b; -endinstr; - -instr(0x79,4); - a=c; -endinstr; - -instr(0x7a,4); - a=d; -endinstr; - -instr(0x7b,4); - a=e; -endinstr; - -instr(0x7c,4); - a=xh; -endinstr; - -instr(0x7d,4); - a=xl; -endinstr; - -HLinstr(0x7e,7,8); - a=fetch(addr); -endinstr; - -instr(0x7f,4); - /* ld a,a */ -endinstr; - -instr(0x80,4); - adda(b,0); -endinstr; - -instr(0x81,4); - adda(c,0); -endinstr; - -instr(0x82,4); - adda(d,0); -endinstr; - -instr(0x83,4); - adda(e,0); -endinstr; - -instr(0x84,4); - adda(xh,0); -endinstr; - -instr(0x85,4); - adda(xl,0); -endinstr; - -HLinstr(0x86,7,8); - adda(fetch(addr),0); -endinstr; - -instr(0x87,4); - adda(a,0); -endinstr; - -instr(0x88,4); - adda(b,cy); -endinstr; - -instr(0x89,4); - adda(c,cy); -endinstr; - -instr(0x8a,4); - adda(d,cy); -endinstr; - -instr(0x8b,4); - adda(e,cy); -endinstr; - -instr(0x8c,4); - adda(xh,cy); -endinstr; - -instr(0x8d,4); - adda(xl,cy); -endinstr; - -HLinstr(0x8e,7,8); - adda(fetch(addr),cy); -endinstr; - -instr(0x8f,4); - adda(a,cy); -endinstr; - -instr(0x90,4); - suba(b,0); -endinstr; - -instr(0x91,4); - suba(c,0); -endinstr; - -instr(0x92,4); - suba(d,0); -endinstr; - -instr(0x93,4); - suba(e,0); -endinstr; - -instr(0x94,4); - suba(xh,0); -endinstr; - -instr(0x95,4); - suba(xl,0); -endinstr; - -HLinstr(0x96,7,8); - suba(fetch(addr),0); -endinstr; - -instr(0x97,4); - suba(a,0); -endinstr; - -instr(0x98,4); - suba(b,cy); -endinstr; - -instr(0x99,4); - suba(c,cy); -endinstr; - -instr(0x9a,4); - suba(d,cy); -endinstr; - -instr(0x9b,4); - suba(e,cy); -endinstr; - -instr(0x9c,4); - suba(xh,cy); -endinstr; - -instr(0x9d,4); - suba(xl,cy); -endinstr; - -HLinstr(0x9e,7,8); - suba(fetch(addr),cy); -endinstr; - -instr(0x9f,4); - suba(a,cy); -endinstr; - -instr(0xa0,4); - anda(b); -endinstr; - -instr(0xa1,4); - anda(c); -endinstr; - -instr(0xa2,4); - anda(d); -endinstr; - -instr(0xa3,4); - anda(e); -endinstr; - -instr(0xa4,4); - anda(xh); -endinstr; - -instr(0xa5,4); - anda(xl); -endinstr; - -HLinstr(0xa6,7,8); - anda(fetch(addr)); -endinstr; - -instr(0xa7,4); - anda(a); -endinstr; - -instr(0xa8,4); - xora(b); -endinstr; - -instr(0xa9,4); - xora(c); -endinstr; - -instr(0xaa,4); - xora(d); -endinstr; - -instr(0xab,4); - xora(e); -endinstr; - -instr(0xac,4); - xora(xh); -endinstr; - -instr(0xad,4); - xora(xl); -endinstr; - -HLinstr(0xae,7,8); - xora(fetch(addr)); -endinstr; - -instr(0xaf,4); - xora(a); -endinstr; - -instr(0xb0,4); - ora(b); -endinstr; - -instr(0xb1,4); - ora(c); -endinstr; - -instr(0xb2,4); - ora(d); -endinstr; - -instr(0xb3,4); - ora(e); -endinstr; - -instr(0xb4,4); - ora(xh); -endinstr; - -instr(0xb5,4); - ora(xl); -endinstr; - -HLinstr(0xb6,7,8); - ora(fetch(addr)); -endinstr; - -instr(0xb7,4); - ora(a); -endinstr; - -instr(0xb8,4); - cpa(b); -endinstr; - -instr(0xb9,4); - cpa(c); -endinstr; - -instr(0xba,4); - cpa(d); -endinstr; - -instr(0xbb,4); - cpa(e); -endinstr; - -instr(0xbc,4); - cpa(xh); -endinstr; - -instr(0xbd,4); - cpa(xl); -endinstr; - -HLinstr(0xbe,7,8); - cpa(fetch(addr)); -endinstr; - -instr(0xbf,4); - cpa(a); -endinstr; - -instr(0xc0,5); - if(!(f&0x40))ret; -endinstr; - -instr(0xc1,10); - pop1(b,c); -endinstr; - -instr(0xc2,10); - if(!(f&0x40))jp; - else pc+=2; -endinstr; - -instr(0xc3,10); - jp; -endinstr; - -instr(0xc4,10); - if(!(f&0x40))call; - else pc+=2; -endinstr; - -instr(0xc5,11); - push1(b,c); -endinstr; - -instr(0xc6,7); - adda(fetch(pc),0); - pc++; -endinstr; - -instr(0xc7,11); - push2(pc); - pc=0; -endinstr; - -instr(0xc8,5); - if(f&0x40)ret; -endinstr; - -instr(0xc9,4); - ret; -endinstr; - -instr(0xca,10); - if(f&0x40)jp; - else pc+=2; -endinstr; - -instr(0xcb,4); -#include "cbops.h" -endinstr; - -instr(0xcc,10); - if(f&0x40)call; - else pc+=2; -endinstr; - -instr(0xcd,10); - call; -endinstr; - -instr(0xce,7); - adda(fetch(pc),cy); - pc++; -endinstr; - -instr(0xcf,11); - push2(pc); - pc=8; -endinstr; - -instr(0xd0,5); - if(!cy)ret; -endinstr; - -instr(0xd1,10); - pop1(d,e); -endinstr; - -instr(0xd2,10); - if(!cy)jp; - else pc+=2; -endinstr; - -instr(0xd3,11); - tstates+=out(tstates,a,fetch(pc),a); - pc++; -endinstr; - -instr(0xd4,10); - if(!cy)call; - else pc+=2; -endinstr; - -instr(0xd5,11); - push1(d,e); -endinstr; - -instr(0xd6,7); - suba(fetch(pc),0); - pc++; -endinstr; - -instr(0xd7,11); - push2(pc); - pc=16; -endinstr; - -instr(0xd8,5); - if(cy)ret; -endinstr; - -instr(0xd9,4); - swap(b,b1); - swap(c,c1); - swap(d,d1); - swap(e,e1); - swap(h,h1); - swap(l,l1); -endinstr; - -instr(0xda,10); - if(cy)jp; - else pc+=2; -endinstr; - -instr(0xdb,11); - {unsigned short t; - a=t=in(tstates,a,fetch(pc)); - tstates+=t>>8; - pc++; - } -endinstr; - -instr(0xdc,10); - if(cy)call; - else pc+=2; -endinstr; - -instr(0xdd,4); - new_ixoriy=1; - intsample=0; -endinstr; - -instr(0xde,7); - suba(fetch(pc),cy); - pc++; -endinstr; - -instr(0xdf,11); - push2(pc); - pc=24; -endinstr; - -instr(0xe0,5); - if(!(f&4))ret; -endinstr; - -instr(0xe1,10); - if(!ixoriy)pop1(h,l); - else if(ixoriy==1)pop2(ix); - else pop2(iy); -endinstr; - -instr(0xe2,10); - if(!(f&4))jp; - else pc+=2; -endinstr; - -instr(0xe3,19); - if(!ixoriy){ - unsigned short t=fetch2(sp); - store2b(sp,h,l); - l=t; - h=t>>8; - } - else if(ixoriy==1){ - unsigned short t=fetch2(sp); - store2(sp,ix); - ix=t; - } - else{ - unsigned short t=fetch2(sp); - store2(sp,iy); - iy=t; - } -endinstr; - -instr(0xe4,10); - if(!(f&4))call; - else pc+=2; -endinstr; - -instr(0xe5,11); - if(!ixoriy)push1(h,l); - else if(ixoriy==1)push2(ix); - else push2(iy); -endinstr; - -instr(0xe6,7); - anda(fetch(pc)); - pc++; -endinstr; - -instr(0xe7,11); - push2(pc); - pc=32; -endinstr; - -instr(0xe8,5); - if(f&4)ret; -endinstr; - -instr(0xe9,4); - pc=!ixoriy?hl:ixoriy==1?ix:iy; -endinstr; - -instr(0xea,10); - if(f&4)jp; - else pc+=2; -endinstr; - -instr(0xeb,4); - swap(h,d); - swap(e,l); -endinstr; - -instr(0xec,10); - if(f&4)call; - else pc+=2; -endinstr; - -instr(0xed,4); -#include"edops.h" -endinstr; - -instr(0xee,7); - xora(fetch(pc)); - pc++; -endinstr; - -instr(0xef,11); - push2(pc); - pc=40; -endinstr; - -instr(0xf0,5); - if(!(f&0x80))ret; -endinstr; - -instr(0xf1,10); - pop1(a,f); -endinstr; - -instr(0xf2,10); - if(!(f&0x80))jp; - else pc+=2; -endinstr; - -instr(0xf3,4); - iff1=iff2=0; - intsample=0; -endinstr; - -instr(0xf4,10); - if(!(f&0x80))call; - else pc+=2; -endinstr; - -instr(0xf5,11); - push1(a,f); -endinstr; - -instr(0xf6,7); - ora(fetch(pc)); - pc++; -endinstr; - -instr(0xf7,11); - push2(pc); - pc=48; -endinstr; - -instr(0xf8,5); - if(f&0x80)ret; -endinstr; - -instr(0xf9,6); - sp=!ixoriy?hl:ixoriy==1?ix:iy; -endinstr; - -instr(0xfa,10); - if(f&0x80)jp; - else pc+=2; -endinstr; - -instr(0xfb,4); - iff1=iff2=1; - intsample=0; -endinstr; - -instr(0xfc,10); - if(f&0x80)call; - else pc+=2; -endinstr; - -instr(0xfd,4); - new_ixoriy=2; - intsample=0; -endinstr; - -instr(0xfe,7); - cpa(fetch(pc)); - pc++; -endinstr; - -instr(0xff,11); - push2(pc); - pc=56; -endinstr; - +/* Emulations of the Z80 CPU instruction set - part of xz80. + * Copyright (C) 1994 Ian Collier. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define instr(opcode,cycles) case opcode: {tstates+=cycles +#define HLinstr(opcode,cycles,morecycles) \ + case opcode: {unsigned short addr; \ + tstates+=cycles; \ + if(ixoriy==0)addr=hl; \ + else tstates+=morecycles, \ + addr=(ixoriy==1?ix:iy)+ \ + (signed char)fetch(pc),\ + pc++ +#define endinstr }; break + +#define cy (f&1) + +#define xh (ixoriy==0?h:ixoriy==1?(ix>>8):(iy>>8)) +#define xl (ixoriy==0?l:ixoriy==1?(ix&0xff):(iy&0xff)) + +#define setxh(x) (ixoriy==0?(h=(x)):ixoriy==1?(ix=(ix&0xff)|((x)<<8)):\ + (iy=(iy&0xff)|((x)<<8))) +#define setxl(x) (ixoriy==0?(l=(x)):ixoriy==1?(ix=(ix&0xff00)|(x)):\ + (iy=(iy&0xff00)|(x))) + +#define inc(var) /* 8-bit increment */ ( var++,\ + f=(f&1)|(var&0xa8)|\ + ((!(var&15))<<4)|((!var)<<6)|\ + ((var==128)<<2)\ + ) +#define dec(var) /* 8-bit decrement */ ( f=(f&1)|((!(var&15))<<4)|2,\ + --var,\ + f|=(var&0xa8)|((var==127)<<2)|\ + ((!var)<<6)\ + ) +#define swap(x,y) {unsigned char t=x; x=y; y=t;} +#define addhl(hi,lo) /* 16-bit add */ if(!ixoriy){\ + unsigned short t;\ + l=t=l+(lo);\ + f=(f&0xc4)|(((t>>=8)+(h&0x0f)+((hi)&0x0f)>15)<<4);\ + h=t+=h+(hi);\ + f|=(h&0x28)|(t>>8);\ + }\ + else do{unsigned long t=(ixoriy==1?ix:iy);\ + f=(f&0xc4)|(((t&0xfff)+((hi<<8)|lo)>0xfff)<<4);\ + t+=(hi<<8)|lo;\ + if(ixoriy==1)ix=t; else iy=t;\ + f|=((t>>8)&0x28)|(t>>16);\ + } while(0) +#define adda(x,c) /* 8-bit add */ do{unsigned short y;\ + unsigned char z=(x);\ + y=a+z+(c);\ + f=(y&0xa8)|(y>>8)|(((a&0x0f)+(z&0x0f)+(c)>15)<<4)|\ + (((~a^z)&0x80&(y^a))>>5);\ + f|=(!(a=y))<<6;\ + } while(0) +#define suba(x,c) /* 8-bit subtract */ do{unsigned short y;\ + unsigned char z=(x);\ + y=(a-z-(c))&0x1ff;\ + f=(y&0xa8)|(y>>8)|(((a&0x0f)<(z&0x0f)+(c))<<4)|\ + (((a^z)&0x80&(y^a))>>5)|2;\ + f|=(!(a=y))<<6;\ + } while(0) +#define cpa(x) /* 8-bit compare */ do{unsigned short y;\ + unsigned char z=(x);\ + y=(a-z)&0x1ff;\ + f=(y&0xa8)|(y>>8)|(((a&0x0f)<(z&0x0f))<<4)|\ + (((a^z)&0x80&(y^a))>>5)|2|((!y)<<6);\ + } while(0) +#define anda(x) /* logical and */ do{\ + a&=(x);\ + f=(a&0xa8)|((!a)<<6)|0x10|parity(a);\ + } while(0) +#define xora(x) /* logical xor */ do{\ + a^=(x);\ + f=(a&0xa8)|((!a)<<6)|parity(a);\ + } while(0) +#define ora(x) /* logical or */ do{\ + a|=(x);\ + f=(a&0xa8)|((!a)<<6)|parity(a);\ + } while(0) + +#define jr /* execute relative jump */ do{int j=(signed char)fetch(pc);\ + pc+=j+1;\ + tstates+=5;\ + } while(0) +#define jp /* execute jump */ (pc=fetch2(pc)) +#define call /* execute call */ do{\ + tstates+=7;\ + push2(pc+2);\ + jp;\ + } while(0) +#define ret /* execute return */ do{\ + tstates+=6;\ + pop2(pc);\ + } while(0) +#define pop2(var) /* pop 16-bit register */ (var=fetch2(sp),sp+=2) +#define pop1(v1,v2) /* pop register pair */ (v2=fetch(sp),\ + v1=fetch(sp+1),sp+=2) +#define push2(val) /* push 16-bit register */ do{sp-=2;store2(sp,(val));}\ + while(0) +#define push1(v1,v2) /* push register pair */ do{sp-=2;\ + store2b(sp,v1,v2);\ + }while(0) + +instr(0,4); + /* nop */ +endinstr; + +instr(1,10); + c=fetch(pc),pc++; + b=fetch(pc),pc++; +endinstr; + +instr(2,7); + store(bc,a); +endinstr; + +instr(3,6); + if(!++c)b++; +endinstr; + +instr(4,4); + inc(b); +endinstr; + +instr(5,4); + dec(b); +endinstr; + +instr(6,7); + b=fetch(pc),pc++; +endinstr; + +instr(7,4); + a=(a<<1)|(a>>7); + f=(f&0xc4)|(a&0x29); +endinstr; + +instr(8,4); + swap(a,a1); + swap(f,f1); +endinstr; + +instr(9,11); + addhl(b,c); +endinstr; + +instr(10,7); + a=fetch(bc); +endinstr; + +instr(11,6); + if(!c--)b--; +endinstr; + +instr(12,4); + inc(c); +endinstr; + +instr(13,4); + dec(c); +endinstr; + +instr(14,7); + c=fetch(pc),pc++; +endinstr; + +instr(15,4); + f=(f&0xc4)|(a&1); + a=(a>>1)|(a<<7); + f|=a&0x28; +endinstr; + +instr(16,8); + if(!--b)pc++; + else jr; +endinstr; + +instr(17,10); + e=fetch(pc),pc++; + d=fetch(pc),pc++; +endinstr; + +instr(18,7); + store(de,a); +endinstr; + +instr(19,6); + if(!++e)d++; +endinstr; + +instr(20,4); + inc(d); +endinstr; + +instr(21,4); + dec(d); +endinstr; + +instr(22,7); + d=fetch(pc),pc++; +endinstr; + +instr(23,4); + {int t=a>>7; + a=(a<<1)|(f&1); + f=(f&0xc4)|(a&0x28)|t; + } +endinstr; + +instr(24,7); + jr; +endinstr; + +instr(25,11); + addhl(d,e); +endinstr; + +instr(26,7); + a=fetch(de); +endinstr; + +instr(27,6); + if(!e--)d--; +endinstr; + +instr(28,4); + inc(e); +endinstr; + +instr(29,4); + dec(e); +endinstr; + +instr(30,7); + e=fetch(pc),pc++; +endinstr; + +instr(31,4); + {int t=a&1; + a=(a>>1)|(f<<7); + f=(f&0xc4)|(a&0x28)|t; + } +endinstr; + +instr(32,7); + if(f&0x40)pc++; + else jr; +endinstr; + +instr(33,10); + if(!ixoriy){ + l=fetch(pc),pc++; + h=fetch(pc),pc++; + } + else { + if(ixoriy==1)ix=fetch2(pc); + else iy=fetch2(pc); + pc+=2; + } +endinstr; + +instr(34,16); + {unsigned short addr=fetch2(pc); + pc+=2; + if(!ixoriy)store2b(addr,h,l); + else if(ixoriy==1)store2(addr,ix); + else store2(addr,iy); + } +endinstr; + +instr(35,6); + if(!ixoriy){if(!++l)h++;} + else if(ixoriy==1)ix++; + else iy++; +endinstr; + +instr(36,4); + if(ixoriy==0)inc(h); + else{unsigned char t; + t=(ixoriy==1?ix:iy)>>8; + inc(t); + if(ixoriy==1)ix=(ix&0xff)|(t<<8); + else iy=(iy&0xff)|(t<<8); + } +endinstr; + +instr(37,4); + if(ixoriy==0)dec(h); + else{unsigned char t; + t=(ixoriy==1?ix:iy)>>8; + dec(t); + if(ixoriy==1)ix=(ix&0xff)|(t<<8); + else iy=(iy&0xff)|(t<<8); + } +endinstr; + +instr(38,7); + setxh(fetch(pc)); + pc++; +endinstr; + +instr(39,4); + { + /* Frank D. Cringle's DAA implementation, converted from yaze 1.10 */ + unsigned int acu,temp,cbits; + + acu=a; + temp=(acu&15); + cbits=(f&1); + if(f&2) /* if N */ + { + /* last operation was a subtract */ + int hd=(cbits || (acu>0x99)); + if((f&16) || (temp>9)) + { /* adjust low digit */ + if(temp>5) f&=~16; + acu-=6; + acu&=0xff; + } + /* adjust high digit */ + if(hd) + acu-=0x160; + } + else + { + /* last operation was an add */ + if((f&16) || (temp>9)) + { + /* adjust low digit */ + if(temp>9) f|=16; else f&=~16; + acu+=6; + } + /* adjust high digit */ + if(cbits || ((acu&0x1f0)>0x90)) + acu+=0x60; + } + cbits|=((acu>>8)&1); + acu&=0xff; + a=acu; + f=((acu&0xa8)|((acu==0)<<6)|(f&0x12)|parity(a)|cbits); + } +endinstr; + +instr(40,7); + if(f&0x40)jr; + else pc++; +endinstr; + +instr(41,11); + if(!ixoriy)addhl(h,l); + else if(ixoriy==1)addhl((ix>>8),(ix&0xff)); + else addhl((iy>>8),(iy&0xff)); +endinstr; + +instr(42,16); + {unsigned short addr=fetch2(pc); + pc+=2; + if(!ixoriy){ + l=fetch(addr); + h=fetch(addr+1); + } + else if(ixoriy==1)ix=fetch2(addr); + else iy=fetch2(addr); + } +endinstr; + +instr(43,6); + if(!ixoriy){if(!l--)h--;} + else if(ixoriy==1)ix--; + else iy--; +endinstr; + +instr(44,4); + if(!ixoriy)inc(l); + else {unsigned char t; + t=(ixoriy==1?ix:iy); + inc(t); + if(ixoriy==1)ix=(ix&0xff00)|t; + else iy=(iy&0xff00)|t; + } +endinstr; + +instr(45,4); + if(!ixoriy)dec(l); + else {unsigned char t; + t=(ixoriy==1?ix:iy); + dec(t); + if(ixoriy==1)ix=(ix&0xff00)|t; + else iy=(iy&0xff00)|t; + } +endinstr; + +instr(46,7); + setxl(fetch(pc)); + pc++; +endinstr; + +instr(47,4); + a=~a; + f=(f&0xc5)|(a&0x28)|0x12; +endinstr; + +instr(48,7); + if(f&1)pc++; + else jr; +endinstr; + +instr(49,10); + sp=fetch2(pc); + pc+=2; +endinstr; + +instr(50,13); + {unsigned short addr=fetch2(pc); + pc+=2; + store(addr,a); + } +endinstr; + +instr(51,6); + sp++; +endinstr; + +HLinstr(52,11,8); + {unsigned char t=fetch(addr); + inc(t); + store(addr,t); + } +endinstr; + +HLinstr(53,11,8); + {unsigned char t=fetch(addr); + dec(t); + store(addr,t); + } +endinstr; + +HLinstr(54,10,5); + store(addr,fetch(pc)); + pc++; +endinstr; + +instr(55,4); + f=(f&0xc4)|1|(a&0x28); +endinstr; + +instr(56,7); + if(f&1)jr; + else pc++; +endinstr; + +instr(57,11); + addhl((sp>>8),(sp&0xff)); +endinstr; + +instr(58,13); + {unsigned short addr=fetch2(pc); + pc+=2; + a=fetch(addr); + } +endinstr; + +instr(59,6); + sp--; +endinstr; + +instr(60,4); + inc(a); +endinstr; + +instr(61,4); + dec(a); +endinstr; + +instr(62,7); + a=fetch(pc),pc++; +endinstr; + +instr(63,4); + f=(f&0xc4)|(cy^1)|(cy<<4)|(a&0x28); +endinstr; + +instr(0x40,4); + /* ld b,b */ +endinstr; + +instr(0x41,4); + b=c; +endinstr; + +instr(0x42,4); + b=d; +endinstr; + +instr(0x43,4); + b=e; +endinstr; + +instr(0x44,4); + b=xh; +endinstr; + +instr(0x45,4); + b=xl; +endinstr; + +HLinstr(0x46,7,8); + b=fetch(addr); +endinstr; + +instr(0x47,4); + b=a; +endinstr; + +instr(0x48,4); + c=b; +endinstr; + +instr(0x49,4); + /* ld c,c */ +endinstr; + +instr(0x4a,4); + c=d; +endinstr; + +instr(0x4b,4); + c=e; +endinstr; + +instr(0x4c,4); + c=xh; +endinstr; + +instr(0x4d,4); + c=xl; +endinstr; + +HLinstr(0x4e,7,8); + c=fetch(addr); +endinstr; + +instr(0x4f,4); + c=a; +endinstr; + +instr(0x50,4); + d=b; +endinstr; + +instr(0x51,4); + d=c; +endinstr; + +instr(0x52,4); + /* ld d,d */ +endinstr; + +instr(0x53,4); + d=e; +endinstr; + +instr(0x54,4); + d=xh; +endinstr; + +instr(0x55,4); + d=xl; +endinstr; + +HLinstr(0x56,7,8); + d=fetch(addr); +endinstr; + +instr(0x57,4); + d=a; +endinstr; + +instr(0x58,4); + e=b; +endinstr; + +instr(0x59,4); + e=c; +endinstr; + +instr(0x5a,4); + e=d; +endinstr; + +instr(0x5b,4); + /* ld e,e */ +endinstr; + +instr(0x5c,4); + e=xh; +endinstr; + +instr(0x5d,4); + e=xl; +endinstr; + +HLinstr(0x5e,7,8); + e=fetch(addr); +endinstr; + +instr(0x5f,4); + e=a; +endinstr; + +instr(0x60,4); + setxh(b); +endinstr; + +instr(0x61,4); + setxh(c); +endinstr; + +instr(0x62,4); + setxh(d); +endinstr; + +instr(0x63,4); + setxh(e); +endinstr; + +instr(0x64,4); + /* ld h,h */ +endinstr; + +instr(0x65,4); + setxh(xl); +endinstr; + +HLinstr(0x66,7,8); + h=fetch(addr); +endinstr; + +instr(0x67,4); + setxh(a); +endinstr; + +instr(0x68,4); + setxl(b); +endinstr; + +instr(0x69,4); + setxl(c); +endinstr; + +instr(0x6a,4); + setxl(d); +endinstr; + +instr(0x6b,4); + setxl(e); +endinstr; + +instr(0x6c,4); + setxl(xh); +endinstr; + +instr(0x6d,4); + /* ld l,l */ +endinstr; + +HLinstr(0x6e,7,8); + l=fetch(addr); +endinstr; + +instr(0x6f,4); + setxl(a); +endinstr; + +HLinstr(0x70,7,8); + store(addr,b); +endinstr; + +HLinstr(0x71,7,8); + store(addr,c); +endinstr; + +HLinstr(0x72,7,8); + store(addr,d); +endinstr; + +HLinstr(0x73,7,8); + store(addr,e); +endinstr; + +HLinstr(0x74,7,8); + store(addr,h); +endinstr; + +HLinstr(0x75,7,8); + store(addr,l); +endinstr; + +instr(0x76,4); + /* Was HALT - ZXCC ignores HALT */ +endinstr; + +HLinstr(0x77,7,8); + store(addr,a); +endinstr; + +instr(0x78,4); + a=b; +endinstr; + +instr(0x79,4); + a=c; +endinstr; + +instr(0x7a,4); + a=d; +endinstr; + +instr(0x7b,4); + a=e; +endinstr; + +instr(0x7c,4); + a=xh; +endinstr; + +instr(0x7d,4); + a=xl; +endinstr; + +HLinstr(0x7e,7,8); + a=fetch(addr); +endinstr; + +instr(0x7f,4); + /* ld a,a */ +endinstr; + +instr(0x80,4); + adda(b,0); +endinstr; + +instr(0x81,4); + adda(c,0); +endinstr; + +instr(0x82,4); + adda(d,0); +endinstr; + +instr(0x83,4); + adda(e,0); +endinstr; + +instr(0x84,4); + adda(xh,0); +endinstr; + +instr(0x85,4); + adda(xl,0); +endinstr; + +HLinstr(0x86,7,8); + adda(fetch(addr),0); +endinstr; + +instr(0x87,4); + adda(a,0); +endinstr; + +instr(0x88,4); + adda(b,cy); +endinstr; + +instr(0x89,4); + adda(c,cy); +endinstr; + +instr(0x8a,4); + adda(d,cy); +endinstr; + +instr(0x8b,4); + adda(e,cy); +endinstr; + +instr(0x8c,4); + adda(xh,cy); +endinstr; + +instr(0x8d,4); + adda(xl,cy); +endinstr; + +HLinstr(0x8e,7,8); + adda(fetch(addr),cy); +endinstr; + +instr(0x8f,4); + adda(a,cy); +endinstr; + +instr(0x90,4); + suba(b,0); +endinstr; + +instr(0x91,4); + suba(c,0); +endinstr; + +instr(0x92,4); + suba(d,0); +endinstr; + +instr(0x93,4); + suba(e,0); +endinstr; + +instr(0x94,4); + suba(xh,0); +endinstr; + +instr(0x95,4); + suba(xl,0); +endinstr; + +HLinstr(0x96,7,8); + suba(fetch(addr),0); +endinstr; + +instr(0x97,4); + suba(a,0); +endinstr; + +instr(0x98,4); + suba(b,cy); +endinstr; + +instr(0x99,4); + suba(c,cy); +endinstr; + +instr(0x9a,4); + suba(d,cy); +endinstr; + +instr(0x9b,4); + suba(e,cy); +endinstr; + +instr(0x9c,4); + suba(xh,cy); +endinstr; + +instr(0x9d,4); + suba(xl,cy); +endinstr; + +HLinstr(0x9e,7,8); + suba(fetch(addr),cy); +endinstr; + +instr(0x9f,4); + suba(a,cy); +endinstr; + +instr(0xa0,4); + anda(b); +endinstr; + +instr(0xa1,4); + anda(c); +endinstr; + +instr(0xa2,4); + anda(d); +endinstr; + +instr(0xa3,4); + anda(e); +endinstr; + +instr(0xa4,4); + anda(xh); +endinstr; + +instr(0xa5,4); + anda(xl); +endinstr; + +HLinstr(0xa6,7,8); + anda(fetch(addr)); +endinstr; + +instr(0xa7,4); + anda(a); +endinstr; + +instr(0xa8,4); + xora(b); +endinstr; + +instr(0xa9,4); + xora(c); +endinstr; + +instr(0xaa,4); + xora(d); +endinstr; + +instr(0xab,4); + xora(e); +endinstr; + +instr(0xac,4); + xora(xh); +endinstr; + +instr(0xad,4); + xora(xl); +endinstr; + +HLinstr(0xae,7,8); + xora(fetch(addr)); +endinstr; + +instr(0xaf,4); + xora(a); +endinstr; + +instr(0xb0,4); + ora(b); +endinstr; + +instr(0xb1,4); + ora(c); +endinstr; + +instr(0xb2,4); + ora(d); +endinstr; + +instr(0xb3,4); + ora(e); +endinstr; + +instr(0xb4,4); + ora(xh); +endinstr; + +instr(0xb5,4); + ora(xl); +endinstr; + +HLinstr(0xb6,7,8); + ora(fetch(addr)); +endinstr; + +instr(0xb7,4); + ora(a); +endinstr; + +instr(0xb8,4); + cpa(b); +endinstr; + +instr(0xb9,4); + cpa(c); +endinstr; + +instr(0xba,4); + cpa(d); +endinstr; + +instr(0xbb,4); + cpa(e); +endinstr; + +instr(0xbc,4); + cpa(xh); +endinstr; + +instr(0xbd,4); + cpa(xl); +endinstr; + +HLinstr(0xbe,7,8); + cpa(fetch(addr)); +endinstr; + +instr(0xbf,4); + cpa(a); +endinstr; + +instr(0xc0,5); + if(!(f&0x40))ret; +endinstr; + +instr(0xc1,10); + pop1(b,c); +endinstr; + +instr(0xc2,10); + if(!(f&0x40))jp; + else pc+=2; +endinstr; + +instr(0xc3,10); + jp; +endinstr; + +instr(0xc4,10); + if(!(f&0x40))call; + else pc+=2; +endinstr; + +instr(0xc5,11); + push1(b,c); +endinstr; + +instr(0xc6,7); + adda(fetch(pc),0); + pc++; +endinstr; + +instr(0xc7,11); + push2(pc); + pc=0; +endinstr; + +instr(0xc8,5); + if(f&0x40)ret; +endinstr; + +instr(0xc9,4); + ret; +endinstr; + +instr(0xca,10); + if(f&0x40)jp; + else pc+=2; +endinstr; + +instr(0xcb,4); +#include "cbops.h" +endinstr; + +instr(0xcc,10); + if(f&0x40)call; + else pc+=2; +endinstr; + +instr(0xcd,10); + call; +endinstr; + +instr(0xce,7); + adda(fetch(pc),cy); + pc++; +endinstr; + +instr(0xcf,11); + push2(pc); + pc=8; +endinstr; + +instr(0xd0,5); + if(!cy)ret; +endinstr; + +instr(0xd1,10); + pop1(d,e); +endinstr; + +instr(0xd2,10); + if(!cy)jp; + else pc+=2; +endinstr; + +instr(0xd3,11); + tstates+=out(tstates,a,fetch(pc),a); + pc++; +endinstr; + +instr(0xd4,10); + if(!cy)call; + else pc+=2; +endinstr; + +instr(0xd5,11); + push1(d,e); +endinstr; + +instr(0xd6,7); + suba(fetch(pc),0); + pc++; +endinstr; + +instr(0xd7,11); + push2(pc); + pc=16; +endinstr; + +instr(0xd8,5); + if(cy)ret; +endinstr; + +instr(0xd9,4); + swap(b,b1); + swap(c,c1); + swap(d,d1); + swap(e,e1); + swap(h,h1); + swap(l,l1); +endinstr; + +instr(0xda,10); + if(cy)jp; + else pc+=2; +endinstr; + +instr(0xdb,11); + {unsigned short t; + a=t=in(tstates,a,fetch(pc)); + tstates+=t>>8; + pc++; + } +endinstr; + +instr(0xdc,10); + if(cy)call; + else pc+=2; +endinstr; + +instr(0xdd,4); + new_ixoriy=1; + intsample=0; +endinstr; + +instr(0xde,7); + suba(fetch(pc),cy); + pc++; +endinstr; + +instr(0xdf,11); + push2(pc); + pc=24; +endinstr; + +instr(0xe0,5); + if(!(f&4))ret; +endinstr; + +instr(0xe1,10); + if(!ixoriy)pop1(h,l); + else if(ixoriy==1)pop2(ix); + else pop2(iy); +endinstr; + +instr(0xe2,10); + if(!(f&4))jp; + else pc+=2; +endinstr; + +instr(0xe3,19); + if(!ixoriy){ + unsigned short t=fetch2(sp); + store2b(sp,h,l); + l=t; + h=t>>8; + } + else if(ixoriy==1){ + unsigned short t=fetch2(sp); + store2(sp,ix); + ix=t; + } + else{ + unsigned short t=fetch2(sp); + store2(sp,iy); + iy=t; + } +endinstr; + +instr(0xe4,10); + if(!(f&4))call; + else pc+=2; +endinstr; + +instr(0xe5,11); + if(!ixoriy)push1(h,l); + else if(ixoriy==1)push2(ix); + else push2(iy); +endinstr; + +instr(0xe6,7); + anda(fetch(pc)); + pc++; +endinstr; + +instr(0xe7,11); + push2(pc); + pc=32; +endinstr; + +instr(0xe8,5); + if(f&4)ret; +endinstr; + +instr(0xe9,4); + pc=!ixoriy?hl:ixoriy==1?ix:iy; +endinstr; + +instr(0xea,10); + if(f&4)jp; + else pc+=2; +endinstr; + +instr(0xeb,4); + swap(h,d); + swap(e,l); +endinstr; + +instr(0xec,10); + if(f&4)call; + else pc+=2; +endinstr; + +instr(0xed,4); +#include"edops.h" +endinstr; + +instr(0xee,7); + xora(fetch(pc)); + pc++; +endinstr; + +instr(0xef,11); + push2(pc); + pc=40; +endinstr; + +instr(0xf0,5); + if(!(f&0x80))ret; +endinstr; + +instr(0xf1,10); + pop1(a,f); +endinstr; + +instr(0xf2,10); + if(!(f&0x80))jp; + else pc+=2; +endinstr; + +instr(0xf3,4); + iff1=iff2=0; + intsample=0; +endinstr; + +instr(0xf4,10); + if(!(f&0x80))call; + else pc+=2; +endinstr; + +instr(0xf5,11); + push1(a,f); +endinstr; + +instr(0xf6,7); + ora(fetch(pc)); + pc++; +endinstr; + +instr(0xf7,11); + push2(pc); + pc=48; +endinstr; + +instr(0xf8,5); + if(f&0x80)ret; +endinstr; + +instr(0xf9,6); + sp=!ixoriy?hl:ixoriy==1?ix:iy; +endinstr; + +instr(0xfa,10); + if(f&0x80)jp; + else pc+=2; +endinstr; + +instr(0xfb,4); + iff1=iff2=1; + intsample=0; +endinstr; + +instr(0xfc,10); + if(f&0x80)call; + else pc+=2; +endinstr; + +instr(0xfd,4); + new_ixoriy=2; + intsample=0; +endinstr; + +instr(0xfe,7); + cpa(fetch(pc)); + pc++; +endinstr; + +instr(0xff,11); + push2(pc); + pc=56; +endinstr; + diff --git a/Tools/unix/zx/zxbdos.c b/Tools/unix/zxcc/zxbdos.c similarity index 95% rename from Tools/unix/zx/zxbdos.c rename to Tools/unix/zxcc/zxbdos.c index 3c4dd931..811dcd6d 100644 --- a/Tools/unix/zx/zxbdos.c +++ b/Tools/unix/zxcc/zxbdos.c @@ -1,4 +1,4 @@ -#include "zx.h" +#include "zxcc.h" #define BDOS_DEF #include "zxbdos.h" @@ -12,11 +12,14 @@ #define BCD(x) (((x % 10)+16*(x/10)) & 0xFF) /* Convert time_t to CP/M day count/hours/minutes */ +/* there is a duplicate of this code in util.c. +* same modification applied here +*/ dword cpmtime(time_t t) { - long d = (t / 86400) - 2921; /* CP/M day 0 is unix day 2921 */ - long h = (t % 86400) / 3600; /* Hour, 0-23 */ - long m = (t % 3600) / 60; /* Minute, 0-59 */ + dword d = (dword)((t / 86400) - 2921); /* CP/M day 0 is unix day 2921 */ + dword h = (t % 86400) / 3600; /* Hour, 0-23 */ + dword m = (t % 3600) / 60; /* Minute, 0-59 */ return (d | (BCD(h) << 16) | (BCD(m) << 24)); } @@ -203,7 +206,7 @@ void cpmbdos(byte *a, byte *b, byte *c, byte *d, byte *e, byte *f, /* For GENCOM's benefit, claim to be v3.1 */ *l = 0x31; /* v3.1 */ - //*l = 0x22; /* v2.2 */ + /* *l = 0x22; * v2.2 */ *h = 0; /* CP/M, no network */ break; @@ -237,9 +240,6 @@ void cpmbdos(byte *a, byte *b, byte *c, byte *d, byte *e, byte *f, case 0x14: /* Sequential read using FCB */ setw(l, h, fcb_read(pde, pdma)); - - //Msg("fcb_read L=%02x H=%02x\n", *l, *h); - break; case 0x15: /* Sequential write using FCB */ @@ -470,14 +470,12 @@ void cpmbdos(byte *a, byte *b, byte *c, byte *d, byte *e, byte *f, fprintf(stderr,"%s: Unsupported BDOS call %d\n", progname, (int)(*c)); dump_regs(stderr,*a,*b,*c,*d,*e,*f,*h,*l,*pc,*ix,*iy); - zx_exit(1); + zxcc_exit(1); break; } *a = *l; *b = *h; - - Msg("BDOS service completion.\n"); } @@ -492,7 +490,7 @@ void cpmbios(byte *a, byte *b, byte *c, byte *d, byte *e, byte *f, switch(func) /* BIOS function */ { case 1: - zx_exit(zx_term()); /* Program termination */ + zxcc_exit(zxcc_term()); /* Program termination */ break; case 2: /* CONST */ @@ -540,8 +538,8 @@ void cpmbios(byte *a, byte *b, byte *c, byte *d, byte *e, byte *f, printf("This program has attempted to call USERF, which " "is not implemented.\n"); #endif - zx_term(); - zx_exit(1); + zxcc_term(); + zxcc_exit(1); break; default: @@ -554,8 +552,6 @@ void cpmbios(byte *a, byte *b, byte *c, byte *d, byte *e, byte *f, fprintf(stderr,"%s: Unsupported BIOS call %d\n", progname, func); dump_regs(stderr,*a,*b,*c,*d,*e,*f,*h,*l,*pc,*ix,*iy); - zx_exit(1); + zxcc_exit(1); } - - Msg("BIOS service completion.\n"); } diff --git a/Tools/unix/zx/zxbdos.h b/Tools/unix/zxcc/zxbdos.h similarity index 100% rename from Tools/unix/zx/zxbdos.h rename to Tools/unix/zxcc/zxbdos.h diff --git a/Tools/unix/zx/zxcbdos.c b/Tools/unix/zxcc/zxcbdos.c similarity index 77% rename from Tools/unix/zx/zxcbdos.c rename to Tools/unix/zxcc/zxcbdos.c index 355dd687..e3eb1f2f 100644 --- a/Tools/unix/zx/zxcbdos.c +++ b/Tools/unix/zxcc/zxcbdos.c @@ -1,10 +1,8 @@ -#include "zx.h" +#include "zxcc.h" #include "zxbdos.h" #include "zxcbdos.h" -#if !(defined(__MINGW32__) || defined(_MSC_BUILD) || defined(__WATCOMC__)) -#include -#endif -#ifdef WIN32 + +#ifdef _WIN32 #include #endif @@ -76,7 +74,6 @@ void bdos_rdline(word line, word *PC) #ifndef USE_CPMIO - int cpm_bdos_6(byte e) { int c; @@ -100,11 +97,10 @@ int cpm_bdos_6(byte e) } #endif -#if defined(__MINGW32__) || defined(_MSC_BUILD) || defined(__WATCOMC__) - +#ifdef _WIN32 byte cin() { - if (_isatty(_fileno(stdin))) + if (_isatty(STDIN_FILENO)) return getch(); else return getchar(); @@ -112,7 +108,7 @@ byte cin() void cout(byte c) { - if (_isatty(_fileno(stdout))) + if (_isatty(STDOUT_FILENO)) putch(c); else putchar(c); @@ -120,30 +116,34 @@ void cout(byte c) int cstat() { - if (_isatty(_fileno(stdin))) + if (_isatty(STDIN_FILENO)) return _kbhit() ? 0xFF : 0; else return 0xFF; } -#else /* defined(__MINGW32__) || defined(_MSC_BUILD) || defined(__WATCOMC__) */ +#else /* def _WIN32 */ byte cin() { - return getchar(); + char c = 0; + + read(STDIN_FILENO, &c, 1); + return c; } void cout(byte c) { - putchar(c); + write(STDOUT_FILENO, &c, 1); + return; } int cstat() { int i; - ioctl(_fileno(stdin), FIONREAD, &i); - if (i > 0) return 0xff; + ioctl(STDIN_FILENO, FIONREAD, &i); + if (i > 0) return 0xFF; return 0; } diff --git a/Tools/unix/zx/zxcbdos.h b/Tools/unix/zxcc/zxcbdos.h similarity index 100% rename from Tools/unix/zx/zxcbdos.h rename to Tools/unix/zxcc/zxcbdos.h diff --git a/Tools/unix/zx/zx.c b/Tools/unix/zxcc/zxcc.c similarity index 61% rename from Tools/unix/zx/zx.c rename to Tools/unix/zxcc/zxcc.c index 88b20cb3..9668243b 100644 --- a/Tools/unix/zx/zx.c +++ b/Tools/unix/zxcc/zxcc.c @@ -1,8 +1,4 @@ -#include "zx.h" - -#ifdef WIN32 -#include "windows.h" -#endif +#include "zxcc.h" /* Global variables */ @@ -11,16 +7,26 @@ char **argv; int argc; byte cpm_drive; -char *mypath; - byte cpm_user; extern byte cpm_error; +char bindir80[CPM_MAXPATH] = ""; +char libdir80[CPM_MAXPATH] = ""; +char incdir80[CPM_MAXPATH] = ""; + byte RAM[65536]; /* The Z80's address space */ void load_comfile(void); /* Forward declaration */ static int deinit_term, deinit_gsx; +static void mkpath(char* fullpath, char* path, char* subdir); + +#ifndef _WIN32 +struct termios tc_orig; + +void raw_init(void); +void deinit_raw(void); +#endif void dump_regs(FILE *fp, byte a, byte b, byte c, byte d, byte e, byte f, byte h, byte l, word pc, word ix, word iy) @@ -39,8 +45,10 @@ char *parse_to_fcb(char *s, int afcb) RAM[afcb] = 0; memset(fcb, ' ', 11); - while (*s == ' ') ++s; - + while (s[0]==' ') /* skip leading spaces */ + { + s++; + } while (1) { if (s[0] == 0) break; @@ -73,10 +81,9 @@ void Msg(char *s, ...) va_list ap; va_start(ap, s); - printf("%s trace: ", progname); - vprintf(s, ap); - fflush(stdout); - if (s[strlen(s) - 1] == '\n') putchar('\r'); + fprintf(stderr, "%s trace: ", progname); + vfprintf(stderr, s, ap); + fflush(stderr); va_end(ap); #endif } @@ -97,8 +104,8 @@ void ed_fe(byte *a, byte *b, byte *c, byte *d, byte *e, byte *f, case 0xC2: fprintf(stderr,"%s: Incompatible BIOS.BIN\n", progname); - zx_term(); - zx_exit(1); + zxcc_term(); + zxcc_exit(1); case 0xC3: cpmbios(a,b,c,d,e,f,h,l,pc,ix,iy); @@ -107,8 +114,8 @@ void ed_fe(byte *a, byte *b, byte *c, byte *d, byte *e, byte *f, default: fprintf(stderr, "%s: Z80 encountered invalid trap\n", progname); dump_regs(stderr,*a,*b,*c,*d,*e,*f,*h,*l,*pc,*ix,*iy); - zx_term(); - zx_exit(1); + zxcc_term(); + zxcc_exit(1); } } @@ -121,54 +128,52 @@ void ed_fe(byte *a, byte *b, byte *c, byte *d, byte *e, byte *f, void load_bios(void) { - int bios_len; - - FILE * fp = NULL; - char biospath[CPM_MAXPATH + 1] = ""; + char dir[CPM_MAXPATH + 1], fname[CPM_MAXPATH + 1]; + char* q; + size_t bios_len; -#ifdef WIN32 + FILE* fp = fopen("bios.bin", "rb"); if (!fp) { - GetModuleFileName(NULL, biospath, sizeof(biospath)); - strcpy(strrchr(biospath, '\\'), "\\bios.bin"); - fp = fopen(biospath, "rb"); + strcpy(fname, bindir80); + strcat(fname, "bios.bin"); + fp = fopen(fname, "rb"); } + if (!fp) + { +#ifdef _WIN32 + dir[0] = 0; /* use strncat in case the path is very long */ + strncat(dir, _pgmptr, CPM_MAXPATH - 8); /* copy the executable path */ +#elif defined(__APPLE__) + uint32_t size = CPM_MAXPATH - 8; + _NSGetExecutablePath(dir, &size); #else - if (!fp) { - strcpy(biospath, mypath); - strcpy(strrchr(biospath, '/'), "/bios.bin"); - fp = fopen(biospath, "rb"); - } + readlink("/proc/self/exe", dir, CPM_MAXPATH - 8); /* allow room for bios.bin */ #endif - - if (!fp && BINDIR80) - { - strcpy(biospath, BINDIR80); - strcat(biospath, "bios.bin"); - fp = fopen(biospath, "rb"); + q = strrchr(dir, DIRSEPCH); + *++q = 0; + strcpy(fname, dir); + strcat(fname, "bios.bin"); + fp = fopen(fname, "rb"); } - - if (!fp) fp = fopen("bios.bin", "rb"); - if (!fp) { fprintf(stderr,"%s: Cannot locate bios.bin\n", progname); - zx_term(); - zx_exit(1); + zxcc_term(); + zxcc_exit(1); } bios_len = fread(RAM + 0xFE00, 1, 512, fp); if (bios_len < 1 || ferror(fp)) { fclose(fp); fprintf(stderr,"%s: Cannot load bios.bin\n", progname); - zx_term(); - zx_exit(1); + zxcc_term(); + zxcc_exit(1); } fclose(fp); Msg("Loaded %d bytes of BIOS\n", bios_len); } - /* * try_com() attempts to open file, file.com, file.COM, file.cpm and file.CPM * @@ -198,32 +203,33 @@ FILE *try_com(char *s) void load_comfile(void) { - int com_len; - char fname[CPM_MAXPATH + 1] = ""; + size_t com_len; + char fname[CPM_MAXPATH + 1]; FILE *fp; - if (BINDIR80) strcpy(fname, BINDIR80); - strcat(fname, argv[1]); + /* Look in current directory first */ + strcpy(fname, argv[1]); fp = try_com(fname); if (!fp) { - strcpy(fname, argv[1]); + strcpy(fname, bindir80); + strcat(fname, argv[1]); fp = try_com(fname); } if (!fp) { fprintf(stderr,"%s: Cannot locate %s, %s.com, %s.COM, %s.cpm _or_ %s.CPM\r\n", progname, argv[1], argv[1], argv[1], argv[1], argv[1]); - zx_term(); - zx_exit(1); + zxcc_term(); + zxcc_exit(1); } com_len = fread(RAM + 0x0100, 1, 0xFD00, fp); if (com_len < 1 || ferror(fp)) { fclose(fp); fprintf(stderr,"%s: Cannot load %s\n", progname, fname); - zx_term(); - zx_exit(1); + zxcc_term(); + zxcc_exit(1); } fclose(fp); @@ -245,7 +251,7 @@ unsigned int out() { return 0; } * the result to the command line. */ -void zx_xltname(char *name, char *pcmd) +void zxcc_xltname(char *name, char *pcmd) { char nbuf[CPM_MAXPATH + 1]; @@ -265,23 +271,31 @@ int main(int ac, char **av) { int n; char *pCmd, *str; + char* tmpenv; + argc = ac; argv = av; #ifdef __PACIFIC__ /* Pacific C doesn't support argv[0] */ - progname="ZX"; + progname="ZXCC"; #endif progname = argv[0]; - mypath = strdup(argv[0]); /* DJGPP includes the whole path in the program name, which looks * untidy... */ - str = strrchr(progname, '/'); - if (!str) str = strrchr(progname, '\\'); - if (str) progname = str + 1; + while ((str = strpbrk(progname, DIRSEP))) + progname = str + 1; + +#ifdef DEBUG + fprintf(stderr, "\n\n"); + Msg("Start of execution: "); + for (n = 0; n < argc; n++) + fprintf(stderr, " %s", argv[n]); + fprintf(stderr, "\n"); +#endif - if (_isatty(_fileno(stdin))) + if (_isatty(STDIN_FILENO)) Msg("Using interactive console mode\n"); else Msg("Using standard input/ouput mode\n"); @@ -290,18 +304,22 @@ int main(int ac, char **av) { fprintf(stderr,"%s: type lengths incorrect; edit typedefs " "and recompile.\n", progname); - zx_exit(1); + zxcc_exit(1); } if (argc < 2) { fprintf(stderr,"%s: No CP/M program name provided.\n",progname); - zx_exit(1); + zxcc_exit(1); } - - setmode(_fileno(stdin), O_BINARY ); - setmode(_fileno(stdout), O_BINARY ); +#ifdef _WIN32 + setmode(STDIN_FILENO, O_BINARY ); + setmode(STDOUT_FILENO, O_BINARY ); +#else + if (_isatty(STDIN_FILENO)) + raw_init(); +#endif /* Parse arguments. An argument can be either: @@ -319,12 +337,37 @@ int main(int ac, char **av) if (!fcb_init()) { fprintf(stderr, "Could not initialise CPMREDIR library\n"); - zx_exit(1); + zxcc_exit(1); } - xlt_map(0, BINDIR80); /* Establish the 3 fixed mappings */ - xlt_map(1, LIBDIR80); - xlt_map(2, INCDIR80); + /* allow environment variables to override default locations */ + /* two options are supported, explicit overrides for each directory + * (BINDIR80, LIBDIR80, INCDIR80) + * or a common directory prefix override (CPMDIR80) + * the explict override takes precedence + */ + if ((tmpenv = getenv("CPMDIR80"))) { + mkpath(bindir80, tmpenv, BIN80); /* use CPMDIR80 & std subdirs */ + mkpath(libdir80, tmpenv, LIB80); + mkpath(incdir80, tmpenv, INC80); + } + if ((tmpenv = getenv("BINDIR80"))) + mkpath(bindir80, tmpenv, ""); + + if ((tmpenv = getenv("LIBDIR80"))) + mkpath(libdir80, tmpenv, ""); + + if ((tmpenv = getenv("INCDIR80"))) + mkpath(incdir80, tmpenv, ""); + + Msg("BINDIR80=\"%s\"\n", bindir80); + Msg("LIBDIR80=\"%s\"\n", libdir80); + Msg("INCDIR80=\"%s\"\n", incdir80); + + xlt_map(0, bindir80); /* Establish the 3 fixed mappings */ + xlt_map(1, libdir80); + xlt_map(2, incdir80); + pCmd = (char *)RAM + 0x81; for (n = 2; n < argc; n++) @@ -342,17 +385,17 @@ int main(int ac, char **av) } else if (argv[n][0] == '+') { - zx_xltname(pCmd, argv[n]+1); + zxcc_xltname(pCmd, argv[n]+1); } else /* Translate a filename */ { strcat(pCmd, " "); - zx_xltname(pCmd, argv[n]); + zxcc_xltname(pCmd, argv[n]); } } pCmd[0x7F] = 0; /* Truncate to fit the buffer */ - RAM[0x80] = strlen(pCmd); + RAM[0x80] = (byte)strlen(pCmd); str = parse_to_fcb(pCmd, 0x5C); parse_to_fcb(str, 0x6C); @@ -401,10 +444,10 @@ int main(int ac, char **av) /* Start the Z80 at 0xFF00, with stack at 0xFE00 */ mainloop(0xFF00, 0xFE00); - return zx_term(); + return zxcc_term(); } -void zx_exit(int code) +void zxcc_exit(int code) { #ifdef USE_CPMIO if (deinit_term) cpm_scr_unit(); @@ -415,10 +458,13 @@ void zx_exit(int code) exit(code); } -int zx_term(void) +int zxcc_term(void) { word n; +#ifndef _WIN32 + deinit_raw(); +#endif //n = RAM[0x81]; /* Get the return code. This is Hi-Tech C */ //n = (n << 8) | RAM[0x80]; /* specific and fails with other COM files */ @@ -438,4 +484,69 @@ int zx_term(void) else return 0; } +/* helper function to build full path */ +/* make sure that a / or \ is present at the end of path + * before appending the subdir + */ +static void mkpath(char* fullpath, char* path, char* subdir) { + char* s; + strcpy(fullpath, path); + s = strchr(fullpath, '\0'); + if (*fullpath && !ISDIRSEP(s[-1])) /* make sure we have dir sep */ + *s++ = '/'; + strcpy(s, subdir); +} + +#ifndef _WIN32 +void raw_init(void) +{ + struct termios tc_raw; + + Msg("Enabling RAW Terminal IO\n"); + + if (tcgetattr(STDIN_FILENO, &tc_orig) == -1) + { + Msg("Failed to enable RAW Terminal IO - tcgetattr() failed\n"); + zxcc_exit(1);; + } + + //tc_raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); + //tc_raw.c_oflag &= ~(OPOST); + //tc_raw.c_cflag |= (CS8); + //tc_raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); + //tc_raw.c_cc[VMIN] = 1; + //tc_raw.c_cc[VTIME] = 0; + + tc_raw.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON); + tc_raw.c_oflag &= ~(OPOST); + tc_raw.c_cflag |= (CS8); + tc_raw.c_lflag &= ~(ECHO | ICANON | IEXTEN); + tc_raw.c_cc[VMIN] = 1; + tc_raw.c_cc[VTIME] = 0; + + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &tc_raw) == -1) + { + Msg("Failed to enable RAW Terminal IO - tcsetattr() failed\n"); + zxcc_exit(1); + } + + Msg("Enabled RAW Terminal IO\n"); + + return; +} + +void deinit_raw(void) +{ + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &tc_orig) == -1) + { + Msg("Failed to disable RAW Terminal IO - tcsetattr() failed\n"); + return; + } + + Msg("Disabled RAW Terminal IO\n"); + + return; +} + +#endif diff --git a/Tools/unix/zxcc/zxcc.doc b/Tools/unix/zxcc/zxcc.doc new file mode 100644 index 00000000..2f30a1ac --- /dev/null +++ b/Tools/unix/zxcc/zxcc.doc @@ -0,0 +1,207 @@ + zxcc v0.5.7 + + zxcc is a wrapper for the Hi-Tech C CP/M compiler, allowing it to be + used as a cross-compiler under UNIX. Version 0.5.0 also works with the + build tools necessary to assemble CP/M 3 (MAC, RMAC, LINK, GENCOM). + + New in this version: + * Compiles on boxes where sync() does not return int (reported by + multiple users). + * BDOS function 10 takes a pointer to unsigned char, thus allowing + input buffers longer than 128 bytes (Andy Parkins) + +Setting up + + Firstly, build the compiler. It should not be necessary to rebuild + bios.bin; but if you have to, it assembles using the z80asm assembler + (part of the z80pack emulation package which can be found on the Walnut + Creek CP/M CDROM) or the [1]ZMAC assembler (downloadable from + ). + + Previous versions of ZXCC could be compiled under DOS using DJGPP; this + may still be possible, but has not been tested since the build system + was changed to use the GNU autotools. + + This version of zxcc contains copies of the CPMIO and CPMREDIR + libraries, so you won't need to obtain them separately. + + You will need the tools you want to use; either the Hi-Tech C compiler + for CP/M <[2]http://www.hitech.com.au> or Digital Research's tools at + <[3]http://www.cpm.z80.de> Once you have obtained the tools, + documentation and possibly the library source, you need to decide where + to put the files. zxcc uses three directories: + * BINDIR80 (by default, /usr/local/lib/cpm/bin80) holds the compiler + itself. You should copy the compiler .com files (or MAC, RMAC etc.) + and bios.bin to this directory. + * LIBDIR80 (by default, /usr/local/lib/cpm/lib80) holds the C + libraries libc.lib, libf.lib, crtcpm.obj and rrtcpm.obj. + * INCDIR80 (by default, /usr/local/lib/cpm/include80) holds the + compiler .h files. + + The locations of these directories are normally set by the configure + script; you can override them by editing zxcc.h and uncommenting the + lines that redefine them. + + Once you have installed zxcc and the build tools, try building Hello + World: + + #include + void main() + { + printf("Hello World\n"); + } + + or for RMAC: + + CSEG + LXI D,HELLO + MVI C,9 + CALL 5 + RST 0 + HELLO: DB 'Hello World',13,10,'$' + + To compile the first example, type + + zxc hello.c + + ; if all goes well, you should end up with a file called hello.com. You + can test the resulting file by typing + + zxcc hello.com + + . + + To assemble the second example, type + + zxcc rmac.com hello + zxcc link.com hello + + and run it as above. NOTE: RMAC requires that lines be terminated with + CR/LF. You may need to put a unix2dos command in your makefile before + you invoke RMAC. + +Using zxcc + + For detailed instructions, see the documentation for Hi-Tech C or the + CP/M tools. zxcc behaves in the same way, but note the following + points: + + Program names + + The names of the programs have been changed between CP/M and UNIX; for + example, you would type + + zxc hello.c + + instead of + + c hello.c + + . The programs to use are: + + zxc + The equivalent of C.COM. + + zxas + The equivalent of ZAS.COM. + + zxlink + The equivalent of LINK.COM. + + zxlibr + The equivalent of LIBR.COM. + + All these programs work by converting their arguments to a form + suitable for zxcc, and then invoking zxcc. + + There are no front-end programs for the CP/M build tools; you will have + to enter arguments to these in the zxcc format given below. + + Filenames + + Where the documentation allows you to enter a CP/M filename, you should + instead enter a UNIX one. The filename itself (as opposed to any + directories in its path) must obey CP/M 8.3 naming conventions and be + all lowercase. + + Where the documentation requires a CP/M driveletter / user number + + -I2:C: + + you should enter a path complete with trailing slash: + + -I/usr/src/linux-80/include/ + +Technical + + zxcc emulates a subset of CP/M 3; hopefully enough to run the Hi-Tech C + compiler. It can be used as a limited general-purpose CP/M 3 emulator + provided the emulated program only uses a restricted subset of system + calls. + + zxcc behaves like the emulator com, allowing CP/M programs to be used + transparently from a UNIX prompt. However com: + * Emulates all of CP/M 2, rather than a subset of CP/M 3; + * Is designed for general use, not tailored to Hi-Tech C; + * Is written partly in assembly language and will only run on + 68000-based computers; + * Cannot map UNIX directories to CP/M drives; + * Contains some bugs connected with command parsing and file I/O. + + Syntax for zxcc is: + + zxcc comfile.com arg1 arg2 ... + + The comfile is the program to run; zxcc searches the current directory + and BINDIR80 for it. + + The arguments are parsed in this way: + * Any argument starting with a - sign is passed to the CP/M program + as-is, minus the leading - sign. + * Any argument starting with a + sign is parsed as a filename (see + below) and then concatenated to the previous argument. + * Any argument starting "+-" is concatenated without being parsed. + * All other arguments are parsed as filenames. The UNIX pathname is + converted to a CP/M driveletter. + + For example: + + zxcc foo.com --Q -A /dev/null --I +/dev/zero +-, +/foo/bar + + would pass these arguments to foo.com: + + -Q A d:null -Id:zero,e:bar + + The other programs are merely wrappers that convert their command lines + into the form required by zxcc. + +Errors + + Any errors raised by the zxcc runtime system will be prefixed with + zxcc:. Some errors you may encounter are: + + Unsupported BDOS call + Part of CP/M 3 that the program uses has not been emulated. Add + the required functionality to zxbdos.c and recompile. + + Z80 encountered invalid trap + The CP/M program being run attempted to call the zxcc runtime + system with an unknown call number. This will happen if the + program was written for my emulator "Joyce". + +Acknowledgements + + * Hi-Tech C was written by Hi-Tech Software. + * The Z80 emulation engine was written by Ian Collier. + * Thanks to Jacob Nevins, Andy Parkins and others for bug fix + suggestions. + __________________________________________________________________ + + + John Elliott, 28 March 2003 + +References + + 1. http://www.nenie.org/cpcip/index.html#zmac + 2. http://www.hitech.com.au/ + 3. http://www.cpm.z80.de/ diff --git a/Tools/unix/zx/zx.h b/Tools/unix/zxcc/zxcc.h similarity index 51% rename from Tools/unix/zx/zx.h rename to Tools/unix/zxcc/zxcc.h index dac69ce0..4d08949a 100644 --- a/Tools/unix/zx/zx.h +++ b/Tools/unix/zxcc/zxcc.h @@ -1,23 +1,44 @@ /* * Change the directories in these #defines if necessary. Note trailing slash. */ +#ifndef _WIN32 + #include "config.h" + #define ISDIRSEP(c) ((c) == '/') + #define DIRSEPCH '/' + #define DIRSEP "/" +#else + #include "config.h" + #define ISDIRSEP(c) ((c) == '/' || (c) == '\\') + #define DIRSEPCH '\\' + #define DIRSEP "/\\:" +#endif + +#ifndef CPMDIR80 + #ifdef _WIN32 + #define CPMDIR80 "d:/local/lib/cpm/" + #else + #define CPMDIR80 "/usr/local/lib/cpm/" + #endif +#endif -#include "config.h" +/* the default sub directories trailing / is required */ +#define BIN80 "bin80/" +#define LIB80 "lib80/" +#define INC80 "include80/" -#ifdef __MSDOS__ - #define BINDIR80 "d:/tools/cpm/bin80/" - #define LIBDIR80 "d:/tools/cpm/lib80/" - #define INCDIR80 "d:/tools/cpm/include/" -#else -/* Unless overridden, these are defined by autoconf. Note trailing slash. - #undef BINDIR80 - #undef LIBDIR80 - #undef INCDIR80 - #define BINDIR80 "/usr/local/lib/cpm/bin80/" - #define LIBDIR80 "/usr/local/lib/cpm/lib80/" - #define INCDIR80 "/usr/local/lib/cpm/include80/" -*/ +#ifndef BINDIR80 + #define BINDIR80 CPMDIR80 BIN80 +#endif +#ifndef LIBDIR80 + #define LIBDIR80 CPMDIR80 LIB80 #endif +#ifndef INCDIR80 + #define INCDIR80 CPMDIR80 INC80 +#endif + +extern char bindir80[]; +extern char libdir80[]; +extern char incdir80[]; #define SERIAL "ZXCC05" @@ -31,30 +52,42 @@ #include #include #include -#if defined(LINUX) || defined(DARWIN) -#include -#define _isatty(a) isatty(a) -#define _fileno(a) fileno(a) -#define setmode(a,b) -#define O_BINARY 0 +#ifdef HAVE_UNISTD_H + #include #endif -#ifdef WIN32 -#include +#ifdef _WIN32 + #include + #include + #define strcasecmp _stricmp + #ifndef STDIN_FILENO + #define STDIN_FILENO _fileno(stdin) + #define STDOUT_FILENO _fileno(stdout) + #define STDERR_FILENO _fileno(stderr) + #endif +#else + #include + #define _isatty(a) isatty(a) + #define _fileno(a) fileno(a) #endif #include #include #ifdef __MSDOS -#include + #include +#endif +#ifndef _WIN32 + #include + #include + #define _S_IFDIR S_IFDIR #endif /* Library includes */ #ifdef USE_CPMIO -#include "cpmio.h" + #include "cpmio.h" #endif #ifdef USE_CPMGSX -#include "cpmgsx.h" + #include "cpmgsx.h" #endif #include "cpmredir.h" /* BDOS disc simulation */ @@ -73,8 +106,8 @@ void cpmbios(byte *a, byte *b, byte *c, byte *d, byte *e, byte *f, void dump_regs(FILE *fp, byte a, byte b, byte c, byte d, byte e, byte f, byte h, byte l, word pc, word ix, word iy); void Msg(char *s, ...); -int zx_term(void); -void zx_exit(int code); +int zxcc_term(void); +void zxcc_exit(int code); byte cin(void); void cout(byte); @@ -87,8 +120,6 @@ extern char **argv; extern int argc; extern byte RAM[65536]; /* The Z80's address space */ -extern int usestdio; - /* Z80 CPU emulation */ #include "z80.h" diff --git a/Tools/unix/zxcc/zxcc.html b/Tools/unix/zxcc/zxcc.html new file mode 100644 index 00000000..502d8777 --- /dev/null +++ b/Tools/unix/zxcc/zxcc.html @@ -0,0 +1,200 @@ +zxcc v0.5.7 + +

zxcc v0.5.7

+ +

zxcc is a wrapper for the Hi-Tech C CP/M compiler, allowing it to +be used as a cross-compiler under UNIX. Version 0.5.0 also works with the build +tools necessary to assemble CP/M 3 (MAC, RMAC, LINK, GENCOM). + +

New in this version: +

    +
  • Compiles on boxes where sync() does not return int (reported by multiple +users). +
  • BDOS function 10 takes a pointer to unsigned char, thus allowing input +buffers longer than 128 bytes (Andy Parkins) +
+ +

Setting up

+ +

Firstly, build the compiler. It should not be necessary to rebuild bios.bin; +but if you have to, it assembles using the z80asm assembler (part of +the z80pack emulation package which can be found on the Walnut Creek +CP/M CDROM) or the +ZMAC assembler +(downloadable from <http://www.nenie.org/cpcip/index.html#zmac>). +

Previous versions of ZXCC could be compiled under DOS using +DJGPP; this may still be possible, but has not been tested since the build +system was changed to use the GNU autotools. + +

This version of zxcc contains copies of the CPMIO and CPMREDIR libraries, +so you won't need to obtain them separately. + +

You will need the tools you want to use; either the Hi-Tech C compiler for +CP/M <http://www.hitech.com.au> + +or Digital Research's tools at + +<http://www.cpm.z80.de> + +Once you have obtained the tools, documentation and possibly the library +source, you need to decide where to put the files. zxcc uses +three directories: + +

    +
  • BINDIR80 (by default, /usr/local/lib/cpm/bin80) + holds the compiler itself. You should copy the compiler .com files + (or MAC, RMAC etc.) and bios.bin to this directory. +
  • LIBDIR80 (by default, /usr/local/lib/cpm/lib80) + holds the C libraries libc.lib, libf.lib, crtcpm.obj and rrtcpm.obj. +
  • INCDIR80 (by default, /usr/local/lib/cpm/include80) + holds the compiler .h files. +
+ +

The locations of these directories are normally set by the configure +script; you can override them by editing zxcc.h and uncommenting the lines +that redefine them. + +

Once you have installed zxcc and the build tools, try +building Hello World: + +

+#include <stdio.h>
+void main()
+{
+ printf("Hello World\n");
+}
+
+ +or for RMAC: + +
+ CSEG
+
+ LXI D,HELLO
+ MVI C,9
+ CALL 5
+ RST 0
+
+HELLO: DB 'Hello World',13,10,'$' + +
+ +

To compile the first example, type

zxc hello.c
; if +all goes well, you should end up with a file called hello.com. You can +test the resulting file by typing
zxcc hello.com
. + +

To assemble the second example, type +

+ zxcc rmac.com hello
+ zxcc link.com hello +
+and run it as above. NOTE: RMAC requires that lines be terminated with CR/LF. +You may need to put a unix2dos command in your makefile before you invoke RMAC. + +

Using zxcc

+ +

For detailed instructions, see the documentation for Hi-Tech C or +the CP/M tools. zxcc behaves in the same way, but note the +following points: + +

Program names

+ +

The names of the programs have been changed between CP/M and UNIX; for +example, you would type

zxc hello.c
instead of +
c hello.c
. The programs to use are: + +
+
zxc
The equivalent of C.COM. +
zxas
The equivalent of ZAS.COM. +
zxlink
The equivalent of LINK.COM. +
zxlibr
The equivalent of LIBR.COM. +
+ +

All these programs work by converting their arguments to a form suitable +for zxcc, and then invoking zxcc. + +

There are no front-end programs for the CP/M build tools; you will have to +enter arguments to these in the zxcc format given below. + +

Filenames

+ +

Where the documentation allows you to enter a CP/M filename, you should +instead enter a UNIX one. The filename itself (as opposed to any directories in +its path) must obey CP/M 8.3 naming conventions and be all lowercase. +

Where the documentation requires a CP/M driveletter / user number +

-I2:C:
you should enter a path complete with + trailing slash:
-I/usr/src/linux-80/include/
+ +

Technical

+ +

zxcc emulates a subset of CP/M 3; hopefully enough to run the +Hi-Tech C compiler. It can be used as a limited general-purpose CP/M 3 +emulator provided the emulated program only uses a restricted subset of +system calls. +

zxcc behaves like the emulator com, allowing CP/M +programs to be used transparently from a UNIX prompt. However com: +

    +
  • Emulates all of CP/M 2, rather than a subset of CP/M 3; +
  • Is designed for general use, not tailored to Hi-Tech C; +
  • Is written partly in assembly language and will only run on 68000-based +computers; +
  • Cannot map UNIX directories to CP/M drives; +
  • Contains some bugs connected with command parsing and file I/O. +
+ +

Syntax for zxcc is: + +

+ zxcc comfile.com arg1 arg2 ... +
+ +

The comfile is the program to run; zxcc searches the current +directory and BINDIR80 for it. +

The arguments are parsed in this way: + +

    +
  • Any argument starting with a - sign is passed to the CP/M program as-is, + minus the leading - sign. +
  • Any argument starting with a + sign is parsed as a filename (see below) + and then concatenated to the previous argument. +
  • Any argument starting "+-" is concatenated without being parsed. +
  • All other arguments are parsed as filenames. The UNIX pathname is + converted to a CP/M driveletter. +
+

For example: +

+ zxcc foo.com --Q -A /dev/null --I +/dev/zero +-, +/foo/bar +
+would pass these arguments to foo.com: +
+ -Q A d:null -Id:zero,e:bar +
+ +

The other programs are merely wrappers that convert their command lines +into the form required by zxcc. + +

Errors

+ +

Any errors raised by the zxcc runtime system will be prefixed +with zxcc:. Some errors you may encounter are: + +

+
Unsupported BDOS call +
Part of CP/M 3 that the program uses has not been emulated. Add the +required functionality to zxbdos.c and recompile. +
Z80 encountered invalid trap +
The CP/M program being run attempted to call the zxcc runtime +system with an unknown call number. This will happen if the program was +written for my emulator "Joyce". +
+

Acknowledgements

+ +
    +
  • Hi-Tech C was written by Hi-Tech Software. +
  • The Z80 emulation engine was written by Ian Collier. +
  • Thanks to Jacob Nevins, Andy Parkins and others for bug fix suggestions. +
+
+
John Elliott, 28 March 2003
+ + diff --git a/Tools/unix/zx/zxdbdos.c b/Tools/unix/zxcc/zxdbdos.c similarity index 64% rename from Tools/unix/zx/zxdbdos.c rename to Tools/unix/zxcc/zxdbdos.c index f5f21f3b..36cbe532 100644 --- a/Tools/unix/zx/zxdbdos.c +++ b/Tools/unix/zxcc/zxdbdos.c @@ -1,88 +1,97 @@ -#include "zx.h" -#include "zxbdos.h" -#include "zxdbdos.h" - -/* This file used to deal with all disc-based BDOS calls. - Now the calls have been moved into libcpmredir, it's a bit empty round - here. - - ZXCC does a few odd things when searching, to make Hi-Tech C behave - properly. -*/ - - -/* If a file could not be found on the default drive, try again on a "search" - drive (A: for .COM files, B: for .LIB and .OBJ files) */ - -int fcbforce(byte *fcb, byte *odrv) -{ - byte drive; - char typ[4]; - int n; - - for (n = 0; n < 3; n++) typ[n] = fcb[n+9] & 0x7F; - typ[3] = 0; - - Msg("fcbforce: typ=%s, fcb=%hhx\r\n", typ, *fcb); - - drive = 0; - if (*fcb) return 0; /* not using default drive */ - //if ((*fcb) != 16) return 0; /* not using default drive */ - if (!strcmpi(typ, "COM")) drive = 1; - if (!strcmpi(typ, "LIB")) drive = 2; - if (!strcmpi(typ, "OBJ")) drive = 2; - if (!strcmpi(typ, "H ")) drive = 3; - - Msg("fcbforce: drive=%i\r\n", drive); - - if (!drive) return 0; - - *odrv = *fcb; - *fcb = drive; - return 1; -} - -/* zxcc has a trick with some filenames: If it can't find them where they - should be, and a drive wasn't specified, it searches BINDIR80, - LIBDIR80 or INCDIR80 (depending on the type of the file). - */ - -word x_fcb_open(byte *fcb, byte *dma) -{ - word rv = fcb_open(fcb, dma); - byte odrv; - - Msg("x_fcb_open: rv=%X\r\n", rv); - - if (rv == 0xFF) - { - if (fcbforce(fcb, &odrv)) - { - rv = fcb_open(fcb, dma); - Msg("x_fcb_open: rv=%X\r\n", rv); - *fcb = odrv; - } - } - return rv; -} - - - -word x_fcb_stat(byte *fcb) -{ - word rv = fcb_stat(fcb); - byte odrv; - - if (rv == 0xFF) - { - if (fcbforce(fcb, &odrv)) - { - rv = fcb_stat(fcb); - *fcb = odrv; - } - } - return rv; -} - - - +#include "zxcc.h" +#include "zxbdos.h" +#include "zxdbdos.h" + +/* This file used to deal with all disc-based BDOS calls. + Now the calls have been moved into libcpmredir, it's a bit empty round + here. + + ZXCC does a few odd things when searching, to make Hi-Tech C behave + properly. +*/ + + +/* If a file could not be found on the default drive, try again on a "search" + drive (A: for .COM files, B: for .LIB and .OBJ files) */ + +int fcbforce(byte *fcb, byte *odrv) +{ + byte drive; + char nam[9]; + char typ[4]; + int n; + + for (n = 0; n < 8; n++) nam[n] = fcb[n+1] & 0x7F; + nam[8] = 0; + for (n = 0; n < 3; n++) typ[n] = fcb[n+9] & 0x7F; + typ[3] = 0; + + drive = 0; + if (*fcb) return 0; /* not using default drive */ + + /* Microsoft BASIC compiler run-time */ + if (!strcmp(nam,"BCLOAD ") && !strcmp(typ, " ")) drive = 2; + + /* HI-TECH C options help file */ + if (!strcmp(nam,"OPTIONS ") && !strcmp(typ, " ")) drive = 1; + + /* binaries, libraries and object files */ + if (!strcmp(typ, "COM")) drive = 1; + if (!strcmp(typ, "LIB")) drive = 2; + if (!strcmp(typ, "OBJ")) drive = 2; + + /* some extras for messages, overlays, includes */ + if (!strcmp(typ, "HLP")) drive = 1; + if (!strcmp(typ, "MSG")) drive = 1; + if (!strcmp(typ, "OVR")) drive = 1; + if (!strcmp(typ, "REL")) drive = 2; + if (!strcmp(typ, "H ")) drive = 3; + + if (!drive) return 0; + + *odrv = *fcb; + *fcb = drive; + return 1; +} + +/* zxcc has a trick with some filenames: If it can't find them where they + should be, and a drive wasn't specified, it searches BINDIR80, + LIBDIR80 or INCDIR80 (depending on the type of the file). + */ + +word x_fcb_open(byte *fcb, byte *dma) +{ + word rv = fcb_open(fcb, dma); + byte odrv; + + if (rv == 0xFF) + { + if (fcbforce(fcb, &odrv)) + { + rv = fcb_open(fcb, dma); + *fcb = odrv; + } + } + return rv; +} + + + +word x_fcb_stat(byte *fcb) +{ + word rv = fcb_stat(fcb); + byte odrv; + + if (rv == 0xFF) + { + if (fcbforce(fcb, &odrv)) + { + rv = fcb_stat(fcb); + *fcb = odrv; + } + } + return rv; +} + + + diff --git a/Tools/unix/zx/zxdbdos.h b/Tools/unix/zxcc/zxdbdos.h similarity index 100% rename from Tools/unix/zx/zxdbdos.h rename to Tools/unix/zxcc/zxdbdos.h diff --git a/Tools/zx/ReadMe.txt b/Tools/zx/ReadMe.txt deleted file mode 100644 index 90a7b1c3..00000000 --- a/Tools/zx/ReadMe.txt +++ /dev/null @@ -1,12 +0,0 @@ -ZX Command - -An adaptation of zxcc-0.5.6 by Wayne Warthen - -This is simply a stripped down variant of John Elliott's zxcc package that -runs under a Windows command line (32 or 64 bit Windows). It contains -only one command, "zx", which is generally equivalent to the original -zxcc command. - -Please see http://www.seasip.info/Unix/Zxcc/ for more information on zxcc. - -Refer to the zx.html document for usage information. diff --git a/Tools/zx/bios.bin b/Tools/zx/bios.bin deleted file mode 100644 index b20e62d901a87453f143ee811a912600c740df47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 384 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 z 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%0D~18g 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 CP/M Command Line Emulator - -

zx CP/M Command Line Emulator

- -

zx allows execution of CP/M 2.2 and 3.X application from a -Windows command line. It is compatible with Windows XP and greater (both -32 and 64 bit).

- -

zx is basically a port of a subset of the zxcc program by John Elliott. -The GPLv2 licensing carries forward. Please refer to the - -zxcc web page for more information.

- -

While the original zxcc package was generally intended to allow -execution of the Hi-Tech C CP/M compiler under Unix, zx is slightly -more general and intended to allow running most CP/M tools. Specific -changes were incorporated to improve interactice console operation of -CP/M applications. Additionally, Curt Mayer added case insensitivity -for filenames under Unix variants.

- -

Setup

- -

The zx application (zx.exe) may be copied to any directory for execution. -The bios.bin file must be copied to the same directory. For ease of use, -you will probably want the directory to part of your PATH environment -variable so that you can run the tool from any location.

- -

You will also need the CP/M applications that you want to run. -zx will load files fromthe current directory or one of the following -directories based on file type. Any of the following environment -variables may be defined to determine where zx searches for the -respective file types:

- -
    -
  • ZXBINDIR may contain a single path which will -be searched for executable files (usually *.com)
  • -
  • ZXLIBDIR may contain a single path which will -be search for library files (usually *.lib)
  • -
  • ZXINCDIR may contain a single path which will -be searched for include files (usually *.inc)
  • -
- -

Usage

- -

In general CP/M applications are executed by prefixing the CP/M command -line with "zx". So for example, you could assemble a test.asm using -rmac with a command line like:

- -
zx rmac hello
- -

In this case, rmac.com would need to be in the directory specified by -environment variable ZXBINDIR or in the current directory. Also, -hello.asm would need to be in the current directory.

- -

Filenames

- -

Where you would normally enter a CP/M filename you instead enter -a Windows filename. Note that you will need to use a forward slash -instead of the traditional backslash as a directory separator. The -filename itself (as opposed to any directories in -its path) must obey CP/M 8.3 naming conventions.

- -

Where the documentation requires a CP/M drive letter/user number -you should enter a path complete with trailing slash, for example:

-
-I/usr/src/linux-80/include/
- -

Technical

- -

zx emulates a subset of CP/M 3; hopefully enough to run the -most CP/M tools. It can be used as a limited general-purpose CP/M 3 -emulator provided the emulated program only uses a common subset of -system calls.

- -

Syntax for zx is:

- -
-zx comfile.com arg1 arg2 ... -
- -

The comfile is the program to run; zx searches the current -directory and ZXBINDIR for it.

- -

The arguments are parsed in this way:

- -
    -
  • Any argument starting with a - sign is passed to the CP/M program as-is, -minus the leading - sign. -
  • Any argument starting with a + sign is parsed as a filename (see below) -and then concatenated to the previous argument. -
  • Any argument starting "+-" is concatenated without being parsed. -
  • All other arguments are parsed as filenames. The path is -converted to a CP/M driveletter. -
- -

For example: -

-zx foo.com --Q -A /src/main --I +/src/sub +-, +/foo/bar -
- -

would pass these arguments to foo.com:

- -
--Q A d:main -Id:sub,e:bar -
- -

The other programs are merely wrappers that convert their command lines -into the form required by zx.

- -

Errors

- -

Any errors raised by the zx runtime system will be prefixed -with zx:. Some errors you may encounter are:

- -
-
Unsupported BDOS call
-
Part of CP/M 3 that the program uses has not been emulated. Add the -required functionality to zxbdos.c and recompile.
-
Z80 encountered invalid trap
-
The CP/M program being run attempted to call the zx runtime -system with an unknown call number.
-
- -

Acknowledgements

- -
    -
  • zxcc was written by John Elliott
  • -
  • Hi-Tech C was written by Hi-Tech Software.
  • -
  • The Z80 emulation engine was written by Ian Collier.
  • -
  • Thanks to Jacob Nevins, Andy Parkins and others for bug fix suggestions.
  • -
- - diff --git a/Tools/zx/zxdbg.exe b/Tools/zx/zxdbg.exe deleted file mode 100644 index 598ace60d8893647757c8ceddc154c1dad81467f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102400 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 diff --git a/Tools/zx/COPYING b/Tools/zxcc/COPYING similarity index 100% rename from Tools/zx/COPYING rename to Tools/zxcc/COPYING diff --git a/Tools/zxcc/ReadMe.txt b/Tools/zxcc/ReadMe.txt new file mode 100644 index 00000000..ba94bf5d --- /dev/null +++ b/Tools/zxcc/ReadMe.txt @@ -0,0 +1,86 @@ +This is an adaptation of zxcc-0.5.7 for RomWBW by Wayne Warthen. + +In general, this is a stripped down variant of John Elliott's zxcc package that +runs under a Windows command line (32 or 64 bit Windows), Linux, or MacOS. +This adaptation implements only the main "zxcc" command. The other programs +(zxc, zxas, zxlink, and zslibr) are not inluded here because they are fairly +specific to Hi-Tech C. + +Please see http://www.seasip.info/Unix/Zxcc/ for more information on the original +version of zxcc. Also, refer to https://github.com/agn453/ZXCC which has an +updated version of the code. + +The included zxcc.html documentation is from the original version, so it does not +reflect the changes made here. + +To build under Open Watcom, use Build-OW.cmd. To build under Microsoft Visual C, +use Build-VC.cmd. To build under Linux or MacOS, use the Makefile. + +The GPL status of everything remains in place and carries forward. + +December 5, 2014 + +After struggling to get the entire zxcc package to build nicely using autoconf, +I finally gave up and took a much more direct approach. I have extracted just +the source files needed and created a simple batch file to build the tool. I +realize this could be done much better, but I cheated in the interest of time. + +The one "real" change I made in the source code was that I modified the tool +to look for bios.bin in the same directory as the executable is in. This +just makes it much easier to set up (for me, anyway). + +Wayne Warthen +wwarthen@gmail.com + +March 15, 2017 + +- Updated to compile under Open Watcom. +- Implemented BDOS console status function. +- Set stdin and stdout to binary mode at startup. + +August 21, 2021 + +- Incorporated filename case insensitivity changes from Curt Mayer +- Incorporated fixes from Tony Nicholson at https://github.com/agn453/ZXCC + - Emulation of CP/M BDOS function 60 (call resident system extension) + should be disabled and return 0xFF in both the A and L registers. + - Change cpm_bdos_10() to return an unsigned result to avoid buffer + size being interpreted as negative. + - Fix the emulation of Z80 opcodes for IN (HL),(C) and + OUT (C),(HL) - opcodes 0xED,0x70 and 0xED,0x71 respectively. + This is noted in Fred Weigel's AM9511 arithmetic processing unit + emulation from https://github.com/ratboy666/am9511 in the howto.txt + description. NB: I have not included Fred's am9511 support at this + time into ZXCC. +- Fixed parse_to_fcb function in zxcc.c to handle parsing second automatic + FCB from command line + +Wayne Warthen +wwarthen@gmail.com + +--WBW 4:09 PM 8/21/2021 + +January 9, 2022 + +- Running zxcc under WSL (Windows Subsystem for Linux) was gererating output + that was correct but did not match standard Windows or Linux runs. This + turned out to be an assumption in a few places in the code that reading + into a buffer would not modify the area of the buffer that was beyond + the space required by the data being read. Under WSL, this "slack" space + was mangled. I made changes in these locations to clean up the slack + space after such reads. This fixed WSL runs to produce binary identical + output. Although only required by WSL, the changes cause no problems for + other environments and are actually correct per POSIX. + +--WBW 11:56 AM 1/9/2022 + +- I have attempted to sync my code up with the latest code found in Tony + Nicholson's GitHub repo at https://github.com/agn453/ZXCC. The most + significant difference in my code is that I am using the WIN32 API + for all disk I/O. Although the file tracking code is retained, I have + found this mechanism to fail insome scenarios. By using the WIN32 API + I can achieve the same file sharing attributes as Unix which makes the + file tracking mechanism optional. + +--WBW 9:34 AM 2/10/2022 + diff --git a/Tools/unix/zx/cpm/bios.bin b/Tools/zxcc/bios.bin similarity index 100% rename from Tools/unix/zx/cpm/bios.bin rename to Tools/zxcc/bios.bin diff --git a/Tools/zxcc/zxcc-src.zip b/Tools/zxcc/zxcc-src.zip new file mode 100644 index 0000000000000000000000000000000000000000..16bedad54b5b901c188b9e649c5088963527bb78 GIT binary patch literal 69549 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 literal 0 HcmV?d00001 diff --git a/Tools/zxcc/zxcc.exe b/Tools/zxcc/zxcc.exe new file mode 100644 index 0000000000000000000000000000000000000000..54681729808f2e75d650385f6acb9dca08afb9fd GIT binary patch literal 95744 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%0A7bG8>c3;xuqRSWOSHxPTzp;o52O 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%0D#er1=?3rVj@RO#UArw}7| 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 I|0eD~0V9dMbpQYW literal 0 HcmV?d00001 diff --git a/Tools/zxcc/zxcc.html b/Tools/zxcc/zxcc.html new file mode 100644 index 00000000..502d8777 --- /dev/null +++ b/Tools/zxcc/zxcc.html @@ -0,0 +1,200 @@ +zxcc v0.5.7 + +

zxcc v0.5.7

+ +

zxcc is a wrapper for the Hi-Tech C CP/M compiler, allowing it to +be used as a cross-compiler under UNIX. Version 0.5.0 also works with the build +tools necessary to assemble CP/M 3 (MAC, RMAC, LINK, GENCOM). + +

New in this version: +

    +
  • Compiles on boxes where sync() does not return int (reported by multiple +users). +
  • BDOS function 10 takes a pointer to unsigned char, thus allowing input +buffers longer than 128 bytes (Andy Parkins) +
+ +

Setting up

+ +

Previous versions of ZXCC could be compiled under DOS using +DJGPP; this may still be possible, but has not been tested since the build +system was changed to use the GNU autotools. + +

This version of zxcc contains copies of the CPMIO and CPMREDIR libraries, +so you won't need to obtain them separately. + +

You will need the tools you want to use; either the Hi-Tech C compiler for +CP/M <http://www.hitech.com.au> + +or Digital Research's tools at + +<http://www.cpm.z80.de> + +Once you have obtained the tools, documentation and possibly the library +source, you need to decide where to put the files. zxcc uses +three directories: + +

    +
  • BINDIR80 (by default, /usr/local/lib/cpm/bin80) + holds the compiler itself. You should copy the compiler .com files + (or MAC, RMAC etc.) and bios.bin to this directory. +
  • LIBDIR80 (by default, /usr/local/lib/cpm/lib80) + holds the C libraries libc.lib, libf.lib, crtcpm.obj and rrtcpm.obj. +
  • INCDIR80 (by default, /usr/local/lib/cpm/include80) + holds the compiler .h files. +
+ +

The locations of these directories are normally set by the configure +script; you can override them by editing zxcc.h and uncommenting the lines +that redefine them. + +

Once you have installed zxcc and the build tools, try +building Hello World: + +

+#include <stdio.h>
+void main()
+{
+ printf("Hello World\n");
+}
+
+ +or for RMAC: + +
+ CSEG
+
+ LXI D,HELLO
+ MVI C,9
+ CALL 5
+ RST 0
+
+HELLO: DB 'Hello World',13,10,'$' + +
+ +

To compile the first example, type

zxc hello.c
; if +all goes well, you should end up with a file called hello.com. You can +test the resulting file by typing
zxcc hello.com
. + +

To assemble the second example, type +

+ zxcc rmac.com hello
+ zxcc link.com hello +
+and run it as above. NOTE: RMAC requires that lines be terminated with CR/LF. +You may need to put a unix2dos command in your makefile before you invoke RMAC. + +

Using zxcc

+ +

For detailed instructions, see the documentation for Hi-Tech C or +the CP/M tools. zxcc behaves in the same way, but note the +following points: + +

Program names

+ +

The names of the programs have been changed between CP/M and UNIX; for +example, you would type

zxc hello.c
instead of +
c hello.c
. The programs to use are: + +
+
zxc
The equivalent of C.COM. +
zxas
The equivalent of ZAS.COM. +
zxlink
The equivalent of LINK.COM. +
zxlibr
The equivalent of LIBR.COM. +
+ +

All these programs work by converting their arguments to a form suitable +for zxcc, and then invoking zxcc. + +

There are no front-end programs for the CP/M build tools; you will have to +enter arguments to these in the zxcc format given below. + +

Filenames

+ +

Where the documentation allows you to enter a CP/M filename, you should +instead enter a UNIX one. The filename itself (as opposed to any directories in +its path) must obey CP/M 8.3 naming conventions and be all lowercase. +

Where the documentation requires a CP/M driveletter / user number +

-I2:C:
you should enter a path complete with + trailing slash:
-I/usr/src/linux-80/include/
+ +

Technical

+ +

zxcc emulates a subset of CP/M 3; hopefully enough to run the +Hi-Tech C compiler. It can be used as a limited general-purpose CP/M 3 +emulator provided the emulated program only uses a restricted subset of +system calls. +

zxcc behaves like the emulator com, allowing CP/M +programs to be used transparently from a UNIX prompt. However com: +

    +
  • Emulates all of CP/M 2, rather than a subset of CP/M 3; +
  • Is designed for general use, not tailored to Hi-Tech C; +
  • Is written partly in assembly language and will only run on 68000-based +computers; +
  • Cannot map UNIX directories to CP/M drives; +
  • Contains some bugs connected with command parsing and file I/O. +
+ +

Syntax for zxcc is: + +

+ zxcc comfile.com arg1 arg2 ... +
+ +

The comfile is the program to run; zxcc searches the current +directory and BINDIR80 for it. +

The arguments are parsed in this way: + +

    +
  • Any argument starting with a - sign is passed to the CP/M program as-is, + minus the leading - sign. +
  • Any argument starting with a + sign is parsed as a filename (see below) + and then concatenated to the previous argument. +
  • Any argument starting "+-" is concatenated without being parsed. +
  • All other arguments are parsed as filenames. The UNIX pathname is + converted to a CP/M driveletter. +
+

For example: +

+ zxcc foo.com --Q -A /dev/null --I +/dev/zero +-, +/foo/bar +
+would pass these arguments to foo.com: +
+ -Q A d:null -Id:zero,e:bar +
+ +

The other programs are merely wrappers that convert their command lines +into the form required by zxcc. + +

Errors

+ +

Any errors raised by the zxcc runtime system will be prefixed +with zxcc:. Some errors you may encounter are: + +

+
Unsupported BDOS call +
Part of CP/M 3 that the program uses has not been emulated. Add the +required functionality to zxbdos.c and recompile. +
Z80 encountered invalid trap +
The CP/M program being run attempted to call the zxcc runtime +system with an unknown call number. This will happen if the program was +written for my emulator "Joyce". +
+

Acknowledgements

+ +
    +
  • Hi-Tech C was written by Hi-Tech Software. +
  • The Z80 emulation engine was written by Ian Collier. +
  • Thanks to Jacob Nevins, Andy Parkins and others for bug fix suggestions. +
+
+
John Elliott, 28 March 2003
+ + diff --git a/Tools/zxcc/zxccdbg.exe b/Tools/zxcc/zxccdbg.exe new file mode 100644 index 0000000000000000000000000000000000000000..543aac00e58689b1c57506603e428e465ae1524e GIT binary patch literal 104448 zcmeFa34Bvk7C-({x};Ee1wj!(idF~2rEwWWtE6ZUmue{%6|IU&jk|*hZd3wE@V&&0 zj5CZnBMyj;I696SSc_uP)=(Cm78opr(E=6UGgZqnwNz<;-*fJJNeV44ccTSvk^Q5tzEpQNPxW`;sSnt zX+6J)qJHkQBc|1TEJ;&sZDm1su6X2# z$MC803inX@GnoEl(I4y7x!WN-q{(x4(!;i9N}w=%^4uL1DR!nVD3FS@y{OMybLI`D zRXLJ#Ftu+=jx$a|?x|8k7e9E4mJ*%Hm?TO_m&r#GHNr}~aI!<+Gg&xf;5H-fa zwy;vC9M$G|<1@SDab;+K|0l*)MrdNz#c5QiVBG4N&#JXI-f-=8)r1OyK>P3`09x#A zNnMit`UI)SdF6rvDO8%}yy>|DNiE$MD&40I;ofBhORN=?s?9*P{ASyr-Hvy)WM61T z`?Tvyxz;?Y^yKc#^a-E~kL5BRW`;n`Ij^RbY@}YPR z#xonwEIh4OtF77tXGxO2iE0`SL8q_9n*rZ6z{kL8kD?84O_nwSQlo+fxt5AIG&&qL z4Mk0Z@yy0E3r}kiYF(6%x*ko`<&M{NI_k28QCnFs0~Hk6!u&GSd>M?F0KQ}!&n)9< z*1#~^21ZceNKHA=)ulb0VS+dvZ#RNZhD$_&Ga;k23)d5?6i=Po zl8tEPQvj;sPxzyi*8#Utf7pF`W!*ENieKwQU02s56MZ-0w^5u58S#rnsW$hmE5Aoq zL;fZ}5FE02ae)-&cS*aIid-N6sQm%)&_c==wOh=3zCk_7?Q~H*sh!V=@=<@A`&R~K zmI4MrndWtZGG6E&L76-7wo;<*5uqxi*Ct5nZY>|}s#V^0%gpq)iCHKF@@k+?|IQ{>#w z8Sm|$G0Yj=*P5B6-%)LscF*)@k?Bk`QwC=`p?juTB9k0iNN@p$5&&xp(~!GX3^@=@ z(!O6~vJv%jNfs~|EJ`();y4sBUO%Twh^z9FxyphJ2bCF+DD#FW)8;Ul%En8GLIJpM-T%{ab6Oy z_;*}!ww4#K_$a)otz5OX6h$%QBvd|TouyX$J#rgWO?H-|5-saHVva2RQ!t4WB_(Zr zEn%@*L_QD^8k2(wng2k1a-3u8LJRi+16tu&RLifR!Z#2Zp&8$U1kT}9-)t0t#9wL! zUkrmrt%!d zxY`&zbHP;SlV+IcxYBpvG;tcIHmk} zlYB=!X_9ZOs8mpH1r1jkv#4(n>f?9usSl#so-x!J_i*Rg@$#|N+!K*$7K&EffN$C+ zWLG2T_!%p2LtL$@AbF;>A;ZdhkWjJdPe@&>eNG8(N@(~qCv2iBJXFQ+M27~hRFf)L zPM-txdFDZ%sY30K^!fMndCEbbse0`Je0CBb&Sxplm+dS*oK)2L3Z*m{DU{n;Nhwj0 z!UG3bdF3Qvh4NQ`XQX%MzK$$UQ5uz~K=sl}`lES~Cdes=Nc#nuJ=BI^>O9XmW8H&1 z4_Z!vCND|>TRja)7rR>hl*u01l@d%%4`jnENb_`@;vQDH24Eo9Oyr8!GI-vE*oU5u zvF@}`ktH_R%yR|uh~YXo9Yu1$`4{T$uC6W?{c3HrV2-41fe?J&1Hh4E!ngQ#7Xf?@ z-X=TOQI|L370kKvR-{AUPu$dn;vA_fVZyPXxe5xpN*#N!UNel@km!r`3D|(;Ws*!A@z7uhBV;s^IPc8 zU>ZSECnzbw;!^s5Lf=nmq`&>U_*hc_HGH%3}j@3Zh_ecMPMYavmDaE#} zZD~_r#H6~jmrTQRY}%#x3qkb2z{-hutLRJpzYwKjqn1!YRO$;0rmt(er$3d;?&1Pn zY4j~HBzsYT1mdLTbtxOm=6)wZla+bD>vA6rV-es^ac(CZKGDWFR2!yUS8WU9k28x} zxfBpho(hfhsWuM+ORWWdUq;JnwP&2HQt@fk63&dnhEbz)K#{GpfwtEa6&pKFw|#KYwyy4@}5sX zNG_R&SD-(|Ha4k|vdsRJ-xfA2wV=qib!DT{M6yZ$D(agN`P7Io;_DHaQoM2?+Nj+2 zEI{1}byPu7q7B>cuTd7V-&d>kWpg{E)LCio(i9fBR%@RbTUFm)NnKT=YBh}b;{kxW zH707>{fYISZhc5X>3WeS~&rk z0Ef553Pveu(MChB*fV|5 z-iC13D6EJnoZh8)E4b(7*B=q*&?#lPsS7 z<6U2&R6s(x+&Smex<1oc2N1XDe@~Ivs6H7H?dvd2K)fy4Me1g?v_<`AASHJWbEoRq z=WQSFN(GMkE+LjeLM%NrsY@-~x7yK4RmJ*x%UdPc_b0pu9nIQ4vQ``#>^@(Bl1f`b zla9q$tnEr$h5@BriS9tVtqqp!Glp6v4YWv8ilwUJ1rkrse+UMnH)y#P@%IjGu~1A$ zIq92o@bAHkM~-A2sy_romIW`i=7l}Yt!3v+cK3ilI`Cu7_sH|E$H$;UgAItu1T)Ju z08DHDfVkG%l3%3OuOwC%v&>p;UYPhUG}#hxRA@CYor5J64C+b()KV8M$eIptqXqpX zOLeH^J+&cPAbT{6055xr^9%y*5%{a13u2>#j?LOCL_*gNRjVM9j>#cJHF_h%wU>~L zv|23#X@JkP#BY)S-!*`bnfW4&tCCjr(?E)CP3{~e;$P!R^X?z-wg!2W$1In4&)ljx^>2`U^APJ+e(sHPe zjuvqBkjc(Vh*}>(epGY;EF#(O{av$93KhN{ENR7P3f*AQ>c1zZbq_*R`#ppTXVsmk z>&n;$mfO^MB|YGX=FW*u93U}|Diiy64OuW3_CiE(_P?Pb)ao*@|BwXieOIRuwrMQ2 zMJ%pV&lQ=Twn!?y^uN=K0 zd4sw~t2@eI0%hXu%r)93XxQk)n??m4YeQE|*EStvu=JT!i{oRh8VR8*W-y!Qa9WF2 z1pLn}j}k-3zs&)~fDO-sS>t8@5gdsMD(_iJtijE!P9rvC(G`Pj#vU2Ov@_mg)ibvx z6*2N3iHV`y=YYk|n?Yc8ulD6Irmk8GvCzm(`;TcbS$ zYL{WgwLi6d;KZrU`-wqb6{TbSo%1NVh@+`$E%*{vln^U91ksX}1d#zyy_f+lp?0*t zf%;3Rv7(TlrbtE35LH!-s)8dZJvfB&T?i9EUCtK?L*>odYG4fm zplxCrJYuUI&4h1^wQV3_AU&=Unjn7K$GbCFA;c_`R7VpWK8_~sbPOW!cHfFFw5HER z>CnPwK`m7A8u%vUr$`aE7A$Gfu0?Byr~ovt)@gHU@reiM&|)z_Pex{Qfa)hw)rBvF z7Ey&5lVHr#U~7Z^)ueY&7!2HWNZmXLy^&)z`v(aPa~0kvJKrHn)B-7J-&@`+$^JPs z9@9OpGmN22B4agrcZYTWMh}hQn}Q{p_}GLL@wNilVh-`X3uqH>VYBclTG%Lje7x|| zc;V&o0#AqnU2dy?tLz^LIpgng4R_WMl*ciYsU(W57<-JA*ip`p=v#W?TMMv2VzZT8 zn3#8?6*&Fg6_y$-Q{ic?%t12f^ILp?^}E)<8Pr?lY50;x@>5#^S&RPKVEw?X*;tJd za7XlmmDdk>U^1<}e`qLGhPk9&3F}>{4y7JBK^YqRBAR}xEgW~Df;%K_UIjxyCfa7( z2Dku+dcHf?b&==0yxDy{-;JA-R-jxzCI+|Q&^9j_dSO@E1m*gZz6qS;>B^g(=II*u z=-{NU?u?Zr(PLBXvE`Uo%pTLC%s#2r+hLjWg?E3-oE;%x>1HSpQd0f%vmdA@PHi>4 zzWvCCd>dU?ph?`Vp3Z{VuX{R+=Deb`o@}>mRnpalgCzJlC)D&yDTN?>}?Etik!Gx`ySS>>81u6WfuW=^Ek-yK~=7MPc2IKmIl3 zQ4hTfGgXS+2E3K;dlw^Eih1$wI?ub`;yTv9M)s4wBLg>7fEV;;qGgYgq8C$Y7oZ(0 zQY{^pe<~9)^>Zn`yam|@i4T2BTDlx9%7kovBoh2>vTr|7fqDXzIt=30ooWlm($t2r zWUU#D8yEGHRxsk@qJEZf2PEAW|#{yYVI!VDM#c@wbY&XHHN!s}`co<+uM%yLDW z#UuMZLEk(NWl1Edz`^=0D8uUx1(gjX32U`E7+54p-ZZ~dHj58s_yASbO4day+k<4d zR{J-&FM(-S5eEGxbzS0LGwY~OD!41VqLqfFR7KUf`&<%h1|EIaqgH(OoO7-_6Bw4~ zU513{MMqmCy?{Omm+K>72C}<_tpO<|X+vQRi(aF#M=HTN`v|NC?Fqc=X;jwqdyW8B z0BBTHR^)6WIKDt41e||E`4!sP*+Pn4Wah~D19E&Qa;S|45b4NeW;l^DydW~f+gXlf zLpAE{>~fEGo=q9NoFP^FMCSTsUp|Ok(FH5i97>^rLD7Qj1L~e=!9X}0hmZ&fOwNMI zwqw9b^g+@VqE)pOgX&#W61sLcI?|x+gakw4RwO@q=ZqfejM4JZrNSICg}DQCKcSRHINgr z+uI7#JnmbjI`5&HibT^>yN2YGv50AM*O0|{EAqFwGAgb@^RcvwiFgz_Rmz{k`Lq06 z-Gc?rWh5BNF*PO&TzrQP!ZXS$AmQWBCzN!)DMT0+Q4q!K0#;KKA;rqnrq?3p>(tT; zuEYwdKM8N-mIP8T%p{$77|HJs0QI&)RkMB97cr(FyJx=dPY{Pu4-j{ks3|z29X1ve z&WN{Q4AFbh)XC0G)Yhe(Bl`|1La!qn)!hQkgb;Z)5&%4~R*)m{Rg8rix|C-rHiqvsi%Cp9-BR_#n^U+5~bF#6m zMuH_Rk?k3lwQ4)L7243TU}>{|Yq^2{CxAELTDuLj za+BdngzIy@U=_8)8y&9A0~~;K54t+8y*yLxK%^eXg8G0s>#J=C>Gjn>!FkL%a_C*W zvoB1i1sTHPImG)ZubWt8aS&zmL9K#=dIHcQgafMXL~{wHaxZEyg~g`??{fe{AeiKc z$VfKtL}WziR{$8?gyYiARrG)*-=et@`H`8QN~fvEfr$?3sJyCdZe z>5e{5yoHTiT|*|(kXUV?^=ju)e?+N%Tq?`k)n%%TcVQfhBI@qpS9 zoe0rOgu^TkBjPcl@$nq0i(&}GhgkgOLF`8i|FqVxPF#}rIg8bS$R7I`! zAu329E)%OLLREwcvbC4_o4Xm=b|H5HZ98DR2P}}IhO*m$cb^{>^hRH-tZ{xCXgo5 zlo49Ejo1USvR!))uJe$e;ziCG1pDP+IO3>w?NeY0cqSK`DQv&Nqz)no>s`yxHmAca zCF!3~x*<_P#WiTXyG(6EUB=LC>PeJz9(_mwopkzy5b*i}zsFOJaazF+Zsr;jp?N zsK8oMXhN#yB&-O?9s2;}TbO4jDDVj?LgFsaGXZ%OCx%K|wcjA!=)-y7Lu5Ha3qkRc zei~_j)~MZw6y!EC4iXvrYX3%IeHQAnh4p(4fSYLm^k;y{4;V(YD6}vSc-4k=11$I- z5ZZq-eYm6>a5Li{LM3l&b<{gQm(Rvb1}OA@iD4OBNG01QWO`g_Y;~CleLb#}tW-1B z&*M(X%E7EQt-^y+aD-A#MO{PMVbO@z+wAEc+4tQ(V$`>dmi`K#3$;XLm{UZ3+7pZ| z2Ie8WI#UQQqDt*qc!o(jMg8H~m%%xmJU~Tp46(qp9CdYD^&D50(&*U%Z$ZbHc6Bv! zk6Z1!wftC?sjr|SV7~-Ha~WQ>2Y>;+6!4u_zV^}a>i)5XYv=AK$R165mjR?dmBa8S zN-@i5#F?MwXEVg+>ii->*=MJU##ixG8p z($G8!C2u#X~>^LH_eL%pTV_C~JgH|~NNekad*D{Eo2>YkckK(mKJO2$lqEX9fp(`z5vKug~ zMS-J3*BlE0+n{Y=m#+JBR^B!$-Kte0PiRKVjR|kT$<%t?^Fm(3;R)Bo#;D^fDS#P0 z+%8qNE^o(pcM9A$=IVgAePnqbZ`dBXB6D)+3d`go=c9!0d%$QQI^1N|AaACKSuQ=q zJrA&6f}rB<46*bA@BXavD?_ORXo*j8wB(O>r+t8Gz;o~y3Jtivbxo?yGxSgXC^L88FLNHv+XPhe6?WQR3#t!)h+SnkiP2Nkj- z+p&6*Sqn~OWd%62fz(6Vv+Nx5H1@qFb}MUl;0v}aqmB4(<##}9tcyAJiOtIuh|<ihMWH);OloyF;djx)Eb9mBwD`o#DQg z2Cn$dhWxp!Z-?;|xFkhvQHBZeF^%fzn5cJ`Ob_g5i5INxYuRn)i!}8agC*xQ3;v{9 zuyLtOZNEKC7_v0zMWCb*vcA8NFsxUyBf2&6Wwt0Sx~)vIC`Bm{NGy%76B&_BnIyxM2rKA~O=X#Bw6_RlQ$Z0;dk#Iv zSmT_oT-x_Bva^EJq zd9YjMr&8r(%*t5;-$9iZqxQE&*}Udl3mcJu*lgxs0?_fusy&FA4H-o+oS~1awGpso zgVh2@UX-u4l$5#IJAU0Jc?yzQB;e%|&}_fYnLVfPk>A^uwEFaFRw{dK}SfXz*d z00!F;McOn7SuAwH8V=7sQhR}7v{z#(%U*XXDIgxCCIVkVSp%2P;#F-hX!!&ppot;x zCPY)k&N6R@JUdo78iTSz3uBe-6%4l3Y2@L6Z$#{pG_`Ia)l4HgF9k4;M~voYv;$t< zs2z((k&|p`=U5uyVr~@*wUQ~94%-8Qx6+0$fc;m9s#QQ+f6qDByZd05TZpfS65@=(V&Y875B9`@ zd^YygTnv;7L$yy85sme=+et_!N_)!nRX&p~P(5dw-VxeV}1$5}?V3nj;kfw3jRLtT z&Uq=K6rTVyblcNZg|eUz{+b(lA0hy-2NspE-Oa58xJA<29)c&+u)bmF zB&=`y!3C+-fI=;>x)T-=R}`xd8lyjol${UHct+Whfly4BNN7HCyvISF_ zS=Q(26>lPq-b4lKpMo?SD)uQyzOx#=9>y~HDiA_@1sP~q<>J^=&^;JiVzAdnEp1Q> zH^I1KgQPmL(;7(0ti}$@Kt^6yq{$jMHnRav0~iaS;k(pf6?<-=Kv&Xx*%B+kh5XyF z*fb?r+CakqtCb{hZ(jqCc^|l>@{g70{lkK>HU9!A+WdTZ-cXL!VUm~coH;?BzZ>x7 z-!=1id45Sc-kz3yv*_uPeWmogTlQUwr+yJ-yHoZJqr^L8UpggzO|{%Q^B8&lU+L{O z*|(0KWwP%bJoV=(a*OPHke)ZozA`+6g#@Q1ek^4^z-6m8SeT=I`$v)}ka%T5OR!KJ z9m9(_I%c8sVd>(qSRo%8Q8NHn@`)F>RZTvTq`N96}#Q5oUDg-~3$JC)4NS;krOv|C|zYWM3to72$tO zkXDAl=-SI0;7fWI1j?6Z-Y3srOm9cdJXfCIL2tvTx?fSr5wdRvJ%`J_DR}B{~#e%PBHY_FYSnizt##EiEQG_oGr8y$z6k zo%HN4`&#hScTl9S?5m(>rtI_JslNt|o}V&v@T@EH)8Ig(SgP!M8qe6J`4-wvBKuPj z!%@OAQW|KrCp+rtU+ zsI&v86&_+h4>90nb*S(ds&FNBp8Zpc>FuPXR%>EN*vn{Tyc~xNdChueQkK4-BTF5! zn20NpbUbW(n(O-8Ge?Ch%yC5lH3sLcu1b4qm z@ezoFLhlg5&rZthp^p+JUqUS~0Wm|LOPV_qe#*dHA_sIGoC9Ha zG6G(<0cz(~(UVVQ6Z2p+=~Gb`8BF9=&`w(*bZ-_pan!=rU}3hPP+l|34R9R}E3`m7 zOV4~;-V!S6Dt5kr9%#8$>|w#i+L%ASv%09AIy&c0`H|u1^dOHTY zF48^x*2i^%wQ*0nAo>s30M#JqeO2>3Rrr(~1K~h<$}#_0b+72}~2# zm1OPU1UKeDF965-t(0*eifWy3vOnKW>{)~~=Z6Gd-&fEyc9qrVqwkBHL zC;Hbs`c(x_T>1bd6*>5LiPnz4oOr4B6<%ZO#_cYL^G0bX(Eg3MGHgPuq5{rqiBA7Z z(G(nR13Qq&z;zz&-Z1q{sVyoha*hU8lqZOZv`fN7+QGuz2IVeknE)HdvIgXL%Dxn| zo`1mAFE&{F7T+)*K8nx7u^U4y!fDg-f$Tp9cYTPa@L}yVn0d&Zpd z$N#`3C*w&DIPaJJy&e4@$gZFSP5C>iFr{uzbHF~GF-8%cLsG|k- z@rO*~!#6kuMIZJ`d0XkUUIx~u{)6f&^Fc7|_R{WKMs2!}sB~~bt9GMENO>!z@)9G@ zf(A}8C5JmF>t7I| zQOs5(_pw;xgP463S`8G*W?%hRo9Hw4Fe`BD$KH(BauU}n|ZBVfbuz{9oA}SEH@MtJ6-6}WSDUUs2esrCkJ?9#sj6uSxy-y zT&U%6hAeM~b#`N0LH|^DzhJ@Ou?4AgRCEBJ5{1M&1{`*6br450#UarzJeTy(?kY&_ zf+KN3$G`2;itFrB3qscQcIi}vs}TNzP=(NpkXmY&4j|;*V3#gJcobn3!d8TSH`=8M z2=^mAhOijnJ%oJ-18=fR;}D7vhD}G^2$v!}im(D|^dv$p z0_FK0ojjhuW0z*m1>F(W&I4Y&=z|aR z^4q1o2o3Y?(qA6~uPAniTDw$ZxOl>mjBr<-TN$HTV$91gwTXA_&MMc z;ZB5qB8*!C-hLkKBRsqcd`C}&+upQG4v2WzlXje zEJb)^t6lmV!haAf+dx-@0)$HuRv>Ig==X1o0R%U~y9iqmwj;D5q_m`Wu}dQm#v+VI zxE|plgx@2)h7dy-@~T}r17R{kIYK4Ez`uiM5w1j-kFW^gZG;#?zt?~>1d`(~SfCAV z_6zH3Zp(d$VlrAE_1^>yB2|)?qfA{?14&+{hT8G4VIE^^Q+XG=>R*o()nChh>GB(u z_w}g$FuyOu-!gSMZ4$2VLTsz={{gSOK45FhYtGxC%&1dJ8uHrm!isy7;&@$|u}mp> zTXDatI2J22o>fX-P~1-|eivX-Uc8U~mNYBwCWTLhC@N}!Hk6Zxf1H< z;?%B;pr3JiUfN(_*xip;mAcZ7M1(=2O`4H*tK!fCylW6E&74jP6O`^JWCVDfLZFAg zzG{|g3i#<=!OVv`NSn$~D!7o^RQ!at04D|)5kUkxZQ%=%m2yl_IXS>uw@l?ytbDt2 z{f}M+*#uQx=Z*Fi877#;)s09tvR`NxX4cUk8%*{dY*o?rLORp~Uu0%ophWXVGxYB# zfJpCCsyCY6xmw{@*&jo4Cl}G1D2JmZ*Aif=ch(5%dzzO87E*t#HQs2d{x}F9SWa=o z+M=@jhj6$lH87*a(`-@pTAMo8Wu+*Km~F6h|J@w^o}z3+HP#x~O_V*|+GKUK==Y*Q z?x^UAz?xcT2e@S_qe;JqlmHR#nhqeH7dVtY`^Yjau<2lWNyb)*6M=+Nup6NFr~I=R1%7a2iU61jnVeMY?f{wMqFXE2Z-z3_7Jn`8#Fu958rA zaLQMDJ^T`I5!Ula$S5$`Jw)S2pFIebGY^3HxfTF31H%{ZwC5j>`VQ>vVNS^%&1{Rx zOt!UleylJD%f89!%z|Q2%BvVN;J>soi{QWY;|&&7>qYwoV!*4l2G3$apcZ1AU_!aR z`h^TMPR$Y=wBX@r)*pmd15X-vVHB7BvrucNqe;I9Pjn(s+JwOa%r@jM6NoKs(qAN| zxVs7Qwhs?N9R?WCrghdTj;4GdttQ-@l8e#hDQ}YWKcg{VjRXZqe2|bh30O0S5%@PS zL-XvgNX^zwh+z1DpFPc^t()}R0Yv0>S?ef)r@*E=1Q8923(+| zS)T+cMu;c~8VaS&p6@Ua)}Ieb6*lQLc+w~+#P)^Gh_W6$DkxRh9OrEC z{~ANQ)p+)U|5FHCscoQmvXDgckdkXbL?~K_$PR;oN*&SAw?W?m&s(p2e>ub*#(o%5 z9q<@j9w>z5qj+u&k+gZVXS)R=7GpY9pLQ)lkBr?I zNml0Nv6!Nd&o>|sc&Gum0Wro7Zp6%;hw+x3S%>~$c^}8@1B=+i`4c&rn2qfGS7-qJ z)ANM5KE=pOFe;oE2|)%K`_hxj>93-Mk(q!@%1qH%J(vh>j|{v|&62*Qr|f?O#X1>* z`h7;5S!G?UBlH`QfOnSOQ}7P*p^6KLuF%P(UPvd?lXWt^SZms<65@A5oc%gHc-1?n z_o#%p8!%RI0tdss1|on&?v7=s2%;p_x&!Mz^pu@ORdd7_3ri!aGv9EAb9&vO-53u*g0K8WTsFqZvTz5zKyqErq2QyM&sBDGI@9 zvTIUL6P!Ehpe*sOa~6t$hODEW7)Sg{#tF76Mu2AA76m(5*b*ces&NV%dnYr_e+Cxx ztc;apNXM{Zg~6Kb#$7O(vj%$ir_DtEIDnh?92bo^lg%#?EM~HgXN3tm&S@ zmh70w8%{^H@a4_j-in-a_b;IOv48U>HG)k6-t87+1s+lZxL0hFz3gjq!OiSbSvqEW5J!hUyi>R=5)##Ew|{u<5( z5Zm~#1p25?PomAdHet&NwU_t9S`V8z%Yq>iCAgFYv^UMiLmEdm7BPVk!2m%++mpLs z|J5l~f;&AsMhmtv$FBZz&sYd9qV_nKZ9^U|PvVNzMa@XHZAH~(L4GI1^rSkwnYL_a zCd41g2%}Y0n%4%90A)WmWO20`A?#5sc)$WBAh2KQOKU{S_U;&+$wpa=KH>~Qr~5WS zC5@CHjY{l-1spuoI;`02d013ZHvM({>48g<>q+Vl6=9?SGPcJ>*Lp&c*949o;ldKNg(7chA%3@_Vm!<%${CdlA zGja$`b)2E8{wXw-hm_UFXVNr)cv7#%E1?t0iaA<;6A5@{T>lmCLRpPso7^IXKCE39 z0lAn!lJ?WDz#3Q&G!bQxyUMfU$LgW}f(Ml^mnwhZu`vNv{P3bFtTv>KIFf*F9c%%LG2T>Txktzby>GvWkrshY9sX0qv zW)<>WRK?EpMy);Y3$rv3)NR&gC|wJggr)|Efm2Eb&Q3OPcE$~yopH+Tj2k#R71qp< zX9{0YuGia4=#IwlW$gfqbE9Bw?D@*9j{W*4z-Os5AXKsM8S5~@#sHHsRA4i*yt>&l zJ#rfLy%9!@K9#wQ>~$b7AWZTq131WbMqb*_L7u>>kbeS5)1KK0y75@8@vO%sdRp#i z;SySL3t@_;7*GISOn@io-&|%Q4_=obvyOl*ug$im$LXR%B3`Ys2uV*Y0%dg=Ne`(@ znN;M5b~ViS8mwmb+-H#+RVK-3D*s;yeFMgWD%3v*3+cnLP(BfxF@2==@ND%gdN{-mS&G0+=&?6}S5jc=SH|Kqd0|rN*ZQLcl7UG4K2s z^G@>Rws<;WGQ$^_qU*Ue zJa59ExZqSO(G>d%9)cLb177V5+md-T)<|^1YB)wQ84IyYekDlF!qFywmpu6x}POP1Z@OO^i$A2xLrSvp4>G6r*LQWS5NuB-bV-{#-PxtBq;x9 zeT0i@-O1=6_x1l#I>JBq#n|LNHvM1X)&Dsi#SrQzSXQrsVNPRclsSPH>3MCeYE9E) z+eu=cL*r1mm-EQWrt?8R9>J)OytO(VAEx@U6ZKJg>^0LJAo3;ZXG?K5>KAaqGuot| zVpK9DKDR1q5)Ce=376qmAR+Qjyi~LPEhJp`ra{Cr(0F`W0T16rh>J3(y8DyVVT12I zqv%0yc|(%ui;T~cOi@LJV#9iuJ!+K@U%-)3M<&*1gga-!7@q8~$onz%uMj~Bz%G(ntnVuMBsOz;3UJq{nKbM zQ5Yz!TERp*U+Bp5HzR>=`!q=^#LEZNWV{sfSQ#=2(_So(=*#1!(ugS@ry>K4hTt{+ zHRTr*OEA}aaR||?X8n4QQsigyP*O2+81;i=u8CKkCpd;DK2R}StT$Dqry3c?G0$Lq zhl<6HrKWl-V{%PiSg%E+Kdm6~1PXq_(9$g9e`GxCW0Ucx>BAB2hHp)e!W(4bThlL3 zhUid>wC<;w%T=biZ0KTMHq(E7Vqz@xVDP{h+5|-+}4mXrd#gvfpf2Hg_>z7!-#2>Fjcc1S5SNP-g z6@4_2XlQNx7DK>|8%sUAWb{Ybt!!39w9bsUZB1UYvKxZF52xU8-+nA=M{&DpwX!?! zi^%p=&(38cHyoJQycl{K1u@AI=cF>X2oG82I_x(t)Kqqtsq4PoC>)fw#xpqo+#MdM z@KN}ogf!tG1j6A@q?tGE08lpRPmO!b7AMW~;A+|ISz_zUbR@rOWqE_d9 zK_D4UOv8hzE+VjOThTon*${nD7cC}Gzr!lNfGfzEl->OpN_6coP*c&Kpw=(Ik_MI# z>Gv&u5u6G<5@s1(bsYc}y$NzcKL%QWEV=>rbSW@R5GL>}U{x0q8iIWNvu*A19E;;z z9|q7N#2n3-5i0&`z#lkjf(bZz%>IAJ3#v6`H)QDs=Z-6-G%=!>YCm^xr0hG1Ts;wRG;`0Pe0 zN=uN**oX29lZo2+(PVm-$<(X;@!v=@Ff7Y6=GjRAiq=}t`M@HIh)#QU${-t<)Y2&S zW2_5%O#^%d>;Tud*8q@neMV z&k+;~#vMrn{Z6dPll?;ajxl+Tz+@G>ZQz3|A@v~S0DbB%2jG~5Pf{S&Tx{t9#Z<#G z99?GL9gYuwXYFP5s39S|5<-F6{Ly%&GtdcL0mVbw0>ao*jnR${DZ6tmLS-qNEe)*X z1d*ZW+%1-Mo?R9Q2*SH%%i*NK&%rp0W+<9;SscBH3~{NJSsY zIn?}*=A7Gsd%$W==*i}a4L_Vkr&N)mhe6_QVP#^0GTCcs0NLU)M<``wBe;L3tQhu? zAlWa;Uc$a%_9D|QnY}39%~qkjWYVUAhGuu6Jz3pwcYC%-q1jnfB|2NJwD#OtbT!BZ zqak;)vKm(_b+oZ8>Bp5?%+v zZJSUOXZD6v`tUzODpma>k-C|X8pReOz3YgCY&4gl4yy{F2&#Y$(gm70O!HcKA=k+k6*@kUR2 zv!PAi!9=k1ak4Bo_C6}xz9Efl%p87MFHg6bLw+(}ioOOGQKG{TZ9KI2X5 zFxPqbKF3G+zla$>RPJukXVSTa#7tpKH9RzIxF#5k#`o^S^Vp&4B-#E}>J4UED~7Q! zOW7xr*@%Ihq*j%Bf-IsGw&)Gy?qGK-0HCQgIEQSVF%1AQZf`>inI<&x7@Ox#u-QTtrZ;8j$EIE8I$^5e*H|!5QF@ZFlv#g9 z%q8s?qf&iFOy8*n2n(Pf`1If$58bIPtS#pUF zfiVqWdKv+^iBf4DgZto=jnqTa6+u%rnv-s!`6q_)kK=plhM|{9Z%e-!JWRV$KTieoG=X`4w;^2W~_QgmMpL zHbpG-UTVpolT3A{vq@@2| zVEk0#QLDWPIXxRA&+taMwVWtPGPmYyqy6W5aMpmgetOns>+hTf^&>?03@wMw9O7h> zuNnLM!#mP>cR%k>r>s}e#tq2JLM;cI&{LH{jZWZHDeDtCmDxWu_zJTBk$r@X zWWu$Y0~4|r9+G&*r18fD7m zB~dP{bR?m*UC*UV!XfO|tZ~Y98-n`T@f}~-V~nkRXEIOFAhSmFOE^Nq2^Uz$hf@s* zV~k*ZByXGj>7>c5({DoMKb;ULNLPx*F%A>zm)sv`ju^7q`LN8F@vhcmGXmq>x>|pX z5M!<_L#4I>MGC~in2luXe1Q$fGK|S{cF0fG;CCN)@X{Jdd9^XG6YP_av|GgTnXyih ztR{Jpjn4qt>Q11AGuzrxb&>Y8%!Vx7mRROrqrZjID%5?aki&|jmW)W4x^7w&3zX1- zKtKUKe$Hn3$z(qagMw8)(iw;P^XY3hORKcDH!}-{EDqZ1V+16^mi3c<)o-HiV|$Na3&Dyohkn@g3y+o~40^HYO$RAu7y-Gmy78PE`N=S& zKGKw``bnj$b$R>nyWKz*->XxH(=Hvjw_UhMGwa1_BHw_DlbVHLTfMDr?slTus9Mmh zpPz6l=tgJajk?pp%rB2jh$BGF8ssoL&@j8_<(=v=jR01uQ5VwneZ+LVa9ofx^$H4YAPO~- z69z*Czlkc{oaIChgjI&PDtEkSi>5{n^MxQIYFt&ebGxy)AM* zXXK)&$hG$^qBK;7E--dt7&{GOR3;4?;>`G9Y`~DQ+t!FPDk>K=uDQ_P{GJAskX^o45YfkD zA835=zlw;y3f@gN6vu9U^viw#siDySU z?Oa@&9y>d)xy%0t%ESDMGeAu^*~+C2kQ_USp?2+sty}(iwgg_s-xnF0mpUBskOfKE3Kz7T!XR82QQkisz?@ z$j`T>SgYc9;DFH;90TKH)^+-BKtuC~CgY}?CaR%I!95oaT%BRj7p98u&Bpg;vjs;p zS8uKI;HMnL<~o{1VdTZ0r;d;WGXSGkQLQ-a%-;lXe99BRnKxJvaJBjkC_r_PEHLU| zvA~z`02ve!<@tI8l*fFLFZiMI?fS7)UK~JW^u@eUipC#Mi zCe+J}t{!yhPZhcF81sdiKACG4ZfZfS`VRP`jXQOes>lx1`ZyRtVNW&&p?(=+Xr6Z* z3VQWgL=bJ6K1mc|BJ`G-ZZ=t_x8t%8>Knvfv&i{0mo*@vh_Zi<)_-KNT>>5*47=qyiM>0z0|DOAtgTfZrA6>Sr`1 zvd(CteAX&u7b^aMV5ZSwt>)>*#pc0;rari9zdqcuTb#}Em7+XO@Dx@G*CO_ z`U2*`4Mc?5fV)Y*RR}@{-^vmPq7Vli2?9qmnxASkPq^#eJf#@TGh)~3P9ra&t$SWd z$*iJE>%{qZFwI*1Vanf4)L_kugiU>iDHVX*xLAOkA!)-1wr=#4Z-eM02cuOK3OvbT zxe?lwRUqmSno?hE75rmdG-cqrP&2xzDQgKK9{f~!LK1>>`VsKfnq(5H1JsnTz^t?b zexXa=Gx87x1g)3TtJJ2nA`icV+2Asbi`Z6uB_9@#^Sz@4p+Mq?n}D)hi5=#spO<%&=S z_3gx#oS5O36v37dl*BM-fLJC_-lUH+z8d1u(Ja0;<7;WNeu2>n zVZZ>9UPUYP#(i1N2)YVAH5tapOSlnv=}mNp(~{Vf8BG5icN%m@AajzClO@}v4W6|Y zaE}%lg?=&q70gyuzy#omX<(hszdMB6&EF>v^Bvx;4Vsew$WT*a$;A%#UVMoTyLlj!?o~J+N1&!|GZKVMyb$aGOpO zMtCmkV&G4O76Jilsisdv?Jyd!zqgNfCuTjX#TuBhIUo*|ba>@?e}Hdmg=NDo4qC9^zzpj>jSMp0#_MONtAIiQVc+t<}Sheiy zKs|aZ{&+g(&m4gtcHvk2oYi`Mc})Bgi{6j(`(@ulNLE_g>T+0f>w7tuW9F~r`8Ps6 zc{)5Z2g~z^a_T(UXTytr496~(ef6AUqU^f^FM0(hPoVt2L(e=N7s#j+ zG>P#44%u+IK1vvSCN?(tt6UkC*h3-3(kic_bTV<+dzOi5HE~kzXc5I~M2mi9at*{V zKU4$diM?kwTGI3b`Ejo4iFoGbAIjXU--znX{A_dnKoNoIG0CN9O#e_R$|HV^gcJr% z))J44Zwc1Yx5F@m&cxSBg2KC?~`X(lCnQ*m3qmMRXjrw?&!h$v>+7AE( z6+Hu0y>8jiMC`)@{%ugtOyHrsG?4&xx)3pDHs}h~d>8WTVMK-DAa;|&eAv^r0Ty1) zX7y9D?f3^3VpBzNEmmmd3n^m`D{J}K`BryR>>R7RId+DX#c6D;bvdCdc6@TRpI``E zzYQ*@QKpn{)7PWNR;;RiCHn?_g^?WMS@ZrrGmo5gfoFe)YqDp5n(HFZ{#4i5`tBBt z%>5~@5uW`PS2o0_|1+cn9NYB#RpL4H1M%EvJnOf(2TMDE5iTtAreaDt)GeI7%A_GK%hOR> zt@lRYCK9);e#je3`q|dNg@_H^b+r1kA@DTM>DS_ypNtFdMq-c(KajHg4NA-08_f38*L&Y?3YMd$k0cK$*8MwUkZQ-#9;7V~ZA9gG=CI~ZLr{xo#0^`nc-Op{(>HuyC z3gRbT@UxoLDf*quiAxDO{Dd%V|6z^-g49;+x*HiK%kF%KUe+DL|{_j`t z3rddl7Cq}%G&4KcY5N{87Lf`T`{>>?w#C5y`MLY(5{tEP=aP@98_6jlGkH%_>3cnq zoLESZT)zaPD=}JrK5>Ui`jNn`kO8Us($9HFV_%EyU{SzIDk-ts3enSVKr!G9^RExe z5WjDgc#mA{>>1}vUCqU%)#qRu?~NV-pzlAldAd1E@HPDM z#!$yiTt-@EqjAS8b5T62u@1!7a|?fg!WqP{#iFgkR*t?M=%Q}l7B3lJic7SM*5chx zqz3qs#iW5qt1+f4J$WGF1~&Sn-;1^mZ3fO8qbuF88&3@^+DA;2=pIF>nFJ)Fvsi{o z0&r-B%~A0hr5j4Tn|9YC|vT7|U|JETD(6&)r)EUBTi=f2NrzNEfb;?SZMu zhDkycF@-*JnZW!xNo$5A&ku)HbG1;I zqX-iM%gC@W_{nqNHhG>4^DBA&Wm%Yq9hfc8TMGj~o`2CGioP=QHhF&OQS@3d^JIDc z2gB&KQl57*R;1JOvHl6p81+GMX5EIGA4lCi|{95_xiPX2)}2sq8xy$@-&Q z;!%0te#ROD89-t{=3E6*Rxnea2R9<-B?TR&<`gZ|cM#LYL#^DabTd43d* zR?mUyvab;@SoUKBf!EN4j|Miv*;iwf@yIxVOfZZvsB}wI@Hjg!;F=cRsH<@l%yZxx z`f=FSbb6g8&pRH_%JWZUn6H<8_aI$Q=T=MPc{d>@&p!vF&U4^u+4np8__t%J#gsORMb@iP!=D;(~p z19;vVFYHIA46WZo83_WA*Pav^8ylIV+|-6Kv{eGy!ElI>NydAmSOptyW!!0n^D1;< zvteB|@+NDXG6!|h5sL)SgBW0QUi>g$;q`d&rM;5?KWD9IQsp7$xz&AUhm zy112M>~OCNO>=^s(EXta;^Rly#qA~7wMCOM!3^ok9%(9X zqtJIY_Qp3Gu+)y_f$kE7_av~h-`#Z3g473W!JE8N*d#=T$u8OgRA-6m_oF>=u!eug zqj$N%cxfDi{gppWaxifZFF7bn50ZoEeh}wSk{&_FegY*+o5gQJFyibc9mVj+MPOa1 z4T}zKpAi|wMtdgX_hOSkdp9z6bt7XJ2EINXI+}hl%OQRW366TYj5jT5;jt#*sKfoP z`Vi#oStNXWC6QL#q8eA84s$;VmL>EYbUdK~3Y+y)ksx+ak>QA8O@bY6IM%|300%L# zCl*&PLpowU>b0pyP?8wg4emqLqGbb+6-)=Rpu@aDpLvCX2!nm;t&DkQh z#>CL3>ARl8tNAo5_(56ElVIUn!+u2Lr%Do|wc>9e^Na>hvnRj@b;i zYMOD`Rqx%qzjaqc?`8My!*zGP5LV0s^1v4a#Q;8dsXY#A5Dg))%lUdkA!hF*rjNmCwA z!APUQihDQ)^c@$T``s4) zt+6Yx6y$R7Gt9h~@9#&Z@cD*Yk;xpj+jNk0oRizo*D>GXd6)B|@Jpeu@kEu_zT+&I zw}l#lszh(&CcIb%CFfZ&BcnWLaxpXe8iMzMq{3LmynjRIT)r`a%#<$dseQD#jLT|q zQEi@jRC|`grel*=(&#B0=4H4WH$vj$8zMnR&2iG>1p`4YoUo9gn+=& z0#sM<$N$>I&8=E7-*f5)4D^eb$NAp~_XH<=!_}#-4%*(K6L0)v8J)R0iRl=_zjqdg zP_gdD26U_j-yX~XfXj2mJtZ_Z>wQH)M4mjX2TQ(=9s2Nud4})sqtp71dtn<(6l&D} z_i8schxeTyxIr9!6IpX{VbHg)NbRO-e=_Le{h zhclvjG&e=Sm~v%l4eM7i@D+3dDwmQ8UzPklxANe_l5eSRUgaYmw?8!o@c* z=X2)dU$N_L{Qm=s5@CWje|aSqEiNEcAv%m>6}iM#vELvXj`<2&1m{lr*r^P#>cw6R zzdxgnvjj`gZ=_Jz{zZiXEV?xxRQ)~Ge(^0+vyX?=zxUz+E*0+i;L^RsrTiP1!et*{ z!ko!#Hni4QEe1M_u?vO)OD>!zF<8(WJW{y95qlb6U5t*;qLcgstU|nUM;jszS+fk{ z(1`i|;uYQg-ONGy+_#XqMbAWg>T<{%hmm|_6kP)QU9Yfx_Fag@?|tSJqDm}mp<)OP z3H}B9YEHm(DP7+|2ZUR>i1oZiV9B^Abk?IdZ7OtaGz9YwUp_=>#kcm&2PIvY5w3 zjb|i_aipS>IPjn96k<$86nn7sTZyDwhyf->LF_P_c@mNuuBH&sagfBq5t!yF&id!V zL8(_Xue&k=r~zk<#jgMNIp0oF_HyUjxdM2Fdw4l(Ug3OuAI=4b8RTvii{**EV&z{P z+AxxF)u|`xC2BqYmbC9^Fc(C*JlDQHk;KGhR~>yd1+WBXRT@WJ1`91tSawL*d@rtr z3>Kf21~&h?3?2q#BQpVH@OS0{a3`M*h&$VeJK@g{67aa_aWKxEZNb(HfQ6-w_X4_B zI1c%|RCT0H0!q0gT%1E25e*rM}{JLXQw8TPep@ z?1}j~wqi@f&k=^1+t1;^p64%8iN%U)g&p6|s}`K5acqoF)N33=&8&NRW;d=Vg$7ue)ay-)wi;Y-|8izB5f7b{pIH-x(mX2qt z!RH$|7GhN|MlKo!yhO}*-2gxR6%|hE@_qn%sln6llW)~N?0;iY>y5X2Z68JPZO3s^ zKVOaEpuNQ`1^};u1ZzQ{#B8V}=d3(pe;Dg?V4&*u z^OM!S&EY>9-*3ij7j!j7sH_+!JG#{*;=NJtGp=~Sy)$k?n13-2C&#H{c$oT!d#!+) zhPy_)+wd+G+CDy*Dkz&J1$Tg&L|H)`d+i@%sT*0F2B*VIR(w+Pny4U;C~BRcNMb`M z?MhA?5l6+DyrxJu*lSlEG};-hr45kKGp5irvE8x^vBA|JaECZdX_lZ(pxD>r(K`*J zL%7AkKtY}H62;*92rTz-*~QVzTy}AVl^$25ahU==BbO-z2-tU4dX(dGE4|<=KsSc< zqh3keBq?k$!jCTE$z{>8Pb+B%G+Lz6+}+hfGIyWtm{l51o%DRZ zq;<~8O<1rdL5K5&)HG*%`mgdO?rk1?_j*Yxtw1^3&I`bwrKi_~B)D6QqCZb`-ZO{5 z>4%Y28kpp=W?Ed&Xl_gRXhpf_lm#(q?1VPMmBK78z;NjA0i0*IW!^nas3`VV#txPG zzb1}9$p7dM4VR=jb9=LyBELBLMP7QJNw&Vf@zI|VKZpNHF7p!^e$Ics%ls%E1O5Ns zpQn4_daI}Vu_xj@xU)+NYR*3Rz}Dd%e}g3H)h^mtZK^1nHG3wy05>Ka~_kf9QKA4drjUnfRM1ut;DHqZnl^0L)YGW--5aKG_i!xe@(1X;?*`20t+dyG4w0J zY%OjJ++zSLCjZ(5?-z1$==q7VlHd)?H-`Rg;!5Qi#N83vG%-{0dnURhWn+uQMg5?* z#RU~`-0Sobd?*qE4#5R@d5z~8VB&|N#mh|>$%+vUs3;%>$|dc{tl6xYy`xQYk^9;{ z{Z)87O{}te14z%Vr!SDl(@7VptH~{|g;zm#dpX$HQC>Pre}Jyb-R)rc4o^3z@-%X_ zzU|0)~e4y z_p#Rd7BpHVd`&d;WLJ~P{;XJ;c+1{33!5fdkZJ z&IufpRu6U{ZfJ%{@nd!zsYjs3u_kZ5(hr@6K5Nn$Ro&>Vm#-?d?;1E8w6S8XdH@0n z250J8$|XpswO3>x(YK+VdyJThvU1iCPMr^q*z!$7fdnx9b4x7p5Dh`)+q!PVX=cQZ zqu6xT7&^__5}0JiNm4lVew1Xb^T0b=8XKae5|FL*hdDyWqKrdy7J0MlDQ~n#jrO&m zebl2ZA}2UqDDNDe*JyWH zsXxhQRnJNCK>rjI{5pLlCfw432<1}}Q>dREWG%BZ+a|v(ef@{K{RzH)6D8T7@$PLPzZSt}?)tc4#R{SKDmVs9}BZ!O;; z8sC*~!%2n%$YKBEVJ}vDpCSnM^sKW=;sqiCJ>OMibK7f&fWO#$mqjbGfLIeiBnxZI zXH zvQoXv=0t?(o$Pi@D%P{(To{iaPE#K?L6ghHZ*^19+w}w+M&siwF}gkFOv;QiS*rLw-BThv&^jHsUUB$^ldyMq3adh?a^56>wl=y_BhgdBcTZM{62HWnLt;`}Kou737i^-$MQfnQy1 zCrukcZ=({IA3DHVJ-eNAvGvX$!5dH>KlBg49RMLVJ%iWW_)ef~_xKRjoybDM3Fk8L zx((y(Nj&R_?b*Sc1M>Z12-v-JT+a2ncvH+aHz(eh5y*!AAW;?(wKr*{7SCfgNq#7I zibJXN7uZ~{`wDDEN$j1fZ@PUC*r=H3HtMxLqlMF!V(TQDQ)pF=(g@mXA0x7JHIa9x zF@1;Xc-Q>6FH9gTewYuype@>M(^@eZbO8$DsmWD%YJ`43fS@P|udA987D$pj(v!CtuaM$( z)Zg2o@q+IuO5_Wtjz^fa27hurx-XhVcca?S2duGAu6@B}$QAunl+9!fT7e;zwF0X) z$L2Y2lI@Vm-VMkG{Q=aMx(aM&d+ielArA>@r5_shB|zXc+hvy`kASi)vEE3o7iq$vGS#B+YWoa#A0L3Vh~k5;bYl9zQ57jkVcbSC>q=qpe6EnxWWJCy!AX?Tfr zbbw5-8bkjD`B8Jq4Gw_Hc0jEoz1J)|G;=A0UroN$?BOxcbvpH*g579t9H`%%LE3B0 zZYsyM@Z&5F+KwC1tV0x$dQ)SYvzd?AnKh@zlMrfdp5#h(G}pR#B|2G`NL$)a;61Xw zUl*k*#oOsFOZ_$iO`^>EXAniRxD5QZTk*=rC*eatF+URtIL5;O5ajw3M*G>`K^XX( zYa}&zFMI1!ox*e8{CNMsa#M3{3T2sZWZji@$}O3`V#jA+QQZpEa-jO}pvIE;S%s{C|jx{;9Bcjl!R`yd`mt$u3a{Vu!I?V^LO6#+>Z z+^kZJiM0xPW7f*951nDhHA&A#RcQUS;ne5Rlb-IY zl3LwwyA#!f;PMwIv(6zml_Ky%Zp7J1nSJ4HCqsp2Sui7hX z-k9tT-P+aSRBq{NaVR&|krZH^>N~1l1fLi*{HnUUfsR{$6=8Ioo5yM&-eb{ciBoC;|M|u5!cyama=u8V@3W*wAh+v%se*)fr z!|2#aLH&K?4|souAnVb4IA!E4`>Q;rOa0TwZmC{&s;@nb3=@>A)z_XuV7@XyeeGEU zBoL7vtQ&<#T@TWapPX1tIyFtZ#Bqg${%Br%hu*CP~s9!UnnA@Mb*s4w3BYQIoFpiGU@ z?@xsOu&dsqFJuW?0xP~sE2;|2+`x(lv-4U}xxN>yRLP31fuc(NM`$i9zAjKSOJB`{ z!vjSN^d$&ZwiE*oRy?FqD|X-o2XB7PifybI%aZbzVlKj4ipKyS%6dE4zIZ&c-;!M) zc!|12SR^Pp=2un@u&j_INyj{v5kW7Y^&W?V=sxbxs9RV!mv|@{XE%1Q&O3<$& zChZFa15nyXe571$j79yI!@(`PoqTyv5&GPS=1MY;Z1eM7 z*W27(O~%5HtW~(_8s)FX(u;K(bfXe(+5Q>^qG8L;2Z3Ls1$SK>{shP1wX4xBpRU7+ zEGc*cUIF6(W&!;pC-ojDKP-LlHZ}!+gk(<`=hUkZAopWhFUObwRgS^4I9(XUAa=$g znmH;ptenD-8z2hUi>Q}U&TY~F3# zyy20K2bRAWCitE*CZkf2WWsWDpw?wYO6hF&OBX?ziL6u}4|Ud-h2=omGSE-rpf#?k_p=cF(Wz!mC;?p+SUHX$88cW_2 z%@OQq5$8sq12%{HjKFFWuPM9U^wGdZCX$#)Vx2jA?Hh?rl;jAK8}A_qwY&`Cs9nk! zyb~qyPJor+qzJ{32W_I{OwqJp1t4%_iP)t`g;Xf0MRP|>)i-&*R49B38iA;&ZYf{(SbQ#5a0#z+wQBs#W8 zf8+!X?T>=cUw{w_HRwkmM_7@bN21fd@wcDA7(~5W^SGXcM|J!z6$ydjIM;>DquKTB zGgfp8**%YcBdxhjE9#DePw)67Wwlmxs@c*n84ovdNQR?ykDkIC=;^lEy(Cw(BHe^*iTV>4;?|9#lb#-%ya%zY=p?Wx zIwh(GEWhNlOrUDRl!%(;0mznH^o@Pvy(k^p9D~OniNXR8do7txqOk3?OZaOHd;#Mc zL?pE)48rg_J!tQ zU#Q;ME8|2TdFm}jRBofa)(--dZHu#e{~Lj>Mg(>tP_bD{(~@%EP#!tEzosdC@#4iB z4#7(bKV_aa$D&QKAZ_M%(tfDTv1(JSNXz+7+He>%v?(^E4fWJJJdKV^bI657rdX7bh;&U@ z9o&^|c)Cq; z9t3YnDJCN5Dx{fxz%?^vJ|AMDh$zlPaSqC}J58*tGnz5G41gAwz-}Y3tUL66OFV@z z-lR|`5NgkG6-wTA&ZQ0?i zRFrk|Jvh|)A@&nbi%g_4Az?mxCU)}2ijvxo34P0MRE^3U*!@eTFnF2U1%wRLy+q3< zc9fd0qWRFE!l|cd>g~{X&`@sHU}G@iU~lJAixdt4#UM5wR38MJo7>Ffng0CbZBBW> zwgfq8JE>N>tsjIzzExdlJC97vq~+Ugl&ELvkCLm+b$E{`$&!*4I~@;{$v2iw}`^Yk;2;Cl+eeD z4Om>;d&VS!}_IHqJv2Z_kOD$ny5CTEAYS(JI~t?Vvr4T4?m>~OwL z_Yn~Srx=a2A^z%Q_0w~{PMgJ7n2ceU2o`-c4qe@h7Ylnk<4dg&)Te2cb&5488aNKB zMCdu+ZuR6jA1+TZ^F3@|MRJI1y}bxhNtR*I?$n3&$JRAT zcWjH36MYVM!(QuTW)W3p`Xtu{@T6Ois(ZEo7ke<=Cjwqe*K za|GO$$;vlWOr9`V&R`B!YMIPRt*q20r;RUlvQosPASR8KrU%?k<->rxGvIdcj3OW2 zcx|Zynw)Gr3aXX#92<{EsvgqcUOKhqIHsrb1 zmO?9$3L>-Fok9;!!w|#8feoc?de5UaNx>~*ESa|YX;ktJy6yF5T$%9{6r>2H#gos6 z57iHOoe;@BVrt>FWw&9lU8iNig@~8Nj;324s=to&&xMH%40D)r9Of%0AN*q4Ll&#@ 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

Firstly, build the compiler. It should not be necessary to rebuild bios.bin; +but if you have to, it assembles using the z80asm assembler (part of +the z80pack emulation package which can be found on the Walnut Creek +CP/M CDROM) or the +ZMAC assembler +(downloadable from <http://www.nenie.org/cpcip/index.html#zmac>). +