From 70b8b7f2d766f4ca131f9fa299546eb3697db8d4 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Thu, 23 Mar 2017 20:42:26 +0100 Subject: changed scheme layout hw: changed scheme and annotated components doc: added build script for windows sw: added res/ folder with blaster and created jedec document for address decoder pld --- res/ATFBlast_ALL/ATFblast.TIF | Bin 0 -> 19566 bytes res/ATFBlast_ALL/ATFblast.pcb | Bin 0 -> 65534 bytes res/ATFBlast_ALL/AtfBlast.exe | Bin 0 -> 80384 bytes res/ATFBlast_ALL/AtfBlast_board_bottom.pdf | Bin 0 -> 11891 bytes res/ATFBlast_ALL/AtfBlast_board_top.pdf | Bin 0 -> 17259 bytes res/ATFBlast_ALL/AtfBlast_sch.pdf | Bin 0 -> 30668 bytes res/ATFBlast_ALL/direct.gif | Bin 0 -> 43180 bytes res/ATFBlast_ALL/program.htm | 636 +++++++++++++++++++++ .../userport/UserPort/Examples/IOPort.c | 76 +++ .../userport/UserPort/Examples/IOPort.h | 18 + .../userport/UserPort/Examples/IOPort.pas | 72 +++ res/ATFBlast_ALL/userport/UserPort/UserPort.exe | Bin 0 -> 11776 bytes res/ATFBlast_ALL/userport/UserPort/UserPort.pdf | Bin 0 -> 13959 bytes res/ATFBlast_ALL/userport/UserPort/UserPort.sys | Bin 0 -> 4256 bytes .../userport/UserPort/UserPort_EXE/Resource.h | 30 + .../userport/UserPort/UserPort_EXE/UserPort.c | 512 +++++++++++++++++ .../userport/UserPort/UserPort_EXE/UserPort.ico | Bin 0 -> 766 bytes .../userport/UserPort/UserPort_EXE/UserPort.mak | 240 ++++++++ .../userport/UserPort/UserPort_EXE/UserPort.mdp | Bin 0 -> 35328 bytes .../userport/UserPort/UserPort_EXE/UserPort.rc | 130 +++++ .../userport/UserPort/UserPort_SYS/Makefile | 7 + .../userport/UserPort/UserPort_SYS/Sources | 7 + .../userport/UserPort/UserPort_SYS/UserPort.C | 312 ++++++++++ res/ATFBlast_ALL/userport/Win_XP.txt | 25 + 24 files changed, 2065 insertions(+) create mode 100644 res/ATFBlast_ALL/ATFblast.TIF create mode 100644 res/ATFBlast_ALL/ATFblast.pcb create mode 100644 res/ATFBlast_ALL/AtfBlast.exe create mode 100644 res/ATFBlast_ALL/AtfBlast_board_bottom.pdf create mode 100644 res/ATFBlast_ALL/AtfBlast_board_top.pdf create mode 100644 res/ATFBlast_ALL/AtfBlast_sch.pdf create mode 100644 res/ATFBlast_ALL/direct.gif create mode 100644 res/ATFBlast_ALL/program.htm create mode 100644 res/ATFBlast_ALL/userport/UserPort/Examples/IOPort.c create mode 100644 res/ATFBlast_ALL/userport/UserPort/Examples/IOPort.h create mode 100644 res/ATFBlast_ALL/userport/UserPort/Examples/IOPort.pas create mode 100644 res/ATFBlast_ALL/userport/UserPort/UserPort.exe create mode 100644 res/ATFBlast_ALL/userport/UserPort/UserPort.pdf create mode 100644 res/ATFBlast_ALL/userport/UserPort/UserPort.sys create mode 100644 res/ATFBlast_ALL/userport/UserPort/UserPort_EXE/Resource.h create mode 100644 res/ATFBlast_ALL/userport/UserPort/UserPort_EXE/UserPort.c create mode 100644 res/ATFBlast_ALL/userport/UserPort/UserPort_EXE/UserPort.ico create mode 100644 res/ATFBlast_ALL/userport/UserPort/UserPort_EXE/UserPort.mak create mode 100644 res/ATFBlast_ALL/userport/UserPort/UserPort_EXE/UserPort.mdp create mode 100644 res/ATFBlast_ALL/userport/UserPort/UserPort_EXE/UserPort.rc create mode 100644 res/ATFBlast_ALL/userport/UserPort/UserPort_SYS/Makefile create mode 100644 res/ATFBlast_ALL/userport/UserPort/UserPort_SYS/Sources create mode 100644 res/ATFBlast_ALL/userport/UserPort/UserPort_SYS/UserPort.C create mode 100644 res/ATFBlast_ALL/userport/Win_XP.txt (limited to 'res/ATFBlast_ALL') diff --git a/res/ATFBlast_ALL/ATFblast.TIF b/res/ATFBlast_ALL/ATFblast.TIF new file mode 100644 index 0000000..b582a5b Binary files /dev/null and b/res/ATFBlast_ALL/ATFblast.TIF differ diff --git a/res/ATFBlast_ALL/ATFblast.pcb b/res/ATFBlast_ALL/ATFblast.pcb new file mode 100644 index 0000000..21e6f17 Binary files /dev/null and b/res/ATFBlast_ALL/ATFblast.pcb differ diff --git a/res/ATFBlast_ALL/AtfBlast.exe b/res/ATFBlast_ALL/AtfBlast.exe new file mode 100644 index 0000000..e4582fa Binary files /dev/null and b/res/ATFBlast_ALL/AtfBlast.exe differ diff --git a/res/ATFBlast_ALL/AtfBlast_board_bottom.pdf b/res/ATFBlast_ALL/AtfBlast_board_bottom.pdf new file mode 100644 index 0000000..f08d5ec Binary files /dev/null and b/res/ATFBlast_ALL/AtfBlast_board_bottom.pdf differ diff --git a/res/ATFBlast_ALL/AtfBlast_board_top.pdf b/res/ATFBlast_ALL/AtfBlast_board_top.pdf new file mode 100644 index 0000000..2ae18a2 Binary files /dev/null and b/res/ATFBlast_ALL/AtfBlast_board_top.pdf differ diff --git a/res/ATFBlast_ALL/AtfBlast_sch.pdf b/res/ATFBlast_ALL/AtfBlast_sch.pdf new file mode 100644 index 0000000..f8705ff Binary files /dev/null and b/res/ATFBlast_ALL/AtfBlast_sch.pdf differ diff --git a/res/ATFBlast_ALL/direct.gif b/res/ATFBlast_ALL/direct.gif new file mode 100644 index 0000000..7d4fcca Binary files /dev/null and b/res/ATFBlast_ALL/direct.gif differ diff --git a/res/ATFBlast_ALL/program.htm b/res/ATFBlast_ALL/program.htm new file mode 100644 index 0000000..b91db8d --- /dev/null +++ b/res/ATFBlast_ALL/program.htm @@ -0,0 +1,636 @@ + + + + +Minimum effort GAL programming + + + + +

