home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / asmlib.lbr / SMEPLI.AZM / SMEPLI.ASM
Encoding:
Assembly Source File  |  1991-06-25  |  9.3 KB  |  337 lines

  1. ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2. ; This is a library of routines for interfacing to PL/I-80
  3. ; which supports some added features due to SME Systems hardware 
  4. ; and some other nifty things.
  5. ;
  6. ; This version contains....
  7. ;
  8. ; INITRND    Initialize a random number seed
  9. ; RAND16    Return a random number +-32k in size
  10. ; RANDP16    Return a positive random number 0..32k
  11. ; RAND8        Return an 8 bit number +-127
  12. ; CLKRD        Read the real time clock on SBC-800 into ram
  13. ; CONIN        Return a character from the console
  14. ; CONST        Return the console status
  15. ;
  16. ;    Extended and patchable screen functions.
  17. ;
  18. ; CLEAR        Erase the screen
  19. ; CLEOL        Clear to end of line
  20. ; CLEOP        Clear to end of page
  21. ; SETXY        Position cursor to X, Y co-ords
  22. ; SETREV    Initialize reverse video
  23. ; SETUND    Initialize underlined characters
  24. ; SETHLF    Initialize half intensity characters
  25. ; SETBLK    Initialize blinking characters
  26. ; CLRATT    Clear the current attribute
  27. ; CURON        Enale the cursor
  28. ; CUROFF    Disable the cursor
  29. ;
  30. ;
  31. ; For full documentation on this lot, see SMEPLI DOCUMENTATION which
  32. ; contains examples etc. (if you are lucky)
  33. ;
  34. ;            Written        R.C.H.         26/10/83
  35. ;                      Last Update    R.C.H.           28/11/83
  36. ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  37. ;
  38.     name    'SMEPLI'
  39.     maclib    z80
  40.     public    conin,const,initrnd,randp16,rand16
  41.     public    rand8,clkrd
  42. ;
  43. ;
  44. bdos    equ    5
  45. ;
  46. ;----------------------------------------------------------------
  47. ;           CONIN - Get a character from the console
  48. ; This function returns the first character typed on the keyboard.
  49. ; The character is returned as char(1) to PL/I.
  50. ;
  51. ; This function uses the bdos function 10 to return the character 
  52. ; which is not echoed as it is received. This is l;eft to the user.
  53. ;----------------------------------------------------------------
  54. ;
  55. conin:
  56.     call    cst
  57.     jrz    conin            ; wait for a character
  58. ; Now do a direct bdos call for the character
  59. conin1:
  60.     mvi    e,0ffh            ; get character routine
  61.     mvi    c,06            ; direct console i/o
  62.     call    bdos            ; character is in A now
  63.     ora    a
  64.     jrz    conin1            ; if no character, wait for it
  65. ; Now load the character onto PL/I's stack
  66.     pop    h            ; drop off return address
  67.     push    psw            ; put the character onto it
  68.     inx    sp            ; bump stack
  69.     mvi    a,1            ; characters on stack = 1
  70.     pchl                ; trick return
  71. ;
  72. ;----------------------------------------------------------------
  73. ;             CONST - Get the console status. 
  74. ;
  75. ; If a character is ready then the return is a true flag else
  76. ; a false flag is returned. This function uses the bdos function 
  77. ; 10 to detect if the character is there.
  78. ;----------------------------------------------------------------
  79. ;
  80. const:
  81.     call    cst            ; get the status 
  82.     ora    a            ; zero ?
  83.     rz                ; return if so
  84.     mvi    a,0ffh            ; clean true value
  85.     ret                ; if not then make it positively so
  86. ;
  87. ; The following code merely uses bdos function 11 to return the console
  88. ; status.
  89. ;
  90. cst:    
  91.     push    h
  92.     push    b
  93.     push    d
  94.     mvi    c,11            ; get console status fumction
  95.     call    bdos
  96.     pop    d
  97.     pop    b
  98.     pop    h
  99.     ora    a            ; Set the flag 00 = not ready
  100.     ret
  101. ;
  102. ;----------------------------------------------------------------
  103. ;         CLKRD - Read the real time clock
  104. ;
  105. ; This function uses the SBC-800 real time clock to return the 
  106. ; time into a piece of memory that may be either bit(8) or bin(7)
  107. ; or whatever. I like using a structure laid out with
  108. ; fileds called year,month,day,dow,hour,minute,second declared as
  109. ; bit(8) or bin(7) where appropriate.
  110. ;
  111. ; The following equates specify the port addresses of the real time clock
  112. ; chip and interface. The clock chip is an OKI 5832 and the interface 
  113. ; is an intel 8255.
  114. ;
  115. ; HACKERS - The following is a particularly nasty piece of code
  116. ;            which holds the OKI 5832 clock chip and reads all the 
  117. ;            internal registers. If running at 6Mhz then the timing loops
  118. ;            for the hold times may need expanding out to suit.
  119. ;
  120. ;----------------------------------------------------------------
  121. ;
  122. ;Clock and centronics ports on the sbc-800
  123. ;
  124. pp0a    equ    84h            ; Port a 0
  125. pp0b    equ    pp0a+1            ; Port b 0
  126. pp0c    equ    pp0a+2            ; Port c 0
  127. pp0d    equ    pp0a+3            ; Control port 0
  128. ;
  129. ;    I/O lines and part of clock strobe
  130. ;
  131. pp1a    equ    80h            ; Port a 1
  132. pp1b    equ    pp1a+1            ; Port b 1
  133. pp1c    equ    pp1a+2            ; Port c 1
  134. pp1d    equ    pp1a+3            ; Control port 1
  135. ;
  136. ;****************************************************************
  137. ;*        Read Real Time Clock to memory            *
  138. ;*        pointed by DE, and stored as follows        *
  139. ;*                                *
  140. ;*    hl+0 =>    years    1 byte 2 digit bcd            *
  141. ;*      +1 => months  1 byte 2 digit bcd            *
  142. ;*      +2 => days    1 byte 2 digit bcd            *
  143. ;*      +3 => dweek    1 byte 1 digit bcd ** low nibble only ***
  144. ;*      +4 => hours   1 byte 2 digit bcd            *
  145. ;*      +5 => minutes 1 byte 2 digit bcd            *
  146. ;*      +6 => seconds 1 byte 2 digit bcd            *
  147. ;*                                *
  148. ;****************************************************************
  149. ;
  150. ; Note that the user passes a POINTER to this function which then
  151. ; writes the bytes to the address for 7 bytes. Use carefully, it is
  152. ; a good routine to corrupt memory if poorly used.
  153. ;
  154. clkrd:    ; Read clock into memory at DE 
  155.     call    getp2             ; return the address in de
  156.     xchg                ; put into hl
  157. ;
  158. ; Here try to hold the clock chip for 150 us. 
  159.     mvi    a,00001101b        ; Hld bit
  160.     out    pp0d            ; Set bit
  161. ; Now load a counter for a 150 us delay.
  162.     mvi    b,120            ; 7 T
  163. ;
  164. hld$wait:
  165.     djnz    hld$wait        ; 8/10 T
  166. ;
  167.     out    pp1d            ; this is the read bit load
  168. ; Loop to read all registers in one go
  169.     mvi    b,12            ; register count
  170. rclk1:
  171.     call    get$reg
  172.     mov    a,b
  173.     cpi    6            ; Was it day of week
  174.     jrz    rclk2            ; Skip second register if so
  175.     dcr    b            ; Next register
  176.     call    get$reg            ; read the register
  177. rclk2:    ; Jump here after reading day of week
  178.     inx    h            ; next byte in ram to rotate into
  179.     dcr    b            ; register number
  180.     xra    a
  181.     ora    b            ; set the minus flag
  182.     jp    rclk1
  183. ; restore the port bits
  184.            mvi    a,00001100b        ; Reset bit 6
  185.     out    pp0d
  186.     out    pp1d               ; Clear hold+read
  187.     ret
  188. ;
  189. get$reg:    ; Read register in B into memory with an RLD
  190.     mov    a,b
  191.     out    pp0b
  192.     mvi    a,8
  193. rdreg1:    ; This loop is needed for a 6 us delay for reading the register
  194.     dcr    a
  195.     jrnz    rdreg1            ; another wait of 15 us or better
  196.     in    pp0a
  197.     ani    15            ; Get data
  198.     rld                ; Saved in memory
  199.     ret
  200. ;
  201. ;----------------------------------------------------------------
  202. ;         RANDOM NUMBER ROUTINES
  203. ;
  204. ; These routines intialize/return random numbers. The user must
  205. ; feed these routines a string of bytes (5 minimum) which are used as
  206. ; a seed. The initialization uses the Z-80 refresh register as a
  207. ; jumble function of these bytes.
  208. ;
  209. ;         This is a module in the ASMLIB Library.
  210. ;
  211. ; This module generates PSEUDO RANDOM NUMBERS by using a seed array
  212. ; and doing adds and shifts on the bytes in the array. 
  213. ;
  214. ;----------------------------------------------------------------
  215. ;
  216. initrnd:    ; initialize the random number seed string pointed to
  217.     call    getp2        ; get the pointer to the string
  218.     ldax    d        ; get the string size
  219.     cpi    5
  220.     rc            ; Error if less than 5 elements in the array
  221.     push    d
  222.     push    b
  223.     mov    b,a        ; Load counter
  224.     xchg
  225.     inx    h        ; Now HL -> first seed byte
  226.     ldar            ; Get refresh register value
  227.     dcr    b        ; Do one less than the required
  228. initloop:
  229.     add    m
  230.     rrc
  231.     mov    m,a
  232.     inr    m
  233.     mov    a,m
  234.     inx    h
  235.     djnz    initloop
  236. ; Restore and exit gracefully
  237.     xchg            ; Restore HL
  238.     pop    b
  239.     pop    d        ; Restore other registers
  240.     ret
  241. ;
  242. ; Return an 8 bit random number in A
  243. ;
  244. rand8:    
  245.     call    getp2        ; get the strings address
  246. rand81:
  247.     ldax    d        ; A = number of seeds
  248.     cpi    5        ; Check if less than 5 seed values
  249.     rc            ; Return with a carry to indicate an error
  250. ; Here we load the number of cells into B then decrtement so as to skip
  251. ; these which are operated on later.
  252.     push    b
  253.     push    d        ; Saver address of seed array
  254.     mov    b,a
  255.     dcr    b
  256.     dcr    b
  257.     inx    d        ; DE -> first seed in the array
  258.     xchg            ; Put memory pointer into HL
  259. ;
  260. ;Loop for N-2 times.
  261. loop:    inr    m        ;INCREMENT SEED VALUE.
  262.     mov    a,m
  263.     inx    h        ;HL POINTS TO NEXT SEED VALUE IN ARRAY.
  264.     add    m
  265.     rrc            ;ROTATE RIGHT CIRCULAR ACCUMULATOR.
  266.     mov    m,a
  267.     djnz    loop
  268. ;
  269. ; Last iteration to compute random byte in register a.
  270.     inx    h         ; HL -> last byte in the array
  271.     add    m
  272.     cma            ; complement the accumulator
  273.     rrc            ; rotate it right
  274.     mov    m,a
  275.     xra    a        ; Clear carry
  276.     mov    a,m        ; Re-load value, carry not set.
  277. ;
  278. ; Restore the registers and return with the value in A
  279. error:    
  280.     xchg            ; Restore HL
  281.     pop    d
  282.     pop    b
  283.     ret
  284. ;
  285. ; Return a 16 bit random number in HL.
  286. ;
  287. rand16:
  288.     call    getp2        ; get string address
  289.     push    d
  290.     call    rand81
  291.     mov    h,a        ; msb byte
  292.     pop    d        ; restore string address
  293.     call    rand81
  294.     mov    l,a        ; lsb byte
  295.     ret
  296. ;
  297. ; Return a positive 16 bit random number
  298. ;
  299. randp16:
  300.     call    rand16        ; get the number
  301.     mov    a,h
  302.     ani    07fh        ; Mask off top bit
  303.     mov    h,a        ; restore
  304.     mov    a,l        ; echo lsb in a
  305.     ret
  306. ;
  307. getp1:
  308.     mov    e,m
  309.     inx    h
  310.     mov    d,m
  311.     xchg
  312.     mov    e,m
  313.     ret
  314. ;
  315. ;
  316. getp2:
  317.     call    getp1
  318.     inx    h
  319.     mov    d,m
  320.     ret
  321. ;
  322. ;----------------------------------------------------------------
  323. ;         Screen Based Functions.....
  324. ;
  325. ; These are taken from the ASMLIB source code modules and as such are
  326. ; patchable to suit a termial in use by using the SETUP.COM program
  327. ; to write the correct terminal driver into the code patch area.
  328. ;----------------------------------------------------------------
  329.  
  330.  
  331.  
  332.     end
  333.  
  334.  
  335.  
  336.