├── .gitignore ├── AUTHORS ├── src ├── Ascii.h ├── Dams.h ├── Basic.h ├── Desass.h ├── ViewFile.h ├── Ascii.cpp ├── Main.h ├── Outils.h ├── MyType.h ├── endianPPC.cpp ├── endianPPC.h ├── ViewFile.cpp ├── BitmapCPC.h ├── Outils.cpp ├── GestDsk.h ├── Dams.cpp ├── BitmapCPC.cpp ├── firmware.h ├── getopt_pp.cpp ├── Main.cpp ├── Basic.cpp ├── Desass.cpp ├── getopt_pp.h └── GestDsk.cpp ├── .travis.yml ├── CMakeLists.txt ├── README.md ├── .gitattributes ├── test_travis └── test.sh └── COPYING /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeFiles 2 | CMakeCache.txt 3 | *.cmake 4 | iDSK.* 5 | Makefile 6 | *.swp 7 | *.dsk 8 | .vscode/ 9 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | cpcemu - Marco Vieth 2 | manageDSK - Ludovic Deplanque 3 | iDSK - Sid from IMPACT / PulkoMandy from the Shinra Team 4 | -------------------------------------------------------------------------------- /src/Ascii.h: -------------------------------------------------------------------------------- 1 | #ifndef ASCII_H 2 | #define ASCII_H 3 | 4 | void Ascii(unsigned char *Prg, char *Listing, int Longueur); 5 | 6 | #endif -------------------------------------------------------------------------------- /src/Dams.h: -------------------------------------------------------------------------------- 1 | #ifndef DAMS_H 2 | #define DAMS_H 3 | 4 | 5 | void Dams( unsigned char * BufFile, int TailleFic, char * Listing ); 6 | 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/Basic.h: -------------------------------------------------------------------------------- 1 | #ifndef BASIC_H 2 | #define BASIC_H 3 | 4 | 5 | void Basic( unsigned char * BufFile, char * Listing, bool IsBasic, bool CrLf ); 6 | 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/Desass.h: -------------------------------------------------------------------------------- 1 | #ifndef DESASS_H 2 | #define DESASS_H 3 | 4 | 5 | void Desass( unsigned char * Prg, char * Desass, int Longueur, int Offset ); 6 | 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | addons: 3 | apt: 4 | packages: 5 | - cmake 6 | script: 7 | - cmake . && make 8 | - cd test_travis/ && ./test.sh 9 | -------------------------------------------------------------------------------- /src/ViewFile.h: -------------------------------------------------------------------------------- 1 | #ifndef __VIEWFILE_H__ 2 | #define __VIEWFILE_H__ 3 | 4 | string ViewDams(); 5 | string ViewLine(); 6 | string ViewDesass(); 7 | string ViewAscii(); 8 | string ViewBasic(bool AddCrLf); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT(iDSK) 2 | 3 | add_executable(iDSK 4 | src/Basic.cpp 5 | src/BitmapCPC.cpp 6 | src/Dams.cpp 7 | src/Desass.cpp 8 | src/endianPPC.cpp 9 | src/GestDsk.cpp 10 | src/getopt_pp.cpp 11 | src/Main.cpp 12 | src/Outils.cpp 13 | src/ViewFile.cpp 14 | src/Ascii.cpp 15 | ) 16 | -------------------------------------------------------------------------------- /src/Ascii.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "MyType.h" 9 | #include "Ascii.h" 10 | 11 | void Ascii(unsigned char *Prg, char *Listing, int Longueur) 12 | { 13 | int Adr = 0; 14 | * Listing = 0; 15 | strncpy(Listing,(const char*)Prg,Longueur); 16 | } -------------------------------------------------------------------------------- /src/Main.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIN_CPP__ 2 | #define __MAIN_CPP__ 3 | #define VERSION "iDSK version 0.20" 4 | #define PROGNAME "iDSK" 5 | char Nom[256]; 6 | char Msg[128]; 7 | StDirEntry TabDir[64]; 8 | int PosItem[64]; 9 | int Langue; 10 | bool IsDsk, IsDskValid, IsDskSaved; 11 | int TypeModeImport, TypeModeExport; 12 | 13 | void help(void); 14 | void DecomposeArg(char **argv, int argc); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/cpcsdk/idsk.svg?branch=master)](https://travis-ci.org/cpcsdk/idsk) 2 | 3 | iDSK is a tool to edit DSK (Amstrad CPC disk images) files from the command 4 | line. You can add and remove files from your image, but also list BASIC and 5 | DAMS source files (which are usually in a tokenized format, not plain ASCII). 6 | 7 | iDSK can add and remove AMSDOS headers as needed. 8 | -------------------------------------------------------------------------------- /src/Outils.h: -------------------------------------------------------------------------------- 1 | #ifndef __OUTILS_H__ 2 | #define __OUTILS_H__ 3 | 4 | 5 | void Hex( char Chaine[], int Valeur, int Digit ); 6 | 7 | int HexToDec( char * Valeur ); 8 | 9 | void SetBuffViewHexa( unsigned char * src, char * Hex, char * Ascii,unsigned short Offset, int AddOffset); 10 | 11 | char * GetNomAmsdos( const char * AmsName ); 12 | 13 | char * GetUser( int u ); 14 | 15 | char * GetTaille( int t ); 16 | 17 | 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/MyType.h: -------------------------------------------------------------------------------- 1 | #ifndef MYTYPE_H_ 2 | #define MYTYPE_H_ 3 | 4 | /* types definitions to be coherent with Visual Basic C++ types */ 5 | 6 | typedef unsigned char BYTE; /* unsigned 8-bit type */ 7 | typedef unsigned short WORD; /* unsigned 16-bit type */ 8 | typedef unsigned long DWORD; /* unsigned 32-bit type */ 9 | 10 | 11 | /* constant defintion usefull in the code */ 12 | 13 | #define TRUE 1 14 | #define FALSE 0 15 | #define MODE_ASCII 0 16 | #define MODE_BINAIRE 1 17 | #define MODE_RAW 2 18 | 19 | 20 | #endif /*MYTYPE_H_*/ 21 | -------------------------------------------------------------------------------- /src/endianPPC.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | #include "endianPPC.h" 5 | 6 | #ifndef _MSC_VER 7 | #include 8 | #if defined(__FreeBSD__) || defined(__APPLE__) 9 | #include 10 | #else 11 | #include 12 | #endif 13 | #endif 14 | 15 | bool isBigEndian(void) 16 | { 17 | #ifdef BYTE_ORDER 18 | return BYTE_ORDER == BIG_ENDIAN; 19 | #elif defined _MSC_VER 20 | return true; // It doesn't run on anything except x86, right? 21 | #else 22 | return __BYTE_ORDER == __BIG_ENDIAN; 23 | #endif 24 | } 25 | -------------------------------------------------------------------------------- /src/endianPPC.h: -------------------------------------------------------------------------------- 1 | #ifndef __ENDIANPPC_H__ 2 | #define __ENDIANPPC_H__ 3 | 4 | /* macros convertion little endian convertion to big endian convertion */ 5 | 6 | 7 | #define SWAP_2(x) ( (((x) & 0xff) << 8) | ((unsigned short)(x) >> 8) ) 8 | #define SWAP_4(x) ( ((x) << 24) | \ 9 | (((x) << 8) & 0x00ff0000) | \ 10 | (((x) >> 8) & 0x0000ff00) | \ 11 | ((x) >> 24) ) 12 | #define FIX_SHORT(x) (*(unsigned short *)&(x) = SWAP_2(*(unsigned short *)&(x))) 13 | #define FIX_INT(x) (*(unsigned int *)&(x) = SWAP_4(*(unsigned int *)&(x))) 14 | #define FIX_FLOAT(x) FIX_INT(x) 15 | 16 | 17 | 18 | /* endianness test function */ 19 | 20 | bool isBigEndian(void); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files you want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.c text 7 | *.cpp text 8 | *.h text 9 | *.txt text 10 | *.py text 11 | *.pl text 12 | *.lua text 13 | *.nsi text 14 | *.ini text 15 | 16 | # Declare files that will always have CRLF line endings on checkout. 17 | *.sln text eol=crlf 18 | *.msi text eol=crlf 19 | *.vbs text eol=crlf 20 | *.vcxproj text eol=crlf 21 | *.vcxproj.filters text eol=crlf 22 | *.rtf text eol=crlf 23 | 24 | # Denote all files that are truly binary and should not be modified. 25 | *.png binary 26 | *.gif binary 27 | *.bmp binary 28 | *.dll binary 29 | *.xls binary 30 | *.ico binary 31 | -------------------------------------------------------------------------------- /test_travis/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | IDSK=../iDSK 4 | 5 | function clean { 6 | rm test.dsk 7 | } 8 | 9 | function test_create { 10 | echo test_create 11 | clean 12 | 13 | $IDSK test.dsk -n 14 | test -e test.dsk || exit -1 15 | 16 | } 17 | 18 | function test_ascii { 19 | echo test_ascii 20 | clean 21 | 22 | echo "HELLO WORLD" > /tmp/hello.asc 23 | $IDSK test.dsk -n 24 | 25 | echo " > Add file" 26 | $IDSK test.dsk -i /tmp/hello.asc -t 0 || exit -1 27 | 28 | echo " > Check file presence" 29 | $IDSK test.dsk -l | grep "HELLO .ASC 0" || exit -1 30 | 31 | echo " > Retreive file" 32 | $IDSK test.dsk -g "HELLO.ASC" && test -e HELLO.ASC || exit -1 33 | 34 | echo " > Check file content" 35 | test "$(cat HELLO.ASC)" = "HELLO WORLD" 36 | 37 | echo "> Get content with iDSK" 38 | ../iDSK test.dsk -a HELLO.ASC 2>/dev/null > HELLO.ASC2 39 | test "$(cat HELLO.ASC)" = "$(cat HELLO.ASC2)" 40 | } 41 | 42 | 43 | test_create && \ 44 | test_ascii 45 | -------------------------------------------------------------------------------- /src/ViewFile.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #include "GestDsk.h" 4 | #include "Outils.h" 5 | #include "Basic.h" 6 | #include "Desass.h" 7 | #include "Dams.h" 8 | #include "endianPPC.h" 9 | #include "ViewFile.h" 10 | #include "Ascii.h" 11 | 12 | string ViewDams() 13 | { 14 | cerr << "Taille du fichier : " << TailleFic << endl; 15 | Dams(BufFile, TailleFic, Listing); 16 | return Listing; 17 | //cout << Listing << endl; 18 | } 19 | 20 | string ViewDesass() 21 | { 22 | cerr << "Taille du fichier : " << TailleFic << endl; 23 | Desass(BufFile, Listing, TailleFic, AdresseCharg); 24 | return Listing; 25 | //cout << Listing << endl; 26 | } 27 | 28 | string ViewBasic(bool AddCrLf) 29 | { 30 | bool IsBasic = true; 31 | //cout << "Entre Ici\n"; 32 | cerr << "Taille du fichier : " << TailleFic << endl; 33 | Basic(BufFile, Listing, IsBasic, AddCrLf); 34 | //cout << Listing << endl; 35 | return Listing; 36 | } 37 | 38 | string ViewAscii() 39 | { 40 | cerr << "Taille du fichier : " << TailleFic << endl; 41 | Ascii(BufFile, Listing, TailleFic); 42 | //cout << Listing << endl; 43 | return Listing; 44 | } 45 | -------------------------------------------------------------------------------- /src/BitmapCPC.h: -------------------------------------------------------------------------------- 1 | #ifndef BITMAPCPC_H 2 | #define BITMAPCPC_H 3 | 4 | 5 | #define TAILLE_CPC_X 640 6 | 7 | #define TAILLE_CPC_Y 200 8 | 9 | #define MARKER_OCP 1 // Marker pour compression RLE 10 | int Mode, NbCol, NbLignes; 11 | unsigned char BitmapCPC[ 0x4000 ]; 12 | unsigned char Palette[ 16 ]; 13 | typedef struct 14 | { 15 | unsigned char b, v, r, a; 16 | } StRVB; 17 | 18 | 19 | 20 | void CBitmapCPC( void ) { NbCol = 80; NbLignes = 200; } 21 | bool LireImage( char * Nom, StRVB * Bitmap ); 22 | void Render( StRVB * Bitmap, bool Flat ); 23 | void SetBitmapCPC( unsigned char * BitmapSource ); 24 | unsigned char * GetBitmapCPC( void ) { return( BitmapCPC ); } 25 | void SetMode( int m ) { Mode = m; } 26 | void InitPalette( unsigned char Pal[ 16 ], bool SetPal ); 27 | unsigned char * GetPalette( void ) { return( Palette ); } 28 | int GetMode( void ) { return( Mode ); } 29 | void SetNbCol( int n ); 30 | void SetNbLignes( int n ); 31 | 32 | 33 | void DepactOCP( void ); 34 | void LisseBitmap( StRVB * Bitmap ); 35 | 36 | 37 | 38 | 39 | 40 | 41 | StRVB GetPalCPC( int Coul ); 42 | 43 | int GetRgbCPC( int Coul ); 44 | 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Portions parts of CPCemu, (C) 1991-2002 Marco Vieth & Rainer Loritz 2 | Portions parts of ManageDSK, (c) 2005-2015 Ludovic Deplanque (Demoniak) 3 | 4 | iDSK is copyright (c) ????-2019 Jérôme Le Saux (Sid), Colin Pitrat, Thomas Bernard (miniupnp), Romain Giot (Krusty) and Adrien Destugues (PulkoMandy) 5 | 6 | Distributed under the terms of the MIT License 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 9 | software and associated documentation files (the "Software"), to deal in the Software 10 | without restriction, including without limitation the rights to use, copy, modify, 11 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 12 | permit persons to whom the Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all copies 16 | or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 19 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 22 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 23 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /src/Outils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | #include "Outils.h" 6 | 7 | // 8 | // Initialise une chaine au format hexad�cimal en fonction de la valeur d'entr�e 9 | // 10 | void Hex( char Chaine[], int Valeur, int Digit ) 11 | { 12 | static char TabDigit[ 17 ] = "0123456789ABCDEF"; 13 | 14 | while( Digit ) 15 | * Chaine++ = TabDigit[ ( Valeur >> ( 4 * ( --Digit ) ) ) & 0x0F ]; 16 | } 17 | 18 | 19 | // 20 | // Conversion hexa->d�cimal 21 | // 22 | int HexToDec( char * Valeur ) 23 | { 24 | char * p = strchr( Valeur, 'X' ); 25 | if ( p ) 26 | Valeur = ++p; 27 | 28 | p = strchr( Valeur, 'x' ); 29 | if ( p ) 30 | Valeur = ++p; 31 | 32 | p = strchr( Valeur, '#' ); 33 | if ( p ) 34 | Valeur = ++p; 35 | 36 | p = strchr( Valeur, '$' ); 37 | if ( p ) 38 | Valeur = ++p; 39 | 40 | p = strchr( Valeur, '&' ); 41 | if ( p ) 42 | Valeur = ++p; 43 | 44 | int Ret = 0, i = 0; 45 | while( Valeur[ i ] ) 46 | { 47 | Ret <<= 4; 48 | char c = Valeur[ i++ ]; 49 | if ( c >= '0' && c <= '9' ) 50 | Ret += c - '0'; 51 | else 52 | Ret += ( c & 0x5F ) - 0x37; 53 | } 54 | return( Ret ); 55 | } 56 | 57 | 58 | // 59 | // Conversion d'un secteur (512 octets) en affichage Hexa et ASCII 60 | // 61 | void SetBuffViewHexa( unsigned char * src, char * Hex, char * Ascii, unsigned short Offset, int AddOffset) 62 | { 63 | const char * CodeHexa = "0123456789ABCDEF"; 64 | int q = 0,i; 65 | 66 | // 67 | // Parcourir les 512 octets de la source et remplir les buffers 68 | // 69 | for ( i = 0; i < 512; i++ ) 70 | { 71 | unsigned char b = * src++; 72 | if ( b > 32 && b < 127 ) 73 | { 74 | Ascii[ i ] = b; 75 | // cout << "b32:" << (int)b <<" Ascii["<> 12 ]; 85 | Hex[ q++ ] = CodeHexa[ ( Offset >> 8 ) & 0x0F ]; 86 | Hex[ q++ ] = CodeHexa[ ( Offset >> 4 ) & 0x0F ]; 87 | Hex[ q++ ] = CodeHexa[ Offset & 0x0F ]; 88 | Hex[ q++ ] = ':'; 89 | } 90 | Offset++; 91 | Hex[ q++ ] = CodeHexa[ b >> 4 ]; 92 | Hex[ q++ ] = CodeHexa[ b & 0x0F ]; 93 | Hex[ q++ ] = ' '; 94 | } 95 | Hex[ q ] = 0; 96 | Ascii[ i ] = 0; 97 | } 98 | 99 | 100 | // 101 | // Retourne le num�ro d'user sous forme de chaine 102 | // 103 | char * GetUser( int u ) 104 | { 105 | static char User[ 8 ]; 106 | sprintf(User, "%d", u); 107 | return( User); 108 | } 109 | 110 | 111 | 112 | // 113 | // Retourne la taille du fichier sous forme de chaine 114 | // 115 | char * GetTaille( int t ) 116 | { 117 | static char Taille[ 16 ]; 118 | 119 | sprintf( Taille, "%d Ko", t ); 120 | return( Taille ); 121 | } 122 | 123 | 124 | // 125 | // Retourne le nom du fichier formatt� amsdos (8+3) 126 | // 127 | char * GetNomAmsdos(const char * AmsName ) 128 | { 129 | // Extract the name (without directory components) 130 | const char* lastSlash = strrchr(AmsName, '/'); 131 | const char* lastBackslash = strrchr(AmsName, '\\'); 132 | if (lastSlash > lastBackslash) 133 | AmsName = lastSlash + 1; 134 | else if (lastSlash < lastBackslash) 135 | AmsName = lastBackslash + 1; 136 | 137 | static char NomAmsdos[ 16 ]; 138 | int i; 139 | 140 | char * p = NomAmsdos; 141 | for ( i = 0; i < 8; i++ ) { 142 | if ( * AmsName != ' ' && *AmsName != '.' ) 143 | * p++ = * AmsName++; 144 | /*if ( * AmsName == '-' ) 145 | * p++ = * AmsName++;*/ 146 | } 147 | 148 | while( * AmsName != '.' && * AmsName ) 149 | AmsName++; 150 | 151 | AmsName++; 152 | 153 | * p = 0; 154 | strcat( NomAmsdos, "." ); 155 | 156 | for ( i = 0; * AmsName && i < 3; i++ ) 157 | *++p = * AmsName++; 158 | 159 | * ++p = 0; 160 | i = 0; 161 | while( NomAmsdos[ i ] ) 162 | NomAmsdos[ i++ ] &= 0x7F; 163 | 164 | return( NomAmsdos ); 165 | } 166 | -------------------------------------------------------------------------------- /src/GestDsk.h: -------------------------------------------------------------------------------- 1 | #ifndef GESTDSK_H 2 | #define GESTDSK_H 3 | 4 | #include 5 | 6 | #define USER_DELETED 0xE5 7 | 8 | 9 | extern char Listing[ 0x280000 ]; 10 | extern unsigned char BufFile[ 0x10000 ]; 11 | 12 | 13 | extern int TailleFic, CurLigne, AdresseCharg, AdresseExec; 14 | 15 | #pragma pack(1) //evite le padding des structures qui sont utilisées dans des memcpy par la suite 16 | 17 | // 18 | // Structure d'une entree AMSDOS 19 | // 20 | typedef struct 21 | { 22 | unsigned char UserNumber; // 00 User 23 | unsigned char FileName[15]; // 01-0F Nom + extension 24 | unsigned char BlockNum; // 10 Numéro du bloc (disquette) 25 | unsigned char LastBlock; // 11 Flag "dernier bloc" bloc (disquette) 26 | unsigned char FileType; // 12 Type de fichier 27 | unsigned short Length; // 13-14 Longueur 28 | unsigned short Adress; // 15-16 Adresse 29 | unsigned char FirstBlock; // 17 Flag premier bloc de fichier (disquette) 30 | unsigned short LogicalLength; // 18-19 Longueur logique 31 | unsigned short EntryAdress; // 1A-1B Point d'entree 32 | unsigned char Unused[0x24]; 33 | unsigned short RealLength; // 40-42 Longueur reelle 34 | unsigned char BigLength; // Longueur reelle (3 octets) 35 | unsigned short CheckSum; // 43-44 CheckSum Amsdos 36 | unsigned char Unused2[0x3B]; 37 | } StAmsdos; 38 | 39 | 40 | #define SECTSIZE 512 41 | 42 | 43 | typedef struct 44 | { 45 | char debut[0x30]; // "MV - CPCEMU Disk-File\r\nDisk-Info\r\n" 46 | unsigned char NbTracks; 47 | unsigned char NbHeads; 48 | unsigned short DataSize; // 0x1300 = 256 + ( 512 * nbsecteurs ) 49 | unsigned char Unused[0xCC]; 50 | } CPCEMUEnt; 51 | 52 | 53 | typedef struct 54 | { 55 | unsigned char C; // track 56 | unsigned char H; // head 57 | unsigned char R; // sect 58 | unsigned char N; // size 59 | short Un1; 60 | short SizeByte; // Taille secteur en octets 61 | } CPCEMUSect; 62 | 63 | 64 | typedef struct 65 | { 66 | char ID[0x10]; // "Track-Info\r\n" 67 | unsigned char Track; 68 | unsigned char Head; 69 | short Unused; 70 | unsigned char SectSize; // 2 71 | unsigned char NbSect; // 9 72 | unsigned char Gap3; // 0x4E 73 | unsigned char OctRemp; // 0xE5 74 | CPCEMUSect Sect[29]; 75 | } CPCEMUTrack; 76 | 77 | #ifdef __GNUC__ 78 | #define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__)) 79 | #else 80 | #define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) ) 81 | #endif 82 | 83 | // see http://www.cpcwiki.eu/index.php/Disk_structure#Directory_entries 84 | PACK(typedef struct 85 | { 86 | unsigned char User; // 00 87 | char Nom[8]; // 01-08 88 | char Ext[3]; // 09-0B 89 | unsigned char NumPage; // 0C 90 | unsigned char Unused[2]; // 0D-0E 91 | unsigned char NbPages; // 0F 92 | unsigned char Blocks[16]; // 10-1F 93 | }) StDirEntry; 94 | 95 | #pragma pack() 96 | 97 | enum { ERR_NO_ERR = 0, ERR_NO_DIRENTRY, ERR_NO_BLOCK, ERR_FILE_EXIST }; 98 | 99 | bool CheckAmsdos( unsigned char * Buf ); 100 | StAmsdos * CreeEnteteAmsdos( char * NomFic, unsigned short Length ); 101 | void ClearAmsdos( unsigned char * Buf ); 102 | void SetChecksum( StAmsdos * pEntete ); 103 | bool CheckAmsdos( unsigned char * Buf ); 104 | 105 | 106 | class DSK 107 | { 108 | unsigned char ImgDsk[ 0x80000 ]; 109 | unsigned char Bitmap[ 256 ]; 110 | 111 | unsigned char * GetRawData( int Pos ); 112 | void WriteRawData( int Pos, unsigned char * Data, int Longueur ); 113 | int GetNbTracks( void ); 114 | void WriteBloc( int bloc, unsigned char * BufBloc ); 115 | void WriteSect( int Track, int Sect, unsigned char * Buff, int AmsdosMode ); 116 | unsigned char * ReadSect( int Track, int Sect, int AmsdosMode ); 117 | CPCEMUTrack * GetInfoTrack( int Track ); 118 | int FillBitmap( void ); 119 | void DskEndian(); 120 | CPCEMUEnt* CPCEMUEntEndian ( CPCEMUEnt* Infos ); 121 | CPCEMUTrack* CPCEMUTrackEndian ( CPCEMUTrack* tr ); 122 | CPCEMUSect CPCEMUSectEndian ( CPCEMUSect Sect); 123 | const char * GetType( int Langue, StAmsdos * Ams ); 124 | int GetMinSect( void ); 125 | int GetPosData( int track, int sect, bool SectPhysique ); 126 | int RechercheBlocLibre( int MaxBloc ); 127 | void FormatTrack( CPCEMUEnt * Infos, int t, int MinSect, int NbSect ); 128 | 129 | public: 130 | DSK(){} 131 | DSK(const DSK& d) 132 | { 133 | for (int i=0; i< 0x80000; i++) 134 | ImgDsk[i]=d.ImgDsk[i]; 135 | for (int j=0; j< 256 ; j++ ) 136 | Bitmap[j]=d.Bitmap[j]; 137 | } 138 | 139 | ~DSK(){} 140 | 141 | int GetTailleDsk(); 142 | StDirEntry * GetNomDir(std::string Nom ); 143 | int CopieFichier( unsigned char * BufFile, char * NomFic, int TailleFic, int MaxBloc, int, bool,bool ); 144 | bool WriteDsk( std::string NomDsk ); 145 | unsigned char * ReadBloc( int bloc ); 146 | bool ReadDsk( std::string NomFic ); 147 | bool CheckDsk( void ); 148 | int FileExist( char * Nom ); 149 | StDirEntry * GetInfoDirEntry( int NumDir ); 150 | int FileIsIn( std::string FileName ); 151 | int RechercheDirLibre( void ); 152 | void FormatDsk( int NbSect, int NbTrack ); 153 | StAmsdos* StAmsdosEndian ( StAmsdos * pEntete ); 154 | void SetInfoDirEntry( int NumDir, StDirEntry * Dir ); 155 | char * GetEntryNameInCatalogue ( int num , char* Nom ); 156 | char * GetEntrySizeInCatalogue ( int num , char* Size ); 157 | bool GetFileInDsk( char* path, int Indice ); 158 | bool PutFileInDsk( std::string Masque ,int TypeModeImport ,int loadAdress, int exeAdress, int,bool,bool ); 159 | bool OnViewFic(int nItem); 160 | bool Hexdecimal(); 161 | void RemoveFile ( int item ); 162 | void FixEndianDsk( bool LittleToBig ); 163 | void FixEndianTrack( CPCEMUEnt * Infos, int t, int NbSect ); 164 | void RenameFile( int item , char *NewName); 165 | std::string ReadDskDir(void); 166 | 167 | }; 168 | 169 | #endif 170 | -------------------------------------------------------------------------------- /src/Dams.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | 7 | // 8 | // Convertir le buffer en listing au format Dams 9 | // Adaptation des sources de Thierry JOUIN ( Ramlaid ) 10 | // 11 | void Dams( unsigned char * BufFile, int TailleFic, char * Listing ) 12 | { 13 | const char * MotCleDams[ 0x80 ] = 14 | { 15 | "LD","INC","DEC","ADD","ADC","SUB","SBC","AND","XOR","OR","CP", 16 | "PUSH","POP","BIT","RES","SET","RLC","RRC","RL","RR","SLA","SRA", 17 | "SRL","IN","OUT","RST","DJNZ","EX","IM","JR","CALL","RET","JP", 18 | "NOP","RLCA","RRCA","RLA","RRA","DAA","CPL","SCF","CCF","HALT", 19 | "EXX","DI","EI","NEG","RETN","RETI","RRD","RLD","LDI","CPI","INI", 20 | "OUTI","LDD","CPD","IND","OUTD","LDIR","CPIR","INIR","OTIR","LDDR", 21 | "CPDR","INDR","OTDR","DB","DW","DM","DS","EQU","ORG","ENT", 22 | "IF","ELSE","END" 23 | }; 24 | char Tmp[ 32 ]; 25 | int PosFile = 0; 26 | int PosDest = 0; 27 | unsigned char c; 28 | 29 | * Listing = 0; 30 | c = BufFile[ PosFile++ ]; 31 | while( c ) 32 | { 33 | if ( c == 0xFF ) 34 | { 35 | // Commentaire ligne 36 | Listing[ PosDest++ ] = ';'; 37 | c = BufFile[ PosFile++ ]; 38 | while( c != 0x0D && PosFile < TailleFic ) 39 | { 40 | Listing[ PosDest++ ] = c; 41 | c = BufFile[ PosFile++ ]; 42 | } 43 | Listing[ PosDest++ ] = '\r'; 44 | Listing[ PosDest++ ] = '\n'; 45 | } 46 | else 47 | { 48 | if ( c >= 0x80 && c != 0x0D ) 49 | { 50 | // Mnemonique sans label 51 | // ENT 52 | if ( c == 0xC9 ) 53 | Listing[ PosDest++ ] = ';'; 54 | 55 | sprintf( Tmp, "\t%s\t", MotCleDams[ c & 0x7F ] ); 56 | int l = strlen( Tmp ); 57 | memcpy( &Listing[ PosDest ], Tmp, l ); 58 | PosDest += l; 59 | // DS ?,? 60 | if ( c == 0xC6 ) 61 | { 62 | c = BufFile[ PosFile++ ]; 63 | // Fin de ligne 64 | while( c != 0x0D && PosFile < TailleFic ) 65 | { 66 | if ( c == ',' ) 67 | { 68 | while( c != 0x0D && c != 0xFF && PosFile < TailleFic ) 69 | c = BufFile[ PosFile++ ]; 70 | } 71 | if ( c != 0x0D ) 72 | { 73 | if ( c == 0xFF ) 74 | Listing[ PosDest++ ] = '\t'; 75 | else 76 | Listing[ PosDest++ ] = c; 77 | 78 | c = BufFile[ PosFile++ ]; 79 | } 80 | } 81 | } 82 | else 83 | { 84 | c = BufFile[ PosFile++ ]; 85 | // Fin de ligne 86 | while( c != 0x0D && PosFile < TailleFic ) 87 | { 88 | if ( c == 0xFF ) 89 | Listing[ PosDest++ ] = '\t'; 90 | else 91 | Listing[ PosDest++ ] = c; 92 | 93 | c = BufFile[ PosFile++ ]; 94 | } 95 | } 96 | Listing[ PosDest++ ] = '\r'; 97 | Listing[ PosDest++ ] = '\n'; 98 | } 99 | else 100 | { 101 | // Label 102 | while( c < 0x80 && c != 0x0D && PosFile < TailleFic ) 103 | { 104 | Listing[ PosDest++ ] = c; 105 | c = BufFile[ PosFile++ ]; 106 | } 107 | if ( c != 0x0D ) 108 | { 109 | // Mnemonique apres label 110 | // ENT 111 | if ( c == 0xC9 ) 112 | Listing[ PosDest++ ] = ';'; 113 | 114 | if ( c != 0xFF ) 115 | { 116 | sprintf( Tmp, "\t%s\t", MotCleDams[ c & 0x7F ] ); 117 | int l = strlen( Tmp ); 118 | memcpy( &Listing[ PosDest ], Tmp, l ); 119 | PosDest += l; 120 | } 121 | else 122 | { 123 | Listing[ PosDest++ ] = '\t'; 124 | Listing[ PosDest++ ] = '\t'; 125 | Listing[ PosDest++ ] = '\t'; 126 | } 127 | // DS ?,? 128 | if ( c == 0xC6 ) 129 | { 130 | c = BufFile[ PosFile++ ]; 131 | // Fin de ligne 132 | while( c != 0x0D && PosFile < TailleFic ) 133 | { 134 | if ( c == ',' ) 135 | { 136 | while( c != 0x0D && c != 0xFF && PosFile < TailleFic ) 137 | c = BufFile[ PosFile++ ]; 138 | } 139 | if ( c != 0x0D ) 140 | { 141 | if ( c == 0xFF ) 142 | { 143 | Listing[ PosDest++ ] = '\t'; 144 | Listing[ PosDest++ ] = ';'; 145 | } 146 | else 147 | Listing[ PosDest++ ] = c; 148 | 149 | c = BufFile[ PosFile++ ]; 150 | } 151 | } 152 | } 153 | else 154 | { 155 | c = BufFile[ PosFile++ ]; 156 | // Fin de ligne 157 | while( c != 0x0D && PosFile < TailleFic ) 158 | { 159 | if ( c == 0xFF ) 160 | { 161 | Listing[ PosDest++ ] = '\t'; 162 | Listing[ PosDest++ ] = ';'; 163 | } 164 | else 165 | Listing[ PosDest++ ] = c; 166 | 167 | c = BufFile[ PosFile++ ]; 168 | } 169 | } 170 | Listing[ PosDest++ ] = '\r'; 171 | Listing[ PosDest++ ] = '\n'; 172 | } 173 | else 174 | { 175 | Listing[ PosDest++ ] = '\r'; 176 | Listing[ PosDest++ ] = '\n'; 177 | } 178 | } 179 | } 180 | c = BufFile[ PosFile++ ]; 181 | if ( PosFile > TailleFic ) 182 | break; 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /src/BitmapCPC.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "MyType.h" 4 | #include "BitmapCPC.h" 5 | #include "GestDsk.h" 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | 11 | // 12 | // Couleurs du CPC converties en composantes r, v, b 13 | // 14 | static StRVB RgbCPC[ 27 ] = 15 | { 16 | { 0x00, 0x00, 0x00, 0x00 }, 17 | { 0x7F, 0x00, 0x00, 0x00 }, 18 | { 0xFF, 0x00, 0x00, 0x00 }, 19 | { 0x00, 0x00, 0x7F, 0x00 }, 20 | { 0x7F, 0x00, 0x7F, 0x00 }, 21 | { 0xFF, 0x00, 0x7F, 0x00 }, 22 | { 0x00, 0x00, 0xFF, 0x00 }, 23 | { 0x7F, 0x00, 0xFF, 0x00 }, 24 | { 0xFF, 0x00, 0xFF, 0x00 }, 25 | { 0x00, 0x7F, 0x00, 0x00 }, 26 | { 0x7F, 0x7F, 0x00, 0x00 }, 27 | { 0xFF, 0x7F, 0x00, 0x00 }, 28 | { 0x00, 0x7F, 0x7F, 0x00 }, 29 | { 0x7F, 0x7F, 0x7F, 0x00 }, 30 | { 0xFF, 0x7F, 0x7F, 0x00 }, 31 | { 0x00, 0x7F, 0xFF, 0x00 }, 32 | { 0x7F, 0x7F, 0xFF, 0x00 }, 33 | { 0xFF, 0x7F, 0xFF, 0x00 }, 34 | { 0x00, 0xFF, 0x00, 0x00 }, 35 | { 0x7F, 0xFF, 0x00, 0x00 }, 36 | { 0xFF, 0xFF, 0x00, 0x00 }, 37 | { 0x00, 0xFF, 0x7F, 0x00 }, 38 | { 0x7F, 0xFF, 0x7F, 0x00 }, 39 | { 0xFF, 0xFF, 0x7F, 0x00 }, 40 | { 0x00, 0xFF, 0xFF, 0x00 }, 41 | { 0x7F, 0xFF, 0xFF, 0x00 }, 42 | { 0xFF, 0xFF, 0xFF, 0x00 } 43 | }; 44 | 45 | 46 | int GetRgbCPC( int Coul ) 47 | { 48 | if ( Coul >= 0 && Coul < 27 ) 49 | { 50 | StRVB i = RgbCPC[ Coul ]; 51 | return( ( i.b << 16 ) + ( i.v << 8 ) + i.r ); 52 | } 53 | return( -1 ); 54 | } 55 | 56 | 57 | StRVB GetPalCPC( int Coul ) 58 | { 59 | if ( Coul >= 0 && Coul < 27 ) 60 | return( RgbCPC[ Coul ] ); 61 | 62 | return( RgbCPC[ 0 ] ); 63 | } 64 | 65 | 66 | void InitPalette( unsigned char NewPal[ 16 ], bool SetNewPal ) 67 | { 68 | /* 69 | Si sauvegard� avec ConvImgCpc, alors la palette se trouve 70 | dans l'image... 71 | */ 72 | int i; 73 | if ( BitmapCPC[ 0x7D0 ] == 0x3A 74 | && BitmapCPC[ 0x7D1 ] == 0xD0 75 | && BitmapCPC[ 0x7D2 ] == 0xD7 76 | && BitmapCPC[ 0x7D3 ] == 0xCD 77 | ) 78 | { 79 | Mode = BitmapCPC[ 0x17D0 ]; 80 | for ( i = 0; i < 16; i++ ) 81 | Palette[ i ] = BitmapCPC[ 0x17D1 + i ]; 82 | } 83 | if ( SetNewPal ) 84 | for ( i = 0; i < 16; i++ ) 85 | Palette[ i ] = NewPal[ i ]; 86 | } 87 | 88 | 89 | // 90 | // D�compacter une image au format OCP 91 | // 92 | void DepactOCP( void ) 93 | { 94 | static unsigned char BufTmp[ 0x4000 ]; 95 | int PosIn = 0, PosOut = 0; 96 | int LgOut, CntBlock = 0; 97 | int c,i; 98 | unsigned char a; 99 | memcpy( BufTmp, BitmapCPC, sizeof( BufTmp ) ); 100 | memset( BitmapCPC, 0, 0x4000 ); 101 | while( PosOut < 0x4000 ) 102 | { 103 | if ( ! strncmp( ( char * )&BufTmp[ PosIn ], "MJH", 3 ) ) 104 | { 105 | PosIn += 3; 106 | LgOut = BufTmp[ PosIn++ ]; 107 | LgOut += ( BufTmp[ PosIn++ ] << 8 ); 108 | CntBlock = 0; 109 | while( CntBlock < LgOut ) 110 | { 111 | if ( ! strncmp( ( char * )&BufTmp[ PosIn ], "MJH", 3 ) ) 112 | break; 113 | 114 | a = BufTmp[ PosIn++ ]; 115 | if ( a == MARKER_OCP ) 116 | { 117 | c = BufTmp[ PosIn++ ]; 118 | a = BufTmp[ PosIn++ ]; 119 | if ( ! c ) 120 | c = 0x100; 121 | 122 | for ( i = 0; i < c && CntBlock < LgOut; i++ ) 123 | { 124 | BitmapCPC[ PosOut++ ] = a; 125 | CntBlock++; 126 | } 127 | } 128 | else 129 | { 130 | BitmapCPC[ PosOut++ ] = a; 131 | CntBlock++; 132 | } 133 | } 134 | } 135 | else 136 | PosOut = 0x4000; 137 | } 138 | } 139 | 140 | 141 | bool LireImage( char * Nom, StRVB * Bitmap ) 142 | { 143 | static unsigned char Entete[ 0x80 ]; 144 | bool Ret = FALSE; 145 | //DWORD Nb; 146 | FILE* hFile; 147 | 148 | 149 | if ( (hFile=fopen(Nom,"rb"))!=NULL ) 150 | { 151 | fread(Entete,sizeof(Entete),1,hFile); 152 | // ReadFile( hFile, Entete, sizeof( Entete ), &Nb, NULL ); 153 | if ( CheckAmsdos( Entete ) ) 154 | { 155 | fread(BitmapCPC,sizeof( BitmapCPC ),1,hFile); 156 | // ReadFile( hFile, BitmapCPC, sizeof( BitmapCPC ), &Nb, NULL ); 157 | if ( ! strncmp( ( char * )BitmapCPC, "MJH", 3 ) ) 158 | DepactOCP(); 159 | 160 | InitPalette( NULL, FALSE ); 161 | Ret = TRUE; 162 | } 163 | // CloseHandle( hFile ); 164 | fclose(hFile); 165 | if ( Ret ) 166 | Render( Bitmap, 1 ); 167 | } 168 | return( Ret ); 169 | 170 | } 171 | 172 | 173 | // 174 | // Affiche l'image � l'�cran 175 | // 176 | void Render( StRVB * Bitmap, bool Flat ) 177 | { 178 | int AdrCPC = 0, i, p0, p1, p2, p3; 179 | int y,x,AdrBitmap; 180 | unsigned char Octet; 181 | for ( y = 0; y < NbLignes; y++ ) 182 | { 183 | AdrBitmap = TAILLE_CPC_X * ( y + ( ( 200 - NbLignes ) >> 1 ) ) 184 | + ( ( ( 80 - NbCol ) >> 1 ) << 3 ); 185 | for ( x = 0; x < NbCol; x++ ) 186 | { 187 | Octet = BitmapCPC[ AdrCPC + x ]; 188 | switch( Mode ) 189 | { 190 | case 0 : 191 | case 3 : // Mode 3 = Mode 0 192 | p0 = ( Octet >> 7 ) 193 | + ( ( Octet & 0x20 ) >> 3 ) 194 | + ( ( Octet & 0x08 ) >> 2 ) 195 | + ( ( Octet & 0x02 ) << 2 ); 196 | p1 = ( ( Octet & 0x40 ) >> 6 ) 197 | + ( ( Octet & 0x10 ) >> 2 ) 198 | + ( ( Octet & 0x04 ) >> 1 ) 199 | + ( ( Octet & 0x01 ) << 3 ); 200 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p0 ] ); 201 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p0 ] ); 202 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p0 ] ); 203 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p0 ] ); 204 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p1 ] ); 205 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p1 ] ); 206 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p1 ] ); 207 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p1 ] ); 208 | break; 209 | 210 | case 1 : 211 | p0 = ( ( Octet >> 7 ) & 1 ) + ( ( Octet >> 2 ) & 2 ); 212 | p1 = ( ( Octet >> 6 ) & 1 ) + ( ( Octet >> 1 ) & 2 ); 213 | p2 = ( ( Octet >> 5 ) & 1 ) + ( ( Octet >> 0 ) & 2 ); 214 | p3 = ( ( Octet >> 4 ) & 1 ) + ( ( Octet << 1 ) & 2 ); 215 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p0 ] ); 216 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p0 ] ); 217 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p1 ] ); 218 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p1 ] ); 219 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p2 ] ); 220 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p2 ] ); 221 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p3 ] ); 222 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ p3 ] ); 223 | break; 224 | 225 | case 2 : 226 | for ( i = 8; i--; ) 227 | Bitmap[ AdrBitmap++ ] = GetPalCPC( Palette[ ( Octet >> i ) & 1 ] ); 228 | break; 229 | } 230 | } 231 | if ( Flat ) 232 | AdrCPC += NbCol; 233 | else 234 | { 235 | AdrCPC += 0x800; 236 | if ( AdrCPC > 0x3FFF ) 237 | AdrCPC -= 0x3FB0; 238 | } 239 | } 240 | } 241 | 242 | 243 | void SetBitmapCPC( unsigned char * BitmapSource ) 244 | { 245 | memcpy( BitmapCPC, BitmapSource, 0x4000 ); 246 | if ( ! strncmp( ( char * )BitmapCPC, "MJH", 3 ) ) 247 | DepactOCP(); 248 | 249 | InitPalette( NULL, FALSE ); 250 | } 251 | 252 | 253 | void SetNbCol( int n ) 254 | { 255 | if ( n > 0 && n <= 80 ) 256 | NbCol = n; 257 | } 258 | 259 | 260 | void SetNbLignes( int n ) 261 | { 262 | if ( n > 0 && n <= 200 ) 263 | NbLignes = n; 264 | } 265 | -------------------------------------------------------------------------------- /src/firmware.h: -------------------------------------------------------------------------------- 1 | struct { 2 | unsigned short address; 3 | const char * label; 4 | } FirmWareVectors[] = { 5 | {0x0000, "RESET_ENTRY"}, 6 | {0x0008, "LOW_JUMP"}, 7 | {0x000B, "KL_LOW_PCHL"}, 8 | {0x000E, "PCBC"}, 9 | {0x0010, "SIDE_CALL"}, 10 | {0x0013, "KL_SIDE_PCHL"}, 11 | {0x0016, "PCDE"}, 12 | {0x0018, "FAR_CALL"}, 13 | {0x001B, "KL_FAR_PCHL"}, 14 | {0x001E, "PCHL"}, 15 | {0x0020, "RAM_LAM"}, 16 | {0x0023, "KL_FAR_CALL"}, 17 | {0x0028, "FIRM_JUMP"}, 18 | {0x0030, "USER_RESTART"}, 19 | {0x0038, "INTERRUPT_ENTRY"}, 20 | {0x003B, "EXT_INTERRUPT"}, 21 | {0xB900, "KL_U_ROM_ENABLE"}, 22 | {0xB903, "KL_U_ROM_DISABLE"}, 23 | {0xB906, "KL_L_ROM_ENABLE"}, 24 | {0xB909, "KL_L_ROM_DISABLE"}, 25 | {0xB90C, "KL_ROM_RESTORE"}, 26 | {0xB90F, "KL_ROM_SELECT"}, 27 | {0xB912, "KL_CURR_SELECTION"}, 28 | {0xB915, "KL_PROBE_ROM"}, 29 | {0xB918, "KL_ROM_DESELECT"}, 30 | {0xB91B, "KL_LDIR"}, 31 | {0xB91E, "KL_LDDR"}, 32 | {0xB921, "KL_POLL_SYNCHRONOUS"}, 33 | {0xB92A, "KL_SCAN_NEEDED"}, 34 | {0xBB00, "KM_INITIALISE"}, 35 | {0xBB03, "KM_RESET"}, 36 | {0xBB06, "KM_WAIT_CHAR"}, 37 | {0xBB09, "KM_READ_CHAR"}, 38 | {0xBB0C, "KM_CHAR_RETURN"}, 39 | {0xBB0F, "KM_SET_EXPAND"}, 40 | {0xBB12, "KM_GET_EXPAND"}, 41 | {0xBB15, "KM_EXP_BUFFER"}, 42 | {0xBB18, "KM_WAIT_KEY"}, 43 | {0xBB1B, "KM_READ_KEY"}, 44 | {0xBB1E, "KM_TEST_KEY"}, 45 | {0xBB21, "KM_GET_STATE"}, 46 | {0xBB24, "KM_GET_JOYSTICK"}, 47 | {0xBB27, "KM_SET_TRANSLATE"}, 48 | {0xBB2A, "KM_GET_TRANSLATE"}, 49 | {0xBB2D, "KM_SET_SHIFT"}, 50 | {0xBB30, "KM_GET_SHIFT"}, 51 | {0xBB33, "KM_SET_CONTROL"}, 52 | {0xBB36, "KM_GET_CONTROL"}, 53 | {0xBB39, "KM_SET_REPEAT"}, 54 | {0xBB3C, "KM_GET_REPEAT"}, 55 | {0xBB3F, "KM_SET_DELAY"}, 56 | {0xBB42, "KM_GET_DELAY"}, 57 | {0xBB45, "KM_ARM_BREAKS"}, 58 | {0xBB48, "KM_DISARM_BREAK"}, 59 | {0xBB4B, "KM_BREAK_EVENT"}, 60 | {0xBB4E, "TXT_INITIALISE"}, 61 | {0xBB51, "TXT_RESET"}, 62 | {0xBB54, "TXT_VDU_ENABLE"}, 63 | {0xBB57, "TXT_VDU_DISABLE"}, 64 | {0xBB5A, "TXT_OUTPUT"}, 65 | {0xBB5D, "TXT_WR_CHAR"}, 66 | {0xBB60, "TXT_RD_CHAR"}, 67 | {0xBB63, "TXT_SET_GRAPHIC"}, 68 | {0xBB66, "TXT_WIN_ENABLE"}, 69 | {0xBB69, "TXT_GET_WINDOW"}, 70 | {0xBB6C, "TXT_CLEAR_WINDOW"}, 71 | {0xBB6F, "TXT_SET_COLUMN"}, 72 | {0xBB72, "TXT_SET_ROW"}, 73 | {0xBB75, "TXT_SET_CURSOR"}, 74 | {0xBB78, "TXT_GET_CURSOR"}, 75 | {0xBB7B, "TXT_CUR_ENABLE"}, 76 | {0xBB7E, "TXT_CUR_DISABLE"}, 77 | {0xBB81, "TXT_CUR_ON"}, 78 | {0xBB84, "TXT_CUR_OFF"}, 79 | {0xBB87, "TXT_VALIDATE"}, 80 | {0xBB8A, "TXT_PLACE_CURSOR"}, 81 | {0xBB8D, "TXT_REMOVE_CURSOR"}, 82 | {0xBB90, "TXT_SET_PEN"}, 83 | {0xBB93, "TXT_GET_PEN"}, 84 | {0xBB96, "TXT_SET_PAPER"}, 85 | {0xBB99, "TXT_GET_PAPER"}, 86 | {0xBB9C, "TXT_INVERSE"}, 87 | {0xBB9F, "TXT_SET_BACK"}, 88 | {0xBBA2, "TXT_GET_BACK"}, 89 | {0xBBA5, "TXT_GET_MATRIX"}, 90 | {0xBBA8, "TXT_SET_MATRIX"}, 91 | {0xBBAB, "TXT_SET_M_TABLE"}, 92 | {0xBBAE, "TXT_GET_M_TABLE"}, 93 | {0xBBB1, "TXT_GET_CONTROLS"}, 94 | {0xBBB4, "TXT_STR_SELECT"}, 95 | {0xBBB7, "TXT_SWAP_STREAMS"}, 96 | {0xBBBA, "GRA_INITIALISE"}, 97 | {0xBBBD, "GRA_RESET"}, 98 | {0xBBC0, "GRA_MOVE_ABSOLUTE"}, 99 | {0xBBC3, "GRA_MOVE_RELATIVE"}, 100 | {0xBBC6, "GRA_ASK_CURSOR"}, 101 | {0xBBC9, "GRA_SET_ORIGIN"}, 102 | {0xBBCC, "GRA_GET_ORIGIN"}, 103 | {0xBBCF, "GRA_WIN_WIDTH"}, 104 | {0xBBD2, "GRA_WIN_HEIGHT"}, 105 | {0xBBD5, "GRA_GET_W_WIDTH"}, 106 | {0xBBD8, "GRA_GET_W_HEIGHT"}, 107 | {0xBBDB, "GRA_CLEAR_WINDOW"}, 108 | {0xBBDE, "GRA_SET_PEN"}, 109 | {0xBBE1, "GRA_GET_PEN"}, 110 | {0xBBE4, "GRA_SET_PAPER"}, 111 | {0xBBE7, "GRA_GET_PAPER"}, 112 | {0xBBEA, "GRA_PLOT_ABSOLUTE"}, 113 | {0xBBED, "GRA_PLOT_RELATIVE"}, 114 | {0xBBF0, "GRA_TEST_ABSOLUTE"}, 115 | {0xBBF3, "GRA_TEST_RELATIVE"}, 116 | {0xBBF6, "GRA_LINE_ABSOLUTE"}, 117 | {0xBBF9, "GRA_LINE_RELATIVE"}, 118 | {0xBBFC, "GRA_WR_CHAR"}, 119 | {0xBBFF, "SCR_INITIALISE"}, 120 | {0xBC02, "SCR_RESET"}, 121 | {0xBC05, "SCR_SET_OFFSET"}, 122 | {0xBC08, "SCR_SET_BASE"}, 123 | {0xBC0B, "SCR_GET_LOCATION"}, 124 | {0xBC0E, "SCR_SET_MODE"}, 125 | {0xBC11, "SCR_GET_MODE"}, 126 | {0xBC14, "SCR_CLEAR"}, 127 | {0xBC17, "SCR_CHAR_LIMITS"}, 128 | {0xBC1A, "SCR_CHAR_POSITION"}, 129 | {0xBC1D, "SCR_DOT_POSITION"}, 130 | {0xBC20, "SCR_NEXT_BYTE"}, 131 | {0xBC23, "SCR_PREV_BYTE"}, 132 | {0xBC26, "SCR_NEXT_LINE"}, 133 | {0xBC29, "SCR_PREV_LINE"}, 134 | {0xBC2C, "SCR_INK_ENCODE"}, 135 | {0xBC2F, "SCR_INK_DECODE"}, 136 | {0xBC32, "SCR_SET_INK"}, 137 | {0xBC35, "SCR_GET_INK"}, 138 | {0xBC38, "SCR_SET_BORDER"}, 139 | {0xBC3B, "SCR_GET_BORDER"}, 140 | {0xBC3E, "SCR_SET_FLASHING"}, 141 | {0xBC41, "SCR_GET_FLASHING"}, 142 | {0xBC44, "SCR_FILL_BOX"}, 143 | {0xBC47, "SCR_FLOOD_BOX"}, 144 | {0xBC4A, "SCR_CHAR_INVERT"}, 145 | {0xBC4D, "SCR_HW_ROLL"}, 146 | {0xBC50, "SCR_SW_ROLL"}, 147 | {0xBC53, "SCR_UNPACK"}, 148 | {0xBC56, "SCR_REPACK"}, 149 | {0xBC59, "SCR_ACCESS"}, 150 | {0xBC5C, "SCR_PIXELS"}, 151 | {0xBC5F, "SCR_HORIZONTAL"}, 152 | {0xBC62, "SCR_VERTICAL"}, 153 | {0xBC65, "CAS_INITIALISE"}, 154 | {0xBC68, "CAS_SET_SPEED"}, 155 | {0xBC6B, "CAS_NOISY"}, 156 | {0xBC6E, "CAS_START_MOTOR"}, 157 | {0xBC71, "CAS_STOP_MOTOR"}, 158 | {0xBC74, "CAS_RESTORE_MOTOR"}, 159 | {0xBC77, "CAS_IN_OPEN"}, 160 | {0xBC7A, "CAS_IN_CLOSE"}, 161 | {0xBC7D, "CAS_IN_ABANDON"}, 162 | {0xBC80, "CAS_IN_CHAR"}, 163 | {0xBC83, "CAS_IN_DIRECT"}, 164 | {0xBC86, "CAS_RETURN"}, 165 | {0xBC89, "CAS_TEST_EOF"}, 166 | {0xBC8C, "CAS_OUT_OPEN"}, 167 | {0xBC8F, "CAS_OUT_CLOSE"}, 168 | {0xBC92, "CAS_OUT_ABANDON"}, 169 | {0xBC95, "CAS_OUT_CHAR"}, 170 | {0xBC98, "CAS_OUT_DIRECT"}, 171 | {0xBC9B, "CAS_CATALOG"}, 172 | {0xBC9E, "CAS_WRITE"}, 173 | {0xBCA1, "CAS_READ"}, 174 | {0xBCA4, "CAS_CHECK"}, 175 | {0xBCA7, "SOUND_RESET"}, 176 | {0xBCAA, "SOUND_QUEUE"}, 177 | {0xBCAD, "SOUND_CHECK"}, 178 | {0xBCB0, "SOUND_ARM_EVENT"}, 179 | {0xBCB3, "SOUND_RELEASE"}, 180 | {0xBCB6, "SOUND_HOLD"}, 181 | {0xBCB9, "SOUND_CONTINUE"}, 182 | {0xBCBC, "SOUND_AMPL_ENVELOPE"}, 183 | {0xBCBF, "SOUND_TONE_ENVELOPE"}, 184 | {0xBCC2, "SOUND_A_ADDRESS"}, 185 | {0xBCC5, "SOUND_T_ADDRESS"}, 186 | {0xBCC8, "KL_CHOKE_OFF"}, 187 | {0xBCCB, "KL_ROM_WALK"}, 188 | {0xBCCE, "KL_INIT_BACK"}, 189 | {0xBCD1, "KL_LOG_EXT"}, 190 | {0xBCD4, "KL_FIND_COMMAND"}, 191 | {0xBCD7, "KL_NEW_FRAME_FLY"}, 192 | {0xBCDA, "KL_ADD_FRAME_FLY"}, 193 | {0xBCDD, "KL_DEL_FRAME_FLY"}, 194 | {0xBCE0, "KL_NEW_FAST_TICKER"}, 195 | {0xBCE3, "KL_ADD_FAST_TICKER"}, 196 | {0xBCE6, "KL_DEL_FAST_TICKER"}, 197 | {0xBCE9, "KL_ADD_TICKER"}, 198 | {0xBCEC, "KL_DEL_TICKER"}, 199 | {0xBCEF, "KL_INIT_EVENT"}, 200 | {0xBCF2, "KL_EVENT"}, 201 | {0xBCF5, "KL_SYNC_RESET"}, 202 | {0xBCF8, "KL_DEL_SYNCHRONOUS"}, 203 | {0xBCFB, "KL_NEXT_SYNCH"}, 204 | {0xBCFE, "KL_DO_SYNCH"}, 205 | {0xBD01, "KL_DONE_SYNCH"}, 206 | {0xBD04, "KL_EVENT_DISABLE"}, 207 | {0xBD07, "KL_EVENT_ENABLE"}, 208 | {0xBD0A, "KL_DISARM_EVENT"}, 209 | {0xBD0D, "KL_TIME_PLEASE"}, 210 | {0xBD10, "KL_TIME_SET"}, 211 | {0xBD13, "MC_BOOT_PROGRAM"}, 212 | {0xBD16, "MC_START_PROGRAM"}, 213 | {0xBD19, "MC_WAIT_FLYBACK"}, 214 | {0xBD1C, "MC_SET_MODE"}, 215 | {0xBD1F, "MC_SCREEN_OFFSET"}, 216 | {0xBD22, "MC_CLEAR_INKS"}, 217 | {0xBD25, "MC_SET_INKS"}, 218 | {0xBD28, "MC_RESET_PRINTER"}, 219 | {0xBD2B, "MC_PRINT_CHAR"}, 220 | {0xBD2E, "MC_PRINTER_BUSY"}, 221 | {0xBD31, "MC_SEND_PRINTER"}, 222 | {0xBD34, "MC_SOUND_REGISTER"}, 223 | {0xBD37, "JUMP_RESTORE"}, 224 | {0xBD3A, "KM_SET_LOCKS"}, 225 | {0xBD40, "TXT_ASK_STATE"}, 226 | {0xBD43, "GRA_DEFAULT"}, 227 | {0xBD46, "GRA_SET_BACK"}, 228 | {0xBD49, "GRA_SET_FIRST"}, 229 | {0xBD4C, "GRA_SET_LINE_MASK"}, 230 | {0xBD4F, "GRA_FROM_USER"}, 231 | {0xBD52, "GRA_FILL"}, 232 | {0xBD55, "SCR_SET_POSITION"}, 233 | {0xBD58, "MC_PRINT_TRANSLATION"}, 234 | {0xBD5B, "KL_BANK_SWITCH"}, 235 | {0xBDCD, "IND_TXT_DRAW_CURSOR"}, 236 | {0xBDD0, "IND_TXT_UNDRAW_CURSOR"}, 237 | {0xBDD3, "IND_TXT_WRITE_CHAR"}, 238 | {0xBDD6, "IND_TXT_UNWRITE"}, 239 | {0xBDD9, "IND_TXT_OUT_ACTION"}, 240 | {0xBDDC, "IND_GRA_PLOT"}, 241 | {0xBDDF, "IND_GRA_TEST"}, 242 | {0xBDE2, "IND_GRA_LINE"}, 243 | {0xBDE5, "IND_SCR_READ"}, 244 | {0xBDE8, "IND_SCR_WRITE"}, 245 | {0xBDEB, "IND_SCR_MODE_CLEAR"}, 246 | {0xBDEE, "IND_KM_TEST_BREAK"}, 247 | {0xBDF1, "IND_MC_WAIT_PRINTER"}, 248 | {0xBDF4, "IND_KM_SCAN_KEYS"}, 249 | {0xBD61, "MOVE_REAL"}, 250 | {0xBD64, "INTEGER_TO_REAL"}, 251 | {0xBD67, "BINARY_TO_REAL"}, 252 | {0xBD6A, "REAL_TO_INTEGER"}, 253 | {0xBD6D, "REAL_TO_BINARY"}, 254 | {0xBD70, "REAL_FIX"}, 255 | {0xBD73, "REAL_INT"}, 256 | {0xBD76, "INTERNAL_SUBROUTINE"}, 257 | {0xBD79, "REAL_x10POWA"}, 258 | {0xBD7C, "REAL_ADDITION"}, 259 | {0xBD82, "REAL_REVERSE_SUBTRACTION"}, 260 | {0xBD85, "REAL_MULTIPLICATION"}, 261 | {0xBD88, "REAL_DIVISION"}, 262 | {0xBD8E, "REAL_COMPARISON"}, 263 | {0xBD91, "REAL_UNARY_MINUS"}, 264 | {0xBD94, "REAL_SIGNUM_SGN"}, 265 | {0xBD97, "SET_ANGLE_MODE"}, 266 | {0xBD9A, "REAL_PI"}, 267 | {0xBD9D, "REAL_SQR"}, 268 | {0xBDA0, "REAL_POWER"}, 269 | {0xBDA3, "REAL_LOG"}, 270 | {0xBDA6, "REAL_LOG_10"}, 271 | {0xBDA9, "REAL_EXP"}, 272 | {0xBDAC, "REAL_SINE"}, 273 | {0xBDAF, "REAL_COSINE"}, 274 | {0xBDB2, "REAL_TANGENT"}, 275 | {0xBDB5, "REAL_ARCTANGENT"}, 276 | {0xBD5B, "REAL_SUBTRACTION"}, 277 | {0xBD67, "REAL_EXPONENT_ADDITION"}, 278 | {0xBDAC, "INTEGER_ADDITION"}, 279 | {0xBDAF, "INTEGER_SUBTRACTION"}, 280 | {0xBDB2, "INTEGER_REVERSE_SUBTRACTION"}, 281 | {0xBDB5, "INTEGER_MULTIPLICATION"}, 282 | {0xBDB8, "INTEGER_DIVISION"}, 283 | {0xBDBB, "INTEGER_DIVISION_2"}, 284 | {0xBDC4, "INTEGER_COMPARISON"}, 285 | {0xBDC7, "INTEGER_UNARY_MINUS"}, 286 | {0xBDCA, "INTEGER_SIGNUM_SGN"}, 287 | {0xBD5E, "TEXT_INPUT"}, 288 | {0xBD7F, "REAL_RND"}, 289 | {0xBD8B, "REAL_RND0"}, 290 | {0xC033, "BIOS_SET_MESSAGE"}, 291 | {0xC036, "BIOS_SETUP_DISC"}, 292 | {0xC039, "BIOS_SELECT_FORMAT"}, 293 | {0xC03C, "BIOS_READ_SECTOR"}, 294 | {0xC03F, "BIOS_WRITE_SECTOR"}, 295 | {0xC042, "BIOS_FORMAT_TRACK"}, 296 | {0xC045, "BIOS_MOVE_TRACK"}, 297 | {0xC048, "BIOS_GET_STATUS"}, 298 | {0xC04B, "BIOS_SET_RETRY_COUNT"}, 299 | {0xC56C, "GET_SECTOR_DATA"}, 300 | {0xBE53, "AMSDOS_DRIVE_HSUS"}, 301 | {0xBE54, "AMSDOS_DRIVE_TRACK"}, 302 | {0xBE5E, "AMSDOS_FLAG_RW_SECTOR"}, 303 | {0xBE5F, "AMSDOS_FLAG_MOTOR"}, 304 | {0xBE7D, "AMSDOS_RESERVED_AREA"}, 305 | {0xBE7D, "AMSDOS_MEMORY_POOL"}, 306 | {0xBE7F, "AMSDOS_HOOK"}, 307 | {0, 0} 308 | }; 309 | -------------------------------------------------------------------------------- /src/getopt_pp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | GetOpt_pp: Yet another C++ version of getopt. 3 | This file is part of GetOpt_pp. 4 | 5 | Copyright (C) Daniel Gutson, FuDePAN 2007-2010 6 | Distributed under the Boost Software License, Version 1.0. 7 | (See accompanying file LICENSE_1_0.txt in the root directory or 8 | copy at http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | GetOpt_pp IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 11 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 12 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 13 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 14 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 15 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 16 | DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #if __APPLE__ 22 | #include 23 | #define environ (*_NSGetEnviron()) 24 | #elif _WIN32 25 | #include 26 | #define environ _environ 27 | #else 28 | #include 29 | #if defined(__FreeBSD__) 30 | extern char **environ; 31 | #endif 32 | #endif 33 | 34 | #include "getopt_pp.h" 35 | 36 | namespace GetOpt 37 | { 38 | 39 | GETOPT_INLINE Token* GetOpt_pp::_add_token(const std::string& value, Token::Type type) 40 | { 41 | Token* const ret = new Token(value, type); 42 | if (_first_token == NULL) 43 | _first_token = ret; 44 | else 45 | _last_token->link_to(ret); 46 | _last_token = ret; 47 | return ret; 48 | } 49 | 50 | GETOPT_INLINE void GetOpt_pp::_init_flags() 51 | { 52 | std::stringstream ss; 53 | _flags = ss.flags(); 54 | } 55 | 56 | GETOPT_INLINE void GetOpt_pp::_parse_sub_file(const std::string& file) 57 | { 58 | std::ifstream ifile(file.c_str()); 59 | if (!ifile) 60 | throw OptionsFileNotFoundEx(file); 61 | 62 | std::vector args; 63 | std::string arg; 64 | 65 | while (ifile >> arg) 66 | args.push_back(arg); 67 | 68 | _parse(args); 69 | } 70 | 71 | GETOPT_INLINE void GetOpt_pp::_parse(const std::vector& args) 72 | { 73 | bool any_option_processed = false; 74 | const size_t argc = args.size(); 75 | 76 | size_t start = 0; 77 | if ( _app_name.empty() ) 78 | { 79 | _app_name = args[0]; 80 | start = 1; 81 | } 82 | 83 | // parse arguments by their '-' or '--': 84 | // (this will be a state machine soon) 85 | for (size_t i = start; i < argc; i++) 86 | { 87 | const std::string& currentArg = args[i]; 88 | 89 | if (currentArg[0] == '-' && currentArg.size() > 1) 90 | { 91 | // see what's next, differentiate whether it's short or long: 92 | if (currentArg[1] == '-') 93 | { 94 | if ( currentArg.size() > 2 ) 95 | { 96 | // long option 97 | _longOps[currentArg.substr(2)].token = _add_token(currentArg.substr(2), Token::LongOption); 98 | } 99 | else 100 | { 101 | // it's the -- option alone 102 | _longOps[currentArg].token = _add_token(currentArg, Token::GlobalArgument); 103 | } 104 | 105 | any_option_processed = true; 106 | } 107 | else 108 | { 109 | // check if it is a negative number: rules 110 | // * floating point negative numbers are straight classified as 'arguments' 111 | // * integer negative numbers of more than 1 digit length are also 'arguments' 112 | // * integer negatives of 1 digit length can be either arguments or short options. 113 | // * anything else: short options. 114 | int anInt; 115 | float aFloat; 116 | std::stringstream dummy; 117 | if ( convert(currentArg, anInt, dummy.flags()) == _Option::OK ) 118 | { 119 | if ( currentArg.size() > 2 ) // if it's larger than -d (d=digit), then assume it's a negative number: 120 | _add_token(currentArg, any_option_processed ? Token::UnknownYet : Token::GlobalArgument); 121 | else // size == 2: it's a 1 digit negative number 122 | _shortOps[currentArg[1]].token = _add_token(currentArg, Token::PossibleNegativeArgument); 123 | } 124 | else if ( convert(currentArg, aFloat, dummy.flags()) == _Option::OK ) 125 | _add_token(currentArg, any_option_processed ? Token::UnknownYet : Token::GlobalArgument); 126 | else 127 | { 128 | // short option 129 | // iterate over all of them, keeping the last one in currentData 130 | // (so the intermediates will generate 'existent' arguments, as of '-abc') 131 | for( size_t j = 1; j < currentArg.size(); j++ ) 132 | _shortOps[currentArg[j]].token = _add_token(std::string(currentArg, j, 1), Token::ShortOption); 133 | } 134 | 135 | any_option_processed = true; 136 | } 137 | } 138 | else if ( currentArg[0] == '@' && currentArg.size() > 1 ) 139 | { 140 | // suboptions file 141 | _parse_sub_file(currentArg.substr(1)); 142 | } 143 | else 144 | { 145 | _add_token(currentArg, any_option_processed ? Token::UnknownYet : Token::GlobalArgument); 146 | } 147 | } 148 | 149 | _last = _Option::OK; // TODO: IMPROVE!! 150 | } 151 | 152 | GETOPT_INLINE void GetOpt_pp::_parse_env() 153 | { 154 | // this will be optimized in version 3 155 | std::string var_name; 156 | std::string var_value; 157 | size_t var = 0; 158 | std::string::size_type pos; 159 | OptionData* data; 160 | 161 | while (environ[var] != NULL) 162 | { 163 | var_name = environ[var]; 164 | pos = var_name.find('='); 165 | 166 | if (pos != std::string::npos) 167 | { 168 | var_value = var_name.substr(pos + 1); 169 | var_name = var_name.substr(0, pos); 170 | 171 | if (_longOps.find(var_name) == _longOps.end()) 172 | { 173 | data = &_longOps[var_name]; 174 | data->token = _add_token(var_name, Token::LongOption); 175 | data->flags = OptionData::Envir; 176 | _add_token(var_value, Token::OptionArgument); 177 | } 178 | } 179 | else 180 | (data = &_longOps[var_name])->flags = OptionData::Envir; 181 | 182 | var++; 183 | } 184 | } 185 | 186 | 187 | GETOPT_INLINE void GetOpt_pp::_argc_argv_to_vector(int argc, const char* const* const argv, std::vector& args) 188 | { 189 | for (int i = 0; i < argc; i++) 190 | args.push_back(argv[i]); 191 | } 192 | 193 | GETOPT_INLINE GetOpt_pp::TokensDeleter::~TokensDeleter() 194 | { 195 | Token* next; 196 | Token* current(_first); 197 | while (current != NULL) 198 | { 199 | next = current->next; 200 | delete current; 201 | current = next; 202 | } 203 | } 204 | 205 | GETOPT_INLINE GetOpt_pp::GetOpt_pp(int argc, const char* const* const argv) 206 | : _exc(std::ios_base::goodbit), _first_token(NULL), _last_token(NULL), _tokens_deleter(_first_token) 207 | { 208 | _init_flags(); 209 | std::vector args; 210 | _argc_argv_to_vector(argc, argv, args); 211 | _parse(args); 212 | } 213 | 214 | GETOPT_INLINE GetOpt_pp::GetOpt_pp(int argc, const char* const* const argv, _EnvTag) 215 | : _first_token(NULL), _last_token(NULL), _tokens_deleter(_first_token) 216 | { 217 | _init_flags(); 218 | std::vector args; 219 | _argc_argv_to_vector(argc, argv, args); 220 | _parse(args); 221 | _parse_env(); 222 | } 223 | 224 | GETOPT_INLINE GetOpt_pp& GetOpt_pp::operator >> (const _Option& opt) throw(GetOptEx) 225 | { 226 | if (_last != _Option::ParsingError) 227 | { 228 | _last = opt(_shortOps, _longOps, _first_token, _flags); 229 | 230 | switch (_last) 231 | { 232 | case _Option::OK: 233 | break; 234 | 235 | case _Option::OptionNotFound: 236 | if (_exc & std::ios_base::eofbit) 237 | throw OptionNotFoundEx(); 238 | break; 239 | 240 | case _Option::BadType: 241 | if (_exc & std::ios_base::failbit) 242 | throw InvalidFormatEx(); 243 | break; 244 | 245 | case _Option::NoArgs: 246 | if (_exc & std::ios_base::eofbit) 247 | throw ArgumentNotFoundEx(); 248 | break; 249 | 250 | case _Option::TooManyArgs: 251 | if (_exc & std::ios_base::failbit) 252 | throw TooManyArgumentsEx(); 253 | break; 254 | 255 | case _Option::OptionNotFound_NoEx: 256 | break; // Ok, it will be read by casting to bool 257 | 258 | case _Option::ParsingError: 259 | break; // just to disable warning 260 | } 261 | } 262 | else if (_exc & std::ios_base::failbit) 263 | throw ParsingErrorEx(); 264 | 265 | return *this; 266 | } 267 | 268 | GETOPT_INLINE GetOpt_pp& GetOpt_pp::operator >> (std::ios_base & (*iomanip)(std::ios_base&)) 269 | { 270 | std::stringstream ss; 271 | ss.flags(_flags); 272 | _flags = (ss << iomanip).flags(); 273 | return *this; 274 | } 275 | 276 | GETOPT_INLINE bool GetOpt_pp::options_remain() const 277 | { 278 | bool remain = false; 279 | ShortOptions::const_iterator it = _shortOps.begin(); 280 | while (it != _shortOps.end() && !remain) 281 | { 282 | remain = (it->second.flags == OptionData::CmdLine_NotExtracted); 283 | ++it; 284 | } 285 | 286 | if (!remain) 287 | { 288 | LongOptions::const_iterator it = _longOps.begin(); 289 | while (it != _longOps.end() && !remain) 290 | { 291 | remain = (it->second.flags == OptionData::CmdLine_NotExtracted); 292 | ++it; 293 | } 294 | } 295 | 296 | if (!remain) 297 | { 298 | // check for the global arguments: 299 | Token* token = _first_token; 300 | while (!remain && token != NULL) 301 | { 302 | remain = (token->type == Token::GlobalArgument || token->type == Token::UnknownYet); 303 | token = token->next; 304 | } 305 | } 306 | 307 | return remain; 308 | } 309 | 310 | } 311 | -------------------------------------------------------------------------------- /src/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include // pour contourner un bug de std::vector ... 5 | 6 | #include "getopt_pp.h" /* Command line handling */ 7 | 8 | using namespace std; 9 | 10 | #include "MyType.h" 11 | #include "GestDsk.h" 12 | #include "Outils.h" 13 | #include "Main.h" 14 | #include "endianPPC.h" 15 | #include "ViewFile.h" 16 | 17 | int main(int argc, char **argv) 18 | { 19 | bool IsDskLoc, IsDskSet, 20 | ModeListDsk, ModeImportFile, 21 | ModeRemoveFile, 22 | ModeDisaFile, ModeListBasic, 23 | ModeListDams, ModeListHex, 24 | ModeGetFile, ModeNewDsk, Force_Overwrite, 25 | Read_only, System_file, Split_lines, ModeListAscii, NoOptionSet; 26 | 27 | ModeListDsk = ModeImportFile = ModeListAscii = 28 | ModeRemoveFile = ModeDisaFile = 29 | ModeListBasic = ModeListDams = ModeListHex = ModeNewDsk = 30 | ModeGetFile = IsDskLoc = IsDskSet = Force_Overwrite = Read_only = System_file = false; 31 | NoOptionSet = true; 32 | 33 | string DskFile, AmsdosFile; 34 | vector AmsdosFileList; 35 | 36 | int exeAdress = 0, loadAdress = 0, AmsdosType = 1, UserNumber = 0; 37 | 38 | DSK MyDsk; 39 | 40 | IsDsk = IsDskValid = false; 41 | IsDskSaved = true; 42 | 43 | // Récupération des arguments avec getopt_pp 44 | { 45 | using namespace GetOpt; 46 | GetOpt_pp opts(argc, argv); 47 | 48 | opts >> GlobalOption(DskFile); 49 | if (DskFile != "") 50 | IsDskSet = true; 51 | 52 | opts >> OptionPresent('l', "list", ModeListDsk) 53 | 54 | >> OptionPresent('i', "import", ModeImportFile) >> Option('i', "import", AmsdosFileList) 55 | 56 | >> OptionPresent('r', "remove", ModeRemoveFile) >> Option('r', "remove", AmsdosFileList) 57 | 58 | >> OptionPresent('n', "new", ModeNewDsk) 59 | 60 | >> OptionPresent('z', "disassemble", ModeDisaFile) >> Option('z', "disassemble", AmsdosFileList) 61 | 62 | >> OptionPresent('a', "ascii", ModeListAscii) >> Option('a', "ascii", AmsdosFileList) 63 | 64 | >> OptionPresent('b', "basic", ModeListBasic) >> Option('b', "basic", AmsdosFileList) 65 | 66 | >> OptionPresent('d', "dams", ModeListDams) >> Option('d', "dams", AmsdosFileList) 67 | 68 | >> OptionPresent('h', "hex", ModeListHex) >> Option('h', "hex", AmsdosFileList) 69 | 70 | >> std::hex >> Option('e', "exec", exeAdress) >> Option('c', "load", loadAdress) >> std::dec >> Option('t', "type", AmsdosType) 71 | 72 | >> OptionPresent('g', "get", ModeGetFile) >> Option('g', "get", AmsdosFileList) 73 | 74 | >> OptionPresent('f', "force", Force_Overwrite) >> OptionPresent('o', "write-protect", Read_only) >> OptionPresent('s', "system", System_file) >> OptionPresent('p', "split-lines", Split_lines) >> Option('u', "user", UserNumber); 75 | 76 | if (opts.options_remain()) 77 | { 78 | cout << "Unhandled option ! Check the syntax." << endl; 79 | exit(EXIT_FAILURE); 80 | } 81 | 82 | } //namespace getopt 83 | 84 | if (!IsDskSet) 85 | { 86 | cerr << "You did not select a DSK file to work with !" << endl; 87 | help(); 88 | } 89 | else 90 | cerr << "DSK : " << DskFile << endl; 91 | 92 | if (ModeListBasic || ModeListHex || ModeListDams || ModeDisaFile || ModeListAscii) 93 | { 94 | NoOptionSet = false; 95 | if (!MyDsk.ReadDsk(DskFile)) 96 | { 97 | cerr << "Error reading file (" << DskFile << ")." << endl; 98 | exit(EXIT_FAILURE); 99 | } 100 | if (!MyDsk.CheckDsk()) 101 | { 102 | cerr << "Fichier image non supporté (" << DskFile << ")." << endl; 103 | exit(EXIT_FAILURE); 104 | } 105 | int Indice; 106 | for (vector::iterator iter = AmsdosFileList.begin(); iter != AmsdosFileList.end(); iter++) 107 | { 108 | char *amsdosF = GetNomAmsdos(iter->c_str()); 109 | cerr << "Amsdos file : " << amsdosF << endl; 110 | if ((Indice = MyDsk.FileIsIn(amsdosF)) < 0) 111 | { 112 | cerr << "Error: File " << amsdosF << " not found." << endl; 113 | exit(EXIT_FAILURE); 114 | } 115 | MyDsk.OnViewFic(Indice); 116 | 117 | if (ModeListBasic) 118 | cout << ViewBasic(Split_lines) << endl; 119 | else if (ModeListDams) 120 | cout << "Not yet coded ! Please try a newer version of iDSK ! Sorry !" << endl; 121 | else if (ModeListHex) 122 | { 123 | MyDsk.Hexdecimal(); 124 | cout << Listing << endl; 125 | } 126 | else if (ModeDisaFile) 127 | cout << ViewDesass() << endl; 128 | else if (ModeListAscii) 129 | cout << ViewAscii() << endl; 130 | } 131 | } 132 | 133 | if (ModeNewDsk) 134 | { 135 | NoOptionSet = false; 136 | MyDsk.FormatDsk(9, 42); 137 | if (!MyDsk.WriteDsk(DskFile)) 138 | { 139 | cerr << "Error writing file " << DskFile << endl; 140 | exit(EXIT_FAILURE); 141 | } 142 | } 143 | 144 | 145 | 146 | if (ModeImportFile) 147 | { // Ajouter fichiers sur dsk 148 | NoOptionSet = false; 149 | if (!MyDsk.ReadDsk(DskFile)) 150 | { 151 | cerr << "Error reading file (" << DskFile << ")." << endl; 152 | exit(EXIT_FAILURE); 153 | } 154 | 155 | if (!MyDsk.CheckDsk()) 156 | { 157 | cerr << "Unsupported dsk file (" << DskFile << ")." << endl; 158 | exit(EXIT_FAILURE); 159 | } 160 | 161 | for (vector::iterator iter = AmsdosFileList.begin(); iter != AmsdosFileList.end(); iter++) 162 | { 163 | string amsdosfile = GetNomAmsdos(iter->c_str()); 164 | int Indice; 165 | // Ensure Indice is valid (the file is in the disk already) before atempting to remove it 166 | if ((Indice = MyDsk.FileIsIn(amsdosfile)) != -1) 167 | { 168 | if (!Force_Overwrite) 169 | { 170 | cerr << "(" << amsdosfile << ") File exists, replace ? (Y/N) (try -f switch for autoreplace...):"; 171 | string answer; 172 | cin >> answer; 173 | if (toupper(answer[0]) == 'Y') 174 | MyDsk.RemoveFile(Indice); 175 | else 176 | { 177 | cerr << "Import cancelled, dsk unchanged." << endl; 178 | cout << MyDsk.ReadDskDir(); 179 | exit(EXIT_SUCCESS); 180 | } 181 | } 182 | else 183 | MyDsk.RemoveFile(Indice); 184 | } 185 | cerr << "Amsdos file : " << *iter << endl; 186 | 187 | MyDsk.PutFileInDsk(*iter, AmsdosType, loadAdress, exeAdress, UserNumber, System_file, Read_only); 188 | } 189 | if (MyDsk.WriteDsk(DskFile)) 190 | cout << MyDsk.ReadDskDir(); 191 | else 192 | cerr << "Error writing file : " << DskFile << endl; 193 | } 194 | 195 | if (ModeRemoveFile) 196 | { 197 | NoOptionSet = false; 198 | if (!MyDsk.ReadDsk((char *)DskFile.c_str())) 199 | { 200 | cerr << "Error reading file (" << DskFile << ")." << endl; 201 | exit(EXIT_FAILURE); 202 | } 203 | if (!MyDsk.CheckDsk()) 204 | { 205 | cerr << "unsupported DSK file (" << DskFile << ")." << endl; 206 | exit(EXIT_FAILURE); 207 | } 208 | int Indice; 209 | for (vector::iterator iter = AmsdosFileList.begin(); iter != AmsdosFileList.end(); iter++) 210 | { 211 | char *amsdosF = GetNomAmsdos(iter->c_str()); 212 | cerr << "Amsdos file : " << amsdosF << endl; 213 | if ((Indice = MyDsk.FileIsIn(amsdosF)) < 0) 214 | { 215 | cerr << "Error : file " << amsdosF << " not found." << endl; 216 | exit(EXIT_FAILURE); 217 | } 218 | MyDsk.RemoveFile(Indice); 219 | if (MyDsk.WriteDsk((char *)DskFile.c_str())) 220 | cout << MyDsk.ReadDskDir(); 221 | else 222 | cerr << "Error writing file " << (*iter) << endl; 223 | } 224 | } 225 | 226 | if (ModeGetFile) 227 | { 228 | NoOptionSet = false; 229 | if (!MyDsk.ReadDsk((char *)DskFile.c_str())) 230 | { 231 | cerr << "Error reading dskfile (" << DskFile << ")." << endl; 232 | exit(EXIT_FAILURE); 233 | } 234 | if (!MyDsk.CheckDsk()) 235 | { 236 | cerr << "Unsupported dsk (" << DskFile << ")." << endl; 237 | exit(EXIT_FAILURE); 238 | } 239 | int Indice; 240 | 241 | for (vector::iterator iter = AmsdosFileList.begin(); iter != AmsdosFileList.end(); iter++) 242 | { 243 | char *amsdosF = GetNomAmsdos(iter->c_str()); 244 | cerr << "Fichier Amsdos : " << amsdosF << endl; 245 | if ((Indice = MyDsk.FileIsIn(amsdosF)) < 0) 246 | { 247 | cerr << "Error : file " << amsdosF << " not found." << endl; 248 | exit(EXIT_FAILURE); 249 | } 250 | if (!MyDsk.GetFileInDsk((char *)(*iter).c_str(), Indice)) 251 | { 252 | cerr << "System error : unable to copy (" << AmsdosFile << ")." << endl; 253 | exit(EXIT_FAILURE); 254 | } 255 | } 256 | } 257 | if (ModeListDsk || NoOptionSet) 258 | { // lire Dsk 259 | if (!MyDsk.ReadDsk(DskFile)) 260 | { 261 | cerr << "Error reading file (" << DskFile << ")." << endl; 262 | exit(EXIT_FAILURE); 263 | } 264 | if (!MyDsk.CheckDsk()) 265 | { 266 | cerr << "Unsupported dsk file (" << DskFile << ")." << endl; 267 | exit(EXIT_FAILURE); 268 | } 269 | cout << MyDsk.ReadDskDir(); 270 | } 271 | 272 | cerr << "------------------------------------" << endl; 273 | 274 | return (EXIT_SUCCESS); 275 | } 276 | 277 | void help(void) 278 | { 279 | cout << endl; 280 | cout << "--------------------------------------------------------------------------------" << endl; 281 | cout << "################################################################################" << endl; 282 | cout << VERSION << " (by Demoniak, Sid, PulkoMandy), http://github.com/cpcsdk " << endl; 283 | cout << "################################################################################" << endl; 284 | cout << endl; 285 | cout << "Usage : " << endl; 286 | cout << "\t" << PROGNAME << " [OPTIONS] [files to process]" << endl; 287 | cout << "OPTIONS : EXAMPLE" << endl; 288 | cout << "-l : List disk catalog iDSK floppy.dsk -l (default option is no option is set)" << endl; 289 | cout << "-g : export ('Get') file iDSK floppy.dsk -g myprog.bas" << endl; 290 | cout << "-r : Remove file iDSK floppy.dsk -r myprog.bas" << endl; 291 | cout << "-n : create New dsk file iDSK floppy2.dsk -n" << endl; 292 | cout << "-z : disassemble a binary file iDSK floppy.dsk -z myprog.bin" << endl; 293 | cout << "-b : list a Basic file iDSK floppy.dsk -b myprog.bas" << endl 294 | << "-p : split lines after 80 char ... -p" << endl; 295 | cout << "-a : list a Ascii file iDSK floppy.dsk -a myprog.txt" << endl; 296 | cout << "-d : list a Dams file iDSK floppy.dsk -d myprog.dms" << endl; 297 | cout << "-h : list a binary file as Hexadecimal iDSK floppy.dsk -h myprog.bin" << endl; 298 | cout << "-i : Import file iDSK floppy.dsk -i myprog.bas" << endl 299 | << " -t : fileType (0=ASCII/1=BINARY/2=raw) ... -t 1" << endl; 300 | cout << " -e : hex Execute address of file ... -e C000 -t 1" << endl; 301 | cout << " -c : hex loading address of file ... -e C000 -c 4000 -t 1" << endl; 302 | cout << " -f : Force overwriting if file exists ... -f" << endl 303 | << " -o : insert a read-Only file ... -o" << endl 304 | << " -s : insert a System file ... -s" << endl 305 | << " -u : insert file with User number ... -u 3" << endl; 306 | cout << "--------------------------------------------------------------------------------" << endl; 307 | cout << "Please report bugs ! - Demoniak/Sid/PulkoMandy" << endl; 308 | exit(0); 309 | } 310 | -------------------------------------------------------------------------------- /src/Basic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "MyType.h" 9 | #include "Basic.h" 10 | 11 | 12 | //static char ConvCpcFr[ 128 ] = " !\"#$%&'()*+,-./0123456789:;<=>?àABCDEFGHIJKLMNOPQRSTUVWXYZ[ç]^_`abcdefghijklmnopqrstuvwxyzéùè~"; 13 | 14 | 15 | // 16 | // Tableau de décryptage d'un programme en basic protégé 17 | // 18 | static BYTE DproBasic[ 128 ] = 19 | { 20 | 0xAB, 0x2C, 0xED, 0xEA, 0x6C, 0x37, 0x3F, 0xEC, 21 | 0x9B, 0xDF, 0x7A, 0x0C, 0x3B, 0xD4, 0x6D, 0xF5, 22 | 0x04, 0x44, 0x03, 0x11, 0xDF, 0x59, 0x8F, 0x21, 23 | 0x73, 0x7A, 0xCC, 0x83, 0xDD, 0x30, 0x6A, 0x30, 24 | 0xD3, 0x8F, 0x02, 0xF0, 0x60, 0x6B, 0x94, 0xE4, 25 | 0xB7, 0xF3, 0x03, 0xA8, 0x60, 0x88, 0xF0, 0x43, 26 | 0xE8, 0x8E, 0x43, 0xA0, 0xCA, 0x84, 0x31, 0x53, 27 | 0xF3, 0x1F, 0xC9, 0xE8, 0xAD, 0xC0, 0xBA, 0x6D, 28 | 0x93, 0x08, 0xD4, 0x6A, 0x2C, 0xB2, 0x07, 0x27, 29 | 0xC0, 0x99, 0xEE, 0x89, 0xAF, 0xC3, 0x53, 0xAB, 30 | 0x2B, 0x34, 0x5C, 0x2F, 0x13, 0xEE, 0xAA, 0x2C, 31 | 0xD9, 0xF4, 0xBC, 0x12, 0xB3, 0xC5, 0x1C, 0x68, 32 | 0x01, 0x20, 0x2C, 0xFA, 0x77, 0xA6, 0xB5, 0xA4, 33 | 0xFC, 0x9B, 0xF1, 0x32, 0x5B, 0xC3, 0x70, 0x77, 34 | 0x85, 0x36, 0xBE, 0x5B, 0x8C, 0xC8, 0xB5, 0xC2, 35 | 0xF0, 0x0B, 0x98, 0x0F, 0x36, 0x9D, 0xD8, 0x96 36 | }; 37 | 38 | 39 | BYTE GetByte( BYTE * BufFile, int Pos, int Deprotect ) 40 | { 41 | //BYTE b = ( BYTE )( BufFile[ Pos ] ^ ( DproBasic[ Pos & 0x7F ] * Deprotect ) ); 42 | //cout << "GetByte:"<", "=", ">=", "<", "<>", 108 | "<=", "+", "-", "*", "/", "^", "\\ ", "AND", "MOD", "OR", "XOR", "NOT", 109 | "#FF" 110 | }; 111 | 112 | static const char * Fcts[ 0x80 ] = 113 | { 114 | "ABS", "ASC", "ATN", "CHR$", "CINT", "COS", "CREAL", "EXP", "FIX", 115 | "FRE", "INKEY", "INP", "INT", "JOY", "LEN", "LOG", "LOG10", "LOWER$", 116 | "PEEK", "REMAIN", "SGN", "SIN", "SPACE$", "SQ", "SQR", "STR$", "TAN", 117 | "UNT", "UPPER$", "VAL", "", "", "", "", "", "", "", "", "", "", "", 118 | "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 119 | "", "", "", "", "", "", "EOF", "ERR", "HIMEM", "INKEY$", "PI", "RND", 120 | "TIME", "XPOS", "YPOS", "DERR", "", "", "", "", "", "", "", "", "", "", 121 | "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 122 | "", "", "", "", "", "", "", "", "", "", "", "BIN$", "DEC$", "HEX$", 123 | "INSTR", "LEFT$", "MAX", "MIN", "POS", "RIGHT$", "ROUND", "STRING$", 124 | "TEST", "TESTR", "COPYCHR$", "VPOS" 125 | }; 126 | 127 | 128 | * Listing = 0; 129 | Token = GetByte( BufFile, 0, Deprotect ); 130 | for ( ;; ) 131 | { 132 | //cout << "Listing : " < 0x7F && Token < 0xFF ) 168 | { 169 | // #### Traitement particulier du ':' avant le ELSE 170 | if ( Listing[ strlen( Listing ) - 1 ] == ':' 171 | && Token == 0x97 172 | ) 173 | Listing[ strlen( Listing ) - 1 ] = 0; 174 | 175 | strcat( Listing 176 | , MotsClefs[ Token & 0x7F ] 177 | ); 178 | } 179 | else 180 | if ( Token >= 0x0E && Token <= 0x18 ) 181 | strcat( Listing 182 | , Nbre[ Token - 0x0E ] 183 | ); 184 | else 185 | if ( Token >= 0x20 && Token < 0x7C ) 186 | { 187 | Tmp[ 0 ] = ( char )Token; 188 | Tmp[ 1 ] = 0; 189 | strcat( Listing, Tmp ); 190 | if ( Token == '"' ) 191 | DansChaine ^= 1; 192 | } 193 | else 194 | { 195 | //cout << "Token:" << Token < 80 caractères 335 | // 336 | EndLigne = strlen( &Listing[ StartLigne ] ); 337 | while( EndLigne > 80 ) 338 | { 339 | memmove( &Listing[ StartLigne + 82 ] 340 | , &Listing[ StartLigne + 80 ] 341 | , EndLigne 342 | ); 343 | memcpy( &Listing[ StartLigne + 80 ], "\r\n", 2 ); 344 | StartLigne += 82; 345 | EndLigne -= 80; 346 | } 347 | } 348 | strcat( Listing, "\r\n" ); 349 | StartLigne = strlen( Listing ); 350 | } 351 | // Conversion des caractères accentués si nécessaire 352 | 353 | for ( int i = strlen( Listing); i--; ) 354 | { 355 | //cout << i << " "; 356 | 357 | if ( ! isprint(Listing[ i ]) && Listing[ i ] != '\n' && Listing[ i ] != '\r' ) Listing[ i ] = '?'; 358 | } 359 | } 360 | -------------------------------------------------------------------------------- /src/Desass.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "Outils.h" 6 | using namespace std; 7 | 8 | // Vecteurs du Firmware CPC 9 | #include "firmware.h" 10 | 11 | // 12 | // Tableau des OP-Codes Z80... 13 | // 14 | const char * const TabInstrCB[ 256 ] = 15 | { 16 | "RLC B","RLC C","RLC D","RLC E", 17 | "RLC H","RLC L","RLC (HL)","RLC A", 18 | "RRC B","RRC C","RRC D","RRC E", 19 | "RRC H","RRC L","RRC (HL)","RRC A", 20 | "RL B","RL C","RL D","RL E", 21 | "RL H","RL L","RL (HL)","RL A", 22 | "RR B","RR C","RR D","RR E", 23 | "RR H","RR L","RR (HL)","RR A", 24 | "SLA B","SLA C","SLA D","SLA E", 25 | "SLA H","SLA L","SLA (HL)","SLA A", 26 | "SRA B","SRA C","SRA D","SRA E", 27 | "SRA H","SRA L","SRA (HL)","SRA A", 28 | "SLL B","SLL C","SLL D","SLL E", 29 | "SLL H","SLL L","SLL (HL)","SLL A", 30 | "SRL B","SRL C","SRL D","SRL E", 31 | "SRL H","SRL L","SRL (HL)","SRL A", 32 | "BIT 0,B","BIT 0,C","BIT 0,D","BIT 0,E", 33 | "BIT 0,H","BIT 0,L","BIT 0,(HL)","BIT 0,A", 34 | "BIT 1,B","BIT 1,C","BIT 1,D","BIT 1,E", 35 | "BIT 1,H","BIT 1,L","BIT 1,(HL)","BIT 1,A", 36 | "BIT 2,B","BIT 2,C","BIT 2,D","BIT 2,E", 37 | "BIT 2,H","BIT 2,L","BIT 2,(HL)","BIT 2,A", 38 | "BIT 3,B","BIT 3,C","BIT 3,D","BIT 3,E", 39 | "BIT 3,H","BIT 3,L","BIT 3,(HL)","BIT 3,A", 40 | "BIT 4,B","BIT 4,C","BIT 4,D","BIT 4,E", 41 | "BIT 4,H","BIT 4,L","BIT 4,(HL)","BIT 4,A", 42 | "BIT 5,B","BIT 5,C","BIT 5,D","BIT 5,E", 43 | "BIT 5,H","BIT 5,L","BIT 5,(HL)","BIT 5,A", 44 | "BIT 6,B","BIT 6,C","BIT 6,D","BIT 6,E", 45 | "BIT 6,H","BIT 6,L","BIT 6,(HL)","BIT 6,A", 46 | "BIT 7,B","BIT 7,C","BIT 7,D","BIT 7,E", 47 | "BIT 7,H","BIT 7,L","BIT 7,(HL)","BIT 7,A", 48 | "RES 0,B","RES 0,C","RES 0,D","RES 0,E", 49 | "RES 0,H","RES 0,L","RES 0,(HL)","RES 0,A", 50 | "RES 1,B","RES 1,C","RES 1,D","RES 1,E", 51 | "RES 1,H","RES 1,L","RES 1,(HL)","RES 1,A", 52 | "RES 2,B","RES 2,C","RES 2,D","RES 2,E", 53 | "RES 2,H","RES 2,L","RES 2,(HL)","RES 2,A", 54 | "RES 3,B","RES 3,C","RES 3,D","RES 3,E", 55 | "RES 3,H","RES 3,L","RES 3,(HL)","RES 3,A", 56 | "RES 4,B","RES 4,C","RES 4,D","RES 4,E", 57 | "RES 4,H","RES 4,L","RES 4,(HL)","RES 4,A", 58 | "RES 5,B","RES 5,C","RES 5,D","RES 5,E", 59 | "RES 5,H","RES 5,L","RES 5,(HL)","RES 5,A", 60 | "RES 6,B","RES 6,C","RES 6,D","RES 6,E", 61 | "RES 6,H","RES 6,L","RES 6,(HL)","RES 6,A", 62 | "RES 7,B","RES 7,C","RES 7,D","RES 7,E", 63 | "RES 7,H","RES 7,L","RES 7,(HL)","RES 7,A", 64 | "SET 0,B","SET 0,C","SET 0,D","SET 0,E", 65 | "SET 0,H","SET 0,L","SET 0,(HL)","SET 0,A", 66 | "SET 1,B","SET 1,C","SET 1,D","SET 1,E", 67 | "SET 1,H","SET 1,L","SET 1,(HL)","SET 1,A", 68 | "SET 2,B","SET 2,C","SET 2,D","SET 2,E", 69 | "SET 2,H","SET 2,L","SET 2,(HL)","SET 2,A", 70 | "SET 3,B","SET 3,C","SET 3,D","SET 3,E", 71 | "SET 3,H","SET 3,L","SET 3,(HL)","SET 3,A", 72 | "SET 4,B","SET 4,C","SET 4,D","SET 4,E", 73 | "SET 4,H","SET 4,L","SET 4,(HL)","SET 4,A", 74 | "SET 5,B","SET 5,C","SET 5,D","SET 5,E", 75 | "SET 5,H","SET 5,L","SET 5,(HL)","SET 5,A", 76 | "SET 6,B","SET 6,C","SET 6,D","SET 6,E", 77 | "SET 6,H","SET 6,L","SET 6,(HL)","SET 6,A", 78 | "SET 7,B","SET 7,C","SET 7,D","SET 7,E", 79 | "SET 7,H","SET 7,L","SET 7,(HL)","SET 7,A" 80 | }; 81 | 82 | 83 | const char * const TabInstrED[ 256 ] = 84 | { 85 | 0,0,0,0, 86 | 0,0,0,0, 87 | 0,0,0,0, 88 | 0,0,0,0, 89 | 0,0,0,0, 90 | 0,0,0,0, 91 | 0,0,0,0, 92 | 0,0,0,0, 93 | 0,0,0,0, 94 | 0,0,0,0, 95 | 0,0,0,0, 96 | 0,0,0,0, 97 | 0,0,0,0, 98 | 0,0,0,0, 99 | 0,0,0,0, 100 | 0,0,0,0, 101 | "IN B,(C)","OUT (C),B","SBC HL,BC","LD (nnnn),BC", 102 | "NEG","RETN","IM 0","LD I,A", 103 | "IN C,(C)","OUT (C),C","ADC HL,BC","LD BC,(nnnn)", 104 | 0,"RETI",0,"LD R,A", 105 | "IN D,(C)","OUT (C),D","SBC HL,DE","LD (nnnn),DE", 106 | 0,0,"IM 1","LD A,I", 107 | "IN E,(C)","OUT (C),E","ADC HL,DE","LD DE,(nnnn)", 108 | 0,0,"IM 2","LD A,R", 109 | "IN H,(C)","OUT (C),H","SBC HL,HL",0, 110 | 0,0,0,"RRD", 111 | "IN L,(C)","OUT (C),L","ADC HL,HL",0, 112 | 0,0,0,"RLD", 113 | 0,"OUT (C),0","SBC HL,SP","LD (nnnn),SP", 114 | 0,0,0,0, 115 | "IN A,(C)","OUT (C),A","ADC HL,SP","LD SP,(nnnn)", 116 | 0,0,0,0, 117 | 0,0,0,0, 118 | 0,0,0,0, 119 | 0,0,0,0, 120 | 0,0,0,0, 121 | 0,0,0,0, 122 | 0,0,0,0, 123 | 0,0,0,0, 124 | 0,0,0,0, 125 | "LDI","CPI","INI","OUTI", 126 | 0,0,0,0, 127 | "LDD","CPD","IND","OUTD", 128 | 0,0,0,0, 129 | "LDIR","CPIR","INIR","OTIR", 130 | 0,0,0,0, 131 | "LDDR","CPDR","INDR","OTDR", 132 | 0,0,0,0, 133 | 0,0,0,0, 134 | 0,0,0,0, 135 | 0,0,0,0, 136 | 0,0,0,0, 137 | 0,0,0,0, 138 | 0,0,0,0, 139 | 0,0,0,0, 140 | 0,0,0,0, 141 | 0,0,0,0, 142 | 0,0,0,0, 143 | 0,0,0,0, 144 | 0,0,0,0, 145 | 0,0,0,0, 146 | 0,0,0,0, 147 | 0,0,0,0, 148 | 0,0,0,0 149 | }; 150 | 151 | 152 | const char * const TabInstrDD[ 256 ] = 153 | { 154 | 0,0,0,0, 155 | 0,0,0,0, 156 | 0,"ADD IX,BC",0,0, 157 | 0,0,0,0, 158 | 0,0,0,0, 159 | 0,0,0,0, 160 | 0,"ADD IX,DE",0,0, 161 | 0,0,0,0, 162 | 0,"LD IX,nnnn","LD (nnnn),IX","INC IX", 163 | "INC IXh","DEC IXh","LD IXh,nn",0, 164 | 0,"ADD IX,HL","LD IX,(nnnn)","DEC IX", 165 | "INC IXl","DEC IXl","LD IXl,nn",0, 166 | 0,0,0,0, 167 | "INC (IX+nn)","DEC (IX+nn)","LD (IX+nn),nn",0, 168 | 0,"ADD IX,SP",0,0, 169 | 0,0,0,0, 170 | 0,0,0,0, 171 | "LD B,IXh","LD B,IXl","LD B,(IX+nn)",0, 172 | 0,0,0,0, 173 | "LD C,IXh","LD C,IXl","LD C,(IX+nn)",0, 174 | 0,0,0,0, 175 | "LD D,IXh","LD D,IXl","LD D,(IX+nn)",0, 176 | 0,0,0,0, 177 | "LD E,IXh","LD E,IXl","LD E,(IX+nn)",0, 178 | "LD IXh,B","LD IXh,C","LD IXh,D","LD IXh,E", 179 | "LD IXh,IXh","LD IXh,IXl","LD H,(IX+nn)","LD IXh,A", 180 | "LD IXl,B","LD IXl,C","LD IXl,D","LD IXl,E", 181 | "LD IXl,IXh","LD IXl,IXl","LD L,(IX+nn)","LD IXl,A", 182 | "LD (IX+nn),B","LD (IX+nn),C","LD (IX+nn),D","LD (IX+nn),E", 183 | "LD (IX+nn),H","LD (IX+nn),L",0,"LD (IX+nn),A", 184 | 0,0,0,0, 185 | "LD A,IXh","LD A,IXl","LD A,(IX+nn)",0, 186 | 0,0,0,0, 187 | "ADD A,IXh","ADD A,IXl","ADD A,(IX+nn)",0, 188 | 0,0,0,0, 189 | "ADC A,IXh","ADC A,IXl","ADC A,(IX+nn)",0, 190 | 0,0,0,0, 191 | "SUB IXh","SUB IXl","SUB (IX+nn)",0, 192 | 0,0,0,0, 193 | "SBC A,IXh","SBC A,IXl","SBC A,(IX+nn)",0, 194 | 0,0,0,0, 195 | "AND IXh","AND IXl","AND (IX+nn)",0, 196 | 0,0,0,0, 197 | "XOR IXh","XOR IXl","XOR (IX+nn)",0, 198 | 0,0,0,0, 199 | "OR IXh","OR IXl","OR (IX+nn)",0, 200 | 0,0,0,0, 201 | "CP IXh","CP IXl","CP (IX+nn)",0, 202 | 0,0,0,0, 203 | 0,0,0,0, 204 | 0,0,0,0, 205 | 0,0,0,0, 206 | 0,0,0,0, 207 | 0,0,0,0, 208 | 0,0,0,0, 209 | 0,0,0,0, 210 | 0,"POP IX",0,"EX (SP),IX", 211 | 0,"PUSH IX",0,0, 212 | 0,"JP (IX)",0,0, 213 | 0,0,0,0, 214 | 0,0,0,0, 215 | 0,0,0,0, 216 | 0,"LD SP,IX",0,0, 217 | 0,0,0,0 218 | }; 219 | 220 | 221 | const char * const TabInstrDDCB[ 256 ] = 222 | { 223 | 0,0,0,0,0,0,"RLC (IX+nn)",0, 224 | 0,0,0,0,0,0,"RRC (IX+nn)",0, 225 | 0,0,0,0,0,0,"RL (IX+nn)",0, 226 | 0,0,0,0,0,0,"RR (IX+nn)",0, 227 | 0,0,0,0,0,0,"SLA (IX+nn)",0, 228 | 0,0,0,0,0,0,"SRA (IX+nn)",0, 229 | 0,0,0,0,0,0,"SLL (IX+nn)",0, 230 | 0,0,0,0,0,0,"SRL (IX+nn)",0, 231 | 0,0,0,0,0,0,"BIT 0,(IX+nn)",0, 232 | 0,0,0,0,0,0,"BIT 1,(IX+nn)",0, 233 | 0,0,0,0,0,0,"BIT 2,(IX+nn)",0, 234 | 0,0,0,0,0,0,"BIT 3,(IX+nn)",0, 235 | 0,0,0,0,0,0,"BIT 4,(IX+nn)",0, 236 | 0,0,0,0,0,0,"BIT 5,(IX+nn)",0, 237 | 0,0,0,0,0,0,"BIT 6,(IX+nn)",0, 238 | 0,0,0,0,0,0,"BIT 7,(IX+nn)",0, 239 | 0,0,0,0,0,0,"RES 0,(IX+nn)",0, 240 | 0,0,0,0,0,0,"RES 1,(IX+nn)",0, 241 | 0,0,0,0,0,0,"RES 2,(IX+nn)",0, 242 | 0,0,0,0,0,0,"RES 3,(IX+nn)",0, 243 | 0,0,0,0,0,0,"RES 4,(IX+nn)",0, 244 | 0,0,0,0,0,0,"RES 5,(IX+nn)",0, 245 | 0,0,0,0,0,0,"RES 6,(IX+nn)",0, 246 | 0,0,0,0,0,0,"RES 7,(IX+nn)",0, 247 | 0,0,0,0,0,0,"SET 0,(IX+nn)",0, 248 | 0,0,0,0,0,0,"SET 1,(IX+nn)",0, 249 | 0,0,0,0,0,0,"SET 2,(IX+nn)",0, 250 | 0,0,0,0,0,0,"SET 3,(IX+nn)",0, 251 | 0,0,0,0,0,0,"SET 4,(IX+nn)",0, 252 | 0,0,0,0,0,0,"SET 5,(IX+nn)",0, 253 | 0,0,0,0,0,0,"SET 6,(IX+nn)",0, 254 | 0,0,0,0,0,0,"SET 7,(IX+nn)",0 255 | }; 256 | 257 | 258 | const char * const TabInstrFD[ 256 ] = 259 | { 260 | 0,0,0,0,0,0,0,0, 261 | 0,"ADD IY,BC",0,0,0,0,0,0, 262 | 0,0,0,0,0,0,0,0, 263 | 0,"ADD IY,DE",0,0,0,0,0,0, 264 | 0,"LD IY,nnnn","LD (nnnn),IY","INC IY","INC IYh","DEC IYh","LD IYh,nn",0, 265 | 0,"ADD IY,HL","LD IY,(nnnn)","DEC IY","INC IYl","DEC IYl","LD IYl,nn",0, 266 | 0,0,0,0,"INC (IY+nn)","DEC (IY+nn)","LD (IY+nn),nn",0, 267 | 0,"ADD IY,SP",0,0,0,0,0,0, 268 | 0,0,0,0,"LD B,IYh","LD B,IYl","LD B,(IY+nn)",0, 269 | 0,0,0,0,"LD C,IYh","LD C,IYl","LD C,(IY+nn)",0, 270 | 0,0,0,0,"LD D,IYh","LD D,IYl","LD D,(IY+nn)",0, 271 | 0,0,0,0,"LD E,IYh","LD E,IYl","LD E,(IY+nn)",0, 272 | "LD IYh,B","LD IYh,C","LD IYh,D","LD IYh,E","LD IYh,IYh","LD IYh,IYl","LD H,(IY+nn)","LD IYh,A", 273 | "LD IYl,B","LD IYl,C","LD IYl,D","LD IYl,E","LD IYl,IYh","LD IYl,IYl","LD L,(IY+nn)","LD IYl,A", 274 | "LD (IY+nn),B","LD (IY+nn),C","LD (IY+nn),D","LD (IY+nn),E","LD (IY+nn),H","LD (IY+nn),L",0,"LD (IY+nn),A", 275 | 0,0,0,0,"LD A,IYh","LD A,IYl","LD A,(IY+nn)",0, 276 | 0,0,0,0,"ADD A,IYh","ADD A,IYl","ADD A,(IY+nn)",0, 277 | 0,0,0,0,"ADC A,IYh","ADC A,IYl","ADC A,(IY+nn)",0, 278 | 0,0,0,0,"SUB IYh","SUB IYl","SUB (IY+nn)",0, 279 | 0,0,0,0,"SBC A,IYh","SBC A,IYl","SBC A,(IY+nn)",0, 280 | 0,0,0,0,"AND IYh","AND IYl","AND (IY+nn)",0, 281 | 0,0,0,0,"XOR IYh","XOR IYl","XOR (IY+nn)",0, 282 | 0,0,0,0,"OR IYh","OR IYl","OR (IY+nn)",0, 283 | 0,0,0,0,"CP IYh","CP IYl","CP (IY+nn)",0, 284 | 0,0,0,0,0,0,0,0, 285 | 0,0,0,0,0,0,0,0, 286 | 0,0,0,0,0,0,0,0, 287 | 0,0,0,0,0,0,0,0, 288 | 0,"POP IY",0,"EX (SP),IY",0,"PUSH IY",0,0, 289 | 0,"JP (IY)",0,0,0,0,0,0, 290 | 0,0,0,0,0,0,0,0, 291 | 0,"LD SP,IY",0,0,0,0,0,0 292 | }; 293 | 294 | 295 | const char * const TabInstrFDCB[ 256 ] = 296 | { 297 | 0,0,0,0,0,0,"RLC (IY+nn)",0, 298 | 0,0,0,0,0,0,"RRC (IY+nn)",0, 299 | 0,0,0,0,0,0,"RL (IY+nn)",0, 300 | 0,0,0,0,0,0,"RR (IY+nn)",0, 301 | 0,0,0,0,0,0,"SLA (IY+nn)",0, 302 | 0,0,0,0,0,0,"SRA (IY+nn)",0, 303 | 0,0,0,0,0,0,"SLL (IY+nn)",0, 304 | 0,0,0,0,0,0,"SRL (IY+nn)",0, 305 | 0,0,0,0,0,0,"BIT 0,(IY+nn)",0, 306 | 0,0,0,0,0,0,"BIT 1,(IY+nn)",0, 307 | 0,0,0,0,0,0,"BIT 2,(IY+nn)",0, 308 | 0,0,0,0,0,0,"BIT 3,(IY+nn)",0, 309 | 0,0,0,0,0,0,"BIT 4,(IY+nn)",0, 310 | 0,0,0,0,0,0,"BIT 5,(IY+nn)",0, 311 | 0,0,0,0,0,0,"BIT 6,(IY+nn)",0, 312 | 0,0,0,0,0,0,"BIT 7,(IY+nn)",0, 313 | 0,0,0,0,0,0,"RES 0,(IY+nn)",0, 314 | 0,0,0,0,0,0,"RES 1,(IY+nn)",0, 315 | 0,0,0,0,0,0,"RES 2,(IY+nn)",0, 316 | 0,0,0,0,0,0,"RES 3,(IY+nn)",0, 317 | 0,0,0,0,0,0,"RES 4,(IY+nn)",0, 318 | 0,0,0,0,0,0,"RES 5,(IY+nn)",0, 319 | 0,0,0,0,0,0,"RES 6,(IY+nn)",0, 320 | 0,0,0,0,0,0,"RES 7,(IY+nn)",0, 321 | 0,0,0,0,0,0,"SET 0,(IY+nn)",0, 322 | 0,0,0,0,0,0,"SET 1,(IY+nn)",0, 323 | 0,0,0,0,0,0,"SET 2,(IY+nn)",0, 324 | 0,0,0,0,0,0,"SET 3,(IY+nn)",0, 325 | 0,0,0,0,0,0,"SET 4,(IY+nn)",0, 326 | 0,0,0,0,0,0,"SET 5,(IY+nn)",0, 327 | 0,0,0,0,0,0,"SET 6,(IY+nn)",0, 328 | 0,0,0,0,0,0,"SET 7,(IY+nn)",0 329 | }; 330 | 331 | 332 | const char * const TabInstr[ 256 ] = 333 | { 334 | "NOP","LD BC,nnnn","LD (BC),A","INC BC", 335 | "INC B","DEC B","LD B,nn","RLCA", 336 | "EX AF,AF","ADD HL,BC","LD A,(BC)","DEC BC", 337 | "INC C","DEC C","LD C,nn","RRCA", 338 | "DJNZ eeee","LD DE,nnnn","LD (DE),A","INC DE", 339 | "INC D","DEC D","LD D,nn","RLA", 340 | "JR eeee","ADD HL,DE","LD A,(DE)","DEC DE", 341 | "INC E","DEC E","LD E,nn","RRA", 342 | "JR NZ,eeee","LD HL,nnnn","LD (nnnn),HL","INC HL", 343 | "INC H","DEC H","LD H,nn","DAA", 344 | "JR Z,eeee","ADD HL,HL","LD HL,(nnnn)","DEC HL", 345 | "INC L","DEC L","LD L,nn","CPL", 346 | "JR NC,eeee","LD SP,nnnn","LD (nnnn),A","INC SP", 347 | "INC (HL)","DEC (HL)","LD (HL),nn","SCF", 348 | "JR C,eeee","ADD HL,SP","LD A,(nnnn)","DEC SP", 349 | "INC A","DEC A","LD A,nn","CCF", 350 | "LD B,B","LD B,C","LD B,D","LD B,E", 351 | "LD B,H","LD B,L","LD B,(HL)","LD B,A", 352 | "LD C,B","LD C,C","LD C,D","LD C,E", 353 | "LD C,H","LD C,L","LD C,(HL)","LD C,A", 354 | "LD D,B","LD D,C","LD D,D","LD D,E", 355 | "LD D,H","LD D,L","LD D,(HL)","LD D,A", 356 | "LD E,B","LD E,C","LD E,D","LD E,E", 357 | "LD E,H","LD E,L","LD E,(HL)","LD E,A", 358 | "LD H,B","LD H,C","LD H,D","LD H,E", 359 | "LD H,H","LD H,L","LD H,(HL)","LD H,A", 360 | "LD L,B","LD L,C","LD L,D","LD L,E", 361 | "LD L,H","LD L,L","LD L,(HL)","LD L,A", 362 | "LD (HL),B","LD (HL),C","LD (HL),D","LD (HL),E", 363 | "LD (HL),H","LD (HL),L","HALT","LD (HL),A", 364 | "LD A,B","LD A,C","LD A,D","LD A,E", 365 | "LD A,H","LD A,L","LD A,(HL)","LD A,A", 366 | "ADD A,B","ADD A,C","ADD A,D","ADD A,E", 367 | "ADD A,H","ADD A,L","ADD A,(HL)","ADD A,A", 368 | "ADC A,B","ADC A,C","ADC A,D","ADC A,E", 369 | "ADC A,H","ADC A,L","ADC A,(HL)","ADC A,A", 370 | "SUB B","SUB C","SUB D","SUB E", 371 | "SUB H","SUB L","SUB (HL)","SUB A", 372 | "SBC A,B","SBC A,C","SBC A,D","SBC A,E", 373 | "SBC A,H","SBC A,L","SBC A,(HL)","SBC A,A", 374 | "AND B","AND C","AND D","AND E", 375 | "AND H","AND L","AND (HL)","AND A", 376 | "XOR B","XOR C","XOR D","XOR E", 377 | "XOR H","XOR L","XOR (HL)","XOR A", 378 | "OR B","OR C","OR D","OR E", 379 | "OR H","OR L","OR (HL)","OR A", 380 | "CP B","CP C","CP D","CP E", 381 | "CP H","CP L","CP (HL)","CP A", 382 | "RET NZ","POP BC","JP NZ,nnnn","JP nnnn", 383 | "CALL NZ,nnnn","PUSH BC","ADD A,nn","RST 00", 384 | "RET Z","RET","JP Z,nnnn",0, 385 | "CALL Z,nnnn","CALL nnnn","ADC A,nn","RST 08", 386 | "RET NC","POP DE","JP NC,nnnn","OUT (nn),A", 387 | "CALL NC,nnnn","PUSH DE","SUB nn","RST 10", 388 | "RET C","EXX","JP C,nnnn","IN A,(nn)", 389 | "CALL C,nnnn",0,"SBC A,nn","RST 18", 390 | "RET PE","POP HL","JP PE,nnnn","EX (SP),HL", 391 | "CALL PE,nnnn","PUSH HL","AND nn","RST 20", 392 | "RET PO","JP (HL)","JP PO,nnnn","EX DE,HL", 393 | "CALL PO,nnnn",0,"XOR nn","RST 28", 394 | "RET P","POP AF","JP P,nnnn","DI", 395 | "CALL P,nnnn","PUSH AF","OR nn","RST 30", 396 | "RET M","LD SP,HL","JP M,nnnn","EI", 397 | "CALL M,nnnn",0,"CP nn","RST 38" 398 | }; 399 | 400 | const char * GetFirmWareVectorName(unsigned short address) 401 | { 402 | for (int i = 0; FirmWareVectors[i].label; i++) { 403 | if (FirmWareVectors[i].address == address) 404 | return FirmWareVectors[i].label; 405 | } 406 | return NULL; 407 | } 408 | 409 | // 410 | // Convertir le buffer en listing désassemblé 411 | // 412 | void Desass( unsigned char * Prg, char * Listing, int Longueur, int Offset ) 413 | { 414 | int i, Instr, Inst2 = 0, Inst3 = 0, Inst4 = 0, Ad16; 415 | const char * Chaine; 416 | char *p; 417 | char Inst[ 1024 ]; 418 | 419 | int Adr, OldAdr, PosD = 0; 420 | char Ad8; 421 | 422 | * Listing = 0; 423 | for ( Adr = 0; Adr < Longueur; ) 424 | { 425 | OldAdr = Adr; 426 | Instr = Prg[ Adr++ ]; 427 | Chaine = TabInstr[ Instr ]; 428 | if ( Instr == 0xCB ) 429 | { 430 | Inst2 = Prg[ Adr++ ]; 431 | Chaine = TabInstrCB[ Inst2 ]; 432 | } 433 | else 434 | if ( Instr == 0xDD ) 435 | { 436 | Inst2 = Prg[ Adr++ ]; 437 | if ( Inst2 == 0xCB ) 438 | { 439 | Inst3 = Prg[ Adr++ ]; 440 | Inst4 = Prg[ Adr++ ]; 441 | Chaine = TabInstrDDCB[ Inst4 ]; 442 | strcpy( Inst, Chaine ); 443 | p = strstr( Inst, "nn" ); 444 | if ( p ) 445 | { 446 | if ( Inst3 < 0x80 ) 447 | Hex( p, Inst3, 2 ); 448 | else 449 | { 450 | Hex( p, -Inst3, 2 ); 451 | p[ -1 ] = '-'; 452 | } 453 | } 454 | Chaine = Inst; 455 | } 456 | else 457 | Chaine = TabInstrDD[ Inst2 ]; 458 | } 459 | else 460 | if ( Instr == 0xED ) 461 | { 462 | Inst2 = Prg[ Adr++ ]; 463 | Chaine = TabInstrED[ Inst2 ]; 464 | } 465 | else 466 | if ( Instr == 0xFD ) 467 | { 468 | Inst2 = Prg[ Adr++ ]; 469 | if ( Inst2 == 0xCB ) 470 | { 471 | Ad8 = Prg[ Adr++ ]; 472 | Inst3 = Prg[ Adr++ ]; 473 | Chaine = TabInstrFDCB[ Inst3 ]; 474 | if ( Chaine ) 475 | { 476 | strcpy( Inst, Chaine ); 477 | Chaine = Inst; 478 | p = strstr( Inst, "nn" ); 479 | if ( p ) 480 | Hex( p, Ad8, 2 ); 481 | } 482 | } 483 | else 484 | Chaine = TabInstrFD[ Inst2 ]; 485 | } 486 | if ( Chaine ) 487 | { 488 | strcpy( Inst, Chaine ); 489 | p = strstr( Inst, "nnnn" ); 490 | Ad16 = Prg[ Adr++ ]; 491 | Ad16 += Prg[ Adr ] << 8; 492 | Ad8 = ( char ) Ad16; 493 | if ( p ) 494 | { 495 | Hex( p, Ad16, 4 ); 496 | Adr++; 497 | const char * label = GetFirmWareVectorName( Ad16 ); 498 | if (label && 0 == memcmp( Inst, "CALL", 4)) 499 | { 500 | p[4] = ' '; 501 | p[5] = ' '; 502 | p[6] = ' '; 503 | p[7] = ' '; 504 | p[8] = ';'; 505 | p[9] = ' '; 506 | strcpy(p + 10, label); 507 | } 508 | } 509 | else 510 | { 511 | p = strstr( Inst, "nn" ); 512 | if ( p ) 513 | { 514 | Hex( p, Ad16, 2 ); 515 | p = strstr( Inst, "nn" ); 516 | if ( p ) 517 | Hex( p, Ad16 >> 8, 2 ); 518 | } 519 | else 520 | { 521 | p = strstr( Inst, "eeee" ); 522 | if ( p ) 523 | Hex( p, Adr + Ad8 + Offset, 4 ); 524 | else 525 | Adr--; 526 | } 527 | } 528 | } 529 | else 530 | sprintf( Inst, "%02X %02X %02X ????", Instr, Inst2, Inst3 ); 531 | 532 | Hex( &Listing[ PosD ], OldAdr + Offset, 4 ); // current address 533 | Listing[ PosD + 4 ] = ' '; 534 | PosD += 5; 535 | for ( i = OldAdr; i < Adr; i++ ) 536 | { 537 | Hex( &Listing[ PosD ], Prg[ i ], 2 ); 538 | Listing[ PosD + 2 ] = ' '; 539 | PosD += 3; 540 | } 541 | for ( i = 0; i < 5 - Adr + OldAdr; i++ ) 542 | { 543 | Listing[ PosD ] = Listing[ PosD + 1 ] = Listing[ PosD + 2 ] = ' '; 544 | PosD += 3; 545 | } 546 | const char * p = Inst; 547 | while( * p ) 548 | Listing[ PosD++ ] = * p++; 549 | 550 | Listing[ PosD++ ] = '\r'; 551 | Listing[ PosD++ ] = '\n'; 552 | } 553 | } 554 | -------------------------------------------------------------------------------- /src/getopt_pp.h: -------------------------------------------------------------------------------- 1 | /* 2 | GetOpt_pp: Yet another C++ version of getopt. 3 | This file is part of GetOpt_pp. 4 | 5 | Copyright (C) Daniel Gutson, FuDePAN 2007-2010 6 | Distributed under the Boost Software License, Version 1.0. 7 | (See accompanying file LICENSE_1_0.txt in the root directory or 8 | copy at http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | GetOpt_pp IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 11 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 12 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 13 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 14 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 15 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 16 | DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | #ifndef GETOPT_PP_H 20 | #define GETOPT_PP_H 21 | 22 | #include 23 | #include // candidate to be removed 24 | #include 25 | #include 26 | #include 27 | 28 | /* 29 | DESIGN GOALS: 30 | - EASY to use 31 | - EASY to learn 32 | - mimc STL's streams 33 | - EASY to extend 34 | */ 35 | 36 | #ifndef GETOPT_INLINE 37 | # define GETOPT_INLINE 38 | #endif 39 | 40 | namespace GetOpt 41 | { 42 | 43 | struct Token 44 | { 45 | enum Type 46 | { 47 | ShortOption, 48 | LongOption, 49 | GlobalArgument, 50 | GlobalArgumentUsed, // already read, skip in the next read 51 | OptionArgument, 52 | PossibleNegativeArgument, 53 | UnknownYet // can be a global option, or an option of the previous one 54 | }; 55 | 56 | Type type; 57 | std::string value; 58 | Token* next; 59 | 60 | Token(const std::string& value, Type type = UnknownYet) 61 | : type(type), value(value), next(NULL) 62 | {} 63 | 64 | bool is_last() const 65 | { 66 | return next == NULL; 67 | } 68 | 69 | void link_to(Token* new_next) 70 | { 71 | next = new_next; 72 | } 73 | 74 | Token* get_next_option_argument() const 75 | { 76 | if (is_last()) 77 | return NULL; 78 | else 79 | { 80 | if (next->type == UnknownYet || next->type == OptionArgument || next->type == PossibleNegativeArgument) 81 | return next; 82 | else 83 | return NULL; 84 | } 85 | } 86 | }; 87 | 88 | struct OptionData 89 | { 90 | enum _Flags 91 | { 92 | CmdLine_NotExtracted, 93 | CmdLine_Extracted, 94 | Envir 95 | }; 96 | 97 | _Flags flags; 98 | Token* token; 99 | OptionData() : flags(CmdLine_NotExtracted) {} 100 | }; 101 | 102 | typedef std::map LongOptions; 103 | typedef std::map ShortOptions; 104 | 105 | 106 | struct _Option 107 | { 108 | enum Result 109 | { 110 | OK, 111 | ParsingError, 112 | OptionNotFound, 113 | BadType, 114 | NoArgs, 115 | TooManyArgs, 116 | OptionNotFound_NoEx 117 | }; 118 | 119 | virtual Result operator()(ShortOptions& short_ops, LongOptions& long_ops, Token* first, std::ios::fmtflags flags) const = 0; 120 | virtual ~_Option() {} 121 | 122 | static const char NO_SHORT_OPT = 0; 123 | protected: 124 | static void setTokenAsUsed(Token* token, ShortOptions& short_ops, Token::Type usedAs) 125 | { 126 | if (token->type == Token::PossibleNegativeArgument) 127 | short_ops.erase(token->value[1]); 128 | 129 | token->type = usedAs; 130 | } 131 | }; 132 | 133 | template inline _Option::Result convert(const std::string& s, T& result, std::ios::fmtflags flags) 134 | { 135 | std::stringstream ss; 136 | ss.clear(); 137 | ss.flags(flags); 138 | ss << s; 139 | ss >> result; 140 | if (ss.fail() || !ss.eof()) 141 | return _Option::BadType; 142 | else 143 | return _Option::OK; 144 | } 145 | 146 | template <> inline _Option::Result convert(const std::string& s, std::string& result, std::ios::fmtflags /*flags*/) 147 | { 148 | result = s; 149 | return _Option::OK; 150 | } 151 | 152 | 153 | template class _OptionTBase : public _Option 154 | { 155 | const char short_opt; 156 | const std::string long_opt; 157 | protected: 158 | T& target; 159 | virtual Result _assign(Token* token, std::ios::fmtflags flags, ShortOptions& short_ops) const = 0; 160 | 161 | public: 162 | _OptionTBase(const _OptionTBase& other) 163 | : _Option(), short_opt(other.short_opt), long_opt(other.long_opt), target(other.target) 164 | {} 165 | 166 | _OptionTBase(char short_opt, const std::string& long_opt, T& target) 167 | : short_opt(short_opt), long_opt(long_opt), target(target) 168 | {} 169 | 170 | virtual Result operator()(ShortOptions& short_ops, LongOptions& long_ops, Token* /*first*/, std::ios::fmtflags flags) const 171 | { 172 | Result ret = OptionNotFound; 173 | ShortOptions::iterator it; 174 | if (short_opt == _Option::NO_SHORT_OPT) 175 | it = short_ops.end(); 176 | else 177 | it = short_ops.find(short_opt); 178 | 179 | if (it != short_ops.end()) 180 | { 181 | it->second.flags = OptionData::CmdLine_Extracted; 182 | ret = _assign(it->second.token, flags, short_ops); 183 | } 184 | else if (!long_opt.empty()) 185 | { 186 | LongOptions::iterator it = long_ops.find(long_opt); 187 | if (it != long_ops.end()) 188 | { 189 | it->second.flags = OptionData::CmdLine_Extracted; 190 | ret = _assign(it->second.token, flags, short_ops); 191 | } 192 | } 193 | 194 | return ret; 195 | } 196 | }; 197 | 198 | 199 | template class _OptionT : public _OptionTBase 200 | { 201 | protected: 202 | virtual _Option::Result _assign(Token* token, std::ios::fmtflags flags, ShortOptions& short_ops) const 203 | { 204 | Token* const option_token = token->get_next_option_argument(); 205 | if (option_token == NULL) 206 | return _Option::NoArgs; 207 | else 208 | { 209 | this->setTokenAsUsed(option_token, short_ops, Token::OptionArgument); 210 | return convert(option_token->value, this->target, flags); 211 | } 212 | } 213 | public: 214 | _OptionT(const _OptionT& other) 215 | : _OptionTBase(other) 216 | {} 217 | 218 | _OptionT(char short_opt, const std::string& long_opt, T& target) 219 | : _OptionTBase(short_opt, long_opt, target) 220 | {} 221 | 222 | }; 223 | 224 | template class _OptionT > : public _OptionTBase > 225 | { 226 | protected: 227 | virtual _Option::Result _assign(Token* token, std::ios::fmtflags flags, ShortOptions& short_ops) const 228 | { 229 | Token* option_token = token->get_next_option_argument(); 230 | if (option_token != NULL) 231 | { 232 | _Option::Result result; 233 | //OptionArgs::const_iterator it = args.begin(); 234 | T temp; 235 | 236 | do 237 | { 238 | this->setTokenAsUsed(option_token, short_ops, Token::OptionArgument); 239 | result = convert(option_token->value, temp, flags); 240 | if (result == _Option::OK) 241 | this->target.push_back(temp); 242 | 243 | option_token = option_token->get_next_option_argument(); 244 | } 245 | while (option_token != NULL && result == _Option::OK); 246 | 247 | return result; 248 | } 249 | else 250 | return _Option::NoArgs; 251 | } 252 | 253 | public: 254 | _OptionT(const _OptionT >& other) 255 | : _OptionTBase >(other) 256 | {} 257 | 258 | _OptionT(char short_opt, const std::string& long_opt, std::vector& target) 259 | : _OptionTBase >(short_opt, long_opt, target) 260 | {} 261 | }; 262 | 263 | 264 | template 265 | class _DefValOption : public BaseOption 266 | { 267 | const T default_value; 268 | public: 269 | 270 | _DefValOption(const _DefValOption& other) 271 | : BaseOption(other), default_value(other.default_value) 272 | {} 273 | 274 | _DefValOption(char short_opt, const std::string& long_opt, T& target, const T& default_value) 275 | : BaseOption(short_opt, long_opt, target), default_value(default_value) 276 | {} 277 | 278 | virtual _Option::Result operator()(ShortOptions& short_ops, LongOptions& long_ops, Token* first, std::ios::fmtflags flags) const 279 | { 280 | _Option::Result ret = BaseOption::operator()(short_ops, long_ops, first, flags); 281 | 282 | if (ret == _Option::OptionNotFound) 283 | { 284 | this->target = default_value; 285 | ret = _Option::OK; 286 | } 287 | 288 | return ret; 289 | } 290 | }; 291 | 292 | template 293 | class _GlobalOption : public _Option 294 | { 295 | T& target; 296 | virtual Result operator()(ShortOptions& short_ops, LongOptions& long_ops, Token* first, std::ios::fmtflags flags) const 297 | { 298 | // find first token GlobalArgument or UnknownYet (candidate) or PossibleNegativeArgument (candidate too) 299 | Token* token(first); 300 | bool found(false); 301 | while (token != NULL && !found) 302 | { 303 | found = (token->type == Token::GlobalArgument || token->type == Token::UnknownYet || token->type == Token::PossibleNegativeArgument); 304 | if (!found) 305 | token = token->next; 306 | } 307 | if (found) 308 | { 309 | this->setTokenAsUsed(token, short_ops, Token::GlobalArgumentUsed); 310 | return convert(token->value, target, flags); 311 | } 312 | else 313 | return OptionNotFound; 314 | } 315 | public: 316 | _GlobalOption(const _GlobalOption& other) 317 | : target(other.target) 318 | {} 319 | 320 | _GlobalOption(T& target) 321 | : target(target) 322 | {} 323 | }; 324 | 325 | template 326 | class _GlobalOption > : public _Option 327 | { 328 | std::vector& target; 329 | virtual Result operator()(ShortOptions& short_ops, LongOptions& /*long_ops*/, Token* first, std::ios::fmtflags flags) const 330 | { 331 | // find first token GlobalArgument or UnknownYet (candidate) or PossibleNegativeArgument (candidate too) 332 | Token* token(first); 333 | bool found_any(false); 334 | T tmp; 335 | Result res(OK); 336 | 337 | while (token != NULL && res == OK) 338 | { 339 | if (token->type == Token::GlobalArgument || token->type == Token::UnknownYet || token->type == Token::PossibleNegativeArgument) 340 | { 341 | res = convert(token->value, tmp, flags); 342 | if (res == OK) 343 | { 344 | this->setTokenAsUsed(token, short_ops, Token::GlobalArgumentUsed); 345 | found_any = true; 346 | target.push_back(tmp); 347 | } 348 | } 349 | token = token->next; 350 | } 351 | if (res == OK) 352 | { 353 | if (found_any) 354 | return res; 355 | else 356 | return OptionNotFound; 357 | } 358 | else 359 | return res; 360 | } 361 | public: 362 | _GlobalOption(const _GlobalOption >& other) 363 | : target(other.target) 364 | {} 365 | 366 | _GlobalOption(std::vector& target) 367 | : target(target) 368 | {} 369 | }; 370 | 371 | template 372 | inline _OptionT Option(char short_opt, const std::string& long_opt, T& target) 373 | { 374 | return _OptionT(short_opt, long_opt, target); 375 | } 376 | 377 | template 378 | inline _OptionT Option(char short_opt, T& target) 379 | { 380 | return _OptionT(short_opt, std::string(), target); 381 | } 382 | 383 | // LongOpt only 384 | template 385 | inline _OptionT Option(const std::string& long_opt, T& target) 386 | { 387 | return _OptionT(_Option::NO_SHORT_OPT, long_opt, target); 388 | } 389 | 390 | // Defaulted version 391 | template 392 | inline _DefValOption > 393 | Option(char short_opt, const std::string& long_opt, T& target, const T& def) 394 | { 395 | return _DefValOption >(short_opt, long_opt, target, def); 396 | } 397 | 398 | template 399 | inline _DefValOption > Option(char short_opt, T& target, const T& def) 400 | { 401 | return _DefValOption >(short_opt, std::string(), target, def); 402 | } 403 | 404 | // no short opt. 405 | template 406 | inline _DefValOption > 407 | Option(const std::string& long_opt, T& target, const T& def) 408 | { 409 | return _DefValOption >(_Option::NO_SHORT_OPT, long_opt, target, def); 410 | } 411 | 412 | // Defaults for strings: 413 | inline _DefValOption > 414 | Option(char short_opt, const std::string& long_opt, std::string& target, const char* def) 415 | { 416 | return _DefValOption >(short_opt, long_opt, target, def); 417 | } 418 | 419 | inline _OptionT Option(char short_opt, std::string& target, const char* def) 420 | { 421 | return _DefValOption >(short_opt, std::string(), target, def); 422 | } 423 | 424 | // no short opt. 425 | inline _DefValOption > 426 | Option(const std::string& long_opt, std::string& target, const char* def) 427 | { 428 | return _DefValOption >(_Option::NO_SHORT_OPT, long_opt, target, def); 429 | } 430 | 431 | // Global Option: 432 | template 433 | inline _GlobalOption GlobalOption(T& target) 434 | { 435 | return _GlobalOption(target); 436 | } 437 | 438 | class OptionPresent : public _Option 439 | { 440 | const char short_opt; 441 | const std::string long_opt; 442 | bool* const present; 443 | public: 444 | // two combinations: with/without target, and with/without long opt. 445 | 446 | // WITH long_opt: 447 | OptionPresent(char short_opt, const std::string& long_opt, bool& present) 448 | : short_opt(short_opt), long_opt(long_opt), present(&present) 449 | {} 450 | 451 | OptionPresent(char short_opt, const std::string& long_opt) 452 | : short_opt(short_opt), long_opt(long_opt), present(NULL) 453 | {} 454 | 455 | // WITHOUT long_opt: 456 | OptionPresent(char short_opt, bool& present) 457 | : short_opt(short_opt), present(&present) 458 | {} 459 | 460 | OptionPresent(char short_opt) 461 | : short_opt(short_opt), present(NULL) 462 | {} 463 | 464 | // WITHOUT short_opt 465 | OptionPresent(const std::string& long_opt, bool& present) 466 | : short_opt(_Option::NO_SHORT_OPT), long_opt(long_opt), present(&present) 467 | {} 468 | 469 | OptionPresent(const std::string& long_opt) 470 | : short_opt(_Option::NO_SHORT_OPT), long_opt(long_opt), present(NULL) 471 | {} 472 | protected: 473 | virtual Result operator()(ShortOptions& short_ops, LongOptions& long_ops, Token* /*first*/, std::ios::fmtflags /*flags*/) const 474 | { 475 | bool found; 476 | ShortOptions::iterator it = short_ops.find(short_opt); 477 | 478 | found = (it != short_ops.end()); 479 | if (found) 480 | { 481 | it->second.flags = OptionData::CmdLine_Extracted; 482 | } 483 | else if (!long_opt.empty()) 484 | { 485 | LongOptions::iterator it = long_ops.find(long_opt); 486 | found = (it != long_ops.end()); 487 | if (found) 488 | { 489 | it->second.flags = OptionData::CmdLine_Extracted; 490 | } 491 | } 492 | 493 | if (present != NULL) 494 | { 495 | *present = found; 496 | return OK; 497 | } 498 | else 499 | { 500 | return found ? OK : OptionNotFound_NoEx; 501 | } 502 | } 503 | }; 504 | 505 | class GetOptEx : public std::exception {}; 506 | struct ParsingErrorEx : GetOptEx {}; 507 | struct InvalidFormatEx : GetOptEx {}; 508 | struct ArgumentNotFoundEx : GetOptEx {}; 509 | struct TooManyArgumentsEx : GetOptEx {}; 510 | struct OptionNotFoundEx : GetOptEx {}; 511 | struct TooManyOptionsEx : GetOptEx {}; 512 | struct OptionsFileNotFoundEx : GetOptEx 513 | { 514 | const std::string targetFile; 515 | OptionsFileNotFoundEx(const std::string& file) : targetFile(file) {} 516 | ~OptionsFileNotFoundEx() throw() {} 517 | }; 518 | 519 | enum _EnvTag 520 | { 521 | Include_Environment 522 | }; 523 | 524 | class GetOpt_pp 525 | { 526 | ShortOptions _shortOps; 527 | LongOptions _longOps; 528 | std::ios_base::iostate _exc; 529 | _Option::Result _last; 530 | std::ios::fmtflags _flags; 531 | std::string _app_name; 532 | Token* _first_token; 533 | Token* _last_token; 534 | 535 | class TokensDeleter 536 | { 537 | Token*& _first; 538 | public: 539 | TokensDeleter(Token*& first) : _first(first) {} 540 | 541 | GETOPT_INLINE ~TokensDeleter(); 542 | }; 543 | 544 | TokensDeleter _tokens_deleter; 545 | 546 | GETOPT_INLINE Token* _add_token(const std::string& value, Token::Type type); 547 | GETOPT_INLINE void _init_flags(); 548 | GETOPT_INLINE void _parse(const std::vector& args); 549 | GETOPT_INLINE void _parse_env(); 550 | static GETOPT_INLINE void _argc_argv_to_vector(int argc, const char* const* const argv, std::vector& args); 551 | GETOPT_INLINE void _parse_sub_file(const std::string& file); 552 | public: 553 | GETOPT_INLINE GetOpt_pp(int argc, const char* const* const argv); 554 | GETOPT_INLINE GetOpt_pp(int argc, const char* const* const argv, _EnvTag); 555 | 556 | std::ios_base::iostate exceptions() const 557 | { 558 | return _exc; 559 | } 560 | void exceptions(std::ios_base::iostate except) 561 | { 562 | _exc = except; 563 | } 564 | void exceptions_all() 565 | { 566 | _exc = std::ios_base::failbit | std::ios_base::eofbit; 567 | } 568 | 569 | operator bool() const 570 | { 571 | return _last == _Option::OK; 572 | } 573 | 574 | GETOPT_INLINE bool options_remain() const; 575 | 576 | void end_of_options() const throw(GetOptEx) 577 | { 578 | if (options_remain() && (_exc & std::ios_base::eofbit)) 579 | throw TooManyOptionsEx(); 580 | } 581 | 582 | std::ios::fmtflags flags() const 583 | { 584 | return _flags; 585 | } 586 | void flags(std::ios::fmtflags flags) 587 | { 588 | _flags = flags; 589 | } 590 | 591 | const std::string& app_name() const 592 | { 593 | return _app_name; 594 | } 595 | 596 | GETOPT_INLINE GetOpt_pp& operator >> (const _Option& opt) throw(GetOptEx); 597 | 598 | GETOPT_INLINE GetOpt_pp& operator >> (std::ios_base& (*iomanip)(std::ios_base&)); 599 | 600 | // Alternative to manipulators, for those who don't like them: the 'getopt' method :) 601 | // Combination 1: with long option: 602 | template inline T getopt(char short_opt, const std::string& long_opt) throw(GetOptEx) 603 | { 604 | T result; 605 | operator >> (Option(short_opt, long_opt, result)); 606 | return result; 607 | } 608 | 609 | template inline T getopt(char short_opt, const std::string& long_opt, const T& def_value) 610 | { 611 | T result; 612 | operator >> (Option(short_opt, long_opt, result, def_value)); 613 | return result; 614 | } 615 | 616 | // Combination 2: without long option: 617 | template inline T getopt(char short_opt) throw(GetOptEx) 618 | { 619 | T result; 620 | operator >> (Option(short_opt, result)); 621 | return result; 622 | } 623 | 624 | template inline T getopt(char short_opt, const T& def_value) 625 | { 626 | T result; 627 | operator >> (Option(short_opt, result, def_value)); 628 | return result; 629 | } 630 | 631 | struct ItCtorData 632 | { 633 | ShortOptions::const_iterator short_iter; 634 | LongOptions::const_iterator long_iter; 635 | GetOpt_pp* getopt_pp; 636 | }; 637 | 638 | template 639 | class _iterator 640 | { 641 | typename Container::const_iterator _it; 642 | GetOpt_pp* _getopt_pp; 643 | public: 644 | _iterator(const ItCtorData& ctor_data) 645 | { 646 | _it = Adapter::adapt(ctor_data); 647 | _getopt_pp = ctor_data.getopt_pp; 648 | } 649 | 650 | _iterator() : _getopt_pp(NULL) 651 | {} 652 | 653 | _iterator& operator = (const _iterator& other) 654 | { 655 | _it = other._it; 656 | _getopt_pp = other._getopt_pp; 657 | return *this; 658 | } 659 | 660 | bool operator != (const _iterator& other) const 661 | { 662 | return _it != other._it; 663 | } 664 | 665 | OptionType option() const 666 | { 667 | return _it->first; 668 | } 669 | OptionType operator*() const 670 | { 671 | return option(); 672 | } 673 | 674 | _iterator& operator ++() 675 | { 676 | ++_it; 677 | return *this; 678 | } 679 | 680 | template 681 | GetOpt_pp& operator >> (T& t) 682 | { 683 | Adapter::extract(t, *_getopt_pp, option()); 684 | return *_getopt_pp; 685 | } 686 | }; 687 | 688 | ItCtorData begin() 689 | { 690 | ItCtorData ret; 691 | ret.short_iter = _shortOps.begin(); 692 | ret.long_iter = _longOps.begin(); 693 | ret.getopt_pp = this; 694 | return ret; 695 | } 696 | 697 | ItCtorData end() 698 | { 699 | ItCtorData ret; 700 | ret.short_iter = _shortOps.end(); 701 | ret.long_iter = _longOps.end(); 702 | ret.getopt_pp = this; 703 | return ret; 704 | } 705 | 706 | struct ShortAdapter 707 | { 708 | static ShortOptions::const_iterator adapt(const ItCtorData& data) 709 | { 710 | return data.short_iter; 711 | } 712 | 713 | template 714 | static void extract(T& t, GetOpt_pp& getopt_pp, char option) 715 | { 716 | getopt_pp >> Option(option, t); 717 | } 718 | }; 719 | 720 | struct LongAdapter 721 | { 722 | static LongOptions::const_iterator adapt(const ItCtorData& data) 723 | { 724 | return data.long_iter; 725 | } 726 | 727 | template 728 | static void extract(T& t, GetOpt_pp& getopt_pp, const std::string& option) 729 | { 730 | getopt_pp >> Option('\0', option, t); 731 | } 732 | }; 733 | 734 | typedef _iterator short_iterator; 735 | typedef _iterator long_iterator; 736 | }; 737 | 738 | class Environment 739 | { 740 | // Coming soon! 741 | }; 742 | 743 | } 744 | 745 | #endif 746 | -------------------------------------------------------------------------------- /src/GestDsk.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "MyType.h" 9 | #include "GestDsk.h" 10 | #include "endianPPC.h" 11 | #include "Outils.h" 12 | #include 13 | 14 | #ifdef _MSC_VER 15 | #define snprintf _snprintf 16 | #endif 17 | 18 | using namespace std; 19 | 20 | char Listing[ 0x280000 ]; 21 | unsigned char BufFile[ 0x10000 ]; 22 | int TailleFic, CurLigne, AdresseCharg, AdresseExec; 23 | 24 | 25 | // 26 | // Verifie si en-tete AMSDOS est valide 27 | // 28 | bool CheckAmsdos( unsigned char * Buf ) { 29 | int i, Checksum = 0; 30 | bool ModeAmsdos = false; 31 | unsigned short CheckSumFile; 32 | CheckSumFile = Buf[ 0x43 ] + Buf[ 0x43 +1 ] *256; 33 | for ( i = 0; i < 67; i++ ) 34 | Checksum += Buf[ i ]; 35 | 36 | if ( ( CheckSumFile == ( unsigned short )Checksum ) && Checksum ) 37 | ModeAmsdos = true; 38 | 39 | return( ModeAmsdos ); 40 | } 41 | 42 | 43 | 44 | // 45 | // Cr�e une en-t�te AMSDOS par d�faut 46 | // 47 | StAmsdos * CreeEnteteAmsdos( char * NomFic, unsigned short Longueur ) { 48 | static char NomReel[ 256 ]; 49 | static StAmsdos Entete; 50 | static char Nom[ 12 ]; 51 | int i; 52 | 53 | strcpy( NomReel, NomFic ); 54 | memset( &Entete, 0, sizeof( Entete ) ); 55 | memset( Nom, ' ', sizeof( Nom ) ); 56 | char * p = NULL; 57 | do { 58 | p = strchr( NomReel, '/' ); //Sous linux c'est le / qu'il faut enlever ... 59 | if ( p ) 60 | strcpy( NomReel, ++p ); 61 | } while( p ); 62 | p = strchr( NomReel, '.' ); 63 | if ( p ) 64 | * p++ = 0; 65 | 66 | int l = strlen( NomReel ); 67 | if ( l > 8 ) 68 | l = 8; 69 | 70 | for ( int i = 0; i < l; i++ ) 71 | Nom[ i ] = ( char )toupper( NomReel[ i ] ); 72 | 73 | if ( p ) 74 | for ( i = 0; i < 3; i++ ) 75 | Nom[ i + 8 ] = ( char )toupper( p[ i ] ); 76 | 77 | memcpy( Entete.FileName, Nom, 11 ); 78 | Entete.Length = 0; //Non renseign� par AMSDos !! 79 | Entete.RealLength = Entete.LogicalLength = Longueur; 80 | Entete.FileType = 2; //Fichier binaire 81 | 82 | SetChecksum(&Entete); 83 | 84 | return( &Entete ); 85 | } 86 | 87 | 88 | // 89 | // Calcule et positionne le checksum AMSDOS 90 | // 91 | void SetChecksum( StAmsdos * pEntete ) { 92 | int i, Checksum = 0; 93 | unsigned char * p = ( unsigned char * )pEntete; 94 | for ( i = 0; i < 67; i++ ) 95 | Checksum += * (p+i); 96 | 97 | pEntete->CheckSum = ( unsigned short )Checksum; 98 | } 99 | 100 | 101 | // 102 | // Effectue un "nettoyage" de l'en-tete Amsdos : 103 | // remet a zero les octets inutilises 104 | // 105 | void ClearAmsdos( unsigned char * Buf ) { 106 | if ( CheckAmsdos( Buf ) ) { 107 | int i, Checksum = 0; 108 | StAmsdos * pEntete = ( StAmsdos * )Buf; 109 | memset( pEntete->Unused, 0, sizeof( pEntete->Unused ) ); 110 | memset( pEntete->Unused2, 0, sizeof( pEntete->Unused2 ) ); 111 | for ( i = 0; i < 67; i++ ) 112 | Checksum += Buf[ i ]; 113 | 114 | Buf[ 0x43 ] = ( unsigned short )Checksum; 115 | } 116 | } 117 | 118 | // 119 | // Recherche le plus petit secteur d'une piste 120 | // 121 | int DSK::GetMinSect( void ) { 122 | int Sect = 0x100; 123 | CPCEMUTrack * tr = ( CPCEMUTrack * )&ImgDsk[ sizeof( CPCEMUEnt ) ]; 124 | for ( int s = 0; s < tr->NbSect; s++ ) 125 | if ( Sect > tr->Sect[ s ].R ) 126 | Sect = tr->Sect[ s ].R; 127 | 128 | return( Sect ); 129 | } 130 | 131 | 132 | // 133 | // Retourne la position d'un secteur dans le fichier DSK 134 | // 135 | int DSK::GetPosData( int track, int sect, bool SectPhysique ) { 136 | // Recherche position secteur 137 | int Pos = sizeof( CPCEMUEnt ); 138 | CPCEMUTrack * tr = ( CPCEMUTrack * )&ImgDsk[ Pos ]; 139 | short SizeByte; 140 | for ( int t = 0; t <= track; t++ ) { 141 | Pos += sizeof( CPCEMUTrack ); 142 | for ( int s = 0; s < tr->NbSect; s++ ) { 143 | if ( t == track ) { 144 | if ( ( ( tr->Sect[ s ].R == sect ) && SectPhysique ) 145 | || ( ( s == sect ) && ! SectPhysique ) 146 | ) 147 | break; 148 | } 149 | SizeByte = tr->Sect[ s ].SizeByte ; 150 | if (SizeByte) 151 | Pos += SizeByte; 152 | else 153 | Pos += ( 128 << tr->Sect[ s ].N ); 154 | } 155 | } 156 | return( Pos ); 157 | } 158 | 159 | 160 | // 161 | // Recherche un bloc libre et le remplit 162 | // 163 | int DSK::RechercheBlocLibre( int MaxBloc ) { 164 | for ( int i = 2; i < MaxBloc; i++ ) 165 | if ( ! Bitmap[ i ] ) { 166 | Bitmap[ i ] = 1; 167 | return( i ); 168 | } 169 | return( 0 ); 170 | } 171 | 172 | 173 | // 174 | // Recherche une entr�e de r�pertoire libre 175 | // 176 | int DSK::RechercheDirLibre( void ) { 177 | for ( int i = 0; i < 64; i++ ) { 178 | StDirEntry * Dir = GetInfoDirEntry( i ); 179 | if ( Dir->User == USER_DELETED ) 180 | return( i ); 181 | } 182 | return( -1 ); 183 | } 184 | 185 | 186 | // 187 | // Retourne les donn�es "brutes" de l'image disquette 188 | // 189 | unsigned char * DSK::GetRawData( int Pos ) { 190 | return( &ImgDsk[ Pos ] ); 191 | } 192 | 193 | 194 | // 195 | // Ecriture de donn�es "brutes" dans l'image disquette 196 | // 197 | void DSK::WriteRawData( int Pos, unsigned char * Data, int Longueur ) { 198 | memcpy( &ImgDsk[ Pos ], Data, Longueur ); 199 | } 200 | 201 | 202 | // 203 | // Retourne la taille du fichier image 204 | // 205 | int DSK::GetTailleDsk( void ) { 206 | CPCEMUEnt * Infos = ( CPCEMUEnt * )ImgDsk; 207 | int NbTracks = Infos->NbTracks; 208 | int Pos = sizeof( CPCEMUEnt ); 209 | CPCEMUTrack * tr = ( CPCEMUTrack * )&ImgDsk[ Pos ]; 210 | for ( int t = 0; t < NbTracks; t++ ) { 211 | Pos += sizeof( CPCEMUTrack ); 212 | for ( int s = 0; s < tr->NbSect; s++ ) { 213 | if ( tr->Sect[ s ].SizeByte ) 214 | Pos += tr->Sect[ s ].SizeByte; 215 | else 216 | Pos += ( 128 << tr->Sect[ s ].N ); 217 | } 218 | } 219 | return( Pos ); 220 | } 221 | 222 | 223 | // 224 | // Retourne le nombre de pistes de la disquette 225 | // 226 | int DSK::GetNbTracks( void ) { 227 | CPCEMUEnt * Infos = ( CPCEMUEnt * )ImgDsk; 228 | return( Infos->NbTracks ); 229 | } 230 | 231 | 232 | // 233 | // Lecture d'un bloc AMSDOS (1 block = 2 secteurs) 234 | // 235 | unsigned char * DSK::ReadBloc( int bloc ) { 236 | static unsigned char BufBloc[ SECTSIZE * 2 ]; 237 | int track = ( bloc << 1 ) / 9; 238 | int sect = ( bloc << 1 ) % 9; 239 | int MinSect = GetMinSect(); 240 | if ( MinSect == 0x41 ) 241 | track += 2; 242 | else 243 | if ( MinSect == 0x01 ) 244 | track++; 245 | 246 | int Pos = GetPosData( track, sect + MinSect, true ); 247 | memcpy( BufBloc, &ImgDsk[ Pos ], SECTSIZE ); 248 | if ( ++sect > 8 ) { 249 | track++; 250 | sect = 0; 251 | } 252 | 253 | Pos = GetPosData( track, sect + MinSect, true ); 254 | memcpy( &BufBloc[ SECTSIZE ], &ImgDsk[ Pos ], SECTSIZE ); 255 | return( BufBloc ); 256 | } 257 | 258 | 259 | // 260 | // Formatter une piste 261 | // 262 | void DSK::FormatTrack( CPCEMUEnt * Infos, int t, int MinSect, int NbSect ) { 263 | CPCEMUTrack * tr = ( CPCEMUTrack * )&ImgDsk[ sizeof( CPCEMUEnt ) + t * Infos->DataSize ]; 264 | memset( &ImgDsk[ sizeof( CPCEMUEnt ) 265 | + sizeof( CPCEMUTrack ) 266 | + ( t * Infos->DataSize ) 267 | ] 268 | , 0xE5 269 | , 0x200 * NbSect 270 | ); 271 | strcpy( tr->ID, "Track-Info\r\n" ); 272 | tr->Track = ( unsigned char )t; 273 | tr->Head = 0; 274 | tr->SectSize = 2; 275 | tr->NbSect = ( unsigned char )NbSect; 276 | tr->Gap3 = 0x4E; 277 | tr->OctRemp = 0xE5; 278 | int ss = 0; 279 | // 280 | // Gestion "entrelacement" des secteurs 281 | // 282 | for ( int s = 0; s < NbSect; ) { 283 | tr->Sect[ s ].C = ( unsigned char )t; 284 | tr->Sect[ s ].H = 0; 285 | tr->Sect[ s ].R = ( unsigned char )( ss + MinSect ); 286 | tr->Sect[ s ].N = 2; 287 | tr->Sect[ s ].SizeByte = 0x200; 288 | ss++; 289 | if ( ++s < NbSect ) { 290 | tr->Sect[ s ].C = ( unsigned char )t; 291 | tr->Sect[ s ].H = 0; 292 | tr->Sect[ s ].R = ( unsigned char )( ss + MinSect + 4 ); 293 | tr->Sect[ s ].N = 2; 294 | tr->Sect[ s ].SizeByte = 0x200; 295 | s++; 296 | } 297 | } 298 | } 299 | 300 | 301 | // 302 | // Ecriture d'un bloc AMSDOS (1 block = 2 secteurs) 303 | // 304 | void DSK::WriteBloc( int bloc, unsigned char BufBloc[ SECTSIZE * 2 ] ) { 305 | int track = ( bloc << 1 ) / 9; 306 | int sect = ( bloc << 1 ) % 9; 307 | int MinSect = GetMinSect(); 308 | if ( MinSect == 0x41 ) 309 | track += 2; 310 | else 311 | if ( MinSect == 0x01 ) 312 | track++; 313 | 314 | // 315 | // Ajuste le nombre de pistes si d�passement capacit� 316 | // 317 | CPCEMUEnt * Entete = ( CPCEMUEnt * )ImgDsk; 318 | if ( track > Entete->NbTracks - 1 ) { 319 | Entete->NbTracks = ( unsigned char )( track + 1 ); 320 | FormatTrack( Entete, track, MinSect, 9 ); 321 | } 322 | 323 | int Pos = GetPosData( track, sect + MinSect, true ); 324 | memcpy( &ImgDsk[ Pos ], BufBloc, SECTSIZE ); 325 | if ( ++sect > 8 ) { 326 | track++; 327 | sect = 0; 328 | } 329 | Pos = GetPosData( track, sect + MinSect, true ); 330 | memcpy( &ImgDsk[ Pos ], &BufBloc[ SECTSIZE ], SECTSIZE ); 331 | } 332 | 333 | 334 | // 335 | // Ecriture d'un secteur 336 | // 337 | void DSK::WriteSect( int Track, int Sect, unsigned char * Buff, int AmsdosMode ) { 338 | int MinSect = AmsdosMode ? GetMinSect() : 0; 339 | if ( ( MinSect == 0x41 ) && AmsdosMode ) 340 | Track += 2; 341 | else 342 | if ( ( MinSect == 0x01 ) && AmsdosMode ) 343 | Track++; 344 | 345 | int Pos = GetPosData( Track, Sect + MinSect, AmsdosMode ); 346 | memcpy( &ImgDsk[ Pos ], Buff, SECTSIZE ); 347 | } 348 | 349 | 350 | // 351 | // Lecture d'un secteur 352 | // 353 | unsigned char * DSK::ReadSect( int Track, int Sect, int AmsdosMode ) { 354 | int MinSect = AmsdosMode ? GetMinSect() : 0; 355 | if ( ( MinSect == 0x41 ) && AmsdosMode ) 356 | Track += 2; 357 | else 358 | if ( ( MinSect == 0x01 ) && AmsdosMode ) 359 | Track++; 360 | 361 | int Pos = GetPosData( Track, Sect + MinSect, AmsdosMode ); 362 | return( &ImgDsk[ Pos ] ); 363 | } 364 | 365 | 366 | // 367 | // Retourne les informations d'une piste 368 | // 369 | CPCEMUTrack * DSK::GetInfoTrack( int Track ) { 370 | int Pos = sizeof( CPCEMUEnt ); 371 | CPCEMUTrack * tr = ( CPCEMUTrack * )&ImgDsk[ Pos ]; 372 | for ( int t = 0; t < Track; t++ ) { 373 | Pos += sizeof( CPCEMUTrack ); 374 | 375 | for ( int s = 0; s < tr->NbSect; s++ ) { 376 | if ( tr->Sect[ s ].SizeByte ) 377 | Pos += tr->Sect[ s ].SizeByte; 378 | else 379 | Pos += ( 128 << tr->Sect[ s ].N ); 380 | } 381 | } 382 | return( ( CPCEMUTrack * )&ImgDsk[ Pos ] ); 383 | } 384 | 385 | // 386 | // Remplit un "bitmap" pour savoir o� il y a des fichiers sur la disquette 387 | // Retourne �galement le nombre de Ko utilis�s sur la disquette 388 | // 389 | int DSK::FillBitmap( void ) { 390 | int NbKo = 0; 391 | 392 | memset( Bitmap, 0, sizeof( Bitmap ) ); 393 | Bitmap[ 0 ] = Bitmap[ 1 ] = 1; 394 | for ( int i = 0; i < 64; i++ ) { 395 | StDirEntry * Dir = GetInfoDirEntry( i ); 396 | if ( Dir->User != USER_DELETED ) { 397 | for ( int j = 0; j < 16; j++ ) { 398 | int b = Dir->Blocks[ j ]; 399 | if ( b > 1 && ( ! Bitmap[ b ] ) ) { 400 | Bitmap[ b ] = 1; 401 | NbKo++; 402 | } 403 | } 404 | } 405 | } 406 | return( NbKo ); 407 | } 408 | 409 | 410 | // 411 | // Positionne une entr�e dans le r�pertoire 412 | // 413 | void DSK::SetInfoDirEntry( int NumDir, StDirEntry * Dir ) { 414 | int MinSect = GetMinSect(); 415 | int s = ( NumDir >> 4 ) + MinSect; 416 | int t = ( MinSect == 0x41 ? 2 : 0 ); 417 | if ( MinSect == 1 ) 418 | t = 1; 419 | 420 | for (int i =0; i<16; i++) 421 | memcpy( &ImgDsk[ ( ( NumDir & 15 ) << 5 ) + GetPosData( t, s, true ) ] 422 | , Dir 423 | , sizeof( StDirEntry ) 424 | ); 425 | } 426 | 427 | 428 | // 429 | // V�rifie l'existente d'un fichier, retourne l'indice du fichier si existe, 430 | // -1 sinon 431 | // 432 | int DSK::FileExist( char * Nom ) { 433 | int i; 434 | for ( i = 0; i < 64; i++ ) { 435 | StDirEntry * Dir = GetInfoDirEntry( i ); 436 | for(int q=0;q<12;q++) 437 | Dir->Nom[q]=Dir->Nom[q]&127; // Avoid missing hidden files 438 | if ( Dir->User != USER_DELETED 439 | && ! strncmp( Nom, ( char * )Dir->Nom, 11 ) // 11 = 8+3 car le point est enlev� 440 | ) 441 | return( i ); 442 | } 443 | return( -1 ); 444 | } 445 | 446 | 447 | StDirEntry * DSK::GetNomDir( string NomFic ) { 448 | static StDirEntry DirLoc; 449 | int i; 450 | 451 | memset( &DirLoc, 0, sizeof( DirLoc ) ); 452 | memset( DirLoc.Nom, ' ', 8 ); 453 | memset( DirLoc.Ext, ' ', 3 ); 454 | size_t p = NomFic.find('.'); 455 | if ( p!=std::string::npos ) 456 | { 457 | NomFic.copy( DirLoc.Nom, std::min((int)p,8), 0); 458 | p++; 459 | NomFic.copy( DirLoc.Ext, std::min( (int)(NomFic.size()-p), 3 ), p ); 460 | } 461 | else 462 | NomFic.copy( DirLoc.Nom, std::min((int)NomFic.size(), 8 ),0); 463 | 464 | for ( i = 0; i < 11; i++ ) 465 | DirLoc.Nom[ i ] = ( unsigned char )toupper( DirLoc.Nom[ i ] ); 466 | 467 | return( &DirLoc ); 468 | } 469 | 470 | 471 | int DSK::FileIsIn( string FileName ) { 472 | StDirEntry * DirLoc = GetNomDir( FileName ); 473 | return FileExist( ( char*) DirLoc->Nom ); 474 | } 475 | 476 | // 477 | // Copie un fichier sur le DSK 478 | // 479 | // la taille est determine par le nombre de NbPages 480 | // regarder pourquoi different d'une autre DSK 481 | int DSK::CopieFichier( unsigned char * BufFile, char * NomFic, int TailleFic, int MaxBloc, int UserNumber, bool System_file, bool Read_only ) { 482 | int j, l, Bloc, PosFile, NbPages = 0, PosDir, TaillePage; 483 | FillBitmap(); 484 | StDirEntry * DirLoc = GetNomDir( NomFic ); //Construit l'entr�e pour mettre dans le catalogue 485 | for ( PosFile = 0; PosFile < TailleFic; ) { //Pour chaque bloc du fichier 486 | PosDir = RechercheDirLibre(); //Trouve une entr�e libre dans le CAT 487 | if ( PosDir != -1 ) { 488 | DirLoc->User = UserNumber; //Remplit l'entr�e : User 0 489 | // http://www.cpm8680.com/cpmtools/cpm.htm 490 | if(System_file) DirLoc->Ext[1]|=0x80; 491 | if(Read_only) DirLoc->Ext[0]|=0x80; 492 | DirLoc->NumPage = ( unsigned char )NbPages++; // Num�ro de l'entr�e dans le fichier 493 | TaillePage = (TailleFic - PosFile + 127) >> 7 ; // Taille de la page (on arrondit par le haut) 494 | if ( TaillePage > 128 ) // Si y'a plus de 16k il faut plusieurs pages 495 | TaillePage = 128; 496 | 497 | DirLoc->NbPages = ( unsigned char )TaillePage; 498 | l = ( DirLoc->NbPages + 7 ) >> 3; //Nombre de blocs=TaillePage/8 arrondi par le haut 499 | memset( DirLoc->Blocks, 0, 16 ); 500 | for ( j = 0; j < l; j++ ) { //Pour chaque bloc de la page 501 | Bloc = RechercheBlocLibre( MaxBloc ); //Met le fichier sur la disquette 502 | if ( Bloc ) { 503 | DirLoc->Blocks[ j ] = ( unsigned char )Bloc; 504 | WriteBloc( Bloc, &BufFile[ PosFile ] ); 505 | PosFile += 1024; // Passe au bloc suivant 506 | } 507 | else 508 | return( ERR_NO_BLOCK ); 509 | 510 | } 511 | SetInfoDirEntry( PosDir, DirLoc ); 512 | } 513 | else 514 | return( ERR_NO_DIRENTRY ); 515 | } 516 | return( ERR_NO_ERR ); 517 | } 518 | 519 | 520 | // 521 | // Retourne une entr�e du r�pertoire 522 | // 523 | StDirEntry * DSK::GetInfoDirEntry( int NumDir ) { 524 | static StDirEntry Dir; 525 | int MinSect = GetMinSect(); 526 | int s = ( NumDir >> 4 ) + MinSect; 527 | int t = ( MinSect == 0x41 ? 2 : 0 ); 528 | if ( MinSect == 1 ) 529 | t = 1; 530 | 531 | memcpy( &Dir 532 | , &ImgDsk[ ( ( NumDir & 15 ) << 5 ) + GetPosData( t, s, true ) ] 533 | , sizeof( StDirEntry ) 534 | ); 535 | return( &Dir ); 536 | } 537 | 538 | 539 | // 540 | // V�rifier si DSK est "standard" (DATA ou VENDOR) 541 | // 542 | bool DSK::CheckDsk( void ) { 543 | CPCEMUEnt * Infos = ( CPCEMUEnt * )ImgDsk; 544 | if ( Infos->NbHeads == 1 ) { 545 | int MinSectFirst = GetMinSect(); 546 | if ( MinSectFirst != 0x41 && MinSectFirst != 0xC1 && MinSectFirst != 0x01 ) 547 | { 548 | cout << "DSK has wrong sector number!" << endl; 549 | return( false ); 550 | } 551 | 552 | 553 | if ( Infos->NbTracks > 42 ) 554 | Infos->NbTracks = 42; 555 | 556 | for ( int track = 0; track < Infos->NbTracks; track++ ) { 557 | // Recherche position secteur 558 | int Pos = sizeof( CPCEMUEnt ) + ( 0x1200 + sizeof( CPCEMUTrack ) ) * track; 559 | CPCEMUTrack * tr = ( CPCEMUTrack * )&ImgDsk[ Pos ]; 560 | 561 | int MinSect = 0xFF, MaxSect = 0; 562 | if ( tr->NbSect != 9 ) 563 | { 564 | cout << "Warning : track " << track <<" has "<<(int)tr->NbSect<<" sectors ! (wanted 9)" << endl; 565 | // return( false ); 566 | } 567 | for ( int s = 0; s < (int)tr->NbSect; s++ ) { 568 | if ( MinSect > tr->Sect[ s ].R ) 569 | MinSect = tr->Sect[ s ].R; 570 | 571 | if ( MaxSect < tr->Sect[ s ].R ) 572 | MaxSect = tr->Sect[ s ].R; 573 | } 574 | if ( MaxSect - MinSect != 8 ) 575 | { 576 | cout << "Warning : strange sector numbering in track "<NbHeads << endl; 588 | return( false ); 589 | } 590 | 591 | 592 | // 593 | // Lire un fichier DSK 594 | // 595 | bool DSK::ReadDsk( std::string NomFic ) { 596 | bool Ret = false; 597 | CPCEMUEnt * Infos; 598 | if(sizeof(CPCEMUEnt) != 0x100) cout << "INVALID DSK BUILD" << endl; 599 | FILE* fp ; 600 | 601 | if ( (fp=fopen(NomFic.c_str(),"rb"))!=NULL ) { 602 | fread(ImgDsk,sizeof(ImgDsk),1,fp); 603 | Infos = ( CPCEMUEnt * )ImgDsk; 604 | if ( isBigEndian( ) ) FixEndianDsk( false ); // fix endian for Big endianness machines (PPC) 605 | if ( ! strncmp( Infos->debut, "MV -", 4 ) 606 | || ! strncmp( Infos->debut, "EXTENDED CPC DSK", 16 ) 607 | ) 608 | Ret = true; 609 | fclose(fp); 610 | } 611 | return( Ret ); 612 | } 613 | 614 | 615 | // 616 | // Formatter une disquette 617 | // 618 | void DSK::FormatDsk( int NbSect, int NbTrack ) { 619 | CPCEMUEnt * Infos = ( CPCEMUEnt * )ImgDsk; 620 | 621 | strcpy( Infos->debut, "MV - CPCEMU Disk-File\r\nDisk-Info\r\n" ); 622 | Infos->DataSize = ( short )( sizeof( CPCEMUTrack ) + (0x200 * NbSect) ); 623 | Infos->NbTracks = ( unsigned char ) NbTrack; 624 | Infos->NbHeads = 1; 625 | for ( int t = 0; t < NbTrack; t++ ) 626 | FormatTrack( Infos, t, 0xC1, NbSect ); 627 | 628 | 629 | FillBitmap(); 630 | } 631 | 632 | 633 | 634 | // 635 | // Modifie le endianness de la disquette 636 | // 637 | void DSK::FixEndianDsk( bool littleToBig) { 638 | CPCEMUEnt * Infos = ( CPCEMUEnt * )ImgDsk; 639 | //std::cerr<< "FixEndianDsk() Infos->DataSize : " << Infos->DataSize <DataSize = FIX_SHORT( Infos->DataSize ); 643 | for ( int t = 0; t < Infos->NbTracks; t++ ) 644 | FixEndianTrack( Infos, t, 9 ); 645 | if ( littleToBig ) 646 | Infos->DataSize = FIX_SHORT( Infos->DataSize ); 647 | FillBitmap(); 648 | } 649 | 650 | // 651 | // Modifie le endianness de la piste 652 | // 653 | void DSK::FixEndianTrack( CPCEMUEnt * Infos, int t, int NbSect ) { 654 | CPCEMUTrack *tr; 655 | if ( Infos->DataSize != 0 ) 656 | tr = ( CPCEMUTrack * )&ImgDsk[ sizeof( CPCEMUEnt ) + t * Infos->DataSize ]; 657 | else { 658 | int ExtendedDataSize = ImgDsk[ 0x34 + t ] *256; //case of a extended dsk image 659 | tr = ( CPCEMUTrack * )&ImgDsk[ sizeof( CPCEMUEnt ) + t * ExtendedDataSize ]; 660 | } 661 | int ss = 0; 662 | 663 | // 664 | // Gestion "entrelacement" des secteurs 665 | // 666 | for ( int s = 0; s < NbSect; ) { 667 | tr->Sect[ s ].SizeByte = FIX_SHORT( tr->Sect[ s ].SizeByte ); 668 | tr->Sect[ s ].Un1 = FIX_SHORT( tr->Sect[ s ].Un1 ); 669 | ss++; 670 | if ( ++s < NbSect ) { 671 | tr->Sect[ s ].SizeByte = FIX_SHORT( tr->Sect[ s ].SizeByte ); 672 | tr->Sect[ s ].Un1 = FIX_SHORT( tr->Sect[ s ].Un1 ); 673 | s++; 674 | } 675 | } 676 | tr->Unused = FIX_SHORT( tr->Unused ); 677 | } 678 | 679 | 680 | // 681 | // Ecriture du fichier DSK 682 | // 683 | bool DSK::WriteDsk( string NomDsk ) { 684 | CPCEMUEnt * Infos = ( CPCEMUEnt * )ImgDsk; 685 | FILE* fp; 686 | int Taille,Copie; 687 | 688 | 689 | if ( (fp=fopen(NomDsk.c_str(),"wb+")) != NULL) { 690 | if ( ! Infos->DataSize ) Infos->DataSize = 0x100 + SECTSIZE * 9; 691 | Taille = Infos->NbTracks * Infos->DataSize + sizeof( * Infos ); 692 | if ( isBigEndian() ) FixEndianDsk( true ) ; // Fix endianness for Big endian machines (PPC) 693 | 694 | if ( (Copie=(fwrite(ImgDsk,1,Taille,fp))) !=Taille ) 695 | cerr << Copie << "!=" << Taille; 696 | fclose(fp); 697 | // in case of the same DSK image stay in memory 698 | if ( isBigEndian() ) FixEndianDsk( false ) ; // unFix endianness for Big endian machines (PPC) 699 | 700 | return( true ); 701 | } 702 | return( false ); 703 | } 704 | 705 | 706 | void DSK::DskEndian() { 707 | CPCEMUEnt * Infos = ( CPCEMUEnt * )ImgDsk; 708 | for ( int i=1 ; i<(int)Infos->NbTracks ; i++) { 709 | CPCEMUTrack * TrackData = GetInfoTrack( i ); 710 | TrackData = CPCEMUTrackEndian ( TrackData ) ; 711 | } 712 | Infos = CPCEMUEntEndian ( Infos ) ; 713 | } 714 | 715 | 716 | StAmsdos* DSK::StAmsdosEndian ( StAmsdos * pEntete ){ 717 | pEntete->Length = FIX_SHORT( pEntete->Length ); 718 | pEntete->Adress = FIX_SHORT( pEntete->Adress ); 719 | pEntete->LogicalLength = FIX_SHORT( pEntete->LogicalLength); 720 | pEntete->EntryAdress = FIX_SHORT( pEntete->EntryAdress ); 721 | pEntete->RealLength = FIX_SHORT( pEntete->RealLength ); 722 | pEntete->CheckSum = FIX_SHORT( pEntete->CheckSum ) ; 723 | return ( pEntete ); 724 | } 725 | 726 | 727 | CPCEMUEnt* DSK::CPCEMUEntEndian ( CPCEMUEnt* Infos ) { 728 | Infos->DataSize = FIX_SHORT( Infos->DataSize ); 729 | return (Infos); 730 | } 731 | 732 | 733 | CPCEMUTrack* DSK::CPCEMUTrackEndian ( CPCEMUTrack* tr ) { 734 | for ( int i=0;i < (int)tr->NbSect ; i++) { 735 | tr->Sect[i] = CPCEMUSectEndian( tr->Sect[i] ); 736 | } 737 | 738 | return ( tr); 739 | 740 | } 741 | 742 | 743 | CPCEMUSect DSK::CPCEMUSectEndian ( CPCEMUSect Sect) { 744 | Sect.Un1 = FIX_SHORT( Sect.Un1 ); 745 | Sect.SizeByte = FIX_SHORT( Sect.SizeByte ); 746 | return (Sect); 747 | } 748 | 749 | // Retourne le type de fichier sous forme de chaine 750 | // 751 | const char * DSK::GetType( int Langue, StAmsdos * Ams ) { 752 | if ( CheckAmsdos( ( unsigned char * )Ams ) ) { 753 | switch( Ams->FileType ) { 754 | case 0 : // BASIC 755 | return( "BASIC"); //GetTexteLoc( 22, Langue ) ); 756 | 757 | case 1 : // BASIC (P) 758 | return( "BASIC(P)"); // GetTexteLoc( 23, Langue ) ); 759 | 760 | case 2 : // BINAIRE 761 | return("BINAIRE"); // GetTexteLoc( 24, Langue ) ); 762 | 763 | case 3 : // BINAIRE (P) 764 | return( "BINAIRE(P)"); //GetTexteLoc( 25, Langue ) ); 765 | 766 | default : 767 | return( "INCONNU"); // GetTexteLoc( 26, Langue ) ); 768 | } 769 | } 770 | return("ASCII"); // GetTexteLoc( 27, Langue ) ); 771 | } 772 | 773 | char * DSK::GetEntryNameInCatalogue ( int num , char* Nom ) { 774 | int PosItem[ 64 ]; 775 | StDirEntry TabDir[ 64 ]; 776 | 777 | memset( PosItem, 0, sizeof( PosItem ) ); 778 | 779 | for ( int i = 0; i < 64; i++ ) 780 | memcpy( &TabDir[ i ], GetInfoDirEntry( i ), sizeof( StDirEntry )); 781 | 782 | for ( int i = 0; i < 64; i++ ) { 783 | SetInfoDirEntry( i, &TabDir[ i ] ); 784 | 785 | if ( TabDir[ i ].User != USER_DELETED && ! TabDir[ i ].NumPage && num == i) { 786 | memcpy( Nom, TabDir[ i ].Nom, 8 ); 787 | memcpy( &Nom[ 9 ], TabDir[ i ].Ext, 3 ); 788 | Nom[ 8 ] = '.'; 789 | Nom[ 12 ] = 0; 790 | for ( int j = 0; j < 12; j++ ) 791 | Nom[ j ] &= 0x7F; 792 | for ( int j = 0; j < 12; j++ ) 793 | if ( ! isprint( Nom[ j ] ) ) 794 | Nom[ j ] = '?' ; 795 | return Nom; 796 | } 797 | } 798 | return Nom; 799 | } 800 | 801 | char * DSK::GetEntrySizeInCatalogue ( int num , char* Size ) { 802 | int PosItem[ 64 ]; 803 | StDirEntry TabDir[ 64 ]; 804 | 805 | 806 | memset( PosItem, 0, sizeof( PosItem ) ); 807 | 808 | for ( int i = 0; i < 64; i++ ) 809 | memcpy( &TabDir[ i ], GetInfoDirEntry( i ), sizeof( StDirEntry )); 810 | 811 | for ( int i = 0; i < 64; i++ ) { 812 | SetInfoDirEntry( i, &TabDir[ i ] ); 813 | 814 | if ( TabDir[ i ].User != USER_DELETED && ! TabDir[ i ].NumPage && num == i) { 815 | int p = 0, t = 0; 816 | do { 817 | if ( TabDir[ p + i ].User == TabDir[ i ].User ) { 818 | t += TabDir[ p + i ].NbPages; 819 | } 820 | p++; 821 | } 822 | while( TabDir[ p + i ].NumPage && ( p + i ) < 64 ); 823 | sprintf( Size, "%d Ko", ( t + 7 ) >>3 ); 824 | return Size; 825 | } 826 | } 827 | return Size; 828 | } 829 | 830 | 831 | bool DSK::GetFileInDsk( char* path, int Indice ){ 832 | int i = Indice; 833 | char current[ 16 ]; 834 | char NomIndice[ 16 ]; 835 | int lMax = 0x1000000; 836 | int cumul=0; 837 | FILE* f; 838 | StDirEntry TabDir[ 64 ]; 839 | 840 | if ( (f=fopen(path,"wb"))==NULL ) 841 | return false; 842 | 843 | for ( int i = 0; i < 64; i++ ) 844 | memcpy( &TabDir[ i ], GetInfoDirEntry( i ), sizeof( StDirEntry )); 845 | 846 | 847 | memset( NomIndice, 0 , sizeof( NomIndice ) ); 848 | strncpy( NomIndice, GetNomAmsdos( TabDir[ i ].Nom ), 16); 849 | strncat( NomIndice, GetNomAmsdos( TabDir[ i ].Ext), 3); 850 | 851 | do 852 | { 853 | // Longueur du fichier 854 | int l = ( TabDir[ i ].NbPages + 7 ) >> 3; 855 | for ( int j = 0; j < l; j++ ) { 856 | int TailleBloc = 1024; 857 | unsigned char * p = ReadBloc( TabDir[ i ].Blocks[ j ] ); 858 | int NbOctets = min( lMax, TailleBloc ); 859 | if ( NbOctets > 0 ) { 860 | fwrite(p,1,NbOctets,f); 861 | cumul+=NbOctets; 862 | } 863 | lMax -= 1024; 864 | } 865 | memset( current , 0, sizeof( current ) ); 866 | i++; 867 | strncpy(current, GetNomAmsdos( TabDir[ i ].Nom ), 16 ); 868 | strncat(current, GetNomAmsdos( TabDir[ i ].Ext ), 3); 869 | 870 | if ( i > 64 ) return false; 871 | }while (! strncmp( NomIndice, current , max( strlen( NomIndice ), strlen( current ) ))); 872 | 873 | fclose (f); 874 | return true; 875 | } 876 | 877 | 878 | bool DSK::PutFileInDsk(string Masque, int TypeModeImport, 879 | int loadAddress, int exeAddress, int UserNumber, 880 | bool System_file, bool Read_only ) 881 | { 882 | static unsigned char Buff[0x20000]; 883 | static char *cFileName; 884 | unsigned long Lg; 885 | bool ret; 886 | FILE* Hfile; 887 | 888 | // Get AMSDOS-formatted name 889 | cFileName = GetNomAmsdos(Masque.c_str()); 890 | 891 | // Open and read the input file 892 | if ((Hfile = fopen(Masque.c_str(),"rb")) == NULL) 893 | return false; 894 | Lg=fread(Buff,1, 0x20000 ,Hfile); 895 | fclose( Hfile ); 896 | 897 | // Check if file already has an header 898 | bool IsAmsdos = (TypeModeImport != MODE_RAW) && CheckAmsdos(Buff); 899 | 900 | // Force binary mode if a load or execution address is specified 901 | if (loadAddress != 0 || exeAddress != 0) 902 | TypeModeImport = MODE_BINAIRE; 903 | 904 | switch(TypeModeImport) { 905 | case MODE_ASCII: 906 | // In ASCII mode, delete the header if there is one 907 | if (IsAmsdos) { 908 | memmove(Buff, Buff + sizeof(StAmsdos), Lg - sizeof(StAmsdos)); 909 | Lg -= sizeof(StAmsdos); 910 | } 911 | break; 912 | 913 | case MODE_BINAIRE : 914 | // In binary mode, add an header if there is none 915 | if ( ! IsAmsdos ) { 916 | // Sanity check on file size (we cast to unsigned short) 917 | if ( Lg >= 0x10000 ) { 918 | cerr << "Creating an header for files larger than 64K is not supported yet\n"; 919 | return false; 920 | } 921 | 922 | // Create and fill AMSDOS header 923 | cout << "Automatically generating header for file\n"; 924 | StAmsdos * e; 925 | e = CreeEnteteAmsdos(cFileName, (unsigned short)Lg); 926 | if (loadAddress != 0) 927 | { 928 | e->Adress = (unsigned short)loadAddress; 929 | } 930 | if (exeAddress != 0) 931 | { 932 | e->EntryAdress = (unsigned short)exeAddress; 933 | } 934 | // After changing addresses, recompute header checksum 935 | SetChecksum(e); 936 | // Fix endianness if run on big-endian machine 937 | if (isBigEndian()) e = StAmsdosEndian(e); 938 | 939 | // Insert the header before the file 940 | memmove(&Buff[sizeof(StAmsdos)], Buff, Lg); 941 | memcpy(Buff, e, sizeof(StAmsdos)); 942 | Lg += sizeof(StAmsdos); 943 | } 944 | else 945 | cout << "File already has an header\n"; 946 | break; 947 | case MODE_RAW : 948 | cout << "Using raw mode, no header\n"; 949 | 950 | } 951 | 952 | // Copy the file inside the DSK image. 953 | if (CopieFichier(Buff, cFileName, Lg, 256, UserNumber, System_file, Read_only) != ERR_NO_ERR) 954 | ret = false; 955 | else 956 | ret = true; 957 | 958 | return ret; 959 | } 960 | 961 | 962 | bool DSK::OnViewFic(int nItem) { 963 | int LongFic = 0; 964 | memset( BufFile, 0, sizeof( BufFile ) ); 965 | memset( Listing, 0, sizeof( Listing ) ); 966 | char NomFic[ 16 ]; 967 | char current[ 16 ]; 968 | int i = nItem; 969 | bool FirstBlock = true; 970 | StDirEntry TabDir[ 64 ]; 971 | 972 | for ( int j = 0; j < 64; j++ ) 973 | memcpy( &TabDir[ j ], GetInfoDirEntry( j ), sizeof( StDirEntry )); 974 | 975 | memset( NomFic, 0 , sizeof( NomFic ) ); 976 | strncpy( NomFic, GetNomAmsdos( TabDir[ i ].Nom ), 16); 977 | strncat( NomFic, GetNomAmsdos( TabDir[ i ].Ext), 3); 978 | 979 | int lMax = sizeof( BufFile ); 980 | 981 | TailleFic = 0; 982 | 983 | 984 | do 985 | { 986 | // Longueur du fichier 987 | int l = ( TabDir[ i ].NbPages + 7 ) >> 3; 988 | for ( int j = 0; j < l; j++ ) { 989 | int TailleBloc = 1024; 990 | unsigned char * p = ReadBloc( TabDir[ i ].Blocks[ j ] ); 991 | if ( FirstBlock ) { 992 | if ( CheckAmsdos( p ) ) { 993 | TailleFic = p[ 0x18 +1 ] *256 + p[ 0x18 ]; 994 | AdresseCharg = p[ 0x15 +1 ] *256 + p[ 0x15 ]; 995 | AdresseExec = p[ 0x1a +1 ] *256 + p[ 0x1a ]; 996 | TailleBloc -= sizeof( StAmsdos ); 997 | memcpy( p , &p[ 0x80 ] , TailleBloc ); 998 | } 999 | FirstBlock = false; 1000 | 1001 | } 1002 | int NbOctets = min( lMax, TailleBloc ); 1003 | if ( NbOctets > 0 ) { 1004 | memcpy( &BufFile[ LongFic ], p, NbOctets ); 1005 | LongFic += NbOctets; 1006 | } 1007 | lMax -= 1024; 1008 | } 1009 | memset( current , 0, sizeof( current ) ); 1010 | i++; 1011 | strncpy(current, GetNomAmsdos( TabDir[ i ].Nom ), 16 ); 1012 | strncat(current, GetNomAmsdos( TabDir[ i ].Ext ), 3); 1013 | if ( i > 64 ) return false; 1014 | }while( ! strncmp( NomFic, current, max( strlen( current ), strlen( NomFic ) ) ) ); 1015 | 1016 | if ( TailleFic == 0 ) 1017 | TailleFic = LongFic; 1018 | return true; 1019 | } 1020 | 1021 | 1022 | bool DSK::Hexdecimal() { 1023 | 1024 | int TailleCourante=0; 1025 | char OffSet[ 7 ]; 1026 | const char * CodeHexa = "0123456789ABCDEF"; 1027 | 1028 | while (TailleCourante <= TailleFic ) { 1029 | // display the offset 1030 | memset( OffSet, 0 , 7 ); 1031 | snprintf( OffSet,6,"#%.4X:", TailleCourante ); 1032 | strcat( Listing, OffSet ); 1033 | strcat( Listing, " "); 1034 | char Ascii[ 18 ]; 1035 | char Hex[ 16 *3 +1 ]; 1036 | memset( Ascii, 0 , 18 ); 1037 | memset( Hex , 0 , ( 16*3 +1) ); 1038 | for ( int i=0; i<16 ; ++i ) { 1039 | unsigned char cur = BufFile[ TailleCourante + i ]; 1040 | // manage the ascii display 1041 | if ( cur > 32 && cur < 125 ) 1042 | Ascii[ i ] = cur; 1043 | else 1044 | Ascii[ i ] = '.'; 1045 | char Val[ 4 ]; 1046 | // manage the hexadeciaml display 1047 | Val[ 0 ] = CodeHexa[ cur >> 4 ]; 1048 | Val[ 1 ] = CodeHexa[ cur & 0x0F ]; 1049 | Val[ 2 ] = ' '; 1050 | Val[ 3 ] ='\0'; 1051 | strcat( Hex, Val ); 1052 | } 1053 | Ascii[ 16 ] = '\n'; 1054 | strcat( Listing, Hex ); 1055 | strcat( Listing, "| "); 1056 | strcat( Listing, Ascii ); 1057 | TailleCourante += 16; 1058 | } 1059 | 1060 | return true; 1061 | } 1062 | 1063 | 1064 | void DSK::RemoveFile ( int item ) { 1065 | StDirEntry TabDir[ 64 ]; 1066 | 1067 | for ( int j = 0; j < 64; j++ ) 1068 | memcpy( &TabDir[ j ], GetInfoDirEntry( j ), sizeof( StDirEntry )); 1069 | 1070 | char CheckFic[12]; // User - Nom - Ext 1071 | memcpy( CheckFic, & TabDir[ item ], 12); 1072 | 1073 | for (int i = item; i < 64; ++i ) { 1074 | if ( ! memcmp( CheckFic, &TabDir[ i ], 12) ) 1075 | { 1076 | TabDir[ i ].User = USER_DELETED; 1077 | SetInfoDirEntry( i, &TabDir[ i ]); 1078 | } 1079 | } 1080 | 1081 | return ; 1082 | } 1083 | 1084 | 1085 | 1086 | void DSK::RenameFile( int item , char *NewName) { 1087 | char NomFic[ 16 ]; 1088 | StDirEntry TabDir[ 64 ]; 1089 | StDirEntry DirLoc; 1090 | int c = item; 1091 | for ( int j = 0; j < 64; j++ ) 1092 | memcpy( &TabDir[ j ], GetInfoDirEntry( j ), sizeof( StDirEntry )); 1093 | 1094 | memset( DirLoc.Nom, ' ', 8); 1095 | memset( DirLoc.Ext, ' ', 3); 1096 | for ( int i=0; i<(int) strlen( NewName ) ; ++i) 1097 | NewName[ i ] = toupper( NewName[ i ] ); 1098 | 1099 | char *p = strchr( NewName, '.'); 1100 | 1101 | if ( p ) { 1102 | p++; 1103 | memcpy( DirLoc.Nom, NewName, p - NewName -1); 1104 | memcpy( DirLoc.Ext, p, std::min((int)strlen(p),3) ); 1105 | } 1106 | else { 1107 | memcpy( DirLoc.Nom, NewName, min( (int)strlen( NewName) , 8 ) ); 1108 | } 1109 | strcpy( NomFic, GetNomAmsdos( TabDir[ c ].Nom )); 1110 | 1111 | do { 1112 | memcpy( TabDir[ c ].Nom , DirLoc.Nom , 8 ); 1113 | memcpy( TabDir[ c ].Ext , DirLoc.Ext, 3 ); 1114 | SetInfoDirEntry( c, &TabDir[ c ]); 1115 | p = GetNomAmsdos( TabDir[ ++c ].Nom ); 1116 | }while (!strncmp( NomFic, p , max(strlen(p),strlen(NomFic)))); 1117 | } 1118 | 1119 | 1120 | std::string DSK::ReadDskDir( void ) { 1121 | StDirEntry TabDir[ 64 ]; 1122 | string catalogue; 1123 | for ( int i = 0; i < 64; i++ ) { 1124 | memcpy( &TabDir[ i ] 1125 | , GetInfoDirEntry( i ) 1126 | , sizeof( StDirEntry ) 1127 | ); 1128 | } 1129 | // Trier les fichiers 1130 | for ( int i = 0; i < 64; i++ ) { 1131 | // 1132 | // Afficher les fichiers non effac�s 1133 | // 1134 | if ( TabDir[ i ].User != USER_DELETED && ! TabDir[ i ].NumPage ) { 1135 | char Nom[ 13 ]; 1136 | memcpy( Nom, TabDir[ i ].Nom, 8 ); 1137 | memcpy( &Nom[ 9 ], TabDir[ i ].Ext, 3 ); 1138 | Nom[ 8 ] = '.'; 1139 | Nom[ 12 ] = 0; 1140 | // 1141 | // Masquer les bits d'attributs 1142 | // 1143 | for ( int j = 0; j < 12; j++ ) 1144 | { 1145 | Nom[ j ] &= 0x7F; 1146 | 1147 | if ( ! isprint( Nom[ j ] ) ) 1148 | Nom[ j ] = '?' ; 1149 | } 1150 | 1151 | catalogue += Nom; 1152 | catalogue += " "; 1153 | ostringstream c; 1154 | c << (int)TabDir[i].User; 1155 | catalogue += c.str(); 1156 | // 1157 | // Calcule la taille du fichier en fonction du nombre de blocs 1158 | // 1159 | int p = 0, t = 0; 1160 | do { 1161 | if ( TabDir[ p + i ].User == TabDir[ i ].User ) 1162 | t += TabDir[ p + i ].NbPages; 1163 | p++; 1164 | } while( TabDir[ p + i ].NumPage && ( p + i ) < 64 ); 1165 | //string size = GetTaille( ( t + 7 ) >> 3 ); 1166 | //catalogue+= " : " + size + "\n"; 1167 | catalogue += "\n"; 1168 | 1169 | } 1170 | } 1171 | return catalogue; 1172 | } 1173 | --------------------------------------------------------------------------------