source: xtideuniversalbios/trunk/Serial_Server/win32/Win32.cpp @ 258

Last change on this file since 258 was 258, checked in by gregli@…, 12 years ago

Added floppy drive emulation over the serial connection (MODULE_SERIAL_FLOPPY). Along the way, various optimizations were made to stay within the 8K ROM size target. Also, serial code now returns the number of sectors transferred.

File size: 6.3 KB
Line 
1//======================================================================
2//
3// Project:     XTIDE Universal BIOS, Serial Port Server
4//
5// File:        Win32.cpp - Microsoft Windows 32-bit application
6//
7// This file contains the entry point for the Win32 version of the server.
8// It also handles log reporting, timers, and command line parameter parsing.
9//
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <fcntl.h>
14#include <stdarg.h>
15
16#include "../library/library.h"
17#include "../library/flatimage.h"
18
19void usage(void)
20{
21    char *usageStrings[] = {
22        "SerDrive - XTIDE Universal BIOS Serial Drive Server",
23        "Version 1.2.0_wip, Built " __DATE__,
24        "",
25        "usage: SerDrive [options] imagefile [[slave-options] slave-imagefile]",
26        "",
27        "  -g [cyl:head:sect]  Geometry in cylinders, sectors per cylinder, and heads",
28        "                      -g also implies CHS addressing mode (default is LBA28)",
29        "",
30        "  -n [megabytes]      Create new disk with given size or use -g geometry",
31        "                      Maximum size is " USAGE_MAXSECTORS, 
32        "                      (default is a 32 MB disk, with CHS geometry 65:16:63)",
33        "",
34        "  -p [pipename]       Named Pipe mode for emulators",
35        "                      (must begin with \"\\\\\", default is \"" PIPENAME "\")",
36        "",
37        "  -c COMPortNumber    COM Port to use (default is first found)",
38        "                      Available COM ports on this system are:",
39     "COM                          ",
40        "",
41        "  -b BaudRate         Baud rate to use on the COM port, with client machine",
42        "                      rate multiplier in effect:",
43        "                          None:  2400,  4800,  9600,  28.8K,  57.6K, 115.2K",
44        "                          2x:    4800,  9600, 19200,  57.6K, 115.2K, 230.4K",
45        "                          4x:    9600, 19200, 38400, 115.2K, 230.4K, 460.8K",
46        "                          and for completeness:               76.8K, 153.6K",
47        "                      (default is 9600, 115.2K when in named pipe mode)",
48        "",
49        "  -t                  Disable timeout, useful for long delays when debugging",
50        "",
51        "  -r                  Read Only disk, do not allow writes",
52        "",
53        "  -v [level]          Reporting level 1-6, with increasing information",
54        "",
55        "On the client computer, a serial port can be configured for use as a hard disk",
56        "with xtidecfg.com.  Or one can hold down the ALT key at the end of the normal",
57        "IDE hard disk scan and the XTIDE Universal BIOS will scan COM1-7, at each of",
58        "the six speeds given above for BaudRate.  Note that hardware rate multipliers",
59        "must be taken into account on the server end, but are invisible on the client.",
60        "",
61        "Floppy images may also be used.  Image size must be exactly the same size",
62        "as a 2.88MB, 1.44MB, 1.2MB, 720KB, 360KB, 320KB, 180KB, or 160KB disk.",
63        "Floppy images must be the last disks discovered by the BIOS, and only",
64        "two floppy drives are supported by the BIOS at a time.",
65        NULL };
66
67    for( int t = 0; usageStrings[t]; t++ )
68    {
69        if( !strncmp( usageStrings[t], "COM", 3 ) )
70        {
71            char logbuff[ 1024 ];
72
73            SerialAccess::EnumerateCOMPorts( logbuff, 1024 );
74            fprintf( stderr, "%s%s\n", usageStrings[t]+3, logbuff );
75        }
76        else
77            fprintf( stderr, "%s\n", usageStrings[t] );
78    }
79
80    exit( 1 );
81}
82
83int verbose = 0;
84
85int main(int argc, char* argv[])
86{
87    DWORD len;
88
89    unsigned long check;
90    unsigned char w;
91
92    unsigned short wbuff[256];
93
94    SerialAccess serial;
95    Image *img;
96    struct baudRate *baudRate = NULL;
97
98    int timeoutEnabled = 1;
99
100    char *ComPort = NULL, ComPortBuff[20];
101
102    _fmode = _O_BINARY;
103
104    unsigned long cyl = 0, sect = 0, head = 0;
105    int readOnly = 0, createFile = 0;
106    int useCHS = 0;
107
108    int imagecount = 0;
109    Image *images[2] = { NULL, NULL };
110
111    for( int t = 1; t < argc; t++ )
112    {
113        if( argv[t][0] == '/' || argv[t][0] == '-' )
114        {
115            char *c;
116            unsigned long a;
117            for( c = &argv[t][1]; *c && !isdigit( *c ); c++ ) 
118                ;
119            a = atol(c);
120
121            switch( argv[t][1] )
122            {
123            case 'c': case 'C':
124                a = atol( argv[++t] );
125                if( a < 1 )
126                    usage();
127                sprintf( ComPortBuff, "COM%d", a );
128                ComPort = &ComPortBuff[0];
129                break;
130            case 'v': case 'V':
131                if( atol(argv[t+1]) != 0 )
132                    verbose = atol(argv[++t]);
133                else
134                    verbose = 1;
135                break;
136            case 'r': case 'R':
137                readOnly = 1;
138                break;
139            case 'p': case 'P':
140                if( argv[t+1][0] == '\\' && argv[t+1][1] == '\\' )
141                    ComPort = argv[++t];
142                else
143                    ComPort = PIPENAME;
144                if( !baudRate )
145                    baudRate = baudRateMatchString( "115200" );
146                break;           
147            case 'g': case 'G':
148                if( atol(argv[t+1]) != 0 )
149                {
150                    if( !Image::parseGeometry( argv[++t], &cyl, &head, &sect ) )
151                        usage();
152                }
153                useCHS = 1;
154                break;
155            case 'h': case 'H': case '?':
156                usage();
157                break;
158            case 'n': case 'N':
159                createFile = 1;
160                if( atol(argv[t+1]) != 0 )
161                {
162                    unsigned long size = atol(argv[++t]);
163                    sect = 63;
164                    head = 16;
165                    cyl = (size*1024*2) / (16*63);
166                }
167                break;
168            case 't': case 'T':
169                timeoutEnabled = 0;
170                break;
171            case 'b': case 'B':
172                if( !(baudRate = baudRateMatchString( argv[++t] )) || !baudRate->rate )
173                    log( -2, "Unknown Baud Rate \"%s\"", argv[t] );
174                break;
175            default:
176                log( -2, "Unknown Option: \"%s\"", argv[t] );
177            }
178        }
179        else if( imagecount < 2 )
180        {
181            if( createFile && cyl == 0 )
182            {
183                cyl = 65;
184                sect = 63;
185                head = 16;
186            }
187            images[imagecount] = new FlatImage( argv[t], readOnly, imagecount, createFile, cyl, head, sect, useCHS );
188            imagecount++;
189            createFile = readOnly = cyl = sect = head = useCHS = 0;
190        }
191        else
192            usage();
193    }
194
195    if( imagecount == 0 )
196        usage();
197
198    if( !baudRate )
199        baudRate = baudRateMatchString( "9600" );
200
201    do
202    {
203        serial.Connect( ComPort, baudRate );
204
205        processRequests( &serial, images[0], images[1], timeoutEnabled, verbose );
206
207        serial.Disconnect();
208
209        if( serial.resetConnection )
210            log( 0, "Serial Connection closed, reset..." );
211    }
212    while( serial.resetConnection );
213}
214
215void log( int level, char *message, ... )
216{
217    va_list args;
218
219    va_start( args, message );
220
221    if( level < 0 )
222    {
223        fprintf( stderr, "ERROR: " );
224        vfprintf( stderr, message, args );
225        fprintf( stderr, "\n" );
226        if( level < -1 )
227        {
228            fprintf( stderr, "\n" );
229            usage();
230        }
231        exit( 1 );
232    }
233    else if( verbose >= level )
234    {
235        vprintf( message, args );
236        printf( "\n" );
237    }
238
239    va_end( args );
240}
241
242unsigned long GetTime(void)
243{
244    return( GetTickCount() );
245}
246
247unsigned long GetTime_Timeout(void)
248{
249    return( 1000 );
250}
Note: See TracBrowser for help on using the repository browser.