I'm pulling my hair out as I type!!!...

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
darklife

I'm pulling my hair out as I type!!!...

Post by darklife »

I have tried *everything* in my power to get a *simple* little program to run and then have the
timer exit the routine back to the main routine. Okay, that doesn't make much sence so here is
a better explanation...
-save old INT 1CH pointer from IVT
-set INT 1CH to my handler
-jump to Start
-Start: show '!' over and over... Jump back to Start (endless loop).
-My INT 1CH handler will exit the Start: routine and go back to the main code and exit to DOS.
Okay, I know this program sounds silly but this is just an example of something "bigger" im trying
to make but my example below shows the "smaller" problem im having.
#The problem:#- The first and second time I run my program it works great. Once the timer ticks it
exits to DOS with no problem. The third time I run it, it exits to DOS and then stalls. WHY?
First thing I checked was the stack but I can't seem to find a problem there. I *do* have code
in the example to clean up the 8254(8253) timer state using MOV AL,20H : OUT 20H, AL but
that doesn't seem to do the trick either (it does help though).

Here is the assembly (NASM) code. I have only tested it under DOSEMU but I'm sure it fails
under Bochs and real DOS also. (I'll test ASAP).

              ORG       100H
              BITS      16

jmp Init ;goto startup

Done: ;comes here when timer "ticks"
        mov     ah, 0Eh
        mov     al, 'D'
        mov     bx, 0007h
        int     10h ;Print a 'D' for Done (for debug)
        int     20h ;Exit to DOS, 4C00H I21 works also


Init: ;Starts here...
              XOR       AX, AX
              MOV       ES, AX ;IVT start
              MOV       BX, [ES:1CH * 4 + 0]
              MOV       [OldINT1C + 0], BX ;Save old INT 1C
              MOV       BX, [ES:1CH * 4 + 2]
              MOV       [OldINT1C + 2], BX ;...
              MOV       [ES:1CH * 4 + 0], WORD NewINT1C
              MOV       [ES:1CH * 4 + 2], CS
              JMP       Start ;Our endless loop code...

OldINT1C:     DW        0
              DW        0

NewINT1C:

              XOR       AX, AX
              MOV       ES, AX

              MOV       BX, [CS:OldINT1C + 0]
              MOV       [ES:1CH * 4 + 0], BX
              MOV       BX, [CS:OldINT1C + 2]
              MOV       [ES:1CH * 4 + 2], BX ;Resume old original INT 1C handler

              SUB       SP, 4 ;Pop IP and CS, we don't need them here..
              PUSH      CS ;Put our CS on stack
              PUSH      Done ;Put our IP on stack

              MOV       AL, 20H
              OUT       20H, AL ;INT done
              
              IRET ;Return to Done:

Start: ;endless code , only exits when INT 1C wants us to.
        mov     ah, 0Eh
        mov     al, '!'
        mov     bx, 0007h
        int     10h ;Teletype '!' over and over....
        jmp     Start





THANKS. I need the help. I've been trying to get this routine to work for days now.
Once I figure it out I can't wait to continue programming my project.
TTTHHHAAANNNKKKSSS.
Anton

RE:I'm pulling my hair out as I type!!!...

Post by Anton »

Well it's prety obvios.
First:When you set the interrupt vector, you should turn off interrupts :) or use a special BIOS function.
Second:I realy don't like this "Pop IP and CS, we don't need them here..". I would sugest to use a spin lock, in the loop where you type "!". And instead of changing CS and IP(int10 is probobly not threadable, so once you interrupt it's execution, you will stall when a char("D") is about to be printed), you would clear the value which is checked in the spin lock.
Anton
Post Reply