Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ef9652935 | ||
|
|
c0b9a6a5af | ||
|
|
113b836c91 | ||
|
|
2b89372f29 | ||
|
|
2094666e6b | ||
|
|
665b494bd2 |
18
README.ja.md
vendored
18
README.ja.md
vendored
@@ -317,3 +317,21 @@ picoZ80/pico6502 のハードウェア設計、ファームウェア、および
|
||||
**picoZ80**、**pico6502**、**engineers@work** の名称は Philip Smart の商標です。帰属表示、商標、および盗用防止の条項の詳細は [NOTICE](NOTICE) ファイルをご覧ください。
|
||||
|
||||
ライセンス全文: [LICENSE](LICENSE) | [LICENSE-HARDWARE.txt](LICENSE-HARDWARE.txt) | [LICENSE-SOFTWARE.txt](LICENSE-SOFTWARE.txt)
|
||||
|
||||
---
|
||||
|
||||
## 無線規制に関する注意事項
|
||||
|
||||
**本デバイスは 2.4 GHz ISM バンドで送信する ESP32-S3-PICO-1 無線モジュールを搭載しており、世界各国の無線周波数規制(米国の FCC Part 15 Subpart C、欧州連合の無線機器指令 2014/53/EU を含む)において意図的放射器に該当します。**
|
||||
|
||||
ESP32-S3-PICO-1 モジュール自体は既存の規制認証(FCC、CE など)を取得していますが、そのモジュールレベルの認証は、**モジュールを組み込んだ完成品に自動的に適用されるものではありません**。事前認証モジュールの免除規定は、**個人の趣味愛好家**が**個人使用、実験、または教育目的**で少数のデバイスを製作する場合に、個別の機器認可を取得せずに行うことを許可するものです。
|
||||
|
||||
### 重要な制限事項
|
||||
|
||||
- 組み立てられたデバイスは、完成品が独自にテストされ、該当する管轄区域で機器認可(例:FCC ID、認定機関による CE マーキング評価)を取得しない限り、**第三者への販売、販売の申し出、贈与、またはその他の方法での配布を行ってはなりません**。
|
||||
- 個人使用のために少数を製作することは、趣味愛好家および実験使用の規定(例:FCC §15.23)に基づき、デバイスが有害な干渉を引き起こさない限り、一般的に許可されています。
|
||||
- 規制要件は国によって異なります。米国外の製作者は、適用される規則について自国の無線周波数当局に確認してください。
|
||||
|
||||
### 製作者の責任
|
||||
|
||||
本設計に基づいて製作されたデバイスが、管轄区域内の適用されるすべての無線周波数規制に準拠することは、製作者の単独の責任です。著者は本設計を個人使用、教育、および趣味愛好家向けに提供しており、本設計から製作されたデバイスが商業的配布の規制要件を満たすことについて、いかなる表明も行いません。
|
||||
|
||||
18
README.md
vendored
18
README.md
vendored
@@ -317,3 +317,21 @@ The firmware and software are open-source under the GPL v3. The hardware designs
|
||||
The names **picoZ80**, **pico6502**, and **engineers@work** are trademarks of Philip Smart. See the [NOTICE](NOTICE) file for full attribution, trademark, and anti-passing-off terms.
|
||||
|
||||
Full licence texts: [LICENSE](LICENSE) | [LICENSE-HARDWARE.txt](LICENSE-HARDWARE.txt) | [LICENSE-SOFTWARE.txt](LICENSE-SOFTWARE.txt)
|
||||
|
||||
---
|
||||
|
||||
## Wireless Regulatory Notice
|
||||
|
||||
**This device incorporates an ESP32-S3-PICO-1 wireless module that transmits in the 2.4 GHz ISM band, making it an intentional radiator under radio-frequency regulations worldwide (including FCC Part 15 Subpart C in the United States, and the Radio Equipment Directive 2014/53/EU in the European Union).**
|
||||
|
||||
Although the ESP32-S3-PICO-1 module itself carries pre-existing regulatory certifications (FCC, CE, and others), those module-level certifications **do not automatically extend to a finished product** that incorporates the module. The pre-certified module exemption permits **individual hobbyists** to build a limited number of devices for **personal, experimental, or educational use** without obtaining separate equipment authorisation.
|
||||
|
||||
### Important Limitations
|
||||
|
||||
- Assembled devices **must not be sold, offered for sale, gifted, or otherwise distributed** to third parties unless the finished product has been independently tested and granted its own equipment authorisation (e.g. FCC ID, CE marking with a Notified Body assessment) in the relevant jurisdiction.
|
||||
- Building this project for personal use in limited quantities is generally permitted under hobbyist and experimental-use provisions (e.g. FCC §15.23), provided the device does not cause harmful interference.
|
||||
- Regulatory requirements vary by country. Builders outside the United States should consult their national radio-frequency authority for applicable rules.
|
||||
|
||||
### Builder's Responsibility
|
||||
|
||||
It is the builder's sole responsibility to ensure that any device constructed from these designs complies with all applicable radio-frequency regulations in their jurisdiction. The author provides these designs for personal, educational, and hobbyist use and makes no representation that a device built from them satisfies the regulatory requirements for commercial distribution.
|
||||
|
||||
15
WIRELESS.md
vendored
Normal file
15
WIRELESS.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Wireless Regulatory Notice
|
||||
|
||||
**This device incorporates an ESP32-S3-PICO-1 wireless module that transmits in the 2.4 GHz ISM band, making it an intentional radiator under radio-frequency regulations worldwide (including FCC Part 15 Subpart C in the United States, and the Radio Equipment Directive 2014/53/EU in the European Union).**
|
||||
|
||||
Although the ESP32-S3-PICO-1 module itself carries pre-existing regulatory certifications (FCC, CE, and others), those module-level certifications **do not automatically extend to a finished product** that incorporates the module. The pre-certified module exemption permits **individual hobbyists** to build a limited number of devices for **personal, experimental, or educational use** without obtaining separate equipment authorisation.
|
||||
|
||||
## Important Limitations
|
||||
|
||||
- Assembled devices **must not be sold, offered for sale, gifted, or otherwise distributed** to third parties unless the finished product has been independently tested and granted its own equipment authorisation (e.g. FCC ID, CE marking with a Notified Body assessment) in the relevant jurisdiction.
|
||||
- Building this project for personal use in limited quantities is generally permitted under hobbyist and experimental-use provisions (e.g. FCC §15.23), provided the device does not cause harmful interference.
|
||||
- Regulatory requirements vary by country. Builders outside the United States should consult their national radio-frequency authority for applicable rules.
|
||||
|
||||
## Builder's Responsibility
|
||||
|
||||
It is the builder's sole responsibility to ensure that any device constructed from these designs complies with all applicable radio-frequency regulations in their jurisdiction. The author provides these designs for personal, educational, and hobbyist use and makes no representation that a device built from them satisfies the regulatory requirements for commercial distribution.
|
||||
BIN
projects/tzpuPico/kicad/PICOZ80/Output/v2.5/JLCPCB_PicoZ80_54mmx19mm_v2_5_01022026_Y25.zip
vendored
Normal file
BIN
projects/tzpuPico/kicad/PICOZ80/Output/v2.5/JLCPCB_PicoZ80_54mmx19mm_v2_5_01022026_Y25.zip
vendored
Normal file
Binary file not shown.
118
projects/tzpuPico/kicad/PICOZ80/Output/v2.5/JLCPCB_Positions_File.csv
vendored
Normal file
118
projects/tzpuPico/kicad/PICOZ80/Output/v2.5/JLCPCB_Positions_File.csv
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
Designator,Mid X,Mid Y,Rotation,Layer
|
||||
AE1,72.05,-91.49,180.0,top
|
||||
C1,69.69,-99.61,90.0,top
|
||||
C10,80.09,-91.44,90.0,top
|
||||
C11,80.05,-97.81,90.0,top
|
||||
C12,81.05,-97.81,90.0,top
|
||||
C13,80.59,-102.56,90.0,top
|
||||
C14,80.6,-104.44,270.0,top
|
||||
C15,80.16,-118.89,180.0,top
|
||||
C16,78.613,-115.316,180.0,bottom
|
||||
C17,78.613,-113.792,180.0,bottom
|
||||
C18,78.105,-128.877,90.0,bottom
|
||||
C19,76.581,-126.492,0.0,bottom
|
||||
C2,69.69,-104.14,270.0,top
|
||||
C20,75.946,-127.917,90.0,bottom
|
||||
C21,76.962,-127.917,90.0,bottom
|
||||
C22,72.644,-109.601,270.0,bottom
|
||||
C23,74.168,-111.506,0.0,bottom
|
||||
C24,73.787,-117.602,180.0,bottom
|
||||
C25,74.803,-123.599,270.0,bottom
|
||||
C26,73.787,-123.599,270.0,bottom
|
||||
C27,72.771,-127.889,90.0,bottom
|
||||
C28,73.914,-127.889,90.0,bottom
|
||||
C29,74.93,-127.917,90.0,bottom
|
||||
C3,70.4,-106.03,180.0,top
|
||||
C30,70.358,-115.189,180.0,bottom
|
||||
C31,70.345,-113.665,180.0,bottom
|
||||
C32,70.739,-116.967,90.0,bottom
|
||||
C33,72.291,-122.428,180.0,bottom
|
||||
C34,72.291,-123.444,180.0,bottom
|
||||
C35,72.235,-124.46,180.0,bottom
|
||||
C36,72.235,-125.476,180.0,bottom
|
||||
C37,71.755,-127.889,90.0,bottom
|
||||
C38,72.235,-126.492,180.0,bottom
|
||||
C39,69.723,-116.967,90.0,bottom
|
||||
C4,72.29,-106.03,0.0,top
|
||||
C40,75.22,-140.01,180.0,bottom
|
||||
C41,80.88,-133.38,270.0,top
|
||||
C42,79.77,-138.27,270.0,bottom
|
||||
C5,69.878,-136.525,0.0,top
|
||||
C6,73.57,-95.78,180.0,top
|
||||
C7,73.787,-135.791,270.0,top
|
||||
C8,75.692,-119.225,90.0,top
|
||||
C9,78.47,-90.94,0.0,top
|
||||
J1,75.179,-140.322,0.0,top
|
||||
J3,75.08,-100.475,180.0,bottom
|
||||
L1,76.515,-92.01,0.0,top
|
||||
L2,78.46,-92.01,0.0,top
|
||||
L3,77.978,-124.013,270.0,bottom
|
||||
L4,77.0635,-117.348,180.0,bottom
|
||||
R1,67.183,-95.504,0.0,top
|
||||
R10,67.181,-118.237,0.0,top
|
||||
R11,67.183,-123.317,0.0,top
|
||||
R12,67.183,-125.857,0.0,top
|
||||
R13,67.183,-128.397,0.0,top
|
||||
R14,67.183,-130.937,0.0,top
|
||||
R15,67.18,-133.49,180.0,top
|
||||
R16,67.19,-136.0,180.0,top
|
||||
R17,67.17,-138.56,180.0,top
|
||||
R18,67.19,-141.09,180.0,top
|
||||
R19,69.19,-142.35,180.0,top
|
||||
R2,67.183,-97.917,0.0,top
|
||||
R20,73.787,-133.475,90.0,top
|
||||
R21,75.01,-91.54,90.0,top
|
||||
R22,77.4,-95.78,0.0,top
|
||||
R23,75.48,-95.78,0.0,top
|
||||
R24,77.341,-134.62,180.0,top
|
||||
R25,77.345,-135.6106,180.0,top
|
||||
R26,80.15,-120.04,180.0,top
|
||||
R27,80.89,-142.37,0.0,top
|
||||
R28,82.931,-95.377,180.0,top
|
||||
R29,82.933,-97.917,180.0,top
|
||||
R3,67.183,-100.457,0.0,top
|
||||
R30,82.929,-100.457,180.0,top
|
||||
R31,82.931,-102.997,180.0,top
|
||||
R32,82.931,-105.537,180.0,top
|
||||
R33,82.933,-108.077,180.0,top
|
||||
R34,82.931,-110.617,180.0,top
|
||||
R35,82.929,-113.157,180.0,top
|
||||
R36,82.931,-115.697,180.0,top
|
||||
R37,82.929,-118.237,180.0,top
|
||||
R38,82.931,-120.777,180.0,top
|
||||
R39,82.933,-125.857,0.0,top
|
||||
R4,67.181,-102.997,0.0,top
|
||||
R40,82.929,-128.397,0.0,top
|
||||
R41,82.92,-130.93,0.0,top
|
||||
R42,82.93,-133.5,0.0,top
|
||||
R43,82.93,-135.99,0.0,top
|
||||
R44,82.93,-138.56,0.0,top
|
||||
R45,82.93,-141.09,0.0,top
|
||||
R46,80.264,-111.76,270.0,bottom
|
||||
R47,80.88,-133.38,90.0,bottom
|
||||
R48,77.724,-109.599,90.0,bottom
|
||||
R49,78.105,-126.998,270.0,bottom
|
||||
R5,67.183,-105.537,0.0,top
|
||||
R50,75.692,-109.599,90.0,bottom
|
||||
R51,76.708,-109.599,270.0,bottom
|
||||
R52,68.88,-129.05,270.0,bottom
|
||||
R53,69.89,-129.05,270.0,bottom
|
||||
R54,74.676,-109.599,90.0,bottom
|
||||
R55,74.166,-112.522,0.0,bottom
|
||||
R56,70.612,-109.601,90.0,bottom
|
||||
R57,71.628,-109.601,90.0,bottom
|
||||
R58,72.39,-113.286,270.0,bottom
|
||||
R59,69.596,-109.601,90.0,bottom
|
||||
R6,67.19,-108.08,180.0,top
|
||||
R60,72.15,-111.07,180.0,bottom
|
||||
R7,67.183,-110.617,0.0,top
|
||||
R8,67.183,-113.157,0.0,top
|
||||
R9,67.183,-115.697,0.0,top
|
||||
U2,72.115,-114.4,270.0,top
|
||||
U3,75.04,-100.98,0.0,top
|
||||
U4,75.035,-126.2945,270.0,top
|
||||
U5,78.359,-114.365,180.0,top
|
||||
U6,75.0515,-114.874,180.0,bottom
|
||||
U7,76.97,-134.6925,270.0,bottom
|
||||
Y1,71.036,-134.179,0.0,top
|
||||
Y2,71.05,-134.18,180.0,bottom
|
||||
|
38
projects/tzpuPico/kicad/PICOZ80/bom/JLCPCB_BOM.csv
vendored
Normal file
38
projects/tzpuPico/kicad/PICOZ80/bom/JLCPCB_BOM.csv
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
Designator,Footprint,Quantity,Value,LCSC Part #
|
||||
AE1,Walsin_RFANT3216120A5T_3216,1,Chip Antenna,C127629
|
||||
"C1, C6",0402,2,22uF/10V,C3845593
|
||||
"C10, C9",0402,2,1.5pF,C2980160
|
||||
"C11, C14, C15, C2, C20, C25, C26, C27, C28, C3, C32, C33, C34, C35, C36, C37, C38, C39, C4, C40, C42, C8",0402,22,100nF,C1525
|
||||
"C12, C22, C41",0402,3,10uF,C307415
|
||||
C13,0402,1,1uF/6.3V,C314234
|
||||
"C16, C17",0603,2,22uF,C2762594
|
||||
"C18, C19, C21, C29",0402,4,4.7uF,C318563
|
||||
C23,0402,1,6.8pF,C318598
|
||||
C24,0805,1,100uF,C6882730
|
||||
C30,0603,1,10uF,C1691
|
||||
C31,0603,1,1uF,C5199872
|
||||
"C5, C7",0402,2,15pF,C106997
|
||||
J1,USB_Micro-B_Amphenol_10103594-0001LF_Horizontal,1,USB_B_Mini,C428495
|
||||
J2,PinHeader_1x06_P1.00mm_Vertical,1,JST Debug,
|
||||
J3,MOLEX_104031-0811,1,SD Drive,C585350
|
||||
L1,0402,1,6.8nH,C882467
|
||||
L2,0402,1,2.7nH,C412269
|
||||
L3,0805,1,3.3u,C48888263
|
||||
L4,0603,1,2.2uH/1.05A,C337911
|
||||
"R1, R17, R18, R19, R2, R27, R28, R29, R3, R30, R31, R32, R33, R34, R35, R36, R37, R38, R39, R4, R40, R44, R45, R5, R52, R53",0402,26,22R,C2906914
|
||||
"R10, R11, R12, R13, R14, R20, R26, R7, R8, R9",0402,10,1K,C11702
|
||||
"R15, R16, R21, R41, R42, R43, R6",0402,7,0R,C17168
|
||||
"R22, R23, R46, R50, R51, R54, R56, R57, R59, R60",0402,10,10K,C60490
|
||||
"R24, R25",0402,2,27R,C5151586
|
||||
"R47, R48",0402,2,47K,C25792
|
||||
R49,0402,1,33R,C25105
|
||||
R55,0402,1,200K,C114763
|
||||
R58,0402,1,44.2K,C853281
|
||||
U1,DIP-40_W15.24mm_Extender_NoCourtyard_SmallPad,1,EXTENDER,
|
||||
U2,WSON-8-1EP_6x5mm_P1.27mm_EP3.4x4.3mm,1,W25Q128JVPIQ,C190862
|
||||
U3,QFN-56-1EP_7x7mm_P0.4mm_EP4x4mm,1,ESP32-S3-PICO-1 N8R8,C7545129
|
||||
U4,RP2350-QFN-80-1EP_10x10_P0.4mm_EP3.4x3.4mm_ThermalVias,1,RP2350_A4_80QFN,C42415655
|
||||
U5,SOP-8_3.9x4.9mm_P1.27mm,1,APS6404L-3SQR-SN,C5333729
|
||||
U6,SOT-23-5,1,TLV62569DBV,C141836
|
||||
U7,QFN-24-1EP_4x4mm_P0.5mm_EP2.7x2.7mm,1,CH334F,C5187527
|
||||
"Y1, Y2",Crystal_SMD_3225-4Pin_3.2x2.5mm,2,ABM8-272-T3 12MHz,C20625731
|
||||
|
BIN
projects/tzpuPico/tools/MZQD/BASIC_5Z008A_SideA.qdf
vendored
Normal file
BIN
projects/tzpuPico/tools/MZQD/BASIC_5Z008A_SideA.qdf
vendored
Normal file
Binary file not shown.
BIN
projects/tzpuPico/tools/MZQD/BASIC_5Z008A_SideB.qdf
vendored
Normal file
BIN
projects/tzpuPico/tools/MZQD/BASIC_5Z008A_SideB.qdf
vendored
Normal file
Binary file not shown.
BIN
projects/tzpuPico/tools/MZQD/MZQDTool
vendored
Executable file
BIN
projects/tzpuPico/tools/MZQD/MZQDTool
vendored
Executable file
Binary file not shown.
366
projects/tzpuPico/tools/MZQD/MZQDTool.c
Executable file
366
projects/tzpuPico/tools/MZQD/MZQDTool.c
Executable file
@@ -0,0 +1,366 @@
|
||||
/* =========================================================================
|
||||
* MZQDTool — Sharp MZ-700 Quick Disk (QD) image tool
|
||||
*
|
||||
* Creates and manages QD disk images for the MZ-700 Quick Disk system.
|
||||
* Supports format, directory listing, and adding MZF files to QD images.
|
||||
*
|
||||
* Original V0.30 (c) 2002 by BKK
|
||||
* Updated V1.00 (c) 2026 Philip Smart — rewritten with configurable disk
|
||||
* name, fixed file ordering, correct CMT→QD header conversion,
|
||||
* and robust error handling.
|
||||
*
|
||||
* QD disk image format (61455 bytes):
|
||||
*
|
||||
* Disk header:
|
||||
* [00] [16 16] [A5] [block_count] [CRC: 43 52 43]
|
||||
*
|
||||
* Per file (2 blocks each: header + data):
|
||||
*
|
||||
* Header block:
|
||||
* [00] [16 16] [A5] [00] [size_lo=40] [size_hi=00]
|
||||
* [64 bytes: QDHeaderStr]
|
||||
* [CRC: 43 52 43]
|
||||
*
|
||||
* Data block:
|
||||
* [00] [16 16] [A5] [05] [size_lo] [size_hi]
|
||||
* [file data]
|
||||
* [CRC: 43 52 43]
|
||||
*
|
||||
* Usage:
|
||||
* MZQDTool format [-o disk.qd]
|
||||
* MZQDTool dir [-o disk.qd]
|
||||
* MZQDTool add <file.mzf> [-o disk.qd]
|
||||
* ========================================================================= */
|
||||
|
||||
#define VERSION "1.00"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define QDSIZE 61455
|
||||
#define MAXQDFILETYPES 12
|
||||
#define DEFAULTQDFILE "MZ700.qd"
|
||||
#define CMTHDRSIZE 128 /* MZF/CMT file header size */
|
||||
#define QDHDRSIZE 64 /* QD file header size */
|
||||
|
||||
/* MZF/CMT tape file header (128 bytes) */
|
||||
struct CMTHeaderStr {
|
||||
uint8_t Attribute; /* File type: 01=OBJ, 02=BTX, etc. */
|
||||
char Name[17]; /* Filename (CR-terminated, null-padded) */
|
||||
uint16_t Size; /* Data size (0 = use actual file size) */
|
||||
uint16_t LoadAddress; /* Load address (DTADR) */
|
||||
uint16_t ExecAddress; /* Execution address (EXADR) */
|
||||
char Comment[104]; /* Comment area */
|
||||
};
|
||||
|
||||
/* QD file header (64 bytes, stored in header block) */
|
||||
struct QDHeaderStr {
|
||||
uint8_t Attribute; /* File type: 01=OBJ, 02=BTX, etc. */
|
||||
char Name[17]; /* Filename (CR-terminated, null-padded) */
|
||||
uint16_t Unknown; /* Reserved (usually 0) */
|
||||
uint16_t Size; /* Data size in bytes */
|
||||
uint16_t LoadAddress; /* Load address */
|
||||
uint16_t ExecAddress; /* Execution address */
|
||||
char Comment[38]; /* Comment (truncated from CMT's 104) */
|
||||
};
|
||||
|
||||
static const char *QDFileTypes[MAXQDFILETYPES] = {
|
||||
"???", "OBJ", "BTX", "BSD", "BRD", "RB ",
|
||||
"???", "LIB", "???", "???", "SYS", "GR "
|
||||
};
|
||||
|
||||
static uint8_t QDArray[QDSIZE];
|
||||
static char qdFileName[256] = DEFAULTQDFILE;
|
||||
|
||||
/* ------- Low-level QD block I/O helpers ------- */
|
||||
|
||||
static void write_sync(uint16_t *ptr)
|
||||
{
|
||||
QDArray[(*ptr)++] = 0x00; /* BREAK */
|
||||
QDArray[(*ptr)++] = 0x16; /* SYNC */
|
||||
QDArray[(*ptr)++] = 0x16; /* SYNC */
|
||||
QDArray[(*ptr)++] = 0xA5; /* SHARP SYNC */
|
||||
}
|
||||
|
||||
static void write_crc(uint16_t *ptr)
|
||||
{
|
||||
QDArray[(*ptr)++] = 'C';
|
||||
QDArray[(*ptr)++] = 'R';
|
||||
QDArray[(*ptr)++] = 'C';
|
||||
}
|
||||
|
||||
static int save_qd(void)
|
||||
{
|
||||
FILE *f = fopen(qdFileName, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "ERROR: Cannot write '%s'\n", qdFileName);
|
||||
return 0;
|
||||
}
|
||||
fwrite(QDArray, QDSIZE, 1, f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int load_qd(void)
|
||||
{
|
||||
FILE *f = fopen(qdFileName, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "ERROR: Cannot open '%s'\n", qdFileName);
|
||||
return 0;
|
||||
}
|
||||
fread(QDArray, QDSIZE, 1, f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ------- Commands ------- */
|
||||
|
||||
/* Format: create an empty QD image with 0 files */
|
||||
static void QDFormat(void)
|
||||
{
|
||||
uint16_t ptr = 0;
|
||||
|
||||
printf("Formatting '%s' (%d bytes)\n", qdFileName, QDSIZE);
|
||||
memset(QDArray, 0x00, QDSIZE);
|
||||
|
||||
/* Disk header: sync + block_count(0) + CRC */
|
||||
write_sync(&ptr);
|
||||
QDArray[ptr++] = 0x00; /* 0 blocks */
|
||||
write_crc(&ptr);
|
||||
|
||||
if (!save_qd()) exit(1);
|
||||
puts("Done.");
|
||||
}
|
||||
|
||||
/* Dir: list files on the QD */
|
||||
static void QDDir(void)
|
||||
{
|
||||
uint16_t ptr, blockSize;
|
||||
uint8_t blocks, i;
|
||||
|
||||
if (!load_qd()) exit(1);
|
||||
|
||||
/* Disk header: 4 sync bytes + block_count + 3 CRC */
|
||||
ptr = 4;
|
||||
blocks = QDArray[ptr++];
|
||||
ptr += 3; /* skip CRC */
|
||||
|
||||
printf("Directory of '%s': %d block(s), %d file(s)\n\n",
|
||||
qdFileName, blocks, blocks / 2);
|
||||
|
||||
for (i = 0; i < blocks; i++) {
|
||||
if (ptr + 7 >= QDSIZE) {
|
||||
fprintf(stderr, "WARNING: Truncated QD image at block %d\n", i);
|
||||
break;
|
||||
}
|
||||
ptr += 4; /* sync: 00 16 16 A5 */
|
||||
|
||||
uint8_t blockType = QDArray[ptr++];
|
||||
blockSize = QDArray[ptr] | (QDArray[ptr + 1] << 8);
|
||||
ptr += 2;
|
||||
|
||||
if (blockType == 0x00 && blockSize == QDHDRSIZE) {
|
||||
/* File header block */
|
||||
struct QDHeaderStr *hdr = (struct QDHeaderStr *)&QDArray[ptr];
|
||||
uint8_t ft = hdr->Attribute;
|
||||
if (ft >= MAXQDFILETYPES) ft = 0;
|
||||
|
||||
/* Format name: stop at CR or end of field */
|
||||
char name[18];
|
||||
memcpy(name, hdr->Name, 17);
|
||||
name[17] = '\0';
|
||||
for (int j = 0; j < 17; j++) {
|
||||
if (name[j] == '\r' || name[j] == '\0') { name[j] = '\0'; break; }
|
||||
}
|
||||
|
||||
printf(" %-3s %-17s Size=%-6u Load=0x%04X Exec=0x%04X\n",
|
||||
QDFileTypes[ft], name, hdr->Size,
|
||||
hdr->LoadAddress, hdr->ExecAddress);
|
||||
} else if (blockType == 0x05) {
|
||||
/* Data block — skip silently */
|
||||
} else {
|
||||
printf(" [block %d: type=0x%02X size=%u]\n", i, blockType, blockSize);
|
||||
}
|
||||
|
||||
ptr += blockSize;
|
||||
ptr += 3; /* skip CRC */
|
||||
}
|
||||
printf("\n%u bytes free\n", QDSIZE - ptr);
|
||||
}
|
||||
|
||||
/* Add: append an MZF file to the QD image */
|
||||
static void AddFileToQD(const char *mzfFileName)
|
||||
{
|
||||
FILE *mzfFile;
|
||||
uint16_t ptr, fileDataSize;
|
||||
uint8_t blocks, i;
|
||||
uint16_t blockSize;
|
||||
struct CMTHeaderStr cmtHdr;
|
||||
|
||||
if (!load_qd()) exit(1);
|
||||
|
||||
/* Read block count and skip to end of existing data */
|
||||
ptr = 4;
|
||||
blocks = QDArray[ptr];
|
||||
ptr = 5 + 3; /* past block_count + CRC */
|
||||
|
||||
for (i = 0; i < blocks; i++) {
|
||||
ptr += 4; /* sync */
|
||||
ptr++; /* block type */
|
||||
blockSize = QDArray[ptr] | (QDArray[ptr + 1] << 8);
|
||||
ptr += 2;
|
||||
ptr += blockSize;
|
||||
ptr += 3; /* CRC */
|
||||
}
|
||||
|
||||
/* Open and read MZF file */
|
||||
mzfFile = fopen(mzfFileName, "rb");
|
||||
if (!mzfFile) {
|
||||
fprintf(stderr, "ERROR: Cannot open '%s'\n", mzfFileName);
|
||||
exit(1);
|
||||
}
|
||||
fseek(mzfFile, 0, SEEK_END);
|
||||
long mzfTotalSize = ftell(mzfFile);
|
||||
fseek(mzfFile, 0, SEEK_SET);
|
||||
|
||||
if (mzfTotalSize < CMTHDRSIZE) {
|
||||
fprintf(stderr, "ERROR: '%s' is too small for MZF format (%ld bytes)\n",
|
||||
mzfFileName, mzfTotalSize);
|
||||
fclose(mzfFile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fread(&cmtHdr, CMTHDRSIZE, 1, mzfFile);
|
||||
fileDataSize = (uint16_t)(mzfTotalSize - CMTHDRSIZE);
|
||||
|
||||
/* Check available space */
|
||||
uint32_t needed = (4+1+2+QDHDRSIZE+3) + (4+1+2+(uint32_t)fileDataSize+3);
|
||||
if (ptr + needed > QDSIZE) {
|
||||
fprintf(stderr, "ERROR: Not enough space (need %u, have %u)\n",
|
||||
(unsigned)needed, QDSIZE - ptr);
|
||||
fclose(mzfFile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* ---- Write header block ---- */
|
||||
write_sync(&ptr);
|
||||
QDArray[ptr++] = 0x00; /* block type: file header */
|
||||
QDArray[ptr++] = QDHDRSIZE; /* size low */
|
||||
QDArray[ptr++] = 0x00; /* size high */
|
||||
|
||||
struct QDHeaderStr *qdHdr = (struct QDHeaderStr *)&QDArray[ptr];
|
||||
memset(qdHdr, 0, QDHDRSIZE);
|
||||
|
||||
/* Convert CMT header to QD header */
|
||||
qdHdr->Attribute = cmtHdr.Attribute;
|
||||
if (qdHdr->Attribute == 0x05)
|
||||
qdHdr->Attribute = 0x02; /* MZF tape type 05 → QD type 02 (BTX) */
|
||||
memcpy(qdHdr->Name, cmtHdr.Name, 17);
|
||||
qdHdr->Unknown = 0;
|
||||
|
||||
/*
|
||||
* Size field handling:
|
||||
* - If MZF Size > 0: use it directly (normal file)
|
||||
* - If MZF Size == 0: use actual file data size (convention for
|
||||
* ROM images where Size=0 means "whole file"). The QD header
|
||||
* MUST have the real size — the QD loader uses it to determine
|
||||
* how many bytes to read.
|
||||
*/
|
||||
if (cmtHdr.Size != 0)
|
||||
qdHdr->Size = cmtHdr.Size;
|
||||
else
|
||||
qdHdr->Size = fileDataSize;
|
||||
|
||||
qdHdr->LoadAddress = cmtHdr.LoadAddress;
|
||||
qdHdr->ExecAddress = cmtHdr.ExecAddress;
|
||||
memcpy(qdHdr->Comment, cmtHdr.Comment, 38);
|
||||
|
||||
ptr += QDHDRSIZE;
|
||||
write_crc(&ptr);
|
||||
|
||||
/* ---- Write data block ---- */
|
||||
write_sync(&ptr);
|
||||
QDArray[ptr++] = 0x05; /* block type: file data */
|
||||
QDArray[ptr++] = fileDataSize & 0xFF;
|
||||
QDArray[ptr++] = (fileDataSize >> 8) & 0xFF;
|
||||
fread(&QDArray[ptr], 1, fileDataSize, mzfFile);
|
||||
ptr += fileDataSize;
|
||||
write_crc(&ptr);
|
||||
|
||||
fclose(mzfFile);
|
||||
|
||||
/* Update block count (+2: one header block, one data block) */
|
||||
QDArray[4] = blocks + 2;
|
||||
|
||||
/* Format name for display */
|
||||
char name[18];
|
||||
memcpy(name, cmtHdr.Name, 17);
|
||||
name[17] = '\0';
|
||||
for (int j = 0; j < 17; j++) {
|
||||
if (name[j] == '\r' || name[j] == '\0') { name[j] = '\0'; break; }
|
||||
}
|
||||
|
||||
printf(" Added: type=0x%02X name=\"%s\" size=%u load=0x%04X exec=0x%04X\n",
|
||||
qdHdr->Attribute, name, qdHdr->Size,
|
||||
qdHdr->LoadAddress, qdHdr->ExecAddress);
|
||||
printf(" QD: %d blocks, %u bytes free\n", blocks + 2, QDSIZE - ptr);
|
||||
|
||||
if (!save_qd()) exit(1);
|
||||
}
|
||||
|
||||
/* ------- Usage and main ------- */
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
printf("Usage:\n");
|
||||
printf(" MZQDTool format [-o disk.qd] Format empty QD image\n");
|
||||
printf(" MZQDTool dir [-o disk.qd] List QD directory\n");
|
||||
printf(" MZQDTool add <file.mzf> [-o disk.qd] Add MZF file to QD\n");
|
||||
printf("\n");
|
||||
printf("Options:\n");
|
||||
printf(" -o <filename> QD image file (default: %s)\n", DEFAULTQDFILE);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("\nMZQDTool V%s (c) 2002 BKK, 2026 Philip Smart\n\n", VERSION);
|
||||
|
||||
if (argc < 2) {
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Parse -o option from any position */
|
||||
for (int i = 1; i < argc - 1; i++) {
|
||||
if (strcmp("-o", argv[i]) == 0) {
|
||||
strncpy(qdFileName, argv[i + 1], sizeof(qdFileName) - 1);
|
||||
qdFileName[sizeof(qdFileName) - 1] = '\0';
|
||||
/* Remove -o and its argument from argv for command parsing */
|
||||
for (int j = i; j < argc - 2; j++)
|
||||
argv[j] = argv[j + 2];
|
||||
argc -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp("format", argv[1]) == 0) {
|
||||
QDFormat();
|
||||
} else if (strcmp("dir", argv[1]) == 0) {
|
||||
QDDir();
|
||||
} else if (strcmp("add", argv[1]) == 0) {
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "ERROR: No MZF file specified\n");
|
||||
return 2;
|
||||
}
|
||||
AddFileToQD(argv[2]);
|
||||
} else {
|
||||
fprintf(stderr, "ERROR: Unknown command '%s'\n", argv[1]);
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
19
projects/tzpuPico/tools/MZQD/Makefile
vendored
Normal file
19
projects/tzpuPico/tools/MZQD/Makefile
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# MZQDTool - Sharp MZ-700 Quick Disk image tool
|
||||
# (c) 2002 BKK, 2026 Philip Smart
|
||||
#
|
||||
# Usage:
|
||||
# make Build MZQDTool
|
||||
# make clean Remove build artifacts
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wno-unused-result -O2
|
||||
TARGET = MZQDTool
|
||||
SRC = MZQDTool.c
|
||||
|
||||
$(TARGET): $(SRC)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET)
|
||||
|
||||
.PHONY: clean
|
||||
BIN
projects/tzpuPico/tools/MZQD/side_a/AUTO RUN.mzf
vendored
Normal file
BIN
projects/tzpuPico/tools/MZQD/side_a/AUTO RUN.mzf
vendored
Normal file
Binary file not shown.
BIN
projects/tzpuPico/tools/MZQD/side_a/BASIC 5Z008A RFS.mzf
vendored
Normal file
BIN
projects/tzpuPico/tools/MZQD/side_a/BASIC 5Z008A RFS.mzf
vendored
Normal file
Binary file not shown.
BIN
projects/tzpuPico/tools/MZQD/side_a/BASIC 5Z008ADRFS.mzf
vendored
Normal file
BIN
projects/tzpuPico/tools/MZQD/side_a/BASIC 5Z008ADRFS.mzf
vendored
Normal file
Binary file not shown.
BIN
projects/tzpuPico/tools/MZQD/side_a/BASIC MZ-5Z008 ORIG.mzf
vendored
Normal file
BIN
projects/tzpuPico/tools/MZQD/side_a/BASIC MZ-5Z008 ORIG.mzf
vendored
Normal file
Binary file not shown.
BIN
projects/tzpuPico/tools/MZQD/side_a/BASIC MZ-5Z008.mzf
vendored
Normal file
BIN
projects/tzpuPico/tools/MZQD/side_a/BASIC MZ-5Z008.mzf
vendored
Normal file
Binary file not shown.
BIN
projects/tzpuPico/tools/MZQD/side_b/DELETE.mzf
vendored
Normal file
BIN
projects/tzpuPico/tools/MZQD/side_b/DELETE.mzf
vendored
Normal file
Binary file not shown.
BIN
projects/tzpuPico/tools/MZQD/side_b/QDCOPY.mzf
vendored
Normal file
BIN
projects/tzpuPico/tools/MZQD/side_b/QDCOPY.mzf
vendored
Normal file
Binary file not shown.
BIN
projects/tzpuPico/tools/MZQD/side_b/TRANS.mzf
vendored
Normal file
BIN
projects/tzpuPico/tools/MZQD/side_b/TRANS.mzf
vendored
Normal file
Binary file not shown.
BIN
projects/tzpuPico/tools/MZQD/side_b_applications/OPENING 800.mzf
vendored
Normal file
BIN
projects/tzpuPico/tools/MZQD/side_b_applications/OPENING 800.mzf
vendored
Normal file
Binary file not shown.
BIN
projects/tzpuPico/tools/MZQD/side_b_applications/OPENING DATA.mzf
vendored
Normal file
BIN
projects/tzpuPico/tools/MZQD/side_b_applications/OPENING DATA.mzf
vendored
Normal file
Binary file not shown.
BIN
projects/tzpuPico/tools/MZQDTool
vendored
Executable file
BIN
projects/tzpuPico/tools/MZQDTool
vendored
Executable file
Binary file not shown.
@@ -1,385 +0,0 @@
|
||||
#define VERSION "0.30"
|
||||
|
||||
#define FMS 0xEFFF
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define QDSIZE 61455
|
||||
#define MAXQDFILETYPES 12
|
||||
|
||||
|
||||
|
||||
struct CMTHeaderStr
|
||||
{
|
||||
unsigned char Attribute;
|
||||
char Name[17];
|
||||
unsigned short Size;
|
||||
unsigned short LoadAddress;
|
||||
unsigned short ExecAddress;
|
||||
char Comment[104];
|
||||
};
|
||||
|
||||
|
||||
struct QDHeaderStr
|
||||
{
|
||||
unsigned char Attribute;
|
||||
char Name[17];
|
||||
unsigned short Unknown;
|
||||
unsigned short Size;
|
||||
unsigned short LoadAddress;
|
||||
unsigned short ExecAddress;
|
||||
char Comment[38];
|
||||
};
|
||||
|
||||
|
||||
char QDFileTypes[MAXQDFILETYPES][4] = {
|
||||
"???",
|
||||
"OBJ",
|
||||
"BTX",
|
||||
"BSD",
|
||||
"BRD",
|
||||
"RB ",
|
||||
"???",
|
||||
"LIB",
|
||||
"???",
|
||||
"???",
|
||||
"SYS",
|
||||
"GR "
|
||||
};
|
||||
|
||||
|
||||
unsigned char QDArray[QDSIZE];
|
||||
unsigned short QDPtr;
|
||||
|
||||
|
||||
|
||||
|
||||
void QDFormat(void)
|
||||
{
|
||||
FILE *QDFile;
|
||||
unsigned char QDFormatByte;
|
||||
unsigned short Counter;
|
||||
|
||||
|
||||
puts("Format");
|
||||
|
||||
|
||||
QDPtr = 0;
|
||||
|
||||
QDArray[QDPtr++] = 0x00; // BREAK
|
||||
QDArray[QDPtr++] = 0x16; // SYNC CHAR1
|
||||
QDArray[QDPtr++] = 0x16; // SYNC CHAR2
|
||||
QDArray[QDPtr++] = 0xA5; // SHARP SYNC
|
||||
QDArray[QDPtr++] = 0x00; // 0 data blocks on disk
|
||||
QDArray[QDPtr++] = 'C'; // CRC
|
||||
QDArray[QDPtr++] = 'R'; // CRC
|
||||
QDArray[QDPtr++] = 'C'; //
|
||||
QDArray[QDPtr++] = 0x00; // BREAK
|
||||
QDArray[QDPtr++] = 0x16; // SYNC CHAR1
|
||||
QDArray[QDPtr++] = 0x16; // SYNC CHAR2
|
||||
QDArray[QDPtr++] = 0xA5;
|
||||
// 12
|
||||
QDFormatByte = 0xAA;
|
||||
Counter = FMS - 65; // FMS 0xEFFF = 61439, 61455 - 61439 = 16
|
||||
do
|
||||
{
|
||||
QDFormatByte = ~QDFormatByte;
|
||||
QDArray[QDPtr++] = QDFormatByte;
|
||||
Counter--;
|
||||
} while(Counter != 0);
|
||||
|
||||
QDArray[QDPtr++] = 0x00;
|
||||
QDArray[QDPtr++] = 'C'; // CRC
|
||||
QDArray[QDPtr++] = 'R'; // CRC
|
||||
QDArray[QDPtr++] = 'C'; // CRC
|
||||
QDArray[QDPtr++] = 0x00;
|
||||
|
||||
// *** ADD DIRECTORY TERMINATOR ***
|
||||
uint32_t termPos = QDSIZE - 64; // Last 64 bytes
|
||||
memset(&QDArray[termPos], 0, 64);
|
||||
QDArray[termPos + 0] = 0x00; // BREAK
|
||||
QDArray[termPos + 1] = 0x16;
|
||||
QDArray[termPos + 2] = 0x16;
|
||||
QDArray[termPos + 3] = 0xA5;
|
||||
QDArray[termPos + 4] = 0x00; // attribute 0 = end of directory
|
||||
QDArray[termPos + 5] = 0x40; // size low (64)
|
||||
QDArray[termPos + 6] = 0x00; // size high
|
||||
// rest zero
|
||||
|
||||
if((QDFile = fopen("MZ700.QD", "wb")) != NULL)
|
||||
{
|
||||
fwrite(QDArray, QDSIZE, 1, QDFile);
|
||||
fclose(QDFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
unsigned short SeekSync(unsigned short Ptr)
|
||||
{
|
||||
unsigned char SyncFound;
|
||||
|
||||
|
||||
SyncFound = FALSE;
|
||||
do
|
||||
{
|
||||
if(QDArray[Ptr++] == 0x16)
|
||||
{
|
||||
if(QDArray[Ptr++] == 0x16) SyncFound = TRUE;
|
||||
else Ptr--;
|
||||
}
|
||||
} while(!SyncFound && (Ptr <= QDSIZE));
|
||||
|
||||
return(Ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void QDDir(void)
|
||||
{
|
||||
FILE *QDFile;
|
||||
unsigned char QDBlocks;
|
||||
unsigned char Counter;
|
||||
unsigned char QDFileType;
|
||||
unsigned short QDBlockSize;
|
||||
unsigned short PtrSave;
|
||||
|
||||
|
||||
if((QDFile = fopen("MZ700.qd", "rb")) != NULL)
|
||||
{
|
||||
fread(QDArray, QDSIZE, 1, QDFile);
|
||||
fclose(QDFile);
|
||||
|
||||
QDPtr = 0;
|
||||
QDPtr = SeekSync(QDPtr);
|
||||
|
||||
QDPtr++;
|
||||
QDBlocks = QDArray[QDPtr];
|
||||
|
||||
puts("DIRECTORY OF QD:");
|
||||
|
||||
for(Counter = 0; Counter < QDBlocks; Counter++)
|
||||
{
|
||||
QDPtr = SeekSync(QDPtr);
|
||||
PtrSave = QDPtr;
|
||||
|
||||
QDBlockSize = QDArray[QDPtr + 2];
|
||||
QDBlockSize = QDBlockSize + QDArray[QDPtr + 3] * 256;
|
||||
// printf("BLSize: %u -> %04X\n", QDBlockSize, QDBlockSize);
|
||||
|
||||
QDPtr++;
|
||||
if(QDArray[QDPtr] == 0x00)
|
||||
{
|
||||
QDPtr += 3;
|
||||
|
||||
QDFileType = QDArray[QDPtr++];
|
||||
if(QDFileType >= MAXQDFILETYPES) QDFileType = 0;
|
||||
printf(" %s \"", QDFileTypes[QDFileType]);
|
||||
do
|
||||
{
|
||||
printf("%c", QDArray[QDPtr++]);
|
||||
} while(QDArray[QDPtr] != 0x0d);
|
||||
puts("\"");
|
||||
}
|
||||
QDPtr = PtrSave + QDBlockSize;
|
||||
}
|
||||
puts("Ready");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AddFileToQD(char *MZFileName)
|
||||
{
|
||||
FILE *QDFile;
|
||||
FILE *MZFFile;
|
||||
unsigned short FilePos;
|
||||
unsigned short MZFFileSize;
|
||||
unsigned short QDPtr;
|
||||
unsigned char QDBlocks;
|
||||
unsigned short QDBlockSize;
|
||||
unsigned short Counter;
|
||||
unsigned short *usPtr;
|
||||
|
||||
unsigned char CMTHeader[sizeof(struct CMTHeaderStr)];
|
||||
struct CMTHeaderStr *CMTHeaderPtr;
|
||||
struct QDHeaderStr *QDHeaderPtr;
|
||||
|
||||
|
||||
printf("try to add %s\n", MZFileName);
|
||||
|
||||
if((QDFile = fopen("MZ700.QD", "rb")) == NULL)
|
||||
{
|
||||
puts("file MZ700.QD not found");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
fread(QDArray, QDSIZE, 1, QDFile);
|
||||
fclose(QDFile);
|
||||
|
||||
QDPtr = 0;
|
||||
QDPtr = SeekSync(QDPtr);
|
||||
|
||||
QDPtr++;
|
||||
QDBlocks = QDArray[QDPtr++];
|
||||
|
||||
QDPtr = QDPtr + 3; // jump over CRC
|
||||
|
||||
for(Counter = 0; Counter < QDBlocks; Counter++)
|
||||
{
|
||||
QDPtr = SeekSync(QDPtr);
|
||||
|
||||
QDPtr = QDPtr + 2; // jump over 0xA5 and the next byte
|
||||
|
||||
QDBlockSize = QDArray[QDPtr++];
|
||||
QDBlockSize = QDBlockSize + QDArray[QDPtr++] * 256;
|
||||
// printf("BLSize: %u -> %04X\n", QDBlockSize, QDBlockSize);
|
||||
|
||||
QDPtr = QDPtr + QDBlockSize;
|
||||
|
||||
QDPtr = QDPtr + 3; // jump over CRC
|
||||
}
|
||||
|
||||
|
||||
if((MZFFile = fopen(MZFileName, "rb")) == NULL)
|
||||
{
|
||||
printf("file %s not found\n", MZFileName);
|
||||
exit(5);
|
||||
}
|
||||
|
||||
fseek(MZFFile, 0, SEEK_END);
|
||||
MZFFileSize = ftell(MZFFile);
|
||||
fseek(MZFFile, 0, SEEK_SET);
|
||||
|
||||
if(MZFFileSize > (QDSIZE - QDPtr + 14))
|
||||
{
|
||||
printf("file %s is to big, only %u bytes free\n", MZFileName, QDSIZE - QDPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
QDArray[QDPtr++] = 0x00; // BREAK
|
||||
QDArray[QDPtr++] = 0x16; // SYNCCHAR1
|
||||
QDArray[QDPtr++] = 0x16; // SYNCCHAR2
|
||||
|
||||
QDArray[QDPtr++] = 0xA5;
|
||||
QDArray[QDPtr++] = 0x00;
|
||||
|
||||
QDArray[QDPtr++] = 64; // headerlength fixed
|
||||
QDArray[QDPtr++] = 0x00;
|
||||
|
||||
/*
|
||||
fread(&QDArray[QDPtr], 1, 64, MZFFile);
|
||||
if(QDArray[QDPtr] == 0x05) QDArray[QDPtr] = 2; // BTX file
|
||||
QDPtr = QDPtr + 64;
|
||||
fseek(MZFFile, 128, SEEK_SET); // go to end of MZF header
|
||||
*/
|
||||
|
||||
fread(CMTHeader, 1, sizeof(struct CMTHeaderStr), MZFFile);
|
||||
CMTHeaderPtr = (struct CMTHeaderStr *) &CMTHeader[0];
|
||||
|
||||
QDHeaderPtr = (struct QDHeaderStr *) &QDArray[QDPtr];
|
||||
|
||||
QDHeaderPtr->Attribute = CMTHeaderPtr->Attribute;
|
||||
if(CMTHeaderPtr->Size != 0)
|
||||
{
|
||||
if(QDHeaderPtr->Attribute == 0x05) QDHeaderPtr->Attribute = 0x02;
|
||||
}
|
||||
memcpy(QDHeaderPtr->Name, CMTHeaderPtr->Name, 17);
|
||||
|
||||
if(CMTHeaderPtr->Size == 0)
|
||||
{
|
||||
memcpy(&QDHeaderPtr->Unknown, &CMTHeaderPtr->Size, 64 - 18);
|
||||
}
|
||||
else
|
||||
{
|
||||
QDHeaderPtr->Unknown = 0;
|
||||
QDHeaderPtr->Size = CMTHeaderPtr->Size;
|
||||
QDHeaderPtr->LoadAddress = CMTHeaderPtr->LoadAddress;
|
||||
QDHeaderPtr->ExecAddress = CMTHeaderPtr->ExecAddress;
|
||||
memcpy(QDHeaderPtr->Comment, CMTHeaderPtr->Comment, 38);
|
||||
}
|
||||
|
||||
QDPtr = QDPtr + sizeof(struct QDHeaderStr);
|
||||
|
||||
QDArray[QDPtr++] = 'C';
|
||||
QDArray[QDPtr++] = 'R';
|
||||
QDArray[QDPtr++] = 'C';
|
||||
|
||||
QDArray[QDPtr++] = 0x00; // BREAK
|
||||
QDArray[QDPtr++] = 0x16; // SYNCCHAR1
|
||||
QDArray[QDPtr++] = 0x16; // SYNCCHAR2
|
||||
|
||||
QDArray[QDPtr++] = 0xA5;
|
||||
QDArray[QDPtr++] = 0x05;
|
||||
|
||||
usPtr = (unsigned short *) &QDArray[QDPtr];
|
||||
*usPtr = MZFFileSize - 128;
|
||||
QDPtr = QDPtr + 2;
|
||||
|
||||
fread(&QDArray[QDPtr], 1, MZFFileSize - 128, MZFFile);
|
||||
QDPtr = QDPtr + MZFFileSize - 128;
|
||||
|
||||
QDArray[QDPtr++] = 'C';
|
||||
QDArray[QDPtr++] = 'R';
|
||||
QDArray[QDPtr++] = 'C';
|
||||
|
||||
QDArray[4] = QDArray[4] + 2; // increase blockcounts
|
||||
}
|
||||
|
||||
fclose(MZFFile);
|
||||
|
||||
QDFile = fopen("MZ700.QD", "wb");
|
||||
fwrite(QDArray, QDSIZE, 1, QDFile);
|
||||
fclose(QDFile);
|
||||
|
||||
/*
|
||||
// *** ADD DIRECTORY TERMINATOR ***
|
||||
uint32_t termPos = QDSIZE - 64; // Last 64 bytes
|
||||
memset(&QDArray[termPos], 0, 64);
|
||||
QDArray[termPos + 0] = 0x00; // BREAK
|
||||
QDArray[termPos + 1] = 0x16;
|
||||
QDArray[termPos + 2] = 0x16;
|
||||
QDArray[termPos + 3] = 0xA5;
|
||||
QDArray[termPos + 4] = 0x00; // attribute 0 = end of directory
|
||||
QDArray[termPos + 5] = 0x40; // size low (64)
|
||||
QDArray[termPos + 6] = 0x00; // size high
|
||||
// rest zero
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("\nMZQDTool V %s (c) 2002 by BKK\n\n", VERSION);
|
||||
|
||||
if(argc == 1)
|
||||
{
|
||||
puts("usage: mzqdtool [format] [dir] [add filename]");
|
||||
puts("");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(strcmp("format", argv[1]) == 0) QDFormat();
|
||||
if(strcmp("dir", argv[1]) == 0) QDDir();
|
||||
if(strcmp("add", argv[1]) == 0)
|
||||
{
|
||||
if(argc < 3)
|
||||
{
|
||||
puts("error: no file to add");
|
||||
exit(2);
|
||||
}
|
||||
AddFileToQD(argv[2]);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
Reference in New Issue
Block a user