home *** CD-ROM | disk | FTP | other *** search
/ The Best of Select: Games Special 2 / CD_1.iso / slowdown / slowdown.asm < prev    next >
Assembly Source File  |  1986-04-05  |  5KB  |  177 lines

  1.  title    SLOWDOWN.COM   System Slowdown Routine    86.04.05a.dkg
  2.  name    dev
  3.  page   60,132
  4. ;
  5. TUNE_SPEED    equ    224    ; tune to your CPU speed (approx Mhz*28)
  6. ;
  7. CR        equ    0dH
  8. LF        equ    0aH
  9. ;
  10. ;-----------------------------------------------------------------------+
  11. ;                                    |
  12. ; PURPOSE:  Provide a method to run an 8MHz 8086 based machine        |
  13. ;        at a comparable speed to the IBM for stupid programs    |
  14. ;        that assume a certain processor speed in their timing.    |
  15. ;                                    |
  16. ; FUNCTION: Intercept the tick interrupt and run a time-waster        |
  17. ;        loop for a user-settable delay before returning to the    |
  18. ;        running program.                        |
  19. ;                                    |
  20. ; TO USE:   From DOS, type SLOWDOWN [<percent>]  where <percent> is    |
  21. ;        percentage of the CPU wasted.                |
  22. ;                                    |
  23. ; WRITTEN:  85.07.26 by David K. Goodwin                |
  24. ; MODIFIED: 86.04.05.dkg, added intvec removal code            |
  25. ;                                    |
  26. ;-----------------------------------------------------------------------+
  27.  
  28. CODE        SEGMENT
  29.         ASSUME    CS:CODE,DS:CODE
  30.  
  31. ;  Program Segment Prefix
  32.  
  33.         ORG    80H
  34. NUM_CHARS    db    ?        ; number of characters in argument
  35.         db    ?        ; leading blank
  36. ARGTX        db    ?        ; start of text (after leading blank)
  37. ;
  38. ;  Program Area
  39. ;
  40.         ORG    100H
  41. begin:        jmp    start
  42.         db    'Copyright 1986, David K. Goodwin'
  43. ;
  44. ;  Interrupt Service Routine
  45. ;  This routine will perform a time-waster loop every system clock tick
  46. ;  18 times per second.  All memory references must use the CS segment prefix
  47. ;  because that is the only segment setup by the INT call.  I am using a
  48. ;  method of Intercept routine ID somewhat like that done in CPMPLUS RSX's
  49. ;  to prevent any conflict of this routine with any others that might
  50. ;  intercept the interrupt I am using.
  51. ;
  52. intvec        dd    ?        ; next interrupt routine in sequence
  53. loopcnt     db    ?        ; number of 1% loops
  54.         db    'SLOWDOWN'      ; Interrupt Intercept ID
  55. tickint:    pushf            ; save flags
  56.         push    ax        ; save our useful reg
  57.         mov    ah,cs:loopcnt    ; load our loop counter
  58. tick1:        push    cx
  59.         mov    cx,TUNE_SPEED
  60. tick2:        loop    tick2
  61.         pop    cx
  62.         dec    ah
  63.         jnz    tick1
  64.         pop    ax        ; restore reg
  65.         popf            ; restore flags
  66.         jmp    cs:[intvec]    ; go to next routine in chain
  67.  
  68. saveaddr    label    byte        ; used as last location to keep in mem
  69. ;
  70. ;  Start of main routine to process the command line.
  71. ;
  72. start:
  73.         mov    dx,offset signon
  74.         mov    ah,9
  75.         int    21H
  76.         mov    bx,offset argtx ; point to start of text argument
  77.         mov    cl,num_chars    ; set cx to number of chars in argument
  78.         xor    ch,ch        ;    "
  79.         sub    cx,1        ; discount char count for leading blank
  80.         ja    parse_arg    ; if so, handle w/termination routine
  81.  
  82. error:        mov    dx,offset errmsg ; if a problem give user help
  83. error2:     mov    ah,9
  84.         int    21h
  85.         mov    ax,4c01h    ; terminate
  86.         int    21h
  87. ;
  88. ;  Parse the numeric argument
  89. ;  If the number is greater than 99 then we will error out with usage.
  90. ;  If argument is zero, we will "unload" the interrupt service routine.
  91. ;
  92. parse_arg:    mov    al,0        ; initialize char value to 0
  93.         mov    dh,10d        ; digit multiplier
  94. getdigit:    mov    dl,[bx]     ; get char code into dl
  95.         sub    dl,'0'          ; convert digit code to value
  96.         jb    error        ; error checks
  97.         cmp    dl,'9'          ;
  98.         ja    error        ; must be a digit
  99.         mul    dh        ; mult. char value (in al) by 10
  100.         add    al,dl        ; add digit value to char value
  101.         inc    bx        ; skip to next char
  102.         dec    cx        ;    "
  103.         jnz    getdigit    ; exit if at end of text (cx = 0)
  104.         cmp    al,99        ; if over 99, error
  105.         ja    error
  106.         mov    loopcnt,al    ; save our loop counter
  107.         mov    ah,35h        ; get old tick interrupt
  108.         mov    al,1ch
  109.         int    21h
  110.         sub    bx,8        ; check for interrupt already alive
  111.         mov    ax,word ptr es:[bx]     ; get first 2 chars
  112.         cmp    ax,'LS'         ; if SL, already exists
  113.         je    exists        ; do mod of routine
  114.         cmp    loopcnt,0    ; if zero, jump to removal routine
  115.         jnz    chgint
  116.         mov    dx,offset notresmsg
  117.         jmp    error2
  118. chgint:        add    bx,8        ; get intvec back to normal
  119.         mov    word ptr intvec,bx
  120.         mov    word ptr intvec+2,es
  121.         mov    ah,25h        ; save new int vector
  122.         mov    al,1ch
  123.         mov    dx,offset tickint
  124.         int    21h
  125.  
  126. ;
  127. ;  Done with loading and initialize
  128. ;  Print out a message to say we did it and leave
  129. ;
  130. complete:    mov    dx,offset byemsg ; point to completion message
  131.         mov    ah,9        ; code for dos display string function
  132.         int    21h        ; display message via dos function call
  133.         mov    ah,31h        ; keep program in memory for int vector
  134.         mov    al,0
  135.         mov    dx,offset saveaddr
  136.         int    21h        ; bye bye
  137. notresmsg:    db    'SLOWDOWN not resident$'
  138. byemsg:     db    'SLOWDOWN loaded$'
  139.  
  140. exists:        mov    al,loopcnt        ; get specified loopcnt
  141.         cmp    al,0            ; if we are removing
  142.         jz    rmvint    
  143.         dec    bx            ; point int copy of loopcnt
  144.         mov    byte ptr es:[bx],al    ; save percentile
  145.         mov    dx,offset existmsg
  146.         jmp    goodret
  147. existmsg:    db    'SLOWDOWN started at new value$'
  148.  
  149. rmvint:        sub    bx,5            ; point to old intvec
  150.         push    ds
  151.         cli
  152.         lds    dx,es:[bx]        ; get old int vector
  153.         mov    ah,25h            ; restore old int vector
  154.         mov    al,1ch
  155.         int    21h
  156.         sti
  157.         pop    ds
  158.         mov    dx,offset rmvmsg
  159.         jmp    goodret
  160. rmvmsg:        db    'SLOWDOWN removed$'
  161.  
  162. goodret:     mov    ah,9
  163.         int    21h
  164.         mov    ax,4c00h    ; terminate
  165.         int    21h
  166.  
  167. signon:        db    'SLOWDOWN v1.1a   86.04.05.dkg',CR,LF,'$'
  168. errmsg:        db    CR,LF
  169.         db    'usage: a>SLOWDOWN <percent>',CR,LF
  170.         db    '       where <percent> is between 0 and 99',CR,LF
  171.         db    '       if <percent> is 0, remove slowdown interrupt',CR,LF
  172.         db    '$'
  173.  
  174. code        ends
  175.  
  176.         end    begin
  177.