Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

detectxp1541.c

Go to the documentation of this file.
00001 /*
00002  *      This program is free software; you can redistribute it and/or
00003  *      modify it under the terms of the GNU General Public License
00004  *      as published by the Free Software Foundation; either version
00005  *      2 of the License, or (at your option) any later version.
00006  *
00007  *  Copyright 2005 Spiro Trikaliotis
00008  *  Based on code by Wolfgang Moser
00009  *
00010 */
00011 
00023 #define DBG_USERMODE
00024 
00026 #define DBG_PROGNAME "OPENCBM.DLL"
00027 
00028 #include "debug.h"
00029 
00030 #include <stdlib.h>
00031 
00033 #define DLL
00034 #include "opencbm.h"
00035 #include "archlib.h"
00036 
00037 #include "arch.h"
00038 
00039 
00066 static int
00067 pia_to_inputmode(CBM_FILE HandleDevice, unsigned char Drive, unsigned int PiaAddress)
00068 {
00069     int ret = -1;
00070     unsigned char byteval = 0x00;
00071 
00072     FUNC_ENTER();
00073 
00074     if (cbm_upload(HandleDevice, Drive, PiaAddress + 2, &byteval, 1) == 1)
00075         ret = 0;
00076     else
00077         ret = 1;
00078 
00079     FUNC_LEAVE_INT(ret);
00080 }
00081 
00110 static int
00111 output_pia(CBM_FILE HandleDevice, unsigned char Drive, unsigned int PiaAddress, unsigned char Value)
00112 {
00113     int ret = -1;
00114 
00115     FUNC_ENTER();
00116 
00117     do {
00118         unsigned char byteval = 0xff;
00119 
00120         /*
00121          * Set the PIA port to output
00122          */
00123         if (cbm_upload(HandleDevice, Drive, PiaAddress + 2, &byteval, 1) != 1)
00124             break;
00125 
00126         /*
00127          * Output the value via the PIA port
00128          */
00129         if (cbm_upload(HandleDevice, Drive, PiaAddress , &Value, 1) != 1)
00130             break;
00131 
00132         /*
00133          * Give the drive time to be able to execute this command
00134          */
00135         arch_usleep(10000);
00136 
00137         /*
00138          * Read back the value. Hopefully, it is exactly what we just have written.
00139          */
00140         ret = cbm_pp_read(HandleDevice) != Value;
00141 
00142         if (ret)
00143         {
00144             /*
00145              * The test was unsuccessfull. To make sure the PIA
00146              * is not stuck at output mode, set it back to input mode.
00147              */
00148             pia_to_inputmode(HandleDevice, Drive, PiaAddress);
00149         }
00150 
00151     } while (0);
00152 
00153     FUNC_LEAVE_INT(ret);
00154 }
00155 
00187 int CBMAPIDECL 
00188 cbm_identify_xp1541(CBM_FILE HandleDevice, __u_char DeviceAddress,
00189                     enum cbm_device_type_e *CbmDeviceType,
00190                     enum cbm_cable_type_e *CableType)
00191 {
00192     int ret = 0;
00193     enum cbm_device_type_e localDummyDeviceType = cbm_dt_unknown;
00194 
00195     FUNC_ENTER();
00196  
00197     do
00198     {
00199         unsigned int piaAddress;
00200         int value;
00201 
00202         if (!CableType)
00203         {
00204             /*
00205              * We do not have a possibility to send back the
00206              * cable type: This is an error!
00207              */
00208             DBG_ASSERT(("CableType is NULL", 0));
00209             ret = 1;
00210             break;
00211         }
00212 
00213         *CableType = cbm_ct_none;
00214 
00215         /*
00216          * If needed, determine the type of the drive
00217          */
00218         if (!CbmDeviceType)
00219             CbmDeviceType = &localDummyDeviceType;
00220 
00221         if (*CbmDeviceType == cbm_dt_unknown)
00222         {
00223             ret = cbm_identify(HandleDevice, DeviceAddress,
00224                  CbmDeviceType, NULL);
00225         }
00226 
00227         if (ret)
00228         {
00229             /*
00230              * We could not even determine the device type;
00231              * we do not dare trying to determine the cable
00232              * type, as writing into wrong locations can
00233              * make the drive hang.
00234              */
00235             *CableType = cbm_ct_unknown;
00236             break;
00237         }
00238 
00239         /*
00240          * Now that we know the drive type, use this to find the PIA/VIA/CIA address
00241          */
00242         switch (*CbmDeviceType)
00243         {
00244         case cbm_dt_cbm1541:
00245             piaAddress = 0x1801;
00246             break;
00247 
00248         case cbm_dt_cbm1570:
00249         case cbm_dt_cbm1571:
00250             piaAddress = 0x4001;
00251             break;
00252 
00253         default:
00254             piaAddress = 0;
00255             break;
00256         }
00257 
00258         /*
00259          * If we do not have a PIA address, we do not know where a parallel
00260          * cable could be located. This, report "no parallel cable".
00261          */
00262         if (piaAddress == 0)
00263             break;
00264 
00265         /*
00266          * Set parallel port into input mode.
00267          * This prevents us (PC) and the drive driving the lines simultaneously.
00268          */
00269         value = cbm_pp_read(HandleDevice);
00270         DBG_PRINT((DBG_PREFIX "Setting Parport into input mode", value));
00271 
00272         /*
00273          * Try to write some patterns and check if we see them:
00274          */
00275         if (output_pia(HandleDevice, DeviceAddress, piaAddress, 0x55))
00276             break;
00277 
00278         if (output_pia(HandleDevice, DeviceAddress, piaAddress, 0xAA))
00279             break;
00280 
00281         /*
00282          * Ok, it has worked: We have a parallel cable.
00283          */
00284         *CableType = cbm_ct_xp1541;
00285 
00286         /*
00287          * Set PIA back to input mode.
00288          * Again, this prevents PC and drive driving the lines simultaneously
00289          * (in the future).
00290          */
00291         if (piaAddress)
00292         {
00293             pia_to_inputmode(HandleDevice, DeviceAddress, piaAddress);
00294         }
00295 
00296     } while (0);
00297 
00298     FUNC_LEAVE_INT(ret);
00299 }

Generated on Sun Apr 30 18:45:48 2006 for opencbm by  doxygen 1.4.2