home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / sysutl / busy1.arc / BUSY1.ASM < prev    next >
Assembly Source File  |  1989-11-08  |  9KB  |  414 lines

  1. Comment    ~
  2.  
  3. BUSY symbol display for assembly language programs.
  4.  
  5. The original idea came from BUSY.C (credits below).
  6.  
  7. /*
  8. **    This program demonstrates several "busy indicators", and also
  9. **    serves as a example of using the BIOS clock tick timer at 40:40
  10. **    Written in 1989 by Otto Makela, Jyvaskyla, Finland.
  11. **    Permission is granted to copy this code freely, though a small
  12. **    mention of the source would be appreciated... :-)
  13. */
  14.  
  15. However, his demo wasn't really practical .. a REAL busy symbol
  16. should be a "background" process, so your own program can gleefully
  17. go about its business, knowing the user is being entertained at the
  18. console.
  19.  
  20. Plus .. he used a funny clock.  The one at 40:40 is for floppy disk
  21. timeout, and isn't a REAL clock!
  22.  
  23. We'll make our busy signal a background process by sitting on the user-defined
  24. clock tick interrupt (1CH).
  25.  
  26. Rather than mess with clocks (since we have a guaranteed 18.2 ticks-per-
  27. second interrupt), we'll just maintain our own internal clocks.
  28.  
  29. I've arbitrarily decided to blink about every 1/4 of a second.
  30.  
  31. Since this is only a stubbed demo, we're gonna use the Inter-Application
  32. Communications Area (IAC)
  33.     (1) to determine when the "busy" time is over,
  34.     and (2) as two internal byte-sized clocks.
  35.  
  36. Actually, this would probably work ok in a real program .. so long as
  37. you didn't have your own uses for the IAC.  We don't REALLY have to
  38. do this .. there are other ways .. just showing off, and demonstrating
  39. how we don't have to worry about code or data segments by putting
  40. variables entirely outside the program's world!
  41.  
  42. Some notes from an IAC display program I tweaked:
  43.  
  44.     The IAC is 16 bytes beginning at addr 0040:00F0h. Any program can
  45.     write information to the IAC for another program to read. Please
  46.     note: unless the first program directly    invokes the second program,
  47.     it cannot protect the IAC from being altered by an intervening program.
  48.     The IAC can be used, for instance, to pass an address from one program
  49.     to the next.
  50.  
  51. This demo (as BUSY.C did) shows all sorts of likely (?) busy indicators.
  52. Pick the one you like and discard the code for the rest.  (An exercise
  53. for the student.)
  54.  
  55. David Kirschbaum
  56. Toad Hall
  57. kirsch@arsocomvax.socom.mil
  58.  
  59. Comment    ends    ~
  60.  
  61.  
  62. CR    EQU    0DH
  63. LF    EQU    0AH
  64.  
  65. PAGE0    SEGMENT    AT    0
  66.     org    46CH            ;BIOS clock
  67. clock    db    ?
  68.  
  69.     org    4F0H
  70. iac    db    ?
  71. tick    db    ?        ;1st Busy internal clock
  72. tick1    db    ?        ;2d internal clock
  73.     db    13 DUP(?)
  74.  
  75. PAGE0    ENDS
  76.  
  77. CSEG    SEGMENT    PUBLIC PARA 'CODE'
  78.     ASSUME    CS:CSEG, DS:CSEG, ES:CSEG
  79.  
  80.     org    100H
  81.  
  82. Busy_Demo    PROC    NEAR
  83.  
  84.     jmp    Start
  85.  
  86.     EVEN                ;make it easier for snarfing
  87.  
  88. s2_1    db    '▄▀'            ;[i&1]
  89. s2_2    db    '▌▐'            ;[i&1]
  90.  
  91. s4_1    db    '/|\-'            ;[i&3]
  92. s4_2    db    ' -÷:'            ;[i&3]
  93. s4_3    db    '-=≡='            ;[i&3]
  94. s4_4    db    30,16,31,17        ;[i&3]
  95. s4_5    db    '▄▐▀▌'            ;[i&3]
  96.  
  97. s8_1    db    '║╗═╔║╚═╝'        ;[i&7]
  98. s8_2    db    ' ░▒▓█▓▒░'        ;[i&7]
  99. s8_3    db    ' ·∙',9,'O',9,'∙·'    ;[i&7]
  100.  
  101. old_Int1C    dd    0        ;save orig Int 1CH clock vector
  102.  
  103. scr_vec    label    dword            ;screen seg:ofs for writing busy chars
  104.     dw    0            ;this'll be posted during installation
  105.     dw    0B000H            ;default is monochrome screen
  106. cursize    dw    0            ;save cursor size
  107.  
  108. Busy_Demo    ENDP
  109.  
  110.  
  111. Busy    PROC    FAR
  112.  
  113.     sti                ;ints back on
  114.     push    ax            ;save caller's AX
  115.     push    DS            ; and DS
  116.  
  117.     xor    ax,ax
  118.     mov    DS,ax
  119.     ASSUME    DS:PAGE0
  120.  
  121.     cmp    iac,al            ;is busy flag turned on?
  122.     jz    Not_Busy        ;nope, no work to do
  123.  
  124.     cmp    tick,al            ;internal clock 0?
  125.     jz    Ticked            ;yep, go to work
  126.     dec    tick            ;decrement internal clock
  127.     jz    Ticked            ;0, go to work
  128.  
  129. Not_Busy:
  130.     jmp    Old_Clock
  131.  
  132. Ticked:
  133.     mov    al,8            ;handy constant
  134.     mov    tick,al            ;refresh tick counter
  135.  
  136.     mov    ah,tick1        ;pick up 2d clock
  137.     inc    ah            ;bump 2d clock
  138.     cmp    ah,al            ;< 8? (7 is max)
  139.     jb    Ticked1            ;not 8 yet
  140.      xor    ah,ah            ;> 7, reinit to 0
  141. Ticked1:
  142.     mov    tick1,ah        ;update 2d clock
  143.  
  144.     push    bx            ;save regs
  145.     push    dx
  146.     push    si
  147.     push    di
  148.     push    ES
  149.  
  150.     mov    dx,CS
  151.     mov    DS,dx
  152.     ASSUME    DS:CSEG
  153.  
  154.     mov    dl,ah            ;keep 2d clock in DL
  155.     cld                ;insure forward
  156.  
  157.     xor    bh,bh            ;clear msb
  158.     les    di,scr_vec        ;screen offset and seg
  159.     ASSUME    ES:NOTHING
  160.  
  161.     mov    ah,7            ;likely attribute
  162.  
  163. ;2 2-char symbols
  164.     mov    bl,dl            ;i
  165.     and    bl,1            ;mask for 2-char symbols
  166.     mov    si,offset s2_1        ;from first busy char (1 of 2)
  167.     call    Stuff_Busy        ;snarf, stuff, bump to next scr psn
  168.  
  169.     mov    si,offset s2_2        ;from 2d busy char (1 of 2)
  170.     call    Stuff_Busy
  171.  
  172. ;5 4-char symbols
  173.  
  174.     mov    bl,dl            ;get i back
  175.     and    bl,3            ;mask for 4-char symbols
  176.     mov    si,offset s4_1        ;1st 4-char table
  177.     call    Stuff_Busy
  178.  
  179.     mov    si,offset s4_2        ;2nd 4-char table
  180.     call    Stuff_Busy
  181.  
  182.     mov    si,offset s4_3        ;3rd 4-char table
  183.     call    Stuff_Busy
  184.  
  185.     mov    si,offset s4_4        ;4th 4-char table
  186.     call    Stuff_Busy
  187.  
  188.     mov    si,offset s4_5        ;5th 4-char table
  189.     call    Stuff_Busy
  190.  
  191. ;3 8-char tables
  192.  
  193.     mov    bl,dl            ;get i back
  194.     and    bl,7            ;mask
  195.     mov    si,offset s8_1        ;1st 8-char table
  196.     call    Stuff_Busy
  197.  
  198.     mov    si,offset s8_2        ;2nd 8-char table
  199.     call    Stuff_Busy
  200.  
  201.     mov    si,offset s8_3        ;3rd 8-char table
  202.     mov    al,[si][bx]        ;snarf char
  203.     stosw
  204.  
  205.     pop    ES            ;restore caller's regs
  206.     pop    di
  207.     pop    si
  208.     pop    dx
  209.     pop    bx
  210. Old_Clock:
  211.     pop    DS
  212.     pop    ax
  213.     jmp    CS:old_Int1C        ;on to old Int 1CH, IRET from there
  214.  
  215. Busy    ENDP
  216.  
  217.  
  218. ;Common subroutine for Busy
  219. Stuff_Busy    PROC    NEAR
  220.  
  221.     mov    al,[si][bx]        ;snarf char
  222.     stosw
  223.     inc    di            ;bump a space over
  224.     inc    di
  225.  
  226.     ret
  227.  
  228. Stuff_Busy    ENDP
  229.  
  230.  
  231. ;Necessary setup routines for "background" busy routine.
  232. ;Just call once.
  233.  
  234. Busy_Setup    PROC    NEAR
  235.     ASSUME    DS:CSEG
  236.  
  237.     mov    ax,351CH        ;get Int 1CH clock tick vector
  238.     int    21H
  239.     mov    word ptr old_Int1C,bx    ;save offset
  240.     mov    word ptr old_Int1C+2,ES    ;and segment
  241.  
  242.     mov    dx,DS            ;save DS a sec
  243.     xor    ax,ax
  244.     mov    DS,ax
  245.     ASSUME    DS:PAGE0
  246.  
  247.     mov    iac,al    ;0        ;insure IAC busy flag is off
  248.     mov    DS,dx            ;restore DS
  249.     ASSUME    DS:CSEG
  250.  
  251.     mov    dx,offset Busy        ;new Int 1CH clock procedure
  252.     mov    ax,251CH        ;set new Int 1CH vector
  253.     int    21H
  254.  
  255.     ret
  256.  
  257. Busy_Setup    ENDP
  258.  
  259.  
  260. ;Signals Busy via IAC to show busy symbols
  261.  
  262. Busy_On    PROC    NEAR
  263.  
  264.     mov    dx,DS            ;save DS
  265.     xor    ax,ax
  266.     mov    DS,ax
  267.     ASSUME    DS:PAGE0
  268.  
  269.     mov    word ptr tick,ax    ;init 2 internal clocks
  270.     not    al            ;0FFH
  271.     mov    iac,al            ;Turn busy flag on
  272.     mov    DS,dx            ;restore DS
  273.     ASSUME    DS:CSEG
  274.  
  275.     mov    ah,0FH            ;get current video mode
  276.     int    10H            ;via BIOS
  277.  
  278. ;AL=current video mode
  279. ;AH=nr chars per line
  280. ;BH=display page
  281.  
  282. ;We're only handling Mono or CGA for now
  283. ;Anything will probably go out to lunch!
  284.  
  285.     cmp    al,7            ;assume mono (default)
  286.     jz    Is_Mono            ;yep
  287.      mov    byte ptr scr_vec+3,0B8H    ;nope, CGA, make seg 0B800H
  288. Is_Mono:
  289.     push    ax            ;save chars per line in AH
  290.     mov    ah,3            ;get current cursor psn
  291.     int    10H
  292.  
  293. ;DH=row, DL=col
  294. ;CX=current cursor size
  295.     mov    cursize,cx        ;save cursor size
  296.  
  297.     or    ch,20H            ;make cursor disappear
  298.     mov    ah,1            ;set cursor size
  299.     int    10H            ;via BIOS
  300.  
  301.     mov    al,dh            ;current row
  302.     xor    ah,ah            ;clear msb
  303.     pop    cx            ;CH=chars per line
  304.     mul    ch            ;row*(chars per row)
  305.     xor    dh,dh            ;clear msb, DX = curr col
  306.     add    ax,dx            ;row offset + col offset
  307.                     ; = screen offset
  308.     shl    ax,1            ;*2 for words
  309.     mov    word ptr scr_vec,ax    ;save screen offset
  310.  
  311.     ret
  312.     
  313. Busy_On    ENDP
  314.  
  315. ;Signals Busy via IAC to not show busy symbols
  316.  
  317. Busy_Off    PROC    NEAR
  318.  
  319.     mov    dx,DS            ;save DS
  320.     xor    ax,ax
  321.     mov    DS,ax
  322.     ASSUME    DS:PAGE0
  323.  
  324.     mov    iac,al    ;0        ;Turn busy flag off
  325.     mov    DS,dx            ;restore DS
  326.     ASSUME    DS:CSEG
  327.  
  328. Cursor_On:
  329.     mov    ah,1            ;set cursor size
  330.     mov    cx,cursize        ;back to old size
  331.     int    10H            ;via BIOS
  332.     ret
  333.     
  334. Busy_Off    ENDP
  335.  
  336.  
  337. ;Call once when you're done with Busy.
  338. ;This will uninstall the stolen Int 1CH vector
  339.  
  340. Busy_Uninstall    PROC    NEAR
  341.  
  342.     ASSUME    DS:CSEG
  343.  
  344.     mov    bx,DS            ;save
  345.     xor    ax,ax
  346.     mov    DS,ax
  347.     ASSUME    DS:PAGE0
  348.  
  349.     cli                ;be sure clock tick doesn't get us
  350.     mov    iac,al    ;0        ;turn busy flag off
  351.     sti                ;ints back on
  352.  
  353.     lds    dx,CS:old_Int1C        ;DS:DX = old Int 1CH vector
  354.     mov    ax,251CH        ;restore Int 1CH vector
  355.     int    21H
  356.  
  357.     mov    DS,bx            ;restore DS
  358.     jmp    Cursor_On        ;turn cursor back on, return
  359.  
  360. Busy_Uninstall    ENDP
  361.  
  362. ;********* Your program would go here.
  363.  
  364. msg1    db    'Faking busy.',CR,LF
  365.     db    'Press any key to be "non-busy": $'
  366. msg2    db    CR,LF,'Faking busy again.',CR,LF
  367.     db    'Press any key to be "non-busy": $'
  368.  
  369.  
  370. Start    PROC    NEAR
  371.     call    Busy_Setup        ;Some necessary Busy setups
  372.                     ;Just call once
  373.  
  374.     mov    dx,offset msg1        ;'First busy test'
  375.     mov    ah,9            ;display msg
  376.     int    21H
  377.  
  378.     call    Busy_On            ;signal Busy, cursor off
  379.  
  380. Busy_Tst1:
  381.     mov    ah,1            ;check kbd status
  382.     int    16H            ;via BIOS
  383.     jz    Busy_Tst1        ;no key
  384.  
  385.     call    Busy_Off        ;signal Busy, cursor on
  386.     xor    ah,ah            ;read that key
  387.     int    16H            ;via BIOS
  388.  
  389.     mov    dx,offset msg2        ;'Second busy test'
  390.     mov    ah,9            ;display msg
  391.     int    21H
  392.  
  393.     call    Busy_On            ;signal Busy, cursor off
  394.  
  395. Busy_Tst2:
  396.     mov    ah,1            ;check kbd status
  397.     int    16H            ;via BIOS
  398.     jz    Busy_Tst2        ;no key
  399.  
  400.     call    Busy_Uninstall        ;done, turn off Busy,
  401.                     ;cursor on,
  402.                     ;restore stolen vector
  403.  
  404.     xor    ah,ah            ;read that key
  405.     int    16H            ;via BIOS
  406.  
  407.     mov    ax,4C00H        ;terminate
  408.     int    21H
  409.  
  410. Start    ENDP
  411.  
  412. CSEG    ENDS
  413.     END    Busy_Demo
  414.