home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol247 / examples.lbr / PS.AQ6 / ps.a86
Text File  |  1986-02-27  |  12KB  |  338 lines

  1. ;
  2. ; miscellaneous equates...
  3. zero    equ     0
  4. one     equ     1
  5. cr      equ     0dh
  6. lf      equ     0ah
  7.  
  8. ; set up code segment group
  9. codeseg cseg
  10. cgroup  group codeseg
  11.  
  12. ; first initialize the UDA field of all of the sub-process process
  13. ; descriptors.  The UDA field must contain the offset in number of 
  14. ; paragraphs from the beginning of the data segment where each of
  15. ; the sub-process UDA's reside.
  16.  
  17. ; initialize processor descriptor uda field for sub-process 0
  18.         mov     ax,offset uda0
  19.         mov     cl,4
  20.         shr     ax,cl                   ; compute number of paragraphs's
  21.         mov     pd0_uda,ax
  22.  
  23. ; initialize processor descriptor uda field for sub-process 1
  24.         mov     ax,offset uda1
  25.         mov     cl,4
  26.         shr     ax,cl                   ; compute number of paragraphs's
  27.         mov     pd1_uda,ax
  28.  
  29. ; initialize processor descriptor uda field for sub-process 2
  30.         mov     ax,offset uda2
  31.         mov     cl,4
  32.         shr     ax,cl                   ; compute number of paragraphs's
  33.         mov     pd2_uda,ax
  34.  
  35. ; initialize processor descriptor uda field for sub-process 3
  36.         mov     ax,offset uda3
  37.         mov     cl,4
  38.         shr     ax,cl                   ; compute number of paragraphs's
  39.         mov     pd3_uda,ax
  40.  
  41. ; Create initial seed for random number generator.  We'll use the seconds
  42. ; field of the system time of day.
  43.         mov     dx,offset time_of_day
  44.         call    t_seconds               ; get the time of day
  45.         mov     ax,min_sec              ; get seconds
  46.         mov     r,ax                    ; store seed.
  47.  
  48. ; Create the sub processes, since the link fields point from sub-process 0
  49. ; to sub-process 1 on up to sub-process 3, only one process create call
  50. ; is needed.  See the CCP/M Programmer's Guide for more information on the
  51. ; process descriptor fields,
  52.         mov     dx,offset pd0
  53.         call    p_create
  54.  
  55. ; signon and set up the screen.
  56.         mov     dx,offset signon
  57.         call    c_writestr
  58.  
  59. ; Everything is now set up, so loop printing the status of the sub-processes
  60. ; until a character is typed.
  61. print_status:
  62.         mov     dx,offset status_mess   ; print the status message
  63.         call    c_writestr
  64.         mov     dl,0ffh                 ; character status code
  65.         call    c_rawio                 ; character typed ?
  66.         cmp     al,0
  67.         jz      print_status            ; nope, continue looping
  68.  
  69. ; Character has been typed, so set the abort flag so the sub-processes will
  70. ; also abort, and print the exit message
  71.         mov     abort,1                 ; set abort flag
  72.         mov     dx,offset exit_mess
  73.         call    c_writestr              ; print the exit message
  74.         call    p_termcpm               ; abort the main program
  75.  
  76. ; The following is the code for each of the sub-processes.  The sub-process
  77. ; number has already been placed in the BX register of each of the
  78. ; sub-processes.  This value will be used as a seed for the random number
  79. ; generator and as an index into the process status table
  80. sub_proc:
  81.         call    delay                   ; delay for a random period of time
  82.         call    toggle                  ; toggle the processes status
  83.         call    check                   ; check the abort flag
  84.         jmp     sub_proc                ; do this forever
  85.  
  86. ; Delay for some period of time.
  87. delay:
  88. ; First compute a random number, I'm using the same algorithm that is used in
  89. ; the Cbasic compiler.
  90.         push    bx                      ; save device number
  91.         mov     ax,12949                ; knuth multiplier
  92.         mul     r                       ; get the seed
  93.         add     ax,6925                 ; knuth constant
  94.         and     ah,7fh                  ; make it 15 bit value
  95.         cwd                             ; ensure high 16 bits off before devide
  96.         mov     r,ax                    ; save new random number to use as seed
  97.                                         ; for next call.
  98.         mov     si,328                  ; scale it from 0-99
  99.         div     si
  100. ; We've got a random number between 0 and 99, so let's delay that number of
  101. ; ticks. 
  102.         mov     dx,ax                   ; set up number of ticks for delay call
  103.         call    p_delay                 ; pause for some period of time
  104.         pop     bx                      ; restore device number.
  105.         ret
  106.  
  107. ; toggle the current status for the device from '0' to '1' or vise-versa
  108. toggle: push    bx                      ; save sub-process number
  109.         mov     al,4
  110.         mul     bl                      ; compute offset
  111.         mov     bx,ax
  112.         mov     al,status[bx]           ; get current status
  113.         cmp     al,48                   ; is it zero ?
  114.         jz      is_one                  ; yep, change it to one
  115. is_zero:
  116.         mov     al,48                   ; nope, change it to zero
  117.         jmp     update_status
  118. is_one: mov     al,49
  119.  
  120. update_status:
  121.         mov     status[bx],al           ; update status table
  122.         pop     bx                      ; restore sub-process number
  123.         ret
  124.  
  125. ; should we abort ???
  126. check:
  127.         cmp     abort,0                 ; is it zero
  128.         jnz     exit                    ; nope, abort the  program
  129.         ret                             ; otherwise just return
  130. exit:   call    p_termcpm
  131.  
  132. ;
  133. ; Concurrent CP/M System calls
  134. ;
  135. c_assign:       mov     cl,149  ! jmp   call_cpm
  136. c_attach:       mov     cl,146  ! jmp   call_cpm
  137. c_detach:       mov     cl,147  ! jmp   call_cpm
  138. c_read:         mov     cl,1    ! jmp   call_cpm
  139. c_readstr:      mov     cl,10   ! jmp   call_cpm
  140. c_rawio:        mov     cl,6    ! jmp   call_cpm
  141. c_set:          mov     cl,148  ! jmp   call_cpm
  142. c_write:        mov     cl,2    ! jmp   call_cpm
  143. c_writestr:     mov     cl,9    ! jmp   call_cpm
  144. f_open:         mov     cl,15   ! jmp   call_cpm
  145. f_parce:        mov     cl,152  ! jmp   call_cpm
  146. f_read:         mov     cl,20   ! jmp   call_cpm
  147. l_attach:       mov     cl,158  ! jmp   call_cpm
  148. l_writeblk:     mov     cl,112  ! jmp   call_cpm
  149. p_cli:          mov     cl,150  ! jmp   call_cpm
  150. p_create:       mov     cl,144  ! jmp   call_cpm
  151. p_delay:        mov     cl,141  ! jmp   call_cpm
  152. p_priority:     mov     cl,145  ! jmp   call_cpm
  153. p_termcpm:      mov     cl,0    ! jmp   call_cpm
  154. q_cread:        mov     cl,138  ! jmp   call_cpm
  155. q_delete:       mov     cl,136  ! jmp   call_cpm
  156. q_make:         mov     cl,134  ! jmp   call_cpm
  157. q_open:         mov     cl,135  ! jmp   call_cpm
  158. q_read:         mov     cl,137  ! jmp   call_cpm
  159. q_write:        mov     cl,139  ! jmp   call_cpm
  160. s_bios:         mov     cl,50   ! jmp   call_cpm
  161. t_seconds:      mov     cl,155  ! jmp   call_cpm
  162.  
  163. call_cpm:       int     224
  164.                 ret
  165.  
  166. ; set up data segment groups
  167.         dgroup  group   d4,d0,d1,d2,d3  ; dx is used a name of a data
  168.                                         ; group, don't be concerned
  169.                                         ; about their meaning.
  170.  
  171. d4      dseg
  172.  
  173. r       dw      0                       ; storate for rand. number seed
  174.  
  175. ; Time of day structure
  176. time_of_day     dw      0
  177. hour            db      0
  178. min_sec         dw      0
  179.  
  180. ; Signon message clears screen, disables cursor, and displays
  181. ; device status display header.  It uses the escape sequences for the IBM
  182. ; PC, it also works on a Z-19/29
  183. signon  db      1bh,'E',1bh,'f',cr,lf
  184.                 db      '  Device Controller Status',cr
  185.                 db      lf,lf,lf
  186.                 db      '          Device',cr,lf
  187.                 db      '       0   1   2   3',cr,lf,'$'
  188.  
  189. ; Device status message and table.  Each sub-process will toggle one 
  190. ; byte in this message from '1' to a '0' of vise-versa, depending on
  191. ; what the new 'status' of the device is. 
  192. status_mess     db      'State  '
  193. status          db      48,'   '
  194.                 db      48,'   '
  195.                 db      48,'   '
  196.                 db      48,cr,'$'
  197.  
  198. ; Abort flag.  This byte is set to 1 by the parent process when it
  199. ; wants the sub-processes to stop.
  200. abort   db      0
  201.  
  202. ; This message is displayed on termination of the parent process. 
  203. ; (It re-enables the cursor)
  204. exit_mess       db      cr,lf,lf,1bh,'e$'
  205.  
  206. ; declarations for each of the sub-process process descriptors, refer
  207. ; to the CCP/M Programmer's Reference Guide for complete description of
  208. ; the PD fields
  209.  
  210. ; process descriptor 0
  211. pd0     dw      offset pd1,0            ; link, thread fields
  212.         db      0,200,0,0               ; status, priority, flag fields
  213. pd0_name        db      'SP0     '      ; sub-process name
  214. pd0_uda dw      0                       ; offset to UDA
  215. ; remaining fields are initialized to 0
  216.         dw      0,0,0,0,0,0,0
  217. pd0_cns db      0,0,0,0,0,0
  218.         dw      0,0,0,0,0
  219.  
  220. ; process descriptor 1
  221. pd1     dw      pd2,0
  222.         db      0,200,0,0
  223. pd1_name        db      'SP1     '
  224. pd1_uda dw      0
  225.         dw      0,0,0,0,0,0,0
  226. pd1_cns db      0,0,0,0,0,0
  227.         dw      0,0,0,0,0
  228.  
  229. ; process descriptor 2
  230. pd2     dw      pd3,0
  231.         db      0,200,0,0
  232. pd2_name        db      'SP2     '
  233. pd2_uda dw      0
  234.         dw      0,0,0,0,0,0,0
  235. pd2_cns db      0,0,0,0,0,0
  236.         dw      0,0,0,0,0
  237.  
  238. ; process descriptor 3
  239. pd3     dw      0,0
  240.         db      0,200,0,0
  241. pd3_name        db      'SP3     '
  242. pd3_uda dw      0
  243.         dw      0,0,0,0,0,0,0
  244. pd3_cns db      0,0,0,0,0,0
  245.         dw      0,0,0,0,0
  246.  
  247. ; Declarations for each of the sub-process UDA's, refer to the CCP/M
  248. ; Programmer's Reference Guide for description of the UDA fields.
  249.  
  250. ; user date area 0
  251. d0      dseg    para                    ; set to page boundary
  252. uda0    rw      16
  253.         dw      0
  254. bx_reg0 dw      0
  255.         dw      0,0,0,0,0
  256.         rw      3
  257.         dw      init_sp0
  258.         dw      0,0,0,0,0,0,0,0,0,0,0,0,0
  259. init_cs0        dw      codeseg
  260. init_ds0        dw      d0
  261. init_es0        dw      d0
  262. init_ss0        dw      d0
  263.         dw      0,0,0,0,0,0,0,0
  264.         rw      0ffh-67h
  265.  
  266.         rw      20
  267. init_sp0        dw      sub_proc
  268.  
  269. cs_init0        dw      codeseg,0
  270.  
  271. d1      dseg    para
  272.  
  273. ; user date area 1
  274. uda1    rw      16
  275.         dw      0
  276. bx_reg1 dw      1
  277.         dw      0,0,0,0,0
  278.         rw      3
  279.         dw      init_sp1
  280.         dw      0,0,0,0,0,0,0,0,0,0,0,0,0
  281. init_cs1        dw      codeseg
  282. init_ds1        dw      d1
  283. init_es1        dw      d1
  284. init_ss1        dw      d1
  285.         dw      0,0,0,0,0,0,0,0
  286.         rw      0ffh-67h
  287.  
  288.         rw      20
  289. init_sp1        dw      sub_proc
  290.  
  291. cs_init1        dw      codeseg,0
  292.  
  293. d2      dseg    para
  294.  
  295. ; user date area 2
  296. uda2    rw      16
  297.         dw      0
  298. bx_reg2 dw      2
  299.         dw      0,0,0,0,0
  300.         rw      3
  301.         dw      init_sp2
  302.         dw      0,0,0,0,0,0,0,0,0,0,0,0,0
  303. init_cs2        dw      codeseg
  304. init_ds2        dw      d2
  305. init_es2        dw      d2
  306. init_ss2        dw      d2
  307.         dw      0,0,0,0,0,0,0,0
  308.         rw      0ffh-67h
  309.  
  310.         rw      20
  311. init_sp2        dw      sub_proc
  312.  
  313. cs_init2        dw      codeseg,0
  314.  
  315. d3      dseg    para
  316.  
  317. ; user date area 3
  318. uda3    rw      16
  319.         dw      0
  320. bx_reg3 dw      3
  321.         dw      0,0,0,0,0
  322.         rw      3
  323.         dw      init_sp3
  324.         dw      0,0,0,0,0,0,0,0,0,0,0,0,0
  325. init_cs3        dw      codeseg
  326. init_ds3        dw      d3
  327. init_es3        dw      d3
  328. init_ss3        dw      d3
  329.         dw      0,0,0,0,0,0,0,0
  330.         rw      0ffh-67h
  331.  
  332.         rw      20
  333. init_sp3        dw      sub_proc
  334.  
  335. cs_init3        dw      codeseg,0
  336.  
  337.         end
  338.