home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / rng-810.zip / rand.asm < prev    next >
Assembly Source File  |  1994-01-28  |  9KB  |  306 lines

  1. ; RANDDRV.SYS random number driver for RNG-810 or similar hardware
  2. ; Copyright (C) 1994 Paul Elliot
  3. ;
  4. ; This program is free software; you can redistribute it and/or
  5. ; modify it under the terms of the GNU General Public License
  6. ; as published by the Free Software Foundation; either version 2
  7. ; of the License, or (at your option) any later version.
  8. ;
  9. ; This program is distributed in the hope that it will be useful,
  10. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ; GNU General Public License for more details.
  13. ;
  14. ; You should have received a copy of the GNU General Public License
  15. ; along with this program; if not, write to the Free Software
  16. ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ;
  18. ;Paul.Elliott@Hrnowl.LoneStar.Org
  19. ;
  20. ;Paul Elliott
  21. ;
  22. ;3986 South Gessner #224 Houston TX 77063
  23. ;
  24. ;
  25. %pagesize
  26. ;use ideal mode instead of masm mode
  27. IDEAL
  28. %title    "assembly language interface for os/2 random number generator driver"
  29. %pagesize    55,132
  30. ;show code actually assembled by fancy assembler directives!
  31. %MACS
  32.  
  33. ;must use compact because the stack is far in a driver therefore
  34. ;local data is far.
  35. ASMMODEL EQU COMPACT
  36. ;smart code generation
  37. smart
  38.  
  39.  
  40. ;os/2 now requires 386.
  41. P386
  42. ;enable local symbols
  43. locals
  44. %pagesize
  45. ;
  46. ; define all sequences
  47. macro    DefineSegment    segmentName,alignmentType,classType
  48. segment    segmentName    alignmentType public classType
  49. ends    segmentName    
  50. endm
  51. ; make sure the data segment is the first one in the .sys module
  52. ;
  53. ;driver requires first group be data, second code
  54. ;driver header must be first.
  55. group    DGROUP    _HEADER,_RDATA,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_RBSS,_RBSSEND,_BSS,_BSSEND,_DATA
  56. group CGROUP    _TEXT,_ITEXT
  57. ;
  58.     DefineSegment    _TEXT,word,'CODE'
  59.     DefineSegment    _ITEXT,word,'CODE'
  60.     DefineSegment    _HEADER,para,'DATA'
  61.     DefineSegment    _RDATA,para,'DATA'
  62.     DefineSegment    _DATA,para,'DATA'
  63.     DefineSegment    _INIT_,word,'INITDATA'
  64.     DefineSegment    _INITEND_,byte,'INITDATA'
  65.     DefineSegment    _EXIT_,word,'EXITDATA'
  66.     DefineSegment    _EXITEND_,byte,'EXITDATA'
  67.     DefineSegment    _RBSS,word,'DATA'
  68.     DefineSegment    _RBSSEND,byte,'DATA'
  69.     DefineSegment    _BSS,word,'BSS'
  70.     DefineSegment    _BSSEND,byte,'BSSEND'
  71. %pagesize
  72. ;
  73. ;
  74. ;
  75. ; use 16 bit addressing in os/2 driver
  76. ; use c language for interface to c,c++ code
  77.     model USE16 ASMMODEL,C
  78.     ASSUME CS:CGROUP
  79. include "driver.inc"
  80. SEGMENT _ITEXT
  81. extrn    NOLANGUAGE _Entry1:far
  82. ENDS    _ITEXT
  83.  
  84. ; define the header for the device driver.
  85. segment _HEADER
  86. Public    Header
  87. label    Header    far
  88.     DD    -1            ;NEXT
  89.     DW    DAW_OPN OR DAW_CHR OR DAW_LEVEL1 OR DAW_GIO OR DAW_SHR
  90.                     ;device attribute word
  91.  
  92. ; this word defines the entry point for the driver.
  93. Public    Entry
  94. label    Entry    near
  95. ; initial entry point is _Entry1
  96. ; when Entry1 runs at first call, it will change this pointer
  97. ; to point to Entry2, therafter Entry2 will be called instead!
  98.     DW    offset CGROUP:_Entry1        ;strategy entry point
  99.     DW    0            ;idc entry point
  100.     DB    8 DUP ("$RANDOM$")    ;name exactly 8 bytes
  101.     DB    8 DUP (0)        ;RESERVED
  102. ends    _HEADER    
  103. %pagesize
  104. ;
  105. ;define constants needed to call back the device helper services.
  106. ProcBlock        =      4      ;  4    Block on event
  107. ProcRun          =      5      ;  5    Unblock process
  108.  
  109. SetTimer         =     29      ; 1D    set timer r=est handler
  110. ResetTimer       =     30      ; 1E    unset timer request handler
  111.  
  112. CPhysToVirt       =     21      ; 15    convert physical address to virtual
  113. VirtToPhys       =     22      ; 16    convert virtual address to physical
  114. PhysToUVirt      =     23      ; 17    convert physical to LDT
  115. %pagesize
  116. ;DATASEG
  117. segment _RDATA
  118. ;define data shared in common with randdrv.cpp
  119. ;call back dev helper address
  120. extrn    _devHlp:DWORD
  121.  
  122. ;the number of bytes we are waiting for
  123. extrn    waiting_for:word
  124. ;the number of unused random bytes stored in our buffer
  125. extrn    unused_in_buffer:word
  126. ; the address of the start of our buffer (offset)
  127. extrn    buf_start:word
  128. ; the address of the end of our buffer (offset)
  129. extrn    buf_end:word
  130. ;The offset address of the next byte to be read into our buffer
  131. extrn    current_input:word
  132. ; The port address of the random number gneerator
  133. extrn    port:word
  134. ENDS _RDATA
  135. %pagesize
  136. CODESEG     
  137. ;define our public functions
  138. ;turn timer interrupts on
  139. public    TimerOn
  140. ; turn timer interrrupts off
  141. public    TimerOff
  142. ; cause current process to block for event
  143. public  block
  144. ; map a physical address to a virtual
  145. public    PhysToVirt
  146.  
  147.  
  148. ;call the device driver help routines to cause this request/thread to block
  149. proc    block    near
  150.     ;time to block this request
  151.     arg    @@time:dword
  152.     ;flag to pass to helper routine
  153.     arg    @@dflag:word
  154.     ;we use these registers
  155.     uses    bx,cx,dx,si,di
  156.     ;load registers for ID
  157.     mov    bx,SEG Header
  158.     mov    ax,OFFSET Header
  159.     ;load registers for time to block
  160.     mov    cx,[word @@time]
  161.     mov    di,[word @@time+2]
  162.     ;load registers for flags indicating kind of block
  163.     mov    dh,[byte @@dflag]
  164.     ;procedure block routine
  165.     mov    dl,ProcBlock
  166.     ;call back device helper routines.
  167.     call    [_devHlp] NOLANGUAGE
  168.     ;if carry some error
  169.     jc    short @@10
  170.     xor    ax,ax    ;zero indicates normal unblock, woke by a process
  171.     ;done
  172. @@99:    ret
  173. @@10:    jz    short @@20
  174.     ;if c set and z is set then timeout code
  175.     mov    ax,2    ;return interrrupted flag
  176.     jmp    short @@99
  177. @@20:    mov    ax,1    ;timed out flat
  178.     jmp    short @@99
  179.  
  180. endp    block
  181.  
  182. %pagesize
  183. ;this routine is called each for timer interrupt =18.2 times/second
  184. ;this routine reads bytes from the random number generator.
  185. ;this is neccessary because the calnet rng810 random number
  186. ; generator does not return randomly independant numbers if
  187. ; you read it faster than 40usec.
  188. ; 18.2 times per second is way to slow making this driver
  189. ; to slow making this driver extreamly slower than the requirements
  190. ; of the hardware. I do not see any way of getting faster timer
  191. ; resolution.
  192. proc    NOLANGUAGE _TIM_HNDLR FAR
  193.     ;save all registers
  194.     pusha
  195.     push    si di es
  196.     ;is our buffer full?
  197.     cmp    [unused_in_buffer],0
  198.     ; if full skip getting a new random byte.
  199.     jz    short @@100
  200.     ;make es point to ds=our data segment
  201.     mov    ax,ds
  202.     mov    es,ax
  203.     ; offset to read random byte to
  204.     mov    di,[current_input]
  205.     ;port to read
  206.     mov    dx,[port]
  207.     cld                ;go forward direction
  208.     ;read one new byte.
  209.     insb
  210.     ;have we reached the end of the buffer
  211.     cmp    di,[buf_end]
  212.     ;if yes skip
  213.     jne    short @@10
  214.     ;if at end wrap around to the begginig of the buffer
  215.     mov    di,[buf_start]
  216.     ;store new location to store next byte.
  217. @@10:    mov    [current_input],di
  218.  
  219.     ;decrease number of free unused bytes in buffer.
  220.     dec    [unused_in_buffer]
  221. ;;;    jz    short @@20
  222.  
  223.     ; decrement the number of chars we are waiting for
  224.     dec    [waiting_for]
  225.     ;if characters are available now unblock
  226.     jne    short @@100
  227.  
  228. @@20:    mov    [waiting_for],0
  229.     ;set    id in registers to run blocked processes.
  230.     mov    bx,SEG Header
  231.     mov    ax,OFFSET Header
  232.     ;indicate run process request to device helper
  233.     mov    dl,ProcRun
  234.     ;activate device helper call back function.
  235.     call    [_devHlp] NOLANGUAGE
  236.  
  237.     ;pop saved all registers and return
  238. @@100:
  239.     pop    es di si
  240.     popa
  241. @@200:
  242.     ret
  243. endp    _TIM_HNDLR
  244.  
  245. %pagesize
  246. ;run timer interrupt routine.
  247. proc    TimerOn    near
  248.     uses    bx,cx,dx,si,di
  249.     ;offset of timer routine
  250.     mov    ax,offset _TIM_HNDLR
  251.     ;indicate set timer request
  252.     mov    dl,SetTimer
  253.     ; call back device helper routine
  254.     call    [_devHlp] NOLANGUAGE
  255.     ret
  256. endp    TimerOn
  257. proc    TimerOff near
  258.     uses    bx,cx,dx,si,di
  259.     ;offset of timer routine
  260.     mov    ax,offset _TIM_HNDLR
  261.     ; indicate reset timer request
  262.     mov    dl,ResetTimer
  263.     ; call back device helper routine
  264.     call    [_devHlp] NOLANGUAGE
  265.     ret
  266. endp    TimerOff
  267.  
  268. ;map physical address to a virtual address
  269. proc    PhysToVirt    near
  270.     ;physical address of buffer
  271.     arg    @@phyaddr:dword
  272.     ;length of buffer
  273.     arg    @@length:word
  274.     ;address ad which to return virtual address
  275.     arg    @@retaddr:dword
  276.     ;registers that we use
  277.     uses    bx,cx,dx,si,di,es
  278.  
  279.     ;indicate physical address in registers
  280.     mov    bx,[word @@phyaddr]
  281.     mov    ax,[word @@phyaddr+2]
  282.     ;indicate length of buffer
  283.     mov    cx,[@@length]
  284.     ;indicate return address in es:di
  285.     mov    dh,1
  286.     ;indicate map physical to virtual address
  287.     mov    dl,CPhysToVirt
  288.     ;call back device helper routine.
  289.     call    [_devHlp] NOLANGUAGE
  290.  
  291.     ;save address segment in dx
  292.     mov    dx,es
  293.  
  294.     ;make es:si point to place to return address to caller
  295.     les    si,[@@retaddr]
  296.  
  297.     ;return offset to caller
  298.     mov    [word es:si],di
  299.     ;return segment to caller.
  300.     mov    [word es:si+2],dx
  301.  
  302.     ret                ;done
  303. endp    PhysToVirt
  304.     end                        ;
  305.  
  306.