00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "rcs_defs.hh"
00015 #include "dbg_mem.h"
00016
00017 #ifdef EXTERN_C_STD_HEADERS
00018 extern "C"
00019 {
00020 #endif
00021
00022
00023 #ifdef UNDER_CE
00024 #include <winbase.h>
00025 #endif
00026
00027 #include <string.h>
00028 #ifndef NO_STDIO
00029 #include <stdio.h>
00030 #endif
00031 #include <stdlib.h>
00032
00033 #ifdef lynxosPC
00034
00035 #include <smem.h>
00036 #include <errno.h>
00037
00038 #endif
00039
00040 #ifdef LINUX_VME
00041 #include <sys/types.h>
00042 #include <fcntl.h>
00043 #include <unistd.h>
00044 #include <sys/mman.h>
00045 #endif
00046
00047
00048 #ifdef VXWORKS
00049 #include "vxWorks.h"
00050 #include "sysLib.h"
00051 #include "vme.h"
00052 #endif
00053
00054 #ifdef EXTERN_C_STD_HEADERS
00055 }
00056 #endif
00057
00058 #include "physmem.hh"
00059
00060 #if defined(__MSDOS__) && !defined(__WIN32__)
00061 #include "_physmem.h"
00062
00063 #endif
00064
00065
00066 #include "rcs_prnt.hh"
00067
00068
00069 PHYSMEM_HANDLE::PHYSMEM_HANDLE ()
00070 {
00071 size = 0;
00072 offset = 0;
00073 temp_buf = NULL;
00074 local_address = (LOCAL_ADDRESS_TYPE) NULL;
00075 physical_address = 0;
00076 using_bit3 = 0;
00077 isvalid = 1;
00078 #if defined(USE_BIT3) && defined(WIN32)
00079 swap_mode = 0;
00080 bt_lock_timeout = BT_FOREVER;
00081 bt_use_lock = 0;
00082 #endif
00083 total_bytes_moved = 0;
00084 enable_byte_counting = 0;
00085
00086 }
00087
00088 #if defined(USE_BIT3) && defined(WIN32)
00089
00090 PHYSMEM_HANDLE::PHYSMEM_HANDLE (bt_desc_t _btd, unsigned long _btd_offset,
00091 long _size, int _swap_mode)
00092 {
00093 size = _size;
00094 temp_buf = NULL;
00095 offset = 0;
00096 btd = _btd;
00097 btd_offset = _btd_offset;
00098 swap_mode = _swap_mode;
00099 using_bit3 = 1;
00100 local_address = (LOCAL_ADDRESS_TYPE) NULL;
00101 physical_address = 0;
00102 bt_lock_timeout = BT_FOREVER;
00103 bt_use_lock = 0;
00104 };
00105
00106 #endif
00107
00108 PHYSMEM_HANDLE::PHYSMEM_HANDLE (unsigned long _physical_address,
00109 long _address_code, long _size)
00110 {
00111 temp_buf = NULL;
00112 physical_address = _physical_address;
00113 size = _size;
00114 address_code = _address_code;
00115 local_address = (LOCAL_ADDRESS_TYPE) NULL;
00116 isvalid = 1;
00117 offset = 0;
00118 using_bit3 = 0;
00119 #if defined(USE_BIT3) && defined(WIN32)
00120 swap_mode = 0;
00121 bt_lock_timeout = BT_FOREVER;
00122 bt_use_lock = 0;
00123 #endif
00124
00125 if (0 == physical_address)
00126 {
00127 local_address = (LOCAL_ADDRESS_TYPE) NULL;
00128 return;
00129 }
00130 #ifdef VXWORKS
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 bus_address = (char *) physical_address;
00142 if (address_code != 0)
00143 {
00144 if (OK != sysBusToLocalAdrs (address_code,
00145 (char *) bus_address,
00146 (char **) &local_address))
00147 {
00148 rcs_print_error ("sysBusToLocalAdrs returned ERROR. %d %s\n",
00149 errno, strerror (errno));
00150 rcs_print_error ("Try changing vme_code=???");
00151 }
00152 }
00153 else
00154 {
00155 local_address = (char *) physical_address;
00156 }
00157 return;
00158 #endif
00159
00160
00161 #if defined(__MSDOS__) && !defined(__WIN32__)
00162 #if defined(_Windows)
00163 selector = 0;
00164 local_address =
00165 (LOCAL_ADDRESS_TYPE) create_ptr_to_physmem (physical_address, size,
00166 &selector);
00167 return;
00168 #else
00169 if (physical_address < 0x100000L)
00170 {
00171 local_address = (char RCS_FAR *) physical_address;
00172 }
00173 else
00174 {
00175 local_address = NULL;
00176 }
00177 return;
00178 #endif
00179 #endif
00180
00181 #if defined(WIN32) && !defined(gnuwin32) && !defined(UNDER_CE)
00182 if (using_bit3)
00183 {
00184 local_address = (char *) _physical_address;
00185 return;
00186 }
00187 DWORD cbReturned;
00188 ioport = 0;
00189 hMapMemDriver = NULL;
00190 hGenPortDriver = NULL;
00191 switch (address_code)
00192 {
00193 case NT_ISA_MEM_ADDRESS:
00194 pmi.InterfaceType = (INTERFACE_TYPE) Isa;
00195 pmi.AddressSpace = (LONG) 0;
00196 pmi.BusNumber = (ULONG) 0;
00197 pmi.BusAddress.HighPart = (LONG) 0x00000000;
00198 pmi.BusAddress.LowPart = (LONG) physical_address;
00199 pmi.Length = (LONG) size;
00200
00201
00202
00203
00204 hMapMemDriver = CreateFile (TEXT ("\\\\.\\MAPMEM"),
00205 GENERIC_READ | GENERIC_WRITE,
00206 0,
00207 NULL,
00208 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00209
00210 if (!hMapMemDriver)
00211 {
00212 rcs_print_error
00213 ("Can not open MAPMEM driver device. (Error = %d)\n",
00214 GetLastError ());
00215 local_address = NULL;
00216 isvalid = 0;
00217 return;
00218 }
00219
00220
00221 if (!DeviceIoControl (hMapMemDriver,
00222 (DWORD) IOCTL_MAPMEM_MAP_USER_PHYSICAL_MEMORY,
00223 &pmi,
00224 sizeof (PHYSICAL_MEMORY_INFO),
00225 &local_address, sizeof (PVOID), &cbReturned, 0))
00226 {
00227 rcs_print_error
00228 ("DeviceIoControl error accessing MAPMEM driver. (Error = %d)\n",
00229 GetLastError ());
00230 rcs_print_error
00231 ("PHYSMEM_HANDLE: Can not create handle to physical memory at 0x%X(%d) of 0x%X(%d) bytes.(address_code = %d)\n",
00232 physical_address, physical_address, size, size, address_code);
00233 local_address = NULL;
00234 isvalid = 0;
00235 return;
00236 }
00237 break;
00238
00239 case NT_ISA_IO_ADDRESS:
00240 hGenPortDriver = CreateFile ("\\\\.\\GpdDev",
00241 GENERIC_READ | GENERIC_WRITE,
00242 0, NULL, OPEN_EXISTING, 0, NULL);
00243
00244 if (hGenPortDriver == INVALID_HANDLE_VALUE)
00245 {
00246 rcs_print_error ("Unable to open the device.\n");
00247 local_address = NULL;
00248 ioport = 0;
00249 isvalid = 0;
00250 }
00251 ioport = (WORD) physical_address;
00252 break;
00253
00254 default:
00255 rcs_print_error ("PHYSMEM_HANDLE: Invalid address_code (%d)\n",
00256 address_code);
00257 isvalid = 0;
00258 return;
00259 }
00260
00261
00262
00263 return;
00264
00265 #endif
00266
00267 #ifdef lynxosPC
00268 sprintf (smem_name, "rcs_physmem%X", physical_address);
00269
00270
00271 smem_remove (smem_name);
00272
00273 if ((local_address = (void *)
00274 smem_create (smem_name, (char *) physical_address, size,
00275 SM_READ | SM_WRITE)) == NULL)
00276 {
00277 rcs_print_error ("can't get physical memory %X", physical_address);
00278 }
00279 return;
00280 #endif
00281
00282 #ifdef LINUX_VME
00283 {
00284 int fd = open ("/dev/mem", O_RDWR);
00285 if (fd < 0)
00286 {
00287 perror ("open /dev/mem");
00288 return;
00289 }
00290
00291
00292 local_address = (LOCAL_ADDRESS_TYPE) mmap (0, size,
00293 PROT_READ | PROT_WRITE,
00294 MAP_FILE | MAP_SHARED,
00295 fd, physical_address);
00296
00297
00298 close (fd);
00299 }
00300 #endif
00301
00302
00303
00304 #if !defined(__MSDOS__) && !defined(_Windows) && !defined(lynxosPC)
00305 local_address = (LOCAL_ADDRESS_TYPE) physical_address;
00306 #endif
00307
00308
00309 }
00310
00311
00312 PHYSMEM_HANDLE::~PHYSMEM_HANDLE ()
00313 {
00314 #ifdef WIN32
00315 #ifdef USING_BIT3
00316 if (using_bit3)
00317 {
00318 return;
00319 }
00320 #endif
00321 #if !defined(gnuwin32) && !defined(UNDER_CE)
00322 DWORD cbReturned;
00323 if (NULL != hMapMemDriver)
00324 {
00325 DeviceIoControl (hMapMemDriver,
00326 (DWORD) IOCTL_MAPMEM_UNMAP_USER_PHYSICAL_MEMORY,
00327 &pmi,
00328 sizeof (PHYSICAL_MEMORY_INFO),
00329 &local_address, sizeof (PVOID), &cbReturned, 0);
00330 CloseHandle (hMapMemDriver);
00331 hMapMemDriver = NULL;
00332 }
00333 if (NULL != hGenPortDriver)
00334 {
00335 CloseHandle (hGenPortDriver);
00336 hGenPortDriver = NULL;
00337 }
00338 #endif
00339 #endif
00340
00341 #ifdef WIN16
00342 if (selector)
00343 {
00344 FreeSelector (selector);
00345 selector = 0;
00346 }
00347 #endif
00348
00349 #ifdef lynxosPC
00350 smem_create ("", (char *) physical_address, (long int) 0, SM_DETACH);
00351 smem_remove (smem_name);
00352
00353 #endif
00354
00355 #ifdef LINUX_VME
00356 if (local_address != 0 && physical_address != 0)
00357 {
00358 munmap (local_address, size);
00359 }
00360 #endif
00361
00362 }
00363
00364
00365
00366 void
00367 PHYSMEM_HANDLE::set_to_ptr (void *_ptr, long _size)
00368 {
00369 local_address = (LOCAL_ADDRESS_TYPE) _ptr;
00370 size = _size;
00371 offset = 0;
00372 }
00373
00374 static int physmem_read_local_address_is_null_error_print_count = 0;
00375
00376
00377
00378
00379
00380 int
00381 PHYSMEM_HANDLE::read (void *_to, long _read_size)
00382 {
00383 if (NULL == _to)
00384 {
00385 rcs_print_error ("PHYSMEM_HANDLE::read _to = NULL.\n");
00386 return (-1);
00387 }
00388
00389 if (_read_size + offset > size)
00390 {
00391 rcs_print_error
00392 ("PHYSMEM_HANDLE: Can't read %ld bytes at offset %ld from buffer of size %ld.\n",
00393 _read_size, offset, size);
00394 return (-1);
00395 }
00396
00397 if (enable_byte_counting)
00398 {
00399 total_bytes_moved += _read_size;
00400 }
00401
00402 #ifdef USE_BIT3
00403 if (using_bit3)
00404 {
00405 if (swap_mode)
00406 {
00407
00408 if (bt_use_lock)
00409 {
00410 bt_status = bt_lock (btd, bt_lock_timeout);
00411 if (BT_SUCCESS != bt_status)
00412 {
00413 bt_perror (btd, bt_status,
00414 "Could not lock the Bit3 device. ");
00415 return (-1);
00416 }
00417 }
00418
00419
00420
00421 volatile char *fp = ((char *) local_address) + offset;
00422 volatile char *tp = (char *) _to;
00423 for (int i = 0; i < _read_size; i++)
00424 {
00425 *tp = *fp;
00426 tp++;
00427 fp++;
00428 }
00429
00430
00431 if (bt_use_lock)
00432 {
00433 bt_status = bt_unlock (btd);
00434 if (BT_SUCCESS != bt_status)
00435 {
00436 bt_perror (btd, bt_status,
00437 "Could not unlock the Bit3 device. ");
00438 return (-1);
00439 }
00440 }
00441
00442 return 0;
00443 }
00444 unsigned int bt_bytes_read;
00445 bt_devaddr_t transfer_addr = btd_offset + offset;
00446 bt_status =
00447 bt_read (btd, _to, transfer_addr, _read_size, &bt_bytes_read);
00448 if (BT_SUCCESS != bt_status)
00449 {
00450 bt_perror (btd, bt_status, " bt_read failed ");
00451 return (-1);
00452 }
00453 return (0);
00454 }
00455 #endif
00456
00457
00458 if (NULL != local_address)
00459 {
00460 char RCS_FAR *from;
00461 from = ((char *) local_address) + offset;
00462 if (_read_size == 2)
00463 {
00464 short *sfrom = (short *) from;
00465 short sval;
00466 sval = *sfrom;
00467 short *sto = (short *) _to;
00468 *sto = sval;
00469 }
00470 else
00471 {
00472 memcpy (_to, from, _read_size);
00473 }
00474 return (0);
00475 }
00476
00477
00478 #if defined(__MSDOS__) && !defined(__WIN32__)
00479 return (read_physmem (physical_address + offset, _to, _read_size));
00480 #endif
00481 #if defined(WIN32) && !defined(gnuwin32) && !defined(UNDER_CE)
00482 if (address_code == NT_ISA_IO_ADDRESS && ioport != 0)
00483 {
00484 return read_from_genport (_to, _read_size);
00485 }
00486 #endif
00487 if (!(physmem_read_local_address_is_null_error_print_count % 100000))
00488 {
00489 rcs_print_error
00490 ("PHYSMEM_HANDLE: Cannot read from physical memory when local address is NULL.\n");
00491 rcs_print_error ("(This error has occured %d times.)\n",
00492 physmem_read_local_address_is_null_error_print_count +
00493 1);
00494 }
00495 physmem_read_local_address_is_null_error_print_count++;
00496 return (-1);
00497 }
00498
00499 static int physmem_write_local_address_is_null_error_print_count = 0;
00500
00501
00502
00503
00504
00505 int
00506 PHYSMEM_HANDLE::write (void *_from, long _write_size)
00507 {
00508 if (NULL == _from)
00509 {
00510 rcs_print_error ("PHYSMEM_HANDLE:write _from = NULL\n");
00511 return -1;
00512 }
00513
00514
00515 if (_write_size + offset > size)
00516 {
00517 rcs_print_error
00518 ("PHYSMEM_HANDLE: Can't write %ld bytes at offset %ld from buffer of size %ld.\n",
00519 _write_size, offset, size);
00520 return (-1);
00521 }
00522 if (enable_byte_counting)
00523 {
00524 total_bytes_moved += _write_size;
00525 }
00526
00527
00528 #ifdef USE_BIT3
00529 if (using_bit3)
00530 {
00531 if (swap_mode)
00532 {
00533
00534 if (bt_use_lock)
00535 {
00536 bt_status = bt_lock (btd, bt_lock_timeout);
00537 if (BT_SUCCESS != bt_status)
00538 {
00539 bt_perror (btd, bt_status,
00540 "Could not lock the Bit3 device. ");
00541 return (-1);
00542 }
00543 }
00544
00545
00546
00547 volatile char *fp = (char *) _from;
00548 volatile char *tp = ((char *) local_address) + offset;
00549 for (int i = 0; i < _write_size; i++)
00550 {
00551 *tp = *fp;
00552 tp++;
00553 fp++;
00554 }
00555
00556
00557 if (bt_use_lock)
00558 {
00559 bt_status = bt_unlock (btd);
00560 if (BT_SUCCESS != bt_status)
00561 {
00562 bt_perror (btd, bt_status,
00563 "Could not unlock the Bit3 device. ");
00564 return (-1);
00565 }
00566 }
00567 return 0;
00568 }
00569 unsigned int bt_bytes_read;
00570 bt_devaddr_t transfer_addr = btd_offset + offset;
00571 bt_status =
00572 bt_write (btd, _from, transfer_addr, _write_size, &bt_bytes_read);
00573 if (BT_SUCCESS != bt_status)
00574 {
00575 bt_perror (btd, bt_status, " bt_write failed ");
00576 return (-1);
00577 }
00578 return (0);
00579 }
00580 #endif
00581
00582
00583 if (NULL != local_address)
00584 {
00585 char RCS_FAR *to;
00586 to = ((char *) local_address) + offset;
00587 if (_write_size == 2)
00588 {
00589 short *sto = (short *) to;
00590 short sval = *(short *) _from;
00591 *sto = sval;
00592 }
00593 else
00594 {
00595 memcpy (to, _from, _write_size);
00596 }
00597 return (0);
00598 }
00599
00600
00601 #if defined(__MSDOS__) && !defined(__WIN32__)
00602 return (write_physmem (physical_address + offset, _from, _write_size));
00603 #endif
00604 #if defined(WIN32) && !defined(gnuwin32) && !defined(UNDER_CE)
00605 if (address_code == NT_ISA_IO_ADDRESS && ioport != 0)
00606 {
00607 return write_to_genport (_from, _write_size);
00608 }
00609 #endif
00610 if (!(physmem_write_local_address_is_null_error_print_count % 100000))
00611 {
00612 rcs_print_error
00613 ("PHYSMEM_HANDLE: Cannot write to physical memory when local address is NULL.\n");
00614 rcs_print_error ("(This error has occured %d times.)\n",
00615 physmem_write_local_address_is_null_error_print_count +
00616 1);
00617 }
00618 physmem_write_local_address_is_null_error_print_count++;
00619 return (-1);
00620 }
00621
00622
00623 void
00624 PHYSMEM_HANDLE::memsetf (long _memset_offset, char _byte, long _memset_size)
00625 {
00626
00627 if (_memset_size + _memset_offset > size)
00628 {
00629 return;
00630 }
00631
00632
00633 if (NULL != local_address)
00634 {
00635 char *temp_addr;
00636 temp_addr = ((char *) local_address) + _memset_offset;
00637 memset (temp_addr, _byte, _memset_size);
00638 return;
00639 }
00640 else
00641 {
00642
00643
00644 if (NULL == temp_buf)
00645 {
00646 temp_buf = (char *) DEBUG_MALLOC (size);
00647 }
00648 if (NULL != temp_buf)
00649 {
00650 if (_memset_size + _memset_offset <= size)
00651 {
00652 memset (temp_buf, _byte, _memset_size);
00653 unsigned long old_offset;
00654 old_offset = offset;
00655 offset = _memset_offset;
00656 write (temp_buf, _memset_size);
00657 offset = old_offset;
00658 }
00659 else
00660 {
00661 memset (temp_buf, _byte, size - _memset_offset);
00662 unsigned long old_offset;
00663 old_offset = offset;
00664 offset = _memset_offset;
00665 write (temp_buf, size - offset);
00666 offset = old_offset;
00667 }
00668 }
00669 }
00670 }
00671
00672
00673
00674 int
00675 PHYSMEM_HANDLE::clear_memory ()
00676 {
00677
00678 if (NULL != local_address)
00679 {
00680 memset (local_address, 0, size);
00681 return (0);
00682 }
00683 else
00684 {
00685
00686
00687 if (NULL == temp_buf)
00688 {
00689 temp_buf = (char *) DEBUG_MALLOC (size);
00690 }
00691 if (NULL == temp_buf)
00692 {
00693 return (-1);
00694 }
00695 memset (temp_buf, 0, size);
00696 unsigned long old_offset;
00697 old_offset = offset;
00698 offset = 0;
00699 if (-1 == write (temp_buf, size))
00700 {
00701 offset = old_offset;
00702 return (-1);
00703 }
00704 offset = old_offset;
00705 }
00706 return (0);
00707 }
00708
00709 int
00710 PHYSMEM_HANDLE::valid ()
00711 {
00712 return isvalid;
00713 }
00714
00715 #if defined(WIN32) && !defined(gnuwin32) && !defined(UNDER_CE)
00716 int
00717 PHYSMEM_HANDLE::read_from_genport (void *_to, long _read_size)
00718 {
00719 int i;
00720
00721 if ((_read_size % 4) == 0 && ((ioport + offset) % 4) == 0)
00722 {
00723 for (i = 0; i < _read_size / 4; i++)
00724 {
00725 if (read_dword_from_genport (((DWORD *) _to) + i, offset + i * 4) <
00726 0)
00727 {
00728 return -1;
00729 }
00730 }
00731 return 0;
00732 }
00733 if ((_read_size % 2) == 0 && ((ioport + offset) % 2) == 0)
00734 {
00735 for (i = 0; i < _read_size / 2; i++)
00736 {
00737 if (read_word_from_genport (((WORD *) _to) + i, i * 2) < 0)
00738 {
00739 return -1;
00740 }
00741 }
00742 return 0;
00743 }
00744 for (i = 0; i < _read_size; i++)
00745 {
00746 if (read_byte_from_genport (((BYTE *) _to) + i, offset + i) < 0)
00747 {
00748 return -1;
00749 }
00750 }
00751 return 0;
00752 }
00753
00754 int
00755 PHYSMEM_HANDLE::read_dword_from_genport (DWORD * DataBuffer, ULONG PortNumber)
00756 {
00757
00758 BOOL IoctlResult;
00759
00760 DWORD ReturnedLength;
00761
00762 if (hGenPortDriver == NULL || DataBuffer == NULL)
00763 {
00764 return -1;
00765 }
00766
00767
00768 IoctlResult = DeviceIoControl (hGenPortDriver,
00769 IOCTL_GPD_READ_PORT_ULONG,
00770 &PortNumber,
00771 sizeof (PortNumber),
00772 DataBuffer,
00773 4,
00774 &ReturnedLength,
00775 NULL
00776 );
00777
00778 if (!IoctlResult)
00779 {
00780 rcs_print_error ("Read DWORD from IO port 0x%X failed.(Error = %ld)\n",
00781 PortNumber, GetLastError ());
00782 ioport = 0;
00783 return -1;
00784 }
00785 if (ReturnedLength != 4)
00786 {
00787 rcs_print_error
00788 ("GenPort driver returned %d bytes on port 0x%X when 4 were expected.\n",
00789 ReturnedLength, PortNumber);
00790 return -1;
00791 }
00792 return 0;
00793 }
00794
00795 int
00796 PHYSMEM_HANDLE::read_word_from_genport (WORD * DataBuffer, ULONG PortNumber)
00797 {
00798
00799 BOOL IoctlResult;
00800
00801 DWORD ReturnedLength;
00802
00803 if (hGenPortDriver == NULL || DataBuffer == NULL)
00804 {
00805 return -1;
00806 }
00807
00808
00809 IoctlResult = DeviceIoControl (hGenPortDriver,
00810 IOCTL_GPD_READ_PORT_USHORT,
00811 &PortNumber,
00812 sizeof (PortNumber),
00813 DataBuffer,
00814 2,
00815 &ReturnedLength,
00816 NULL
00817 );
00818
00819 if (!IoctlResult)
00820 {
00821 rcs_print_error ("Read WORD from IO port 0x%X failed.(Error = %ld)\n",
00822 PortNumber, GetLastError ());
00823 ioport = 0;
00824 return -1;
00825 }
00826 if (ReturnedLength != 2)
00827 {
00828 rcs_print_error
00829 ("GenPort driver returned %d bytes on port 0x%X when 2 were expected.\n",
00830 ReturnedLength, PortNumber);
00831 return -1;
00832 }
00833 return 0;
00834 }
00835
00836 int
00837 PHYSMEM_HANDLE::read_byte_from_genport (BYTE * DataBuffer, ULONG PortNumber)
00838 {
00839
00840 BOOL IoctlResult;
00841
00842 DWORD ReturnedLength;
00843
00844 if (hGenPortDriver == NULL || DataBuffer == NULL)
00845 {
00846 return -1;
00847 }
00848
00849
00850 IoctlResult = DeviceIoControl (hGenPortDriver,
00851 IOCTL_GPD_READ_PORT_UCHAR,
00852 &PortNumber,
00853 sizeof (PortNumber),
00854 DataBuffer,
00855 1,
00856 &ReturnedLength,
00857 NULL
00858 );
00859
00860 if (!IoctlResult)
00861 {
00862 rcs_print_error ("Read BYTE from IO port 0x%X failed.(Error = %ld)\n",
00863 PortNumber, GetLastError ());
00864 ioport = 0;
00865 return -1;
00866 }
00867 if (ReturnedLength != 1)
00868 {
00869 rcs_print_error
00870 ("GenPort driver returned %d bytes on port 0x%X when 2 were expected.\n",
00871 ReturnedLength, PortNumber);
00872 return -1;
00873 }
00874 return 0;
00875 }
00876
00877
00878 int
00879 PHYSMEM_HANDLE::write_to_genport (void *_from, long _write_size)
00880 {
00881 int i;
00882
00883 if ((_write_size % 4) == 0 && ((ioport + offset) % 4) == 0)
00884 {
00885 for (i = 0; i < _write_size / 4; i++)
00886 {
00887 if (write_dword_to_genport (((DWORD *) _from)[i], offset + i * 4) <
00888 0)
00889 {
00890 return -1;
00891 }
00892 }
00893 return 0;
00894 }
00895 if ((_write_size % 2) == 0 && ((ioport + offset) % 2) == 0)
00896 {
00897 for (i = 0; i < _write_size / 2; i++)
00898 {
00899 if (write_word_to_genport (((WORD *) _from)[i], offset + i * 2) < 0)
00900 {
00901 return -1;
00902 }
00903 }
00904 return 0;
00905 }
00906 for (i = 0; i < _write_size; i++)
00907 {
00908 if (write_byte_to_genport (((BYTE *) _from)[i], offset + i) < 0)
00909 {
00910 return -1;
00911 }
00912 }
00913 return 0;
00914 }
00915
00916
00917 int
00918 PHYSMEM_HANDLE::write_dword_to_genport (DWORD data, ULONG PortNumber)
00919 {
00920
00921 BOOL IoctlResult;
00922
00923 DWORD ReturnedLength;
00924
00925 if (hGenPortDriver == NULL)
00926 {
00927 return -1;
00928 }
00929 gpwi.PortNumber = PortNumber;
00930 gpwi.LongData = data;
00931
00932 IoctlResult = DeviceIoControl (hGenPortDriver,
00933 IOCTL_GPD_WRITE_PORT_ULONG,
00934 &gpwi,
00935 offsetof (GENPORT_WRITE_INPUT, LongData) +
00936 sizeof (gpwi.LongData),
00937 NULL,
00938 0,
00939 &ReturnedLength,
00940 NULL
00941 );
00942
00943 if (!IoctlResult)
00944 {
00945 rcs_print_error ("Write DWORD to IO port 0x%X failed.(Error = %d)\n",
00946 PortNumber, GetLastError ());
00947 ioport = 0;
00948 return -1;
00949 }
00950 return 0;
00951 }
00952
00953 int
00954 PHYSMEM_HANDLE::write_word_to_genport (WORD data, ULONG PortNumber)
00955 {
00956
00957 BOOL IoctlResult;
00958
00959 DWORD ReturnedLength;
00960
00961 if (hGenPortDriver == NULL)
00962 {
00963 return -1;
00964 }
00965 gpwi.PortNumber = PortNumber;
00966 gpwi.ShortData = data;
00967
00968 IoctlResult = DeviceIoControl (hGenPortDriver,
00969 IOCTL_GPD_WRITE_PORT_USHORT,
00970 &gpwi,
00971 offsetof (GENPORT_WRITE_INPUT, ShortData) +
00972 sizeof (gpwi.ShortData),
00973 NULL,
00974 0,
00975 &ReturnedLength,
00976 NULL
00977 );
00978
00979 if (!IoctlResult)
00980 {
00981 rcs_print_error ("Write WORD to IO port 0x%X failed. (Error = %d)\n",
00982 PortNumber, GetLastError ());
00983 ioport = 0;
00984 return -1;
00985 }
00986 return 0;
00987 }
00988
00989
00990 int
00991 PHYSMEM_HANDLE::write_byte_to_genport (BYTE data, ULONG PortNumber)
00992 {
00993
00994 BOOL IoctlResult;
00995
00996 DWORD ReturnedLength;
00997
00998 if (hGenPortDriver == NULL)
00999 {
01000 return -1;
01001 }
01002 gpwi.PortNumber = PortNumber;
01003 gpwi.CharData = data;
01004
01005 IoctlResult = DeviceIoControl (hGenPortDriver,
01006 IOCTL_GPD_WRITE_PORT_UCHAR,
01007 &gpwi,
01008 offsetof (GENPORT_WRITE_INPUT, CharData) +
01009 sizeof (gpwi.CharData),
01010 NULL,
01011 0,
01012 &ReturnedLength,
01013 NULL
01014 );
01015
01016 if (!IoctlResult)
01017 {
01018 rcs_print_error ("Write BYTE to IO port 0x%X failed. (Error = %d)\n",
01019 PortNumber, GetLastError ());
01020 ioport = 0;
01021 return -1;
01022 }
01023 return 0;
01024 }
01025
01026 #endif