00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00021 #include <windows.h>
00022 #include <windowsx.h>
00023
00024 #include <mmsystem.h>
00025
00027 #define DBG_USERMODE
00028
00030 #define DBG_DLL
00031
00033 #define DBG_PROGNAME "OPENCBM.DLL"
00034
00036 #define DBG_IS_DEBUG_C
00037
00038 #include "debug.h"
00039
00040 #include <winioctl.h>
00041 #include "cbmioctl.h"
00042
00043 #include <stdlib.h>
00044
00046 #define DLL
00047 #include "i_opencbm.h"
00048 #include "archlib.h"
00049
00050
00072 static void
00073 fastschedule_start(void)
00074 {
00075 FUNC_ENTER();
00076
00077 if (timeBeginPeriod(1) != TIMERR_NOERROR)
00078 {
00079 DBG_WARN((DBG_PREFIX "Unable to decrease scheduling period."));
00080 }
00081
00082 FUNC_LEAVE();
00083 }
00084
00090 static void
00091 fastschedule_stop(void)
00092 {
00093 FUNC_ENTER();
00094
00095 if (timeEndPeriod(1) != TIMERR_NOERROR)
00096 {
00097 DBG_WARN((DBG_PREFIX "Unable to restore scheduling period."));
00098 }
00099
00100 FUNC_LEAVE();
00101 }
00102
00103
00128 BOOL
00129 opencbm_init(IN HANDLE Module, IN DWORD Reason, IN LPVOID Reserved)
00130 {
00131 static BOOL bIsOpen = FALSE;
00132 BOOLEAN Status = TRUE;
00133
00134 FUNC_ENTER();
00135
00136 #if DBG
00137
00138 if (Reason == DLL_PROCESS_ATTACH)
00139 {
00140
00141
00142 cbm_i_get_debugging_flags();
00143 }
00144
00145 #endif
00146
00147
00148
00149
00150
00151
00152
00153 DBG_ASSERT(IEC_LINE_CLOCK == IEC_CLOCK);
00154 DBG_ASSERT(IEC_LINE_RESET == IEC_RESET);
00155 DBG_ASSERT(IEC_LINE_DATA == IEC_DATA);
00156 DBG_ASSERT(IEC_LINE_ATN == IEC_ATN);
00157
00158 switch (Reason)
00159 {
00160 case DLL_PROCESS_ATTACH:
00161
00162 if (IsDriverStartedAutomatically())
00163 {
00164
00165
00166
00167 Status = TRUE;
00168 }
00169 else
00170 {
00171 if (bIsOpen)
00172 {
00173 DBG_ERROR((DBG_PREFIX "No multiple instances are allowed!"));
00174 Status = FALSE;
00175 }
00176 else
00177 {
00178 Status = TRUE;
00179 bIsOpen = cbm_i_driver_start();
00180 }
00181 }
00182
00183
00184 if (Status)
00185 {
00186 fastschedule_start();
00187 }
00188 break;
00189
00190 case DLL_PROCESS_DETACH:
00191
00192 if (IsDriverStartedAutomatically())
00193 {
00194
00195
00196
00197 Status = TRUE;
00198 }
00199 else
00200 {
00201 if (!bIsOpen)
00202 {
00203 DBG_ERROR((DBG_PREFIX "Driver is not running!"));
00204 Status = FALSE;
00205 }
00206 else
00207 {
00208
00209
00210
00211 cbm_i_driver_stop();
00212 bIsOpen = FALSE;
00213 }
00214 }
00215
00216
00217 if (Status)
00218 {
00219 fastschedule_stop();
00220 }
00221 break;
00222
00223 default:
00224 break;
00225
00226 }
00227
00228 FUNC_LEAVE_BOOL(Status);
00229 }
00230
00250 BOOL CBMAPIDECL
00251 cbm_i_driver_install(OUT PULONG Buffer, IN ULONG BufferLen)
00252 {
00253 FUNC_ENTER();
00254
00255 FUNC_LEAVE_INT(cbm_i_i_driver_install(Buffer, BufferLen));
00256 }
00257
00258
00283 void
00284 cbmarch_lock(CBM_FILE HandleDevice)
00285 {
00286 FUNC_ENTER();
00287
00288 cbm_ioctl(HandleDevice, CBMCTRL(PARPORT_LOCK), NULL, 0, NULL, 0);
00289
00290 FUNC_LEAVE();
00291 }
00292
00310 void
00311 cbmarch_unlock(CBM_FILE HandleDevice)
00312 {
00313 FUNC_ENTER();
00314
00315 cbm_ioctl(HandleDevice, CBMCTRL(PARPORT_UNLOCK), NULL, 0, NULL, 0);
00316
00317 FUNC_LEAVE();
00318 }
00319
00344 int
00345 cbmarch_raw_write(CBM_FILE HandleDevice, const void *Buffer, size_t Count)
00346 {
00347 DWORD BytesWritten;
00348
00349 FUNC_ENTER();
00350
00351 WriteFile(
00352 HandleDevice,
00353 Buffer,
00354 Count,
00355 &BytesWritten,
00356 NULL
00357 );
00358
00359 FUNC_LEAVE_INT(BytesWritten);
00360 }
00361
00385 int
00386 cbmarch_raw_read(CBM_FILE HandleDevice, void *Buffer, size_t Count)
00387 {
00388 DWORD bytesToRead = Count;
00389 DWORD bytesRead;
00390
00391 FUNC_ENTER();
00392
00393 ReadFile(
00394 HandleDevice,
00395 Buffer,
00396 bytesToRead,
00397 &bytesRead,
00398 NULL
00399 );
00400
00401 FUNC_LEAVE_INT(bytesRead);
00402 }
00403
00404
00405
00429 int
00430 cbmarch_listen(CBM_FILE HandleDevice, __u_char DeviceAddress, __u_char SecondaryAddress)
00431 {
00432 CBMT_LISTEN_IN parameter;
00433 int returnValue;
00434
00435 FUNC_ENTER();
00436
00437 parameter.PrimaryAddress = DeviceAddress;
00438 parameter.SecondaryAddress = SecondaryAddress;
00439
00440 returnValue = cbm_ioctl(HandleDevice, CBMCTRL(LISTEN), ¶meter, sizeof(parameter), NULL, 0)
00441 ? 0 : 1;
00442
00443 FUNC_LEAVE_INT(returnValue);
00444 }
00445
00469 int
00470 cbmarch_talk(CBM_FILE HandleDevice, __u_char DeviceAddress, __u_char SecondaryAddress)
00471 {
00472 CBMT_TALK_IN parameter;
00473 int returnValue;
00474
00475 FUNC_ENTER();
00476
00477 parameter.PrimaryAddress = DeviceAddress;
00478 parameter.SecondaryAddress = SecondaryAddress;
00479
00480 returnValue = cbm_ioctl(HandleDevice, CBMCTRL(TALK), ¶meter, sizeof(parameter), NULL, 0)
00481 ? 0 : 1;
00482
00483 FUNC_LEAVE_INT(returnValue);
00484 }
00485
00507 int
00508 cbmarch_open(CBM_FILE HandleDevice, __u_char DeviceAddress, __u_char SecondaryAddress)
00509 {
00510 CBMT_OPEN_IN parameter;
00511 int returnValue;
00512
00513 FUNC_ENTER();
00514
00515 parameter.PrimaryAddress = DeviceAddress;
00516 parameter.SecondaryAddress = SecondaryAddress;
00517
00518 if (cbm_ioctl(HandleDevice, CBMCTRL(OPEN), ¶meter, sizeof(parameter), NULL, 0))
00519 {
00520 returnValue = 0;
00521 }
00522 else
00523 {
00524 returnValue = -1;
00525 }
00526
00527 FUNC_LEAVE_INT(returnValue);
00528 }
00529
00551 int
00552 cbmarch_close(CBM_FILE HandleDevice, __u_char DeviceAddress, __u_char SecondaryAddress)
00553 {
00554 CBMT_CLOSE_IN parameter;
00555 int returnValue;
00556
00557 FUNC_ENTER();
00558
00559 parameter.PrimaryAddress = DeviceAddress;
00560 parameter.SecondaryAddress = SecondaryAddress;
00561
00562 returnValue =
00563 cbm_ioctl(HandleDevice, CBMCTRL(CLOSE), ¶meter, sizeof(parameter), NULL, 0)
00564 ? 0 : 1;
00565
00566 FUNC_LEAVE_INT(returnValue);
00567 }
00568
00589 int
00590 cbmarch_unlisten(CBM_FILE HandleDevice)
00591 {
00592 int returnValue;
00593
00594 FUNC_ENTER();
00595
00596 returnValue = cbm_ioctl(HandleDevice, CBMCTRL(UNLISTEN), NULL, 0, NULL, 0) ? 0 : 1;
00597
00598 FUNC_LEAVE_INT(returnValue);
00599 }
00600
00621 int
00622 cbmarch_untalk(CBM_FILE HandleDevice)
00623 {
00624 int returnValue;
00625
00626 FUNC_ENTER();
00627
00628 returnValue = cbm_ioctl(HandleDevice, CBMCTRL(UNTALK), NULL, 0, NULL, 0) ? 0 : 1;
00629
00630 FUNC_LEAVE_INT(returnValue);
00631 }
00632
00633
00654 int
00655 cbmarch_get_eoi(CBM_FILE HandleDevice)
00656 {
00657 CBMT_GET_EOI_OUT result;
00658
00659 FUNC_ENTER();
00660
00661 cbm_ioctl(HandleDevice, CBMCTRL(GET_EOI), NULL, 0, &result, sizeof(result));
00662
00663 FUNC_LEAVE_INT(result.Decision);
00664 }
00665
00681 int
00682 cbmarch_clear_eoi(CBM_FILE HandleDevice)
00683 {
00684 int returnValue;
00685
00686 FUNC_ENTER();
00687
00688 returnValue = cbm_ioctl(HandleDevice, CBMCTRL(CLEAR_EOI), NULL, 0, NULL, 0);
00689
00690 FUNC_LEAVE_INT(returnValue);
00691 }
00692
00714 int
00715 cbmarch_reset(CBM_FILE HandleDevice)
00716 {
00717 USHORT returnValue;
00718
00719 FUNC_ENTER();
00720
00721 returnValue = cbm_ioctl(HandleDevice, CBMCTRL(RESET), NULL, 0, NULL, 0) ? 0 : 1;
00722
00723 FUNC_LEAVE_INT(returnValue);
00724 }
00725
00726
00727
00728
00729
00751 __u_char
00752 cbmarch_pp_read(CBM_FILE HandleDevice)
00753 {
00754 CBMT_PP_READ_OUT result;
00755
00756 FUNC_ENTER();
00757
00758 cbm_ioctl(HandleDevice, CBMCTRL(PP_READ), NULL, 0, &result, sizeof(result));
00759
00760 FUNC_LEAVE_UCHAR(result.Byte);
00761 }
00762
00786 void
00787 cbmarch_pp_write(CBM_FILE HandleDevice, __u_char Byte)
00788 {
00789 CBMT_PP_WRITE_IN parameter;
00790
00791 FUNC_ENTER();
00792
00793 parameter.Byte = Byte;
00794
00795 cbm_ioctl(HandleDevice, CBMCTRL(PP_WRITE), ¶meter, sizeof(parameter), NULL, 0);
00796
00797 FUNC_LEAVE();
00798 }
00799
00821 int
00822 cbmarch_iec_poll(CBM_FILE HandleDevice)
00823 {
00824 CBMT_IEC_POLL_OUT result;
00825
00826 FUNC_ENTER();
00827
00828 cbm_ioctl(HandleDevice, CBMCTRL(IEC_POLL), NULL, 0, &result, sizeof(result));
00829
00830 FUNC_LEAVE_INT(result.Line);
00831 }
00832
00833
00852 void
00853 cbmarch_iec_set(CBM_FILE HandleDevice, int Line)
00854 {
00855 CBMT_IEC_SET_IN parameter;
00856
00857 FUNC_ENTER();
00858
00859 parameter.Line = (UCHAR) Line;
00860
00861 cbm_ioctl(HandleDevice, CBMCTRL(IEC_SET), ¶meter, sizeof(parameter), NULL, 0);
00862
00863 FUNC_LEAVE();
00864 }
00865
00884 void
00885 cbmarch_iec_release(CBM_FILE HandleDevice, int Line)
00886 {
00887 CBMT_IEC_RELEASE_IN parameter;
00888
00889 FUNC_ENTER();
00890
00891 parameter.Line = (UCHAR) Line;
00892
00893 cbm_ioctl(HandleDevice, CBMCTRL(IEC_RELEASE), ¶meter, sizeof(parameter), NULL, 0);
00894
00895 FUNC_LEAVE();
00896 }
00897
00925 void
00926 cbmarch_iec_setrelease(CBM_FILE HandleDevice, int Set, int Release)
00927 {
00928 CBMT_IEC_SETRELEASE_IN parameter;
00929
00930 FUNC_ENTER();
00931
00932 parameter.State = (UCHAR) Set;
00933 parameter.Line = (UCHAR) Release;
00934
00935 cbm_ioctl(HandleDevice, CBMCTRL(IEC_SETRELEASE), ¶meter, sizeof(parameter), NULL, 0);
00936
00937 FUNC_LEAVE();
00938 }
00939
00966 int
00967 cbmarch_iec_wait(CBM_FILE HandleDevice, int Line, int State)
00968 {
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984 int state;
00985
00986 FUNC_ENTER();
00987 if (State)
00988 {
00989 while((state = cbm_iec_get(HandleDevice, Line)) == 0)
00990 ;
00991 }
00992 else
00993 {
00994 while((state = cbm_iec_get(HandleDevice, Line)) != 0)
00995 ;
00996 }
00997
00998 FUNC_LEAVE_INT(state);
00999 }
01000
01001 #if DBG
01002
01011 int CBMAPIDECL
01012 cbm_get_debugging_buffer(CBM_FILE HandleDevice, char *buffer, size_t len)
01013 {
01014 FUNC_ENTER();
01015
01016 cbm_ioctl(HandleDevice, CBMCTRL(I_READDBG), NULL, 0, buffer, len);
01017
01018 FUNC_LEAVE_INT(0);
01019 }
01020
01021 #endif // #if DBG