home *** CD-ROM | disk | FTP | other *** search
- ;
- ; Copyright (c) Sirius Software 1992.
- ; All rights reserved.
- ; But the readme.doc from Sirius Software files says:
- ; This software is hereby placed in the public domain.
- ; RANDDRV.SYS random number driver for RNG-810 or similar hardware
- ; Copyright (C) 1994 Paul Elliot
- ;
- ; This program is free software; you can redistribute it and/or
- ; modify it under the terms of the GNU General Public License
- ; as published by the Free Software Foundation; either version 2
- ; of the License, or (at your option) any later version.
- ;
- ; This program is distributed in the hope that it will be useful,
- ; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ; GNU General Public License for more details.
- ;
- ; You should have received a copy of the GNU General Public License
- ; along with this program; if not, write to the Free Software
- ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ;
- ;Paul.Elliott@Hrnowl.LoneStar.Org
- ;
- ;Paul Elliott
- ;
- ;3986 South Gessner #224 Houston TX 77063
- ;
- %pagesize
- ;use ideal mode instead of masm mode
- IDEAL
- %title "assembly language interface for os/2 random number generator driver"
- %pagesize 55,132
- ;show code actually assembled by fancy assembler directives!
- %MACS
- ;
- ;
- ; file_name = c0.asm
- ;
- ; Notes :
- ; - created June 28 1991 GWS
- ; - Borland C startup file for OS/2 device drivers
- ; - changed to BC++ for DOS May 2, 1993 GWS
- ;
- ; This is a startup file for OS/2 device drivers written entirely with
- ; Borland 3.0 DOS based tools. OS/2 device drivers are not difficult but
- ; they are different than regular C programs, they don't have a main()
- ; function. The OS calls an entry point defined by the device driver
- ; header. The entry point is called Entry and is in this module. The
- ; entry point calls the startup code if the startup code hasn't been run
- ; before and then transfers to a function called Strategy passing the pointer
- ; to the device request packet as the only parameter.
- ;
- ; This code handles 1 entry point but more can be added by creating more
- ; entry point and strategy handlers.
- ;
- %pagesize
-
- ; Memory layout.
- ;
- ; OS/2 drivers have two segments. Data and code segments.
- ; the data segment must begin with the device header
- ;
- ; When the driver is called with the INIt packet,
- ; the driver returns 2 memory limits for each of these
- ; segments. Memory beond these limits is removed and returned
- ; to OS free store. IT IS IMPORTANT that memory beond
- ; these limits not be used to store data or code to be
- ; used after the INIT functions returned.
-
- ; also it is important that code and data which is not used
- ; after the INIT packet, be placed after these memory limits
- ; to conserve memory.
-
- ; I have used two strategies to place code and data
- ; in their proper places with respect to these memory limits.
-
- ; one strategy is used to group code with respect to its memory
- ; limit. borland c++ uses one segment _TEXT and assumes cs points
- ; to it. In the compact model, no group is used for this code segment.
- ; No group statment generated by bcc mentions _TEXT.
- ; to deal with this I create an assembly module codeend.asm
- ; which defines the memory limit for the code segment in _TEXT
- ; all modules that are to be resident after the INIT packet
- ; are placed before codeend.obj in the TLINK command line
- ; modules that are not to be resident after the INIT packet
- ; are placed after the codend.obj in the TLINK command line.
- ; i.e.
- ; tlink /m/s c0+$(BASENAME)+rand+movmem+codend+startup+start,\
- ; $(BASENAME),,$(COMPILER_PATH)\lib\cc.lib $(OS2_LIB),$(BASENAME)/m;
-
- ; in this example the code for c0.obj, $(BASENAME)=randdrv.obj
- ; rand.obj, movmem.obj
- ; must remain after the INIT packet is processed.
- ; the code from startup.obj, start.obj and the BCC rtl
- ; are only used during the processing for the INIT packet.
- ; movmem.obj is from the BCC RTL but must be compiled seperately
- ; so that it can be placed before codend. as it is used by RANDDRV.OBJ
- ; after INIT.
- ; there is one exception to this strategy, c0.asm does contain
- ; some code to be used only during INIT. But since c0 is written
- ; in assembler, This code is placed in its own segment _ITEXT
- ; a group directive is used to place this segment after _TEXT in
- ; memory.
- ; group CGROUP _TEXT,_ITEXT
- ; since the _TEXT segment appears first, the assumption made
- ; by the BCC code is not broken and the assembly module c0.asm
- ; can use the group statement to address its data.
- %pagesize
- ; layout of the data segment
- ; BCC does use GROUPS segment directives for its data.
- ; therefore GROUP statements and segments can be used
- ; to place data with respect to the data memory limit.
- ; the data memory limit, _memoryend, is placed in the
- ; segment _BBSEND. segments are place before or
- ; after this segment for the DGROUP data segment
- ; depending on wheater the data should be retained
- ; after the INIT.
- ;; BCC modules that must be used after the INIT are compiled
- ; with the switches:
- ; -zD_RBSS -zR_RDATA -zBDATA
- ; this directs data to the segment RDATA
- ; and uninitialized data to RBSS.
-
- ; modules that are not needed after the INIT
- ; are compiled normally and the segments go after the
- ; memory limit. Thus the RTL does not need to be re-compiled.
-
- ; the module movmem is used after the INIT, therefore it must
- ; be specially compiled with the switches to place its data
- ; properly.
-
- ; I have devided the uninitialized data segment _BSS into 2
- ; segments, _BSS and _RBSS. _RBSS is used for data that
- ; remains after INIT. Since we are writting the startup code
- ; c0.asm we can arrange to have both zeroed.
-
- ; like wise there are 2 DATA segments _DATA and _RDATA.
-
- ;must use compact model because the stack is far in a driver therefore
- ;local data is far.
- %pagesize
- ; model
- ASMMODEL EQU COMPACT
-
-
- ;os/2 now requires 386.
- P386
- ;enable local symbols
- locals
-
- ;
- ; define all sequences
- macro DefineSegment segmentName,alignmentType,classType
- segment segmentName alignmentType public classType
- ends segmentName
- endm
- ; make sure the data segment is the first one in the .sys module
- ;
- ; Header must be first in data segment.
- DefineSegment _HEADER,para,'DATA'
- DefineSegment _RDATA,para,'DATA'
- DefineSegment _RBSS,word,'DATA'
- ; _RBSSEND defines end of resident data.
- DefineSegment _RBSSEND,byte,'DATA'
- DefineSegment _DATA,para,'DATA'
- DefineSegment _INIT_,word,'INITDATA'
- DefineSegment _INITEND_,byte,'INITDATA'
- DefineSegment _EXIT_,word,'EXITDATA'
- DefineSegment _EXITEND_,byte,'EXITDATA'
- DefineSegment _BSS,word,'BSS'
- DefineSegment _BSSEND,byte,'BSSEND'
- DefineSegment _TEXT,word,'CODE'
- DefineSegment _ITEXT,word,'CODE'
- ;driver requires first group be data, second code
- ;driver header must be first.
-
- ; segemnts before _RBSSEND are resident
- group DGROUP _HEADER,_RDATA,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_RBSS,_RBSSEND,_BSS,_BSSEND,_DATA
- ;
- ; _ITEXT is used only by c0.asm
- ; only used during INIT.
- group CGROUP _TEXT,_ITEXT
- ;
- PUBLIC _AHINCR,_AHSHIFT
-
-
- _AHINCR = 1000h
- _AHSHIFT = 12
- ;
- ; these segments delimit the startup data for c++
- SEGMENT _INIT_
- label FirstStartupEntry byte
- ENDS _INIT_
- ;
- SEGMENT _INITEND_
- label EndOfStartup byte
- ENDS _INITEND_
- ;
- SEGMENT _BSS
- label BSSStart byte
- ENDS _BSS
- ;
- SEGMENT _BSSEND
- label BSSEnd byte
- ENDS _BSSEND
- SEGMENT _RBSS
- label RBSSStart byte
- ENDS _RBSS
- ;
- SEGMENT _RBSSEND
- label RBSSEnd byte
- ;
- ;delimit end of data segments.
- ;
- ; _memoryEnd is the end of the residnet data in the DATA segment.
- public _memoryEnd
- label _memoryEnd byte
- ENDS _RBSSEND
- ;
- ; use 16 bit addressing in os/2 driver
- ; use c language for interface to c,c++ code
- model USE16 ASMMODEL,C
- ASSUME CS:CGROUP
- ;
- ; external procedures
- extrn _CodeEnd:byte
- extrn memset:proc
- CODESEG
- extrn CallStartup:proc
- extrn Strategy1:proc
- ;
- SEGMENT _HEADER
- extrn Entry:word
- ENDS _HEADER
- CODESEG
- ;
- ; This procedure is the entry point after the INIT is processed.
- ; it is resident.
- proc Entry2 far ;
- ;call driver startegy code defined in randdrv.cpp
- ; simply call the c++ strategy routine using es:bx
- ; as the parameter.
- call near Strategy1 C,es bx ;
- ;add redirect
- ret ;
- endp Entry2 ;
-
- %pagesize
- ; code exists only until INIT is completed.
- SEGMENT _ITEXT
- ASSUME CS:CGROUP
-
- ;
- ; clear the BSS then call all the initialisers
- ;
- proc DoStartup near NOLANGUAGE
- pusha ;
- push es ;
-
-
- ; clear RBSS. resident uninitialized data.
- mov ax,offset DGROUP:RBSSEnd ;
- sub ax,offset DGROUP:RBSSStart ; ax = the length of the BSS
-
- call memset C,ds offset DGROUP:RBSSStart,0,ax ;
-
- ; Clear the BSS
-
- ; clear BSS non-resident uninitialized data.
- mov ax,offset DGROUP:BSSEnd ;
- sub ax,offset DGROUP:BSSStart ; ax = the length of the BSS
-
- call memset C,ds offset DGROUP:BSSStart,0,ax ;
-
- ; call the c++ initializers.
- call near CallStartup C,ds offset DGROUP:FirstStartupEntry,ds offset DGROUP:EndOfStartup
- ;
- pop es ;
- popa ;
- ret
- endp DoStartup
- ;This is the initial entry point for the driver.
- ;entry point is moved after when finished.
- ;
- public Entry1
- proc Entry1 far ;
- ; call startup initialization code
- call near DoStartup NOLANGUAGE ;
- ;call driver startegy code defined in randdrv.cpp
- call near Strategy1 C,es bx ;
-
- ; add redirect
- ; driver has been initialized redefine
- ; driver entry point to be resident code ENTRY2.
- ; by adjusting pointer in DRIVER header.
- mov [Entry],offset CGROUP:Entry2
-
- ret ;
- endp Entry1 ;
- ; end of segment. exists only during INIT.
- ENDS _ITEXT
- %pagesize
- CODESEG
- ;
- ;
- ; The following definitions are required when linking in the sprintf/sscanf
- ; routines to stop them from hauling in all sorts of floating point and
- ; error handling code.
- ;
- public abort
- label abort word
- ;
- public _RealCvtVector
- label _RealCvtVector word
- ;
- public _ScanTodVector
- label _ScanTodVector word
- ;
- end ;
-
-