I'm creating a program, that should print "Hello from handler" five seconds after start. At first I created interrupt 4ah by proc called create_interrupt
.
This interrupt causes int_handler
, that prints string "Hello from handler".
Then proc "alarm" get curent time, add 5 second to it and set alarm by func 06h of int 1ah.
This alarm should call int 4ah after 5 seconds from start, but it doesn't works and I don't know why. If I call 4ah "by hand", just by adding "int 4ah" it works, it means that interruption created and works correctly. But I need to call this interrupt by alarm.
SSEG segment stack
db 256 dup(0)
SSEG ends
DSEG segment
mess db 'Hello',0dh,0ah,'$'
mess2 db 'Hello from handler!',0dh,0ah,'$'
mess3 db 'Ассемблер это жопа, я уже устал''$'
DSEG ends
CSEG segment
assume cs:CSEG,ds:DSEG,ss:SSEG
begin:
mov ax, DSEG
mov ds,ax
mov ah,09h
mov dx,offset mess
int 21h
;call far ptr int_handler
call far ptr create_interrupt
;int 4ah
call far ptr alarm
mov ah,01h
int 21h
mov ah,4ch
int 21h
create_interrupt proc far
push 0
pop es
;pushf
;cli
mov word ptr es:[4ah*4],offset int_handler
mov word ptr es:[4ah*4+2],seg int_handler
;sei
iret
create_interrupt endp
alarm proc far
;pushf
mov ah,02h ;get current time
int 1ah
mov ah,06h
;mov ch,ch ;hour
;mov cl,cl ;min
;mov dh,dh ;sec
;mov dl,dl ;mlsec
add dh,05h ;add 5 to seconds
int 1ah ;ah=06h, so this int sets alarm
;mov ah,01h
;int 21h
iret
alarm endp
int_handler proc far
mov ax,DSEG ;
mov ds,ax ;in ds addres of Data segment
mov ah,09h
mov dx,offset mess2
int 21h
iret
int_handler endp
CSEG ends
end begin
DOSBox does not give access to the Real Time Clock.
Functions like
int 1Ah AH=06h
(BIOS.SetSystemAlarm) andint 21h AH=2Dh
(DOS.SetSystemTime) don't operate correctly!Why is this? Well, DOSBox is an emulator that targets playing (existing) DOS games. Typically games don't set the (real time) clock or use a real time clock alarm. Games rather deal with delays of all kinds. That explains why DOSBox does not support this kind of functionality.
Although we have to accept the developer's choice, it would have been nice if they had provided us with the documented return codes that signal an error.
int 1Ah AH=06h
(BIOS.SetSystemAlarm) had better returnedCF=1
int 21h AH=2Dh
(DOS.SetSystemTime) had better returnedAL=FFh
Luckily the Timer Tick works fine.
In order to create a program that prints "Hello from handler!", we can succesfully use the 1Ch interrupt. A delay of 5 seconds would translate to 91 timer ticks because there're about 18.2 ticks in every second. When using this 1Ch interrupt it's very important to chain to the original (previous) handler so other processes can still manage their business.
Below is my version of this task:
Michael Petch made this valuable comment about DOS re-entrancy or the lack thereof.
I've tested the above program under DOSBox with no problems at all because, quoting from my programmer's manual,
The above program does nothing but waiting for keyboard input so this is fine. In a more elaborate program one could both check the InDOS flag and intercept
int 28h
.However a simple solution remains to avoid using DOS altogether and output the message using e.g. BIOS.Teletype: