rr 
        
    
  Berlin, Germany,  18.02.2020, 21:32   | 
     EIDL version 1.0.0 released (Announce) | 
    
    
     Hi! 
 
Recently I wanted to know, how IDLE.COM in Microsoft Virtual PC works. I can say, it is a rather simple tool and contains lots of garbage in its only 128 bytes. -- IDLE works by hooking the DOS idle interrupt 28h and executing a HLT instruction every time. 
 
At the end I put together a tool, that does the same. I named it EIDL, but you pronounce it "idle". (A little play with the German language.) It's 80 bytes only, but comes with source code for NASM. 
 
See it as little ASM example, because it is not as advanced as all the other DOS idlers including Eric Auer's FDAPM. 
 
You can find EIDL at: https://www.bttr-software.de/products/eidl/ --- Forum admin  | 
    
               
             Japheth 
        
  
  Germany (South),  20.02.2020, 13:16         (edited by Japheth, 20.02.2020, 13:42)                
  @ rr
         | 
     EIDL version 1.0.0 released | 
    
    
     > See it as little ASM example, because it is not as advanced as all the 
> other DOS idlers including Eric Auer's FDAPM. 
 
Thanks! 
 
I wonder a bit why the code sequence 
 
   sti 
   hlt 
 
does work. In both docs, Intel & AMD, it is pointed out that the STI opcode will  
have a "delayed" effect, so interrupts are enabled after the next instruction only. Obviously HLT is a special case. 
 
It's also a mystery to me when and how often Int 28h is called. IMO it's called even if DOS is not "idle" at all. This little program below just displays a string via DOS until terminated by Ctrl-C. I runs significantly slower if EIDL (or any other idle tool) is installed. 
 
;--- create binary with "jwasm -mz forever.asm" 
        .286 
        .model small 
        .stack 1024 
 
        .data 
text db "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
        db "abcdefghijklmnopqrstuvwxyz" 
        db 0 
 
        .code 
 
start: 
        mov ax, dgroup 
        mov ds, ax 
        mov si,offset text 
        .while 1 
                lodsb 
                .if al == 0 
                        mov si,offset text 
                        lodsb 
                .endif 
                mov dl,al 
                mov ah, 2 
                int 21h 
        .endw 
        mov ah, 4ch 
        int 21h 
 
        END start 
 --- MS-DOS forever!  | 
     
                
             rr 
        
    
  Berlin, Germany,  20.02.2020, 15:44                        
  @ Japheth
         | 
     EIDL version 1.0.0 released | 
    
    
     > > See it as little ASM example, because it is not as advanced as all the 
> > other DOS idlers including Eric Auer's FDAPM. 
>  
> Thanks! 
>  
> I wonder a bit why the code sequence 
>  
> sti 
> hlt 
>  
> does work. In both docs, Intel & AMD, it is pointed out that the STI opcode 
> will  
> have a "delayed" effect, so interrupts are enabled after the next 
> instruction only. Obviously HLT is a special case. 
 
Quoting https://lists.freebsd.org/pipermail/freebsd-current/2004-June/029369.html: 
Now, there's a problem... the problem is that if you enable interrupts 
and halt (to wait for the next interrupt), then there is a one-instruction 
window where an interrupt might occur *BEFORE* you HLT.  This interrupt 
may do something (such as schedule a thread) that means that you really 
don't want to halt now waiting for a *SECOND* interrupt to occur. 
 
In order to deal with this problem, Intel specified that the 'STI ; HLT' 
sequence of instructions will *GUARENTEE* that interrupts will remain 
disabled for one additional cycle, which gives HLT a chance to enter into 
its wait state.  An interrupt occuring in between the STI and HLT would 
therefore cause the HLT to resume. 
 
In later cpu's Intel and Amd both guarentee the atomicy of the  
STI; HLT instruction combination.  No interrupt will be allowed to  
take effect inbetween the instructions, no trap will occur.  No NMI 
will occur... nothing (either that or, for an NMI, the cpu will fixup 
the interrupt flag and set the restart point to the STI rather then the 
HLT). 
 
For all intents and purposes you should treat 'STI; HLT' as a single 
instruction. 
 
> It's also a mystery to me when and how often Int 28h is called. IMO it's 
> called even if DOS is not "idle" at all. This little program below just 
> displays a string via DOS until terminated by Ctrl-C. I runs significantly 
> slower if EIDL (or any other idle tool) is installed. 
>  
> ;--- create binary with "jwasm -mz forever.asm" 
> .286 
> .model small 
> .stack 1024 
>  
> .data 
> text db "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
> db "abcdefghijklmnopqrstuvwxyz" 
> db 0 
>  
> .code 
>  
> start: 
> mov ax, dgroup 
> mov ds, ax 
> mov si,offset text 
> .while 1 
> lodsb 
> .if al == 0 
> mov si,offset text 
> lodsb 
> .endif 
> mov dl,al 
> mov ah, 2 
> int 21h 
> .endw 
> mov ah, 4ch 
> int 21h 
>  
> END start 
>  
 
Yes, I noticed this too. 
 
I didn't find it in RBIL now, but I read that INT28h is invoked every 4th character that is written using DOS function 2. So it also affects function 9, because this uses function 2 internally. 
 
Update: 
Wasn't in RBIL, but in Vernon Brooks' DOS API notes. 
- INT 28h was added in DOS 2.0 to allow the resident print spooler (PRINT.COM) to gain control while DOS is idle. 
- The DOS kernel issues INT 28h during the keyboard idle loop and once for every 4 (DOS 2.x and 3.x) or 64 (DOS 4+) characters output via INT 21h function 02h. 
- INT 21h function 09h uses the function 02h code internally so strings printed via function 09h also contribute to the INT 28h character output count. --- Forum admin  | 
     
                
             rr 
        
    
  Berlin, Germany,  20.02.2020, 17:54                        
  @ Japheth
         | 
     EIDL version 1.0.0 released | 
    
    
     > It's also a mystery to me when and how often Int 28h is called. IMO it's 
> called even if DOS is not "idle" at all. This little program below just 
> displays a string via DOS until terminated by Ctrl-C. I runs significantly 
> slower if EIDL (or any other idle tool) is installed. 
 
Which hardware/emu and DOS version did you try it on? --- Forum admin  | 
     
                
             Doug 
        
  
  20.02.2020, 19:20                        
  @ rr
         | 
     EIDL version 1.0.0 released | 
    
    
     > Wasn't in RBIL, but in Vernon Brooks' DOS API notes. 
 
> - INT 28h was added in DOS 2.0 to allow the resident print spooler 
> (PRINT.COM) to gain control while DOS is idle. 
> - The DOS kernel issues INT 28h during the keyboard idle loop and once for 
> every 4 (DOS 2.x and 3.x) or 64 (DOS 4+) characters output via INT 21h 
> function 02h. 
> - INT 21h function 09h uses the function 02h code internally so strings 
> printed via function 09h also contribute to the INT 28h character output 
> count. 
 
Vernon Brooks was lead developer for PC-DOS 7, and has also written a (more-advanced) DOS idling program.  He has this to say about it: 
 
----- 
HLTIDLE - reduce CPU power usage in DOS 
 
HLTIDLE reduces power usage during the DOS keyboard idle loop by executing a HLT  
instruction when the keyboard idle function (INT 2Ah function 84h) is called.   
 
INT 28h is not used because, in addition to being called during the DOS keyboard  
idle loop, INT 28h is called once for every 64 characters output (every 4  
characters output in DOS 2.x and 3.x) via INT 21h function 02h (note INT 21h  
function 09h uses the function 02h code).   
 
HLTIDLE also hooks INT 15h and checks for functions 90h (wait) and 91h (post)  
with device type codes 01h (floppy drive) or 02h (keyboard), so it can execute a  
HLT instruction while waiting for floppy-disk I/O completion or BIOS-keyboard  
input via INT 16h functions 00h or 10h.   
 
HLTIDLE is a small TSR program which uses 192 bytes of memory and may be loaded  
into upper memory.  If the LO parameter is specified, then HLTIDLE will relocate  
itself to the unused area from 556h to 5BFh (segment 50h), effectively using no  
DOS memory at all.   
 
----- 
You can download the HLTIDLE program (asm source included) here:  
 
https://sites.google.com/site/pcdosretro/hltidle 
 
There is a wealth of other DOS-related history and programming info on his website, as well as a few original patches and programs.   
 
- Doug B.  | 
     
                
             rr 
        
    
  Berlin, Germany,  20.02.2020, 20:34                        
  @ Doug
         | 
     EIDL version 1.0.0 released | 
    
    
     > Vernon Brooks was lead developer for PC-DOS 7, and has also written a 
> (more-advanced) DOS idling program.  He has this to say about it: 
>  
> ----- 
> HLTIDLE - reduce CPU power usage in DOS 
 
{snip} 
 
That's the problem with letting stuff laying 'round on your hard disk for several weeks. I'm aware of HLTIDLE, tried it, had a look at its source code... 
 
But I found it not very effective, when run in Virtual PC. Host CPU usage was still at 50 percent, but reduced immediately, after loading IDLE.COM or EIDL.COM. 
 
By the way: I found ROM-DOS' char output much slower than MS-DOS or FreeDOS. Maybe ROM-DOS developers didn't adapt the "every 64 characters output" behavior. --- Forum admin  | 
     
                
             Japheth 
        
  
  Germany (South),  21.02.2020, 20:23                        
  @ rr
         | 
     EIDL version 1.0.0 released | 
    
    
     > > It's also a mystery to me when and how often Int 28h is called. IMO it's 
> > called even if DOS is not "idle" at all. This little program below just 
> > displays a string via DOS until terminated by Ctrl-C. I runs 
> significantly 
> > slower if EIDL (or any other idle tool) is installed. 
>  
> Which hardware/emu and DOS version did you try it on? 
 
I tried under MS-DOS 7.x ( supplied with Win98 ). IIRC FreeDOS does not have this "slowdown" problem. 
 
What might help for MS-DOS is a little filter (taken from my old DOSIDLE tool): 
 
int28 proc 
        pushf 
        call cs:[oldint28] 
if 1 
        cmp ah,2 
        jz @F 
endif 
        sti 
        hlt 
@@: 
        iret 
int28 endp 
 
 
Also, I think it is necessary to hook int 16h, to cover VC: 
 
int16 proc 
        cmp ah,00h 
        jz @F 
        cmp ah,10h 
        jz @F 
oldint: 
        jmp cs:[oldint16] 
@@: 
        push ds 
        push 40h 
        pop ds 
        push ax 
        mov ax,ds:[1Ah] 
        cmp ax,ds:[1Ch] 
        pop ax 
        pop ds 
        jnz oldint 
        sti 
        hlt 
        jmp @B 
int16 endp 
 
 
However, the idea mentioned by Vernon Brooks about hooking int 15h, ah=90h, is perhaps superior and simpler. --- MS-DOS forever!  | 
     
                
             rr 
        
    
  Berlin, Germany,  21.02.2020, 21:57                        
  @ Japheth
         | 
     EIDL version 1.0.0 released | 
    
    
     > What might help for MS-DOS is a little filter (taken from my old DOSIDLE 
> tool): 
>  
> int28 proc 
> pushf 
> call cs:[oldint28] 
> if 1 
> cmp ah,2 
> jz @F 
> endif 
> sti 
> hlt 
> @@: 
> iret 
> int28 endp 
>  
 
How/why does it work? 
 
> Also, I think it is necessary to hook int 16h, to cover VC: 
 
Volkov Commander? 
Visual C? 
 
>  
> int16 proc 
> cmp ah,00h 
> jz @F 
> cmp ah,10h 
> jz @F 
> oldint: 
> jmp cs:[oldint16] 
> @@: 
> push ds 
> push 40h 
> pop ds 
> push ax 
> mov ax,ds:[1Ah] 
> cmp ax,ds:[1Ch] 
> pop ax 
> pop ds 
> jnz oldint 
> sti 
> hlt 
> jmp @B 
> int16 endp 
>  
 
I'm not very familiar with JWasm/MASM/TASM syntax. 
Do I interpret this correctly: 
If keyboard function "GET KEYSTROKE" or "GET ENHANCED KEYSTROKE" is invoked, then execute STI+HLT until keyboard buffer becomes non-empty, i.e., a key is pressed by the user. 
 
> However, the idea mentioned by Vernon Brooks about hooking int 15h, ah=90h, 
> is perhaps superior and simpler. --- Forum admin  | 
     
                
             Japheth 
        
  
  Germany (South),  22.02.2020, 03:14                        
  @ rr
         | 
     EIDL version 1.0.0 released | 
    
    
     > How/why does it work? 
 
I can't remember, it was written in 2006/2007. My guess is that in MS-DOS,  
register AH still holds the DOS function code when Int 28h is issued. 
 
> Volkov Commander? 
 
Yes, of course!    
 
> Do I interpret this correctly: 
> If keyboard function "GET KEYSTROKE" or "GET ENHANCED KEYSTROKE" is 
> invoked, then execute STI+HLT until keyboard buffer becomes non-empty, 
> i.e., a key is pressed by the user. 
 
Yes. --- MS-DOS forever!  | 
     
                
             rr 
        
    
  Berlin, Germany,  23.02.2020, 19:10                        
  @ Japheth
         | 
     EIDL version 1.0.0 released | 
    
    
     > > How/why does it work? 
>  
> I can't remember, it was written in 2006/2007. My guess is that in MS-DOS, 
> register AH still holds the DOS function code when Int 28h is issued. 
 
Hey, it's only 13/14 years ago. Not very much in the DOS era.   
But you can here me now shouting: "Comment your code!" 
 
> > Volkov Commander? 
>  
> Yes, of course!    
 
Could also have been Moenkemeier's VGA-Copy.   
Oh, wait, I just see, he only lives 6 kilometres away from me. 
 
But yes, there's only one Commander to rule them all. --- Forum admin  | 
     
                
             Japheth 
        
  
  Germany (South),  24.02.2020, 19:04                        
  @ rr
         | 
     EIDL version 1.0.0 released | 
    
    
     > Could also have been Moenkemeier's 
> VGA-Copy. 
>   
 
I remember it. The later versions even had built-in soundblaster support.   --- MS-DOS forever!  |