josecash
josecash

Reputation: 339

Trying to understand asm interrupts, specifically 16h func 01H

THIS IS FOR HOMEWORK, I don't expect you to resolve my problem, just need some understanding...

I have to work with ASM and C in a dosbox. My first problem is I don't really understand how to use bios interrupts (any good tutorial with code samples would be really appreciated), ok, I get there's interrupts, and each one has its own functions and parameters...

Anyway I've tried...What I need to do is, theoretically, simple, I just need to get a character from keyboard and if it is a 1 or 0 key, count it, if I have five keystrokes of key 1, I switch on the speaker, if the speaker is on and I have three 0 keys, the speaker is turned off, and also it can be turned off if mouse moves to the right...

I have it almost done, my problem is getting the returned byte from an interrupt and check it.

To get the char I use function 01H from INT 16H, that's why I don't want the asm block to wait until a new char came up, the problem is I can't undertand how to get the ZERO FLAG that tells me if a new char has arrived and if so, get it and remove it from the keyboard buffer.

Here's is my loop:

// Loop
for(;;) {
        initTimer();

        if (key == ESC) break; // If ESC is pressed...

        if (mouseExist == TRUE) currentX = getMouseX(); // Mouse X position

        /* In that block I wait for the user input, it works...
        asm {
            mov AH, 08H  
            int 21H     // DOS-API
            mov key, AL

        }
        */
            // Block I don't get...UPDATED
        asm {
            mov ah, 01H
            int 16h
                    jz not_set // If zero flag is 1, jump to not_set, else
            mov key, al // Getting key
                    mov ah, 04H  // reset buffer
                    int 16H

        }
            not_set:
            // Count ones
        if (key == ONE && countOnes < MAX_ONES) {
            countOnes++;
            resetBuffer(); // Reset keyboard buffer (NOT WORKING)...
        }
        // Count 0s
        else if (key == ZERO && isPlaying == TRUE) countZeros++;

        // If I have enought zeros OR speaker is on AND mouse have been moved to            
            // the right 
        if (countZeros == MAX_ZERO || (initX < currentX && isPlaying == TRUE)) {
            stop(); // Stop speaker...It works...
            // Restore counters
            countOnes = 0;
            countZeros = 0;
            checkMouse(); // Reset Mouse...Works...
            showMouse(); // Works
            initX = getMouseX();
                currentX = initX;
            isPlaying = FALSE;
        } else if (countOnes == MAX_ONES) { // I have the ones
            isPlaying = TRUE;
            play(); // Turn on the speaker.
        }
            key = '\0';
           // I have also try to reset buffer here...No luck...
           //resetBuffer()
    }

Function ResetBuffer:

void resetBuffer() {
    asm {
        mov AH, 04H // Function reset
        int 16H
    }
}

Thanks in advance...

Upvotes: 3

Views: 1322

Answers (1)

jlahd
jlahd

Reputation: 6303

You can push the flags, then pop them into a register to check the corresponding bit:

unsigned short flags;
asm {
    mov ah, 04h
    int 16h
    pushf
    pop ax
    mov flags, ax
}
if (flags & 0x40) {
    // zero flag is set
}

You could also directly check the flag in assembly:

    mov ah, 04h
    int 16h
    jz not_set
    // here, if zero flag was set
not_set:

The exact syntax of labels depends on your compiler.

Upvotes: 1

Related Questions