Minimum effort GAL programming

+

This document describes how to program the GAL chips 16V8/A/B/C/D/Z/ZD, 18V10/B, 20V8/A/B/Z, 20RA10/B, 20XV10/B, 22V10/B/C/Z, 26CV12/B, 6001/B, and 6002B from Lattice, National Semiconductors and STMicrosystems with minimal effort.

+

You need

+
IC socket matching GAL
+
some 4k7 resistors 0.25W
+
100nF ceramic capacitor
+
SubD 25 pin male connector
+
some 4" short patch cables
+
5V/250mA and adjustable 8.5-16.5V/20mA laboratory power supply
+

Pin assignment of the different GAL chips during programming

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

 

+

GAL
+
+Pin

+

16V8

+

18V10

+

20V8

+

22V10
+20XV10
+20RA10

+

6001
+6002

+

26CV12

+

 

+

1(2)

+

VIL

+

VIL

+

VIL

+

VIL

+

VIL

+

VIL

+

 

+

2(3)

+

EDIT

+

EDIT

+

EDIT

+

EDIT

+

EDIT

+

EDIT

+

 

+

3(4)

+

RA1

+

RA3

+

RA1

+

P/V-

+

VIL

+

P/V-

+

 

+

4(5)

+

RA2

+

RA4

+

RA2

+

RA0

+

RA0

+

RA0

+

 

+

5(6)

+

RA3

+

RA5

+

RA3

+

RA1

+

RA1

+

RA1

+

 

+

6(7)

+

RA4

+

SCLK

+

VIL

+

RA2

+

RA2

+

RA2

+

 

+

7(9)

+

RA5

+

SDIN

+

VIL

+

RA3

+

RA3

+

VCC

+

 

+

8(10)

+

SCLK

+

STB-

+

RA4

+

RA4

+

RA4

+

VIL

+

 

+

9(11)

+

SDIN

+

SDOUT

+

RA5

+

RA5

+

RA5

+

RA3

+

 

+

10(12)

+

GND

+

GND

+

SCLK

+

SCLK

+

SCLK

+

RA4

+

 

+

11(13)

+

STB-

+

VIL

+

SDIN

+

SDIN

+

SDIN

+

RA5

+

 

+

12(14)

+

SDOUT

+

VIL

+

GND

+

GND

+

GND

+

SCLK

+

 

+

13(16)

+

VIL

+

VIL

+

STB-

+

STB-

+

STB-

+

SDIN

+

 

+

14(17)

+

VIL

+

VIL

+

VIL

+

SDOUT

+

SDOUT

+

STB-

+

 

+

15(18)

+

VIL

+

VIL

+

SDOUT

+

VIL

+

VIL

+

SDOUT

+

 

+

16(19)

+

VIL

+

RA2

+

VIL

+

VIL

+

VIL

+

VIL

+

 

+

17(20)

+

VIL

+

RA1

+

VIL

+

VIL

+

VIL

+

VIL

+

 

+

18(21)

+

RA0

+

RA0

+

VIL

+

VIL

+

VIL

+

VIL

+

 

+

19(23)

+

P/V-

+

P/V-

+

VIL

+

VIL

+

VIL

+

VIL

+

 

+

20(24)

+

VCC

+

VCC

+

VIL

+

VIL

+

VIL

+

VIL

+

 

+

21(25)

+

 

+

 

+

RA0

+

VIL

+

VIL

+

GND

+

 

+

22(26)

+

 

+

 

+

P/V-

+

VIL

+

VIL

+

VIL

+

 

+

23(27)

+

 

+

 

+

VIL

+

VIL

+

P/V-

+

VIL

+

 

+

24(28)

+

 

+

 

+

VCC

+

VCC

+

VCC

+

VIL

+

 

+

25

+

 

+

 

+

 

+

 

+

 

+

VIL

+

 

+

26

+

 

+

 

+

 

+

 

+

 

+

VIL

+

 

+

27

+

 

+

 

+

 

+

 

+

 

+

VIL

+

 

+

28

+

 

+

 

+

 

+

 

+

 

+

VIL

+ +

PLCC28 pin numbers of DIL24 chips in paranthesis

+

Wiring

+

Use 4k7 resistors to connect all VIL pins to the GND pin (we use 4k7 instead of the 10k mentioned in other documents, because some GALs have internal pull-ups of only 50k and illegal input states would occur using 10k resistors). Use 4k7 resistors to connect all other pins (including GND and EDIT) to the VCC pin to prevent open inputs during programming. Connect a 100nF ceramic capacitor between GND and VCC. If you use a GAL with built-in pull-ups, it is possible to go without the resistors, but I would not spare the 100nF capacitor and the pull-up on STB-. Do not try to program Normal GALs without the pull-ups on SCLK, SDIN, P/V, SDOUT, as the pulse rise time would be too slow without pull-ups to cope with the speed of the GALBlast program handling the LPT port.

