home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 8 Other
/
08-Other.zip
/
rng-810.zip
/
c0.asm
< prev
next >
Wrap
Assembly Source File
|
1994-01-28
|
10KB
|
322 lines
;
; 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 ;