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

Last change on this file since 247 was 233, checked in by gregli@…, 13 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.