source: xtideuniversalbios/trunk/Serial_Server/library/Image.cpp @ 233

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

Serial Port: split single byte port and baud into two bytes, taking advantage of the two bytes in DPT_SERIAL, which supports more serial baud rates and in particular fixed a bug where a 4x client machine couldn't talk to a 115.2K server machine. This is a wide change, touching lots of files, but most are shallow changes. DetectPrint.asm took the most significant changes, now it calculates the baud rate to display instead of using characters provided by the Configurator. The Configurator now has a new menu flag, FLG_MENUITEM_CHOICESTRINGS, for specifying that values are not linear and they should be lookedup rather than indexed. Finally, another important bug fixed here is that in some error cases, the serial port code could get into an infinite loop waiting ont the hardware; now it has a timeout.

File size: 5.2 KB
Line 
1//======================================================================
2//
3// Project:     XTIDE Universal BIOS, Serial Port Server
4//
5// File:        image.cpp - Abstract base class for disk image support
6//
7
8#include "library.h"
9#include <memory.h>
10#include <stdlib.h>
11#include <string.h>
12#include <stdio.h>
13
14Image::Image( char *name, int p_readOnly, int p_drive )
15{
16}
17
18Image::Image( char *name, int p_readOnly, int p_drive, int p_create, unsigned long p_lba )
19{
20}
21
22Image::Image( char *name, int p_readOnly, int p_drive, int p_create, unsigned long p_cyl, unsigned long p_head, unsigned long p_sect, int p_useCHS )
23{
24}
25
26void Image::init( char *name, int p_readOnly, int p_drive, unsigned long p_cyl, unsigned long p_head, unsigned long p_sect, int p_useCHS )
27{
28    double sizef;
29
30    for( char *c = shortFileName = name; *c; c++ )
31        if( *c == '\\' || *c == '/' || *c == ':' )
32            shortFileName = c+1;
33
34    if( *(shortFileName) == 0 )
35    {
36        log( 1, "Can't parse '%s' for short file name\n\n", name );
37        shortFileName = "SerDrive";
38    }
39 
40    readOnly = p_readOnly;
41    drive = p_drive;
42
43    if( totallba > 0xfffffff )     // lba28 limit - 28 bits
44        log( -1, "'%s', Image size larger than LBA28 maximum of 137,438,952,960 bytes, %lu", name, totallba );
45
46    if( totallba == 0 )
47        log( -1, "'%s', Image size zero?" );
48
49    if( p_useCHS )
50    {
51        if( p_cyl )
52        {
53            if( p_sect > 63 || (p_head > 16 || p_head < 1) || (p_cyl > 1024 || p_cyl < 1) )
54                log( -1, "'%s', parts of the CHS geometry (%lu:%lu:%lu) are out of the range (1-1024:1-16:1-63)", name, p_cyl, p_head, p_sect );
55            else if( totallba != (p_sect * p_head * p_cyl) )
56                log( -1, "'%s', file size does not match geometry", name );
57            sect = p_sect;
58            head = p_head;
59            cyl = p_cyl;
60        }
61        else
62        {
63            if( (totallba % 16) != 0 || ((totallba/16) % 63) != 0 )
64                log( -1, "'%s', file size does not match standard CHS geometry (x:16:63), please specify geometry explicitly with -g", name );
65            else
66            {
67                sect = 63;
68                head = 16;
69                cyl = (totallba / sect / head);
70                if( cyl > 1024 )
71                    log( -1, "'%s', CHS geometry of %lu:%lu:%lu is larger than maximum values 1024:16:63", name, cyl, head, sect );
72            }
73        }
74    }
75    else
76    {
77        sect = 0;
78        head = 0;
79        cyl = 0;
80    }
81    useCHS = p_useCHS;
82
83    sizef = totallba/2048.0;
84    if( useCHS )
85        log( 0, "Opening '%s', CHS geometry %u:%u:%u, total LBA %lu, total size %.1lf MB", name, cyl, sect, head, totallba, sizef );
86    else
87        log( 0, "Opening '%s', total LBA %lu, total size %.1lf MB", name, totallba, sizef );
88}
89
90int Image::parseGeometry( char *str, unsigned long *p_cyl, unsigned long *p_head, unsigned long *p_sect )
91{
92    char *c, *s, *h;
93    unsigned long cyl, sect, head;
94
95    c = str;
96    for( h = c; *h && *h != ':' && *h != 'x' && *h != 'X'; h++ ) ;
97    if( !*h )
98        return( 0 );
99
100    *h = '\0';
101    h++;
102    for( s = h+1; *s && *s != ':' && *s != 'x' && *s != 'X'; s++ ) ; 
103    if( !*s )
104        return( 0 );
105
106    *s = '\0';
107    s++;
108
109    cyl = atol(c);
110    head = atol(h);
111    sect = atol(s);
112
113    if( cyl == 0 || sect == 0 || head == 0 )
114        return( 0 );
115
116    *p_cyl = cyl;
117    *p_head = head;
118    *p_sect = sect;
119
120    return( 1 );
121}
122
123#define ATA_wGenCfg 0
124#define ATA_wCylCnt 1
125#define ATA_wHeadCnt 3
126#define ATA_wBpTrck 4
127#define ATA_wBpSect 5
128#define ATA_wSPT 6
129#define ATA_strSerial 10
130#define ATA_strFirmware 23
131#define ATA_strModel 27
132#define ATA_wCaps 49
133#define ATA_wCurCyls 54
134#define ATA_wCurHeads 55
135#define ATA_wCurSPT 56
136#define ATA_dwCurSCnt 57
137#define ATA_dwLBACnt 60
138
139#define ATA_wVendor 159
140
141#define ATA_wCaps_LBA 0x200
142
143#define ATA_wGenCfg_FIXED 0x40
144
145struct comPorts {
146    unsigned long port;
147    unsigned char com;
148};
149struct comPorts supportedComPorts[] = 
150{ 
151  { 0x3f8, '1' }, 
152  { 0x2f8, '2' }, 
153  { 0x3e8, '3' }, 
154  { 0x2e8, '4' }, 
155  { 0x2f0, '5' }, 
156  { 0x3e0, '6' }, 
157  { 0x2e0, '7' }, 
158  { 0x260, '8' },
159  { 0x368, '9' },
160  { 0x268, 'A' },
161  { 0x360, 'B' },
162  { 0x270, 'C' },
163  { 0, 0 } 
164};
165
166void Image::respondInquire( unsigned short *buff, struct baudRate *baudRate, unsigned short port, unsigned char scan )
167{
168    memset( &buff[0], 0, 514 );
169
170    if( scan )
171    {
172        unsigned short comPort = 0;
173        struct comPorts *cp;
174
175        if( port )
176        {
177            for( cp = supportedComPorts; cp->port && cp->port != port; cp++ ) ;
178            if( cp->port )
179                comPort = cp->com;
180        }
181
182        if( comPort )
183            sprintf( (char *) &buff[ATA_strModel], "%.15s (COM%c/%s)", shortFileName, comPort, baudRate->display );
184        else
185            sprintf( (char *) &buff[ATA_strModel], "%.25s (%s baud)", shortFileName, baudRate->display );
186    }
187    else
188        sprintf( (char *) &buff[ATA_strModel], "%.30s", shortFileName );
189
190    strncpy( (char *) &buff[ATA_strSerial], "serial", 20 );
191    strncpy( (char *) &buff[ATA_strFirmware], "firmw", 8 );
192
193    for( int t = ATA_strModel; t < ATA_strModel+40; t++ )
194        buff[t] = (buff[t] >> 8) | (buff[t] << 8);
195
196    if( useCHS )
197    {
198        buff[ ATA_wCylCnt ] = cyl;
199        buff[ ATA_wHeadCnt ] = head;
200        buff[ ATA_wSPT ] = sect;
201    }
202    else
203    {
204        buff[ ATA_wCaps ] = ATA_wCaps_LBA;
205        buff[ ATA_dwLBACnt ] = (unsigned short) (totallba & 0xffff);
206        buff[ ATA_dwLBACnt+1 ] = (unsigned short) (totallba >> 16);
207    }
208
209    buff[ ATA_wGenCfg ] = ATA_wGenCfg_FIXED;
210    //                  buff[ ATA_VendorSpecific_ReturnPortBaud ] = retWord;
211}
Note: See TracBrowser for help on using the repository browser.