home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / c / kernel.zip / K4.ASM < prev    next >
Assembly Source File  |  1986-11-25  |  14KB  |  499 lines

  1. ;Listing 4    High Resolution Clock
  2. ;(C) Copyright 1986 Ken Berry.
  3. ;All rights reserved.
  4. ;Copies may be made for non-commercial, private use only.
  5. ;
  6.  
  7.       include tele.mac ; system defintions (listing 2)
  8.  
  9.       extrn t_syxtm:word ; system execution time accumulator
  10.       extrn sys_dgrp:word ; data segment storage
  11.       extrn sys_stat:word ; original register block
  12.  
  13.       public t__tick ; system tick interrupt service
  14.       public t_astrm ; application task termination flag
  15.       public tmr_dspl ; physical display pointer
  16.       public tmr_dvsr ; timer period
  17.       public tmr_ilck ; tick service reentrant interlock
  18.       public tmr_sync ; synchronization function address
  19.       public tmr_tkct ; tick clock
  20.       public tmr_xtm ; tick service execution time
  21.       public tmr__clr ; reset time base generation
  22.       public tmr__int ; timer initialization function
  23.       public tmr__rst ; timer termination function
  24.       public tmr__sts ; read timer status
  25.       public tmr__tmr ; restart hardware timer
  26.       public t_rdclk ; read high resolution clock
  27.       public t_rtactg ; psuedo time accumulator pointer
  28.       public t_rtmark ; mark execution interval
  29.       public t__rdclk ; read real time clock
  30.       public td_ref ; clock update tick reference count
  31.       public td_tct ; clock tick timer
  32.       public td__set ; set time of day clock
  33.       public td__upd ; update time of day clock
  34.       public w__cdspl ; physical display update function
  35.       public w__sync ; physical display synchronization
  36.  
  37. RLCINT      equ 80h     ; relocated alternate time base interrupt
  38. TMRINT      equ 8      ; hardware timer interrupt
  39. TMRPRT      equ 40h     ; timer (8253) port
  40. TMRPRD      equ 19912     ; timer period (60 Hz rate)
  41. ;TMRPRD    equ 9956      ; timer period (120 Hz rate)
  42. INTPRT      equ 20h     ; interrupt controller (8259) port
  43. TMRMSK      equ 01h     ; hardware timer interrupt mask
  44. INTEOI      equ 20h     ; interrupt termination value
  45. DSPCT      equ 1      ; 60 Hz interrupt rate
  46. ;DSPCT       equ 2      ; 120 Hz interrupt rate
  47. IDV0      equ 3      ; tmr_idv0 divisor
  48. ISKP0      equ 776     ; tmr_ict correction value
  49. ISKP1      equ 11     ; tmr_idv1 correction value
  50. ISKP2      equ 38     ; tmr_idv2 correction value
  51.  
  52.       dseg
  53.  
  54. tmr_tkct  dw 0         ; interrupt counter
  55. tmr_dct   db 0         ; display counter
  56. tmr_ict   dw 0         ; tick clock (for time base generation)
  57. tmr_dvsr  dw TMRPRD     ; 1/2 timer period
  58. t_astrm   db 0FFh     ; application task termination flag
  59. tmrflg      db 0FFh     ; system state flag (t__tick)
  60. tmr_ilck  db 0         ; tick service reentrant interlock
  61. tmr_idv0  db 0         ; clock time base generator
  62. tmr_idv1  db 0         ; primary alternate time base generator
  63. tmr_idv2  db 0         ; secondary alternate time base generator
  64. tmr_dspl  dw 0         ; console display w_pwdw pointer
  65. t_rtactg  dw 0         ; psuedo time accumulator pointer
  66. t_rtrfct  dw 0         ; real time reference count
  67. t_rttick  dw 0         ; tick clock phase
  68. tmr_xtm   dw 3 dup (0)     ; tick service psuedo time accumulator
  69. tmrpxtm   dw 0         ; prior psuedo time accumulator pointer
  70. tmr_sync  dw offset pgroup:w__sync ; synchronization function pointer
  71. td_ref      dw 0         ; clock update tick reference count
  72. td_tct      dw 0         ; clock tick timer
  73.  
  74.       endds
  75.  
  76.       pseg
  77.  
  78. ;t__tick          system tick service
  79. ;
  80. ;t__tick\\
  81. ;
  82. ;Control only comes here in response to an interrupt from the system clock.
  83. ;This function serves three purposes. It maintains the system clock, which
  84. ;provides the current date and time for both system and application uses. It
  85. ;also  performs an update of the first physical display. And finally it
  86. ;terminates the execution interval for the current application task.
  87. ;
  88.  
  89. t__tick   proc far
  90.  
  91. ; reentrant lockout
  92.  
  93.       assume ss:nothing,ds:nothing,es:nothing
  94.       sti         ; interrupts on
  95.       push ds     ; protect ds
  96.       push ax     ; protect ax
  97.       mov ax,dgroup  ; establish data addressability
  98.       mov ds,ax
  99.       assume ds:dgroup
  100.       mov al,INTEOI  ; terminate interrupt
  101.       out INTPRT,al
  102.       ilck al,tmr_ilck ; test for not reentrant call
  103.       or al,al
  104.       jz tick
  105.       pop ax     ; restore ax
  106.       pop ds     ; restore ds
  107.       iret         ; return from interrupt
  108.  
  109. ; system interlock
  110.  
  111. tick:      mov t_astrm,0FFh ; terminate application task
  112.       sys_entr tmrflg ; enter system state
  113.  
  114. ; set machine environment
  115.  
  116.       sys_sctx     ; save processor context
  117.       push bp     ; protect bp
  118.       mov bp,sp     ; mark stack location
  119.       lea ax,tmr_xtm ; accumulate psuedo time
  120.       push ax
  121.       call t_rtmark
  122.       mov sp,bp
  123.       mov tmrpxtm,ax ; store prior pointer
  124.  
  125. ; real time system processing
  126.  
  127.       inc tmr_dct     ; remove display harmonics
  128.       mov al,DSPCT
  129.       xor al,tmr_dct
  130.       jnz tick4
  131.       mov tmr_dct,al
  132.       push tmr_dspl  ; display physical window
  133.       call w__cdspl
  134.       mov sp,bp     ; restore stack pointer
  135.       inc tmr_ict     ; increment interrupt counter
  136.       inc tmr_tkct     ; increment tick clock
  137.  
  138. ; time base generation
  139.  
  140.       mov ax,ISKP0     ; long term time base correction
  141.       xor ax,tmr_ict
  142.       jnz tick1
  143.       mov tmr_ict,ax
  144.       call tick5     ; update system tick clock
  145. tick1:      inc tmr_idv0     ; generate clock time base
  146.       mov al,IDV0
  147.       xor al,tmr_idv0
  148.       jnz tick3
  149.       mov tmr_idv0,al
  150.       call tick5     ; update system tick clock
  151.       inc tmr_idv1     ; primary alternate time base correction
  152.       mov al,ISKP1
  153.       xor al,tmr_idv1
  154.       jnz tick2
  155.       mov tmr_idv1,al
  156.       int RLCINT     ; update alternate time base
  157.       inc tmr_idv2     ; secondary alternate time base correction
  158.       mov al,ISKP2
  159.       xor al,tmr_idv2
  160.       jnz tick2
  161.       mov tmr_idv2,al
  162.       int RLCINT     ; update alternate time base
  163. tick2:      int RLCINT     ; update alternate time base
  164.  
  165. ; terminate interrupt service
  166.  
  167. tick3:      push tmrpxtm     ; restore original psuedo time accumulator
  168.       call t_rtmark
  169.       mov sp,bp
  170.       pop bp     ; restore bp
  171.       test tmrflg,0FFh ; test for interrupted system task
  172.       jnz tick4
  173.       xor ax,ax     ; terminate task
  174.       mov tmr_ilck,al ; enable reentrance
  175.       retn         ; near return to system task management
  176.  
  177. tick4:      sys__rctx     ; restore processor context
  178.       cli         ; interrupts off
  179.       mov tmr_ilck,0 ; enable reentrance
  180.       pop ds     ; restore ds
  181.       iret         ; return to interrupted task
  182.  
  183. ; update system tick counter
  184.  
  185. tick5:      mov ax,td_tct  ; test for no overflow
  186.       inc ax
  187.       cmp ax,td_ref
  188.       jne tick6
  189.       call td__upd     ; update clock
  190.       xor ax,ax     ; reset tick counter
  191.       mov td_ref,ax
  192.       mov td_tct,ax
  193. tick6:      inc td_tct     ; increment tick counter
  194.       retn         ; return
  195.  
  196. t__tick   endp
  197.  
  198. ;tmr__int          initialize timer
  199. ;
  200. ;tmr__int()
  201. ;
  202. ;All data areas necessary for clock maintenance are initialized. The hardware
  203. ;timer is programmed for the appropriate rate and its interrupt vector is made
  204. ;to point to sys_tmr. The original vector is relocated and will be used by
  205. ;sys_tmr as the alternate time base.
  206. ;
  207.  
  208. tmr__int  proc near
  209.       call tmr__dsi  ; diable interrupts
  210.       mov ax,dgroup  ; set data segment
  211.       mov sys_dgrp,ax
  212.       mov ax,cs     ; set code segment
  213.       lea si,sys_stat
  214.       mov [si].rcs,ax
  215.       cli         ; interrupts off
  216.       mov tmr_ilck,0FFh ; lockout t__tick
  217.       mov bx,tmr_sync ; test for no synchronization function
  218.       test bx,bx
  219.       jz int0
  220.       lea bx,tmr_sync ; synchronize timer interrupt
  221.       call [bx]
  222.       jmp short int1 ; continue
  223. int0:      call tmr__tmr  ; start timer
  224. int1:      call t_rdclk     ; set real time clock phase
  225.       mov t_rttick,ax
  226.       mov t_rtrfct,ax ; set reference count
  227.       mov t_rtactg,offset dgroup:t_syxtm ; initialize time accumulator
  228.       call td__set     ; set current time
  229.       sti         ; interrupts on
  230.       xor ax,ax     ; form 0
  231.       push ds     ; protect ds
  232.       mov ds,ax     ; relocate original interrupt vector
  233.       mov di,ax
  234.       cli
  235.       mov ax,[di+4*TMRINT]
  236.       mov [di+4*RLCINT],ax
  237.       mov ax,[di+4*TMRINT+2]
  238.       mov [di+4*RLCINT+2],ax
  239.       mov ax,offset pgroup:t__tick ; set interrupt service
  240.       mov [di+4*TMRINT],ax
  241.       mov ax,cs
  242.       mov [di+4*TMRINT+2],ax
  243.       sti         ; interrupts on
  244.       pop ds     ; restore ds
  245.       call tmr__eni  ; enable interrupts
  246.       ret         ; return
  247. tmr__int  endp
  248.  
  249. ;
  250. ;tmr__clr          reset time base generation
  251. ;
  252. ;tmr__clr()
  253. ;
  254. ;The time base adjustment variables are reset. This function is to be called by
  255. ;td__set when the time of day is initially set from a continuous clock. Nothing
  256. ;is returned.
  257. ;
  258.  
  259. tmr__clr  proc near
  260.       xor ax,ax     ; zero time base generation variables
  261.       mov tmr_idv0,al
  262.       mov tmr_idv1,al
  263.       mov tmr_idv2,al
  264.       ret         ; return
  265. tmr__clr  endp
  266.  
  267.  
  268. ;tmr__rst          reset timer
  269. ;
  270. ;tmr__rst()
  271. ;
  272. ;The original interrupt service routine is restored and the hardware clock is
  273. ;reprogrammed. However, the original hardware values are not available in this
  274. ;edition. Therefore the original system state cannot always be restored.
  275. ;
  276.  
  277. tmr__rst  proc near
  278.       mov tmr_ilck,0FFh ; lock out interrupt service
  279.       push ds     ; protect ds
  280.       xor ax,ax     ; restore original interrupt vector
  281.       mov ds,ax
  282.       mov di,ax
  283.       call tmr__dsi  ; disable timer interrupt
  284.       cli         ; interrupts off
  285.       mov ax,[di+4*RLCINT]
  286.       mov [di+4*TMRINT],ax
  287.       mov ax,[di+4*RLCINT+2]
  288.       mov [di+4*TMRINT+2],ax
  289.       pop ds     ; restore ds
  290.       xor bx,bx     ; restart hardware timer
  291.       call tmr__str
  292.       sti         ; interrupts on
  293.       call tmr__eni  ; enable timer interrupt
  294.       ret         ; return
  295. tmr__rst  endp
  296.  
  297. ;tmr__tmr          restart hardware timer
  298. ;
  299. ;tmr__tmr\\
  300. ;
  301. ;Channel 0 of an 8253 timer is initialized to mode 3. The count in bx is then
  302. ;programmed.
  303. ;
  304.  
  305. tmr__tmr  proc near     ; restart timer
  306.       mov bx,tmr_dvsr ; set tele system tick period
  307. tmr__str  proc near     ; set timer period
  308.       mov al,20     ; reset 8253 (mode 0, count >= 8,192)
  309.       out TMRPRT+3,al ; [> 6.8 msec]
  310.       iowait
  311.       out TMRPRT,al
  312.       mov al,36h     ; initialize 8253 (mode 3, both bytes)
  313.       iowait
  314.       out TMRPRT+3,al
  315.       mov al,bl
  316.       iowait
  317.       out TMRPRT,al
  318.       mov al,bh
  319.       iowait
  320.       out TMRPRT,al
  321.       ret         ; return
  322. tmr__str  endp
  323. tmr__tmr  endp
  324.  
  325. ;tmr__sts          read timer status
  326. ;
  327. ;tmr__sts()
  328. ;
  329. ;The returned value is the current count in the timer.
  330. ;
  331.  
  332. tmr__sts  proc near     ; read timer status
  333.       mov al,00h     ; set read mode
  334.       out TMRPRT+3,al
  335.       nop         ; allow timer chip to recover
  336.       in al,TMRPRT     ; read count
  337.       mov ah,al
  338.       in al,TMRPRT
  339.       xchg ah,al
  340.       ret         ; return
  341. tmr__sts  endp
  342.  
  343. ;
  344. ;tmr__dsi          disable interrupt
  345. ;
  346. ;tmr__dsi()
  347. ;
  348. ;The timer interrupt is disabled at the 8259 interrupt controller.
  349. ;
  350.  
  351. tmr__dsi  proc near
  352.       cli         ; interrupts off
  353.       in al,INTPRT+1 ; disable timer interrupt
  354.       or al,TMRMSK
  355.       iowait
  356.       out INTPRT+1,al
  357.       sti         ; interrupts on
  358.       ret         ; return
  359. tmr__dsi  endp
  360.  
  361. ;tmr__eni          enable interrupt
  362. ;
  363. ;tmr__eni()
  364. ;
  365. ;The timer interrupt is enabled at the 8259 interrupt controller.
  366. ;
  367.  
  368. tmr__eni  proc near
  369.       cli         ; interrupts off
  370.       in al,INTPRT+1; ; enable timer interrupt
  371.       and al,not TMRMSK
  372.       iowait
  373.       out INTPRT+1,al
  374.       sti         ; interrupts on
  375.       ret         ; return
  376. tmr__eni  endp
  377.  
  378. ;
  379. ;t_rdclk          read real time clock
  380. ;
  381. ;t_rdclk()
  382. ;
  383. ;The current value of the real time clock is read and returned.
  384. ;
  385.  
  386. DMAREG      equ 0      ; refresh address DMA register
  387.  
  388. t_rdclk   proc near
  389. rdclk0:   mov dx,DMAREG  ; set DMA register address
  390.       call t__rdclk  ; read time
  391.       mov bx,ax     ; store time
  392.       call t__rdclk  ; read time again
  393.       cmp ah,bh     ; test for interruption
  394.       jne rdclk0
  395.       ret         ; return
  396. t_rdclk   endp
  397.  
  398. t__rdclk  proc near
  399.       cli         ; interrupts off
  400.       in al,dx     ; read time
  401.       mov ah,al
  402.       iowait
  403.       in al,dx
  404.       xchg al,ah
  405.       sti         ; interrupts on
  406.       ret         ; return
  407. t__rdclk  endp
  408.  
  409. ;t_rtmark          mark execution interval
  410. ;
  411. ;t_rtmark(np)
  412. ;pointer *np;
  413. ;
  414. ;The number of refreshes since the last call to t_rtmark is accumulated. Then
  415. ;the reference count is reset. np points to the area that will accumulate the
  416. ;number of refreshes to the next call. The returned value is the original
  417. ;accumulator pointer.
  418. ;
  419.  
  420. t_rtmark  proc near
  421.       push bp     ; protect bp
  422.       mov bp,sp     ; establish parameter addressability
  423.       call tmr__dsi  ; disable timer interrupt
  424.       call t_rdclk     ; read real time clock
  425.       mov bx,ax     ; protect current count
  426.       xchg bx,t_rtrfct ; update reference count
  427.       sub ax,bx     ; compute execution interval
  428.       jnc mark1     ; test for no overflow
  429.       neg ax     ; adjust count
  430. mark1:      mov bx,t_rtactg ; accumulate execution time
  431.       add ax,[bx]
  432.       mov [bx],ax
  433.       jnc markxit
  434.       add word ptr [bx+2],1
  435.       jnc markxit
  436.       inc word ptr [bx+4]
  437. markxit:  mov ax,bx     ; return orginal pointer
  438.       mov bx,[bp].t_np0 ; set new accumulator pointer
  439.       mov t_rtactg,bx
  440.       call tmr__eni  ; enable timer interrupt
  441.       pop bp     ; restore bp
  442.       ret         ; return
  443. t_rtmark  endp
  444.  
  445. ;w__cdspl          display physical buffer
  446. ;
  447. ;w__cdspl(pw)
  448. ;struct w_phys *pw;
  449. ;
  450. ;Physical window pw is displayed.  This function is called by the system tick
  451. ;clock interrupt service function.  Nothing is returned.
  452. ;
  453.  
  454. w__cdspl  proc near
  455.       ret         ; return
  456. w__cdspl  endp
  457.  
  458. ;
  459. ;w__sync          synchronize interrupt to display
  460. ;
  461. ;w__sync()
  462. ;
  463. ;The system tick clock timer is adjusted so that w__dsply executes just prior
  464. ;to the vertical blanking interval.  Nothing is returned.
  465. ;
  466.  
  467. w__sync   proc near
  468.       call tmr__tmr  ; start timer
  469. w__sync   endp
  470.  
  471. ;
  472. ;td__set          set time of day clock
  473. ;
  474. ;td__set()
  475. ;
  476. ;The clock is set to the current time.    Nothing is returned.
  477. ;
  478.  
  479. td__set   proc near
  480.       ret         ; return
  481. td__set   endp
  482.  
  483. ;
  484. ;td__upd          update clock
  485. ;
  486. ;td__upd()
  487. ;
  488. ;The clock is updated based on the number of ticks since it was last updated.
  489. ;The normal return (ax) is _F.    _E is returned if the call was locked out.
  490. ;
  491.  
  492. td__upd   proc near
  493.       ret         ; return
  494. td__upd   endp
  495.  
  496.       endps
  497.  
  498.       end
  499.