+

+

Use short (max. length 4") wires to connect all pins mentioned below to the SubD 25 parallel printer port connector.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

 

+

SubD25 pin

+

GAL

+

 

+

1 (/STB):

+

STB-

+

 

+

2 (D0):

+

SDIN

+

 

+

3 (D1):

+

RA0

+

 

+

4 (D2):

+

RA1

+

 

+

5 (D3):

+

RA2

+

 

+

6 (D4):

+

RA3

+

 

+

7 (D5):

+

RA4

+

 

+

8 (D6):

+

RA5

+

 

+

9 (D7):

+

SCLK

+

 

+

10 (/ACK):

+

SDOUT

+

 

+

17 (/SELIN):

+

P/V-

+

 

+

25 (GND):

+

GND

+ +

This arrangement was choosen so that an uninitialized port cannot affect the GAL.

+

Programming

+

Insert the GAL into the socket. Connect GND and VCC to the +5V output of a laboratory power supply. Connect GND and EDIT to an output of the power supply adjusted to +12V.

+

Launch the GALBlast program and select the parallel printer port used. Load the JEDEC file, the required GAL type should be automatically selected. Plug the SubD25 connector into the printer port, and issue the 'Write GAL' command. The PES of the GAL is read out and the required programming voltage will be displayed. Adjust the power supply to the required programming voltage (without overshoot, or disconnect first the SubD25, than the programming voltage, while adjusting) and continue with 'Write GAL'. Remove the SubD25 plug, turn off the programming voltage, turn off the power supply and remove the GAL from the socket.

+

--That's all --

+

Alternatives

+

If this method appears to risky, you may buffer the signals SCLK,RA0..RA5,STB-,P/V-,SDIN using two hex open collector driver ICs 7417 and 4k7 pull ups to VCC, and buffer SDOUT (4k7 pull up to VCC required) using the same chip before it connects to pin 17 (ACK-) of the parallel connector (4k7 pull up to +5V required). This way all GAL pins are electrically disconnected from the PC parallel port and the GAL may be turned off by removing VCC. Furthermore a D/A converter like the AD7524 can be used to select the programming voltage, if its inputs DB0..DB7 are connected to d0..d7 of the parallel port and WR- connects to pin 16 (FEED-), because the GALBlast program will output the required programming voltage (in 0.09375 volt increments if uncalibrated) to d0..d7 and pulls FEED- for a short time to L before ist starts talking to the GAL. Use an op-amp like the CA3140 to amplify the small output voltage (0 to 2.5V) to the required range (0 to 24V). The VCC power supply of the GAL may be controlled by a 5V SPST reed relay driven by INIT- of the parallel port, because the GALBlast program will take this line to L when it talks to the GAL.

+

AD7524

+

The AD7524 8 bit D/A converter from Analog Devices has been selected because it is wildely available and second sourced (MX7524 from Maxim, TLC7524 from Texas Instruments). The data sheet is available at http://www.analog.com/. The required reference voltage is generated using a 2.5V voltage reference like the LM336Z2.5 (data sheet at http://www.nsc.com). A 4n7 capacitor is used to filter spikes durings changes in the voltage setup completely to prevent the destruction of the GAL chip. You may use an other 8 bit latched DAC like the ZN428 (data sheet at http://www.mitelsemi.com/ under obsolete parts) which already contains the required voltage reference.

+

Power supply

+

The least number of parts are required if you use a regulated power supply delivering 24V at 250mA. The voltage only needs to be filtered using an electrolytic capacitor at the PCB. The op-amp will be powered directly from this voltage, a 7805 will regulate the +5V required for the remaining parts including VCC of the GAL. The 7805 will have to dissipate up to 5 watts and requires a heat sink to prevent overheating.

+

If you have no regulated power supply, you may supply unregulated +27..+35V, as are generated by using a 18V transformer, a bridge B40C250 (or 4 * 1N4004 diodes) and a filter capacitor of 1000uF/40V, and regulate the voltage at the PCB using a 7824. A 1N4004 series diode to protect the circuit from applying power in wrong polarity is not a bad idea.

+

If you don't want to dissipate 5 watts at the 7805, you may use a power supply of only 9V..12V, 250mA. The +24V programming voltage than has to be generated using a step up switching regulator.

+

LM78S40

+

Use a LM78S40 (or uA78S40) switching regulator with a 10nF timing capacitor and a 470uH/300mA storage coil suitable for switch mode converters and a 1R2 current limiting resistor. You will find the circuit and hints on construction in the data sheet available at http://www.nsc.com/. The LM78S40 is a good choice, because it already contains the required op-amp, but you may use a TL497 or other switching regulator and a separate op-amp (like the CA3140) instead.

+

If you want to use my predesigned circuit, look here

+ diff --git a/res/ATFBlast_ALL/userport/UserPort/Examples/IOPort.c b/res/ATFBlast_ALL/userport/UserPort/Examples/IOPort.c new file mode 100644 index 0000000..7cef182 --- /dev/null +++ b/res/ATFBlast_ALL/userport/UserPort/Examples/IOPort.c @@ -0,0 +1,76 @@ +#include +static BOOL bPrivException = FALSE; + +void outport(UINT portid, UINT value) +{ + __asm mov edx,portid; + __asm mov eax,value; + __asm out dx,ax; +} +void outportb(UINT portid, BYTE value) +{ + __asm mov edx,portid + __asm mov al,value + __asm out dx,al +} + +BYTE inportb(UINT portid) +{ + unsigned char value; + + __asm mov edx,portid + __asm in al,dx + __asm mov value,al + return value; +} + +UINT inport(UINT portid) +{ + int value=0; + __asm mov edx,portid + __asm in ax,dx + __asm mov value,eax + return value; +} + +LONG WINAPI HandlerExceptionFilter ( EXCEPTION_POINTERS *pExPtrs ) +{ + + if (pExPtrs->ExceptionRecord->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION) + { + pExPtrs->ContextRecord->Eip ++; // Skip the OUT or IN instruction that caused the exception + bPrivException = TRUE; + return EXCEPTION_CONTINUE_EXECUTION; + } + else + return EXCEPTION_CONTINUE_SEARCH; +} + +BOOL StartUpIoPorts(UINT PortToAccess, BOOL bShowMessageBox, HWND hParentWnd) +{ + HANDLE hUserPort; + + hUserPort = CreateFile("\\\\.\\UserPort", GENERIC_READ, 0, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + CloseHandle(hUserPort); // Activate the driver + Sleep(100); // We must make a process switch + + SetUnhandledExceptionFilter(HandlerExceptionFilter); + + bPrivException = FALSE; + inportb(PortToAccess); // Try to access the given port address + + if (bPrivException) + { + if (bShowMessageBox) + { + MessageBox(hParentWnd,"Privileged instruction exception has occured!\r\n\r\n" + "To use this program under Windows NT or Windows 2000\r\n" + "you need to install the driver 'UserPort.SYS' and grant\r\n" + "access to the ports used by this program.", + NULL,MB_OK); + } + return FALSE; + } + return TRUE; +} + diff --git a/res/ATFBlast_ALL/userport/UserPort/Examples/IOPort.h b/res/ATFBlast_ALL/userport/UserPort/Examples/IOPort.h new file mode 100644 index 0000000..2fd3bf9 --- /dev/null +++ b/res/ATFBlast_ALL/userport/UserPort/Examples/IOPort.h @@ -0,0 +1,18 @@ +#ifndef IOPORTH +#define IOPORTH + +#ifdef __cplusplus +extern "C" { +#endif + +void outport(UINT portid, UINT value); +void outportb(UINT portid, BYTE value); +BYTE inportb(UINT portid); +UINT inport(UINT portid); +BOOL StartUpIoPorts(UINT PortToAccess, BOOL bShowMessageBox, HWND hParentWnd); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/res/ATFBlast_ALL/userport/UserPort/Examples/IOPort.pas b/res/ATFBlast_ALL/userport/UserPort/Examples/IOPort.pas new file mode 100644 index 0000000..941240c --- /dev/null +++ b/res/ATFBlast_ALL/userport/UserPort/Examples/IOPort.pas @@ -0,0 +1,72 @@ +unit IOPort; + +interface +uses windows; + +procedure outport(portid : integer; value : integer); +procedure outportb(portid : integer; value : BYTE); +function inportb(portid : integer) : byte; +function inport(portid : integer) : integer; +function StartUpIoPorts(PortToAccess : integer) : boolean; + +implementation + +var + bPrivException : boolean; + +procedure outport(portid : integer; value : integer); +Begin + asm + mov edx,portid; + mov eax,value; + out dx,ax; + end; +end; + +procedure outportb(portid : integer; value : BYTE); +Begin + asm + mov edx,portid + mov al,value + out dx,al + end; +end; + +function inportb(portid : integer) : byte; +Var value : byte; +Begin + asm + mov edx,portid + in al,dx + mov value,al + end; + inportb := value; +end; + +function inport(portid : integer) : integer; +Var value : integer; +Begin + value := 0; + asm + mov edx,portid + in ax,dx + mov value,eax + end; + inport := value; +end; + +function StartUpIoPorts(PortToAccess : integer) : boolean; +Var hUserPort : THandle; +Begin + hUserPort := CreateFile('\\.\UserPort', GENERIC_READ, 0, nil,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + CloseHandle(hUserPort); // Activate the driver + Sleep(100); // We must make a process switch + + try + inportb(PortToAccess); // Try to access the given port address + except + MessageBox(0,'fel','fel',MB_OK); + end; +end; + +end. \ No newline at end of file diff --git a/res/ATFBlast_ALL/userport/UserPort/UserPort.exe b/res/ATFBlast_ALL/userport/UserPort/UserPort.exe new file mode 100644 index 0000000..ff018b1 Binary files /dev/null and b/res/ATFBlast_ALL/userport/UserPort/UserPort.exe differ diff --git a/res/ATFBlast_ALL/userport/UserPort/UserPort.pdf b/res/ATFBlast_ALL/userport/UserPort/UserPort.pdf new file mode 100644 index 0000000..590b378 Binary files /dev/null and b/res/ATFBlast_ALL/userport/UserPort/UserPort.pdf differ diff --git a/res/ATFBlast_ALL/userport/UserPort/UserPort.sys b/res/ATFBlast_ALL/userport/UserPort/UserPort.sys new file mode 100644 index 0000000..30ad74f Binary files /dev/null and b/res/ATFBlast_ALL/userport/UserPort/UserPort.sys differ diff --git a/res/ATFBlast_ALL/userport/UserPort/UserPort_EXE/Resource.h b/res/ATFBlast_ALL/userport/UserPort/UserPort_EXE/Resource.h new file mode 100644 index 0000000..46cfc3f --- /dev/null +++ b/res/ATFBlast_ALL/userport/UserPort/UserPort_EXE/Resource.h @@ -0,0 +1,30 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by UserPort.rc +// +#define IDD_USERPORT 101 +#define IDI_APP 102 +#define IDC_AUMP_LIST_GRANTS 1000 +#define IDC_AUMP_EDIT_ADD 1001 +#define IDC_AUMP_BUTTON_ADD 1002 +#define IDC_AUMP_BUTTON_REMOVE 1003 +#define IDC_TCF_EDIT_ADD 1004 +#define IDC_BUTTON_UPDATE 1009 +#define IDC_BUTTON_START 1010 +#define IDC_TCF_LIST_GRANTS 1011 +#define IDC_TCF_BUTTON_ADD 1012 +#define IDC_BUTTON_STOP 1013 +#define IDC_AUMP_BUTTON_DEFAULTS 1016 +#define IDC_TCF_BUTTON_REMOVE 1017 +#define IDC_TCF_BUTTON_DEFAULTS 1018 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1017 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/res/ATFBlast_ALL/userport/UserPort/UserPort_EXE/UserPort.c b/res/ATFBlast_ALL/userport/UserPort/UserPort_EXE/UserPort.c new file mode 100644 index 0000000..5129ae5 --- /dev/null +++ b/res/ATFBlast_ALL/userport/UserPort/UserPort_EXE/UserPort.c @@ -0,0 +1,512 @@ +#include +#include +#include "resource.h" + +char szDriverFileName[MAX_PATH]; +char DriverName[]="UserPort"; +HWND hDlg; + +unsigned Chars2Hex (char ch, unsigned oldval) +{ + int nHex; + + if ((ch>='0') && (ch<='9')) + nHex=ch-'0'; + else if ((ch>='a') && (ch<='f')) + nHex=ch-'a'+10; + else if ((ch>='A') && (ch<='F')) + nHex=ch-'A'+10; + else + return oldval; + return oldval*16+nHex; +} + +void UpperString(char *Str) +{ + int i,Len; + + Len=strlen(Str); + for (i=0;i'Z') + Str[i]-=32; +} + +BOOL StopDriver() +{ + SC_HANDLE schService; + SC_HANDLE schSCManager; + SERVICE_STATUS serviceStatus; + + + schSCManager = OpenSCManager (NULL, // machine (NULL == local) + NULL, // database (NULL == default) + SC_MANAGER_ALL_ACCESS // access required + ); + if (schSCManager == NULL) + { + return FALSE; + } + + schService = OpenService (schSCManager, + DriverName, + SERVICE_ALL_ACCESS + ); + + if (schService == NULL) + { + CloseServiceHandle (schSCManager); + return FALSE; + } + + ControlService (schService, SERVICE_CONTROL_STOP, &serviceStatus); + + DeleteService (schService); + + CloseServiceHandle (schService); + CloseServiceHandle (schSCManager); + return TRUE; +} + +BOOL StartDriver() +{ + SC_HANDLE schService = NULL; + SC_HANDLE schSCManager; + HANDLE hDriver; + DWORD LastError; + char szMess[300]; + char szTmp[MAX_PATH]; + + lstrcpy(szTmp,szDriverFileName); + szTmp[12] = '\0'; + if (lstrcmpi(szTmp,"\\SystemRoot\\")==0) + { + GetWindowsDirectory(szTmp,sizeof(szTmp)); + lstrcat(szTmp,szDriverFileName+11); + } + else + lstrcpy(szTmp,szDriverFileName); + + + hDriver = CreateFile (szTmp, + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + if (hDriver==INVALID_HANDLE_VALUE) + { + wsprintf(szMess,"Driver does not exist:\r\n%s",szTmp); + MessageBox(hDlg,szMess,"UserPort",MB_OK); + return FALSE; + } + + CloseHandle(hDriver); + + schSCManager = OpenSCManager (NULL, // machine (NULL == local) + NULL, // database (NULL == default) + SC_MANAGER_ALL_ACCESS // access required + ); + + if (schSCManager == NULL) + { + if (GetLastError() == ERROR_ACCESS_DENIED) + MessageBox(hDlg,"You are not authorized to install drivers.\r\nPlase contact your administrator.","UserPort",MB_OK); + else + MessageBox(hDlg,"Unable to start driver!","UserPort",MB_OK); + + return FALSE; + } + + schService = CreateService (schSCManager, // SCManager database + DriverName, // name of service + DriverName, // name to display + SERVICE_START,//SERVICE_ALL_ACCESS, // desired access + SERVICE_KERNEL_DRIVER, // service type + SERVICE_SYSTEM_START, // start type + SERVICE_ERROR_NORMAL, // error control type + szDriverFileName, // service's binary + NULL, // no load ordering group + NULL, // no tag identifier + NULL, // no dependencies + NULL, // LocalSystem account + NULL // no password + ); + + if (schService == NULL) + { + LastError = GetLastError(); + if (LastError == ERROR_SERVICE_EXISTS) + MessageBox(hDlg,"Driver already started!","UserPort",MB_OK); + else if (LastError == ERROR_ACCESS_DENIED) + MessageBox(hDlg,"You are not authorized to install drivers.\r\nPlase contact your administrator.","UserPort",MB_OK); + else + MessageBox(hDlg,"Unable to start driver!","UserPort",MB_OK); + + CloseServiceHandle (schSCManager); + return FALSE; + } + + StartService (schService, // service identifier + 0, // number of arguments + NULL // pointer to arguments + ); + + CloseServiceHandle (schService); + CloseServiceHandle (schSCManager); + return TRUE; +} + +BOOL GetStartAndStopAddress(char *szStr, unsigned *nStartAddress, unsigned *nStopAddress) +{ + unsigned i, nStart = 0, nStop = 0; + + for (i=0;(szStr[i]!='\0')&&(szStr[i]!='-');i++) + nStart = Chars2Hex(szStr[i], nStart); + + if (szStr[i]=='\0') + return FALSE; + + for (i++;(szStr[i]!='\0')&&(szStr[i]!='-');i++) + nStop = Chars2Hex(szStr[i], nStop); + + *nStartAddress = nStart; + *nStopAddress = nStop; + + if (nStop < nStart) + return FALSE; + if (nStop > 0x3ff) + return FALSE; + + return TRUE; +} + +BOOL AddAUMPBtn() +{ + char szTemp[256]; + char szTemp2[256]; + unsigned nStartAddress,nStopAddress; + + GetDlgItemText(hDlg,IDC_AUMP_EDIT_ADD,szTemp,sizeof(szTemp)); + + if (!GetStartAndStopAddress(szTemp, &nStartAddress, &nStopAddress)) + { + MessageBox(hDlg,"Wrong syntax. Use: \"startadress - stopaddress\" (000 - 3ff)","UserPort",MB_OK); + return FALSE; + } + + wsprintf(szTemp2,"%X - %X",nStartAddress,nStopAddress); + SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_ADDSTRING, 0,(LPARAM)szTemp2); + SetDlgItemText(hDlg,IDC_AUMP_EDIT_ADD,""); + return TRUE; +} + +BOOL AddTCFBtn() +{ + char szTemp[256]; + char szTemp2[256]; + unsigned nStartAddress,nStopAddress; + + GetDlgItemText(hDlg,IDC_TCF_EDIT_ADD,szTemp,sizeof(szTemp)); + + if (!GetStartAndStopAddress(szTemp, &nStartAddress, &nStopAddress)) + { + MessageBox(hDlg,"Wrong syntax. Use: \"startadress - stopaddress\" (000 - 3ff)","UserPort",MB_OK); + return FALSE; + } + + wsprintf(szTemp2,"%X - %X",nStartAddress,nStopAddress); + SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_ADDSTRING, 0,(LPARAM)szTemp2); + SetDlgItemText(hDlg,IDC_TCF_EDIT_ADD,""); + return TRUE; +} + +BOOL UpdateBtn() +{ + HKEY hKey; + DWORD wType; + UCHAR AllProcessesIOPM[0x80]; + UCHAR ThroughCreateFileIOPM[0x80]; + unsigned nCount,i,j; + char szTemp[256]; + unsigned nStartAddress,nStopAddress; + + for (i=0;i>3] &= ~(1 << (j&7)); + } + } + + for (i=0;i>3] &= ~(1 << (j&7)); + } + } + + if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, + "Software\\UserPort",0,"", + REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS, + NULL,&hKey,&wType) == ERROR_SUCCESS) + { + RegSetValueEx(hKey, + "AllProcessesIOPM",0,REG_BINARY, + (BYTE *)AllProcessesIOPM,sizeof(AllProcessesIOPM)); + RegSetValueEx(hKey, + "ThroughCreateFileIOPM",0,REG_BINARY, + (BYTE *)ThroughCreateFileIOPM,sizeof(ThroughCreateFileIOPM)); + + RegCloseKey(hKey); + if (StopDriver()) + { + Sleep(200); + StartDriver(); + } + return TRUE; + } + + return FALSE; +} + +BOOL ReadRegistry() +{ + UCHAR AllProcessesIOPM[0x80]; + UCHAR ThroughCreateFileIOPM[0x80]; + char szTemp[256]; + unsigned i,nStartAddress,nStopAddress; + + DWORD cb,wType, bResult1 = FALSE, bResult2 = FALSE; + HKEY hKey; + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, + "Software\\UserPort",0,KEY_READ, + &hKey) == ERROR_SUCCESS) + { + cb = sizeof(AllProcessesIOPM); + if (RegQueryValueEx(hKey,"AllProcessesIOPM",0,&wType,(BYTE *)AllProcessesIOPM,&cb) == ERROR_SUCCESS) + bResult1 = TRUE; + cb = sizeof(ThroughCreateFileIOPM); + if (RegQueryValueEx(hKey,"ThroughCreateFileIOPM",0,&wType,(BYTE *)ThroughCreateFileIOPM,&cb) == ERROR_SUCCESS) + bResult2 = TRUE; + RegCloseKey(hKey); + } + + if ((bResult1 == FALSE) || (bResult2 == FALSE)) + return FALSE; + + for (i=0;i >3] & (1 << (i&7))) == 0) + { + nStartAddress = i; + do + { + nStopAddress = i; + i++; + } while ((i < sizeof(AllProcessesIOPM)<<3) && ((AllProcessesIOPM[i>>3] & (1 << (i&7))) == 0)); + wsprintf(szTemp,"%X - %X",nStartAddress,nStopAddress); + SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_ADDSTRING, 0,(LPARAM)szTemp); + } + } + + for (i=0;i >3] & (1 << (i&7))) == 0) + { + nStartAddress = i; + do + { + nStopAddress = i; + i++; + } while ((i < sizeof(ThroughCreateFileIOPM)<<3) && ((ThroughCreateFileIOPM[i>>3] & (1 << (i&7))) == 0)); + wsprintf(szTemp,"%X - %X",nStartAddress,nStopAddress); + SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_ADDSTRING, 0,(LPARAM)szTemp); + } + } + + return TRUE; +} + +BOOL AddAUMPDefaults() +{ + int nCount,i; + + nCount = SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_GETCOUNT, 0,0); + + for (i=0;i + +/* + * Make sure our structure is packed properly, on byte boundary, not + * on the default doubleword boundary. +*/ +#pragma pack(push,1) + +/* + * Structures for manipulating the GDT register and a GDT segment + * descriptor entry. Documented in Intel processor handbooks. + */ +typedef struct { + unsigned limit : 16; + unsigned baselo : 16; + unsigned basemid : 8; + unsigned type : 4; + unsigned system : 1; + unsigned dpl : 2; + unsigned present : 1; + unsigned limithi : 4; + unsigned available : 1; + unsigned zero : 1; + unsigned size : 1; + unsigned granularity : 1; + unsigned basehi : 8; +} GDTENT; + +typedef struct { + unsigned short limit; + GDTENT *base; +} GDTREG; + +#pragma pack(pop) +/* + * The name of our device driver. + */ +#define DEVICE_NAME_STRING L"UserPort" + +/* + OriginalMapCopy is used to restore the IOPM when the driver exists. + CurrentMap points to NULL or to the place where the processors IOPM is located. + Accessmap is the IOPM that is used by the driver. + Every port address has one cooresponding bit in the IOPM. The driver supports + addresses from 0x000 to 0x3FF and the IOPM size is then 0x3ff / 8 = 0x80. + */ + +UCHAR OriginalAllProcIOPMCopy[0x80]; +UCHAR OriginalThroughCreateFileIOPMCopy[0x80]; +const UCHAR DefaultMap[0x80]= +/*0x000*/ {0xFF,0xFF, +/*0x010*/ 0xFF,0xFF, +/*0x020*/ 0xFF,0xFF, +/*0x030*/ 0xFF,0xFF, +/*0x040*/ 0xFF,0xFF, +/*0x050*/ 0xFF,0xFF, +/*0x060*/ 0xFF,0xFF, +/*0x070*/ 0xFF,0xFF, +/*0x080*/ 0xFF,0xFF, +/*0x090*/ 0xFF,0xFF, +/*0x0A0*/ 0xFF,0xFF, +/*0x0B0*/ 0xFF,0xFF, +/*0x0C0*/ 0xFF,0xFF, +/*0x0D0*/ 0xFF,0xFF, +/*0x0E0*/ 0xFF,0xFF, +/*0x0F0*/ 0xFF,0xFF, +/*0x100*/ 0xFF,0xFF, +/*0x110*/ 0xFF,0xFF, +/*0x120*/ 0xFF,0xFF, +/*0x130*/ 0xFF,0xFF, +/*0x140*/ 0xFF,0xFF, +/*0x150*/ 0xFF,0xFF, +/*0x160*/ 0xFF,0xFF, +/*0x170*/ 0xFF,0xFF, +/*0x180*/ 0xFF,0xFF, +/*0x190*/ 0xFF,0xFF, +/*0x1A0*/ 0xFF,0xFF, +/*0x1B0*/ 0xFF,0xFF, +/*0x1C0*/ 0xFF,0xFF, +/*0x1D0*/ 0xFF,0xFF, +/*0x1E0*/ 0xFF,0xFF, +/*0x1F0*/ 0xFF,0xFF, +/*0x200*/ 0x00,0x00, +/*0x210*/ 0x00,0x00, +/*0x220*/ 0x00,0x00, +/*0x230*/ 0x00,0x00, +/*0x240*/ 0x00,0x00, +/*0x250*/ 0x00,0x00, +/*0x260*/ 0x00,0x00, +/*0x270*/ 0x00,0x00, +/*0x280*/ 0x00,0x00, +/*0x290*/ 0x00,0x00, +/*0x2A0*/ 0x00,0x00, +/*0x2B0*/ 0x00,0x00, +/*0x2C0*/ 0x00,0x00, +/*0x2D0*/ 0x00,0x00, +/*0x2E0*/ 0x00,0x00, +/*0x2F0*/ 0x00,0x00, +/*0x300*/ 0x00,0x00, +/*0x310*/ 0x00,0x00, +/*0x320*/ 0x00,0x00, +/*0x330*/ 0x00,0x00, +/*0x340*/ 0x00,0x00, +/*0x350*/ 0x00,0x00, +/*0x360*/ 0x00,0x00, +/*0x370*/ 0x00,0x00, +/*0x380*/ 0xFF,0xFF, +/*0x390*/ 0xFF,0xFF, +/*0x3A0*/ 0xFF,0xFF, +/*0x3B0*/ 0xFF,0x0F, +/*0x3C0*/ 0xFF,0xFF, +/*0x3D0*/ 0xFF,0xFF, +/*0x3E0*/ 0xFF,0x00, +/*0x3F0*/ 0x00,0x00}; + +unsigned OrgGDTSize; // The original sise of the TSS + +/* + Ke386IoSetAccessProcess() adjusts the IOPM offset pointer to the IOPM at 0x88 + Ke386IoSetAccessProcess() is located in NTOSKRNL.EXE but is not included in any + header file or documented anywhere... +*/ + +void Ke386IoSetAccessProcess(PEPROCESS, int); + +/********************************************************************* + Service handler for a CreateFile() user mode call. + + This routine is entered in the driver object function call table by +the DriverEntry() routine. When the user mode application calls +CreateFile(), this routine gets called while still in the context of +the user mode application, but with the CPL (the processor's Current +Privelege Level) set to 0. This allows us to do kernel mode +operations. UserPort() is called to give the calling process I/O +access. All the user mode application needs do to obtain I/O access +is open this device with CreateFile(). No other operations are +required. +*********************************************************************/ +NTSTATUS CreateFileDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ) +{ + // Give the current process IO access + Ke386IoSetAccessProcess(PsGetCurrentProcess(), 1); + + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +// remove the link \\.\UserPort and restore the IOPM +void UserPortUnload(IN PDRIVER_OBJECT DriverObject) +{ + WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING; + UNICODE_STRING uniDOSString; + GDTREG gdtreg; + GDTENT *g; + short TaskSeg; + UCHAR *TSSAllProcessesIOPM; + UCHAR *TSSThroughCreateFileIOPM; + unsigned i; + UCHAR *TSSbase; + + _asm cli; + _asm sgdt gdtreg; + _asm str TaskSeg; + g = gdtreg.base + (TaskSeg >> 3); + g->limit = OrgGDTSize; + g->type = 9; + _asm ltr TaskSeg; + _asm sti; + + TSSbase = (UCHAR *) (g->baselo | (g->basemid << 16) | (g->basehi << 24)); + TSSAllProcessesIOPM = *((USHORT *)(TSSbase + 0x66)) + TSSbase; + TSSThroughCreateFileIOPM = TSSbase + 0x88; + + // Restore to the original map + for (i=0;iDeviceObject); +} + +// This routine is the entrypoint of the driver. +// This routine reads the AllProcessesIOPM and ThroughCreateFileIOPM from registry and start the driver +NTSTATUS DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) +{ + PDEVICE_OBJECT deviceObject; + NTSTATUS status; + WCHAR NameBuffer[] = L"\\Device\\" DEVICE_NAME_STRING; + WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING; + UNICODE_STRING uniNameString, uniDOSString; + GDTREG gdtreg; + GDTENT *g; + short TaskSeg; + UCHAR *TSSAllProcessesIOPM; + UCHAR *TSSThroughCreateFileIOPM; + const UCHAR *AllProcessesIOPM = DefaultMap; + const UCHAR *ThroughCreateFileIOPM = DefaultMap; + unsigned i; + UCHAR *TSSbase; + UCHAR InformationBuffer1[sizeof(DefaultMap)+sizeof(KEY_VALUE_PARTIAL_INFORMATION)]; + PKEY_VALUE_PARTIAL_INFORMATION Information1 = (PKEY_VALUE_PARTIAL_INFORMATION)InformationBuffer1; + UCHAR InformationBuffer2[sizeof(DefaultMap)+sizeof(KEY_VALUE_PARTIAL_INFORMATION)]; + PKEY_VALUE_PARTIAL_INFORMATION Information2 = (PKEY_VALUE_PARTIAL_INFORMATION)InformationBuffer2; + ULONG ResultLength; + HANDLE KeyHandle; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING ThroughCreateFileIOPMString,AllProcessesIOPMString,RegPathString; + + RtlInitUnicodeString(&AllProcessesIOPMString, L"AllProcessesIOPM"); + RtlInitUnicodeString(&ThroughCreateFileIOPMString, L"ThroughCreateFileIOPM"); + RtlInitUnicodeString(&RegPathString,L"\\Registry\\Machine\\Software\\UserPort"); + + InitializeObjectAttributes(&ObjectAttributes,&RegPathString,OBJ_CASE_INSENSITIVE,NULL,NULL); + + if (STATUS_SUCCESS == ZwOpenKey(&KeyHandle, KEY_QUERY_VALUE,&ObjectAttributes)) + { + if (STATUS_SUCCESS == ZwQueryValueKey(KeyHandle,&ThroughCreateFileIOPMString,KeyValuePartialInformation,Information1,sizeof(InformationBuffer1),&ResultLength)) + ThroughCreateFileIOPM = Information1->Data; + if (STATUS_SUCCESS == ZwQueryValueKey(KeyHandle,&AllProcessesIOPMString,KeyValuePartialInformation,Information2,sizeof(InformationBuffer2),&ResultLength)) + AllProcessesIOPM = Information2->Data; + ZwClose(KeyHandle); + } + + _asm cli; // don't get interrupted! + _asm str TaskSeg; // get the TSS selector + _asm sgdt gdtreg; // get the GDT address + g = gdtreg.base + (TaskSeg >> 3); // get the TSS descript + // get the TSS address + OrgGDTSize = g->limit; + g->limit += 0x082; // modify TSS segment limit + g->type = 9; // mark TSS as "not busy" + _asm ltr TaskSeg; // reload task register (TR) + _asm sti; // let interrupts continue*/ + + TSSbase = (UCHAR *) (g->baselo | (g->basemid << 16) | (g->basehi << 24)); + TSSAllProcessesIOPM = *((USHORT *)(TSSbase + 0x66)) + TSSbase; + TSSThroughCreateFileIOPM = TSSbase + 0x88; + + // Copy the AccessMap to TSSbase + 0x20ad and save the original map + for (i=0;iMajorFunction[IRP_MJ_CREATE] = CreateFileDispatch; + + DriverObject->DriverUnload = UserPortUnload; + + return STATUS_SUCCESS; +} + diff --git a/res/ATFBlast_ALL/userport/Win_XP.txt b/res/ATFBlast_ALL/userport/Win_XP.txt new file mode 100644 index 0000000..f12ee47 --- /dev/null +++ b/res/ATFBlast_ALL/userport/Win_XP.txt @@ -0,0 +1,25 @@ +Программатор может работать в Windows 95/98/ME, но не работает в +Windows NT/2000/XP, если не установлен драйвер прямого доступа к +портам компьютера UserPort. + + Краткая инструкция. + +Если у Вас Windows NT/2000/XP, то необходимо установить дополнительную +утилиту UserPort, которая позволит программам беспрепятственно +обращаться к указанным Вами портам, в данном случае это LPT. + +Установка UserPort: +1. Распаковываем UserPort.zip во временную папку. +2. Копируем файл UserPort.sys в папку C:\WINDOWS\SYSTEM32\DRIVERS +3. Запускаем файл UserPort.exe, удаляем оттуда все элементы. +4. Заходим в Панель Управления\Система, выбираем закладку Оборудование, + Диспетчер устройств, заходим в Порты (COM и LPT) и смотрим + свойства LPT порта, по которому вы хотите установить соединение. + В Свойствах открываем закладку Ресурсы и смотрим значение + параметра Диапазон ввода/вывода (I/O). (Например, у меня в + Windows XP оно равно 378 - 37F) +5. Добавляем это значение в UserPort.exe (в оба поля) и нажимаем + кнопку Start. + +После этого должен появиться доступ к портам и можно запускать +программу ATFBLAST.EXE. \ No newline at end of file -- cgit v1.2.1