Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

getch and putc C functions

gustavosserragustavosserra Member Posts: 201
Does anyone can tell me if this is the better code to do these functions:
[code]
void putChar(char parChar)
{
asm{
mov dl, parChar
mov ah, 2
int 0x21
}
}
char getChar()
{
char read;
asm{
mov ah, 0
int 0x16
mov read,al
}
return read;
}
[/code]

Comments

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [b][red]This message was edited by AsmGuru62 at 2003-8-30 15:59:44[/red][/b][hr]
    : Does anyone can tell me if this is the better code to do these functions:
    : [code]
    : void putChar(char parChar)
    : {
    : asm{
    : mov dl, parChar
    : mov ah, 2
    : int 0x21
    : }
    : }
    : char getChar()
    : {
    : char read;
    : asm{
    : mov ah, 0
    : int 0x16
    : mov read,al
    : }
    : return read;
    : }
    : [/code]
    :
    [blue]Should be fine... just test the getChar() when pressing arrows or Fx keys.[/blue]


  • gustavosserragustavosserra Member Posts: 201
    Thanks for the reply!

    : [blue]Should be fine... just test the getChar() when pressing arrows or Fx keys.[/blue]

    And how can I do it?

    : : Does anyone can tell me if this is the better code to do these functions:
    : : [code]
    : : void putChar(char parChar)
    : : {
    : : asm{
    : : mov dl, parChar
    : : mov ah, 2
    : : int 0x21
    : : }
    : : }
    : : char getChar()
    : : {
    : : char read;
    : : asm{
    : : mov ah, 0
    : : int 0x16
    : : mov read,al
    : : }
    : : return read;
    : : }
    : : [/code]
    : :
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : Thanks for the reply!
    :
    : : [blue]Should be fine... just test the getChar() when pressing arrows or Fx keys.[/blue]
    :
    : And how can I do it?
    :
    : : : Does anyone can tell me if this is the better code to do these functions:
    : : : [code]
    : : : void putChar(char parChar)
    : : : {
    : : : asm{
    : : : mov dl, parChar
    : : : mov ah, 2
    : : : int 0x21
    : : : }
    : : : }
    : : : char getChar()
    : : : {
    : : : char read;
    : : : asm{
    : : : mov ah, 0
    : : : int 0x16
    : : : mov read,al
    : : : }
    : : : return read;
    : : : }
    : : : [/code]
    : : :
    :
    [code]
    putChar (getChar ()); // Press F1 here and see what will be printed
    [/code]
  • gustavosserragustavosserra Member Posts: 201
    It printed white spaces! But they have different values (integers for example, as char have) dont they? So I must verify each Fx and arrow key, correct?
    : [code]
    : putChar (getChar ()); // Press F1 here and see what will be printed
    : [/code]

  • BitdogBitdog Member Posts: 528
    : It printed white spaces! But they have different values (integers for example, as char have) dont they? So I must verify each Fx and arrow key, correct?
    [code]
    putChar (getChar ()); // Press F1 here and see what will be printed
    [/code]
    [green]
    Extended keys return AL=0 with the key in AH.
    Printing a 0 looks like a space on the screen.
    Enhanced key board interrupts handle F11 & F12 also.
    There are alternate ways of KBD input & here's some.
    You convert & test it for your C program.
    More info is available in Ralf Browns interrupt list. (an internet freebee)

    INT 16h AH=0 pauses for a key press, & returns AL=character/value. On return
    if AL=0 an extended key was pressed (F# arrows) & the character/value is in AH.
    INT 16h AH=10h is the same as above except it gets enhanced keys F11 & F12?

    You can check the key board & get the key/scan code with out removing
    the key from the keyboard buffer or pausing with this code.[/green]
    [code]
    MOV AH,1 ;get KBD key & status, (MOV AH,11h = enhanced KBD)
    INT 16h ;BIOS interrupt
    JNZ NOKEY ;continue on

    ;& it can be followed with this code to remove the key from the buffer.
    MOV AH,0 ;a key is waiting so it doesn't pause (AH=10h enhanced)
    INT 16h ;get/remove key from buffer
    OR AL,AL ;check for AL=0 , if so extended key is in AH
    JZ isEXTENDED
    ;process regular key in AL here, & jump
    isEXTENDED:
    ;process extended key in AH here

    ;DOS interrupts have some of the same functions as BIOS interrupts.
    MOV AH,1 ; function, pause get key with echo (AH=8 no echo)
    INT 21h ; DOS int, return key in AL
    OR AL,AL ; if AL=0 an extended key is waiting in buffer
    JNZ notEXTENDED
    INT 21h ; get extended key in AL (no pause), process & jump
    notEXTENDED: ;process normal key here
    ;See R.B. int list for INT 21h AH=0Ah buffered input strings.
    ;or INT 21h AH=0Ch flush buffer & execute AL as function. AL=1 get key w/echo
    ;or INT 21h AH=0Bh kbd status, returns AL=0 no key waiting


    ;The key board interrupts can be turned off with by disabling IRQ 1
    ;so flushing key board buffer is not required since the buffer is not filled.
    ;But interrupts will not get a key for you, IN AL,60h will though.
    ;Be sure to turn IRQ 1 back on at the end of your program. (TEST it first !)
    PUSHF ;; save flags
    CLI ;; disable interrupts (clears int flag bit 9)
    IN AL,21h ;; port 21h
    OR AL,00000010b ;; set bit 1, disable IRQ 1 & KBD int's
    ; AND AL,11111101b ;; clear bit 1, enable IRQ 1 & KBD int's
    ; JMP SHORT $+2 ;; kill time for 286 & 386 port I/O recovery
    OUT 21h,AL ;; write the value
    POPF ;; restore flags including the previous interrupt flag state

    ;with IRQ 1 off, you might try this, but mouse packets are a whole nuther wurld
    IN AL,64h ;; Get port 60h status byte from port 64h
    TEST AL,00000001b ;; TEST bit 0, if =0 jump & move on
    JZ KBDbye ;; no KEY or MOUSE packet waiting
    TEST AL,00100000b ;; check for mouse packet ready
    JNZ isMOUSE ;; JMP & deal with mouse packet (& die there)
    IN AL,60h ;; get port 60h last key byte
    OR AL,AL ;; check AL
    JS RELEASED ;; bit 7 set = signed, last key was a release
    JZ ESCpressed ;; exit program or some function here?
    ;process the key that is pressed here, & jump KBDbye
    RELEASED:
    AND AL,01111111b ;; clear bit 7, AL = released key in bits 6-0
    ;process the key that was released here.
    KBDbye:

    ;if your in line assembler won't do CLI or STI you can try this.
    PUSHF
    POP AX
    AND AH,11111101b ; clear bit 9 of AX = CLI
    ; OR AH,00000010b ; set bit 9 of AX = STI
    PUSH AX ; CLI & STI = one byte each. Size in C :-)
    POPF ; 16 bit default assembles this to 7 bytes, 32 bit = 11 bytes

    [/code]
    Disreguard any errors above :-)
    Bitdog



  • gustavosserragustavosserra Member Posts: 201
    Thanks SO much! Altough the second part became to complex to my experience Im really grateful! ;)
    You gave me an excelent explanation!

    : : It printed white spaces! But they have different values (integers for example, as char have) dont they? So I must verify each Fx and arrow key, correct?
    : [code]
    : putChar (getChar ()); // Press F1 here and see what will be printed
    : [/code]
    : [green]
    : Extended keys return AL=0 with the key in AH.
    : Printing a 0 looks like a space on the screen.
    : Enhanced key board interrupts handle F11 & F12 also.
    : There are alternate ways of KBD input & here's some.
    : You convert & test it for your C program.
    : More info is available in Ralf Browns interrupt list. (an internet freebee)
    :
    : INT 16h AH=0 pauses for a key press, & returns AL=character/value. On return
    : if AL=0 an extended key was pressed (F# arrows) & the character/value is in AH.
    : INT 16h AH=10h is the same as above except it gets enhanced keys F11 & F12?
    :
    : You can check the key board & get the key/scan code with out removing
    : the key from the keyboard buffer or pausing with this code.[/green]
    : [code]
    : MOV AH,1 ;get KBD key & status, (MOV AH,11h = enhanced KBD)
    : INT 16h ;BIOS interrupt
    : JNZ NOKEY ;continue on
    :
    : ;& it can be followed with this code to remove the key from the buffer.
    : MOV AH,0 ;a key is waiting so it doesn't pause (AH=10h enhanced)
    : INT 16h ;get/remove key from buffer
    : OR AL,AL ;check for AL=0 , if so extended key is in AH
    : JZ isEXTENDED
    : ;process regular key in AL here, & jump
    : isEXTENDED:
    : ;process extended key in AH here
    :
    : ;DOS interrupts have some of the same functions as BIOS interrupts.
    : MOV AH,1 ; function, pause get key with echo (AH=8 no echo)
    : INT 21h ; DOS int, return key in AL
    : OR AL,AL ; if AL=0 an extended key is waiting in buffer
    : JNZ notEXTENDED
    : INT 21h ; get extended key in AL (no pause), process & jump
    : notEXTENDED: ;process normal key here
    : ;See R.B. int list for INT 21h AH=0Ah buffered input strings.
    : ;or INT 21h AH=0Ch flush buffer & execute AL as function. AL=1 get key w/echo
    : ;or INT 21h AH=0Bh kbd status, returns AL=0 no key waiting
    :
    :
    : ;The key board interrupts can be turned off with by disabling IRQ 1
    : ;so flushing key board buffer is not required since the buffer is not filled.
    : ;But interrupts will not get a key for you, IN AL,60h will though.
    : ;Be sure to turn IRQ 1 back on at the end of your program. (TEST it first !)
    : PUSHF ;; save flags
    : CLI ;; disable interrupts (clears int flag bit 9)
    : IN AL,21h ;; port 21h
    : OR AL,00000010b ;; set bit 1, disable IRQ 1 & KBD int's
    : ; AND AL,11111101b ;; clear bit 1, enable IRQ 1 & KBD int's
    : ; JMP SHORT $+2 ;; kill time for 286 & 386 port I/O recovery
    : OUT 21h,AL ;; write the value
    : POPF ;; restore flags including the previous interrupt flag state
    :
    : ;with IRQ 1 off, you might try this, but mouse packets are a whole nuther wurld
    : IN AL,64h ;; Get port 60h status byte from port 64h
    : TEST AL,00000001b ;; TEST bit 0, if =0 jump & move on
    : JZ KBDbye ;; no KEY or MOUSE packet waiting
    : TEST AL,00100000b ;; check for mouse packet ready
    : JNZ isMOUSE ;; JMP & deal with mouse packet (& die there)
    : IN AL,60h ;; get port 60h last key byte
    : OR AL,AL ;; check AL
    : JS RELEASED ;; bit 7 set = signed, last key was a release
    : JZ ESCpressed ;; exit program or some function here?
    : ;process the key that is pressed here, & jump KBDbye
    : RELEASED:
    : AND AL,01111111b ;; clear bit 7, AL = released key in bits 6-0
    : ;process the key that was released here.
    : KBDbye:
    :
    : ;if your in line assembler won't do CLI or STI you can try this.
    : PUSHF
    : POP AX
    : AND AH,11111101b ; clear bit 9 of AX = CLI
    : ; OR AH,00000010b ; set bit 9 of AX = STI
    : PUSH AX ; CLI & STI = one byte each. Size in C :-)
    : POPF ; 16 bit default assembles this to 7 bytes, 32 bit = 11 bytes
    :
    : [/code]
    : Disreguard any errors above :-)
    : Bitdog
    :
    :
    :
    :

  • BitdogBitdog Member Posts: 528
    : Thanks, Altough the second part became to complex.
    [green]
    I don't understand it either !
    But, now ya got some new stuff to try anyway.

    Bitdog
    [/green]

  • darkraven32darkraven32 Member Posts: 14
    I believe I'm reading this correctly:

    Mind you this is FPC [Pascal/Delphi] syntax, YMMV.

    keyboardhandler(var r:regs); scancode:byte; c:char; begin if readportb($64) and 32=0 then begin handleMouse; end; scancode=ReadPortb($60); if scancode and $80)=0 then begin //keypressed case scancode of . . . end; //case while readportb($64) and 1=0 do begin //wait to clear buffer DisableInterrupts; toggleLEDs; EnableInterrupts; end; c:=keymap[scancode]; //keymap has to be set, you can look online for these case c of #0:begin // function keys doSomething; end; end else begin //not a function key writechar(ch); end; //case end; //if we get here, key is released //put the released keycode info here end;

    I'm not an expert in assembler, but I have half of it written for me already.We had a '2' where the '1' was supposed to be.

    Pascal is a lot simpler to understand than C, but assembler sometimes a bit more complex than C to read, easy as it may be to code for.

    You don't need int21.Whatever that does, it calls DOS to do it.I have irq 1 already hooked in the kernel's isr, you may need to hook int33[irq 1] to do this correctly.

    By that, I mean setIntVec(33,@YourCustom33); and restoreIntVec(33,@OltInt33); or similar when done.I don't need to do this.


    You have to define your own keymap for this to work, of course.Basically, its a list of char[#,then number] and a displayed char, 'f', for example.We use three sets of these to get the numpad working. Well, I did, anyway, it was a quick shortcut.

    Thanks for the help on the mouse.Was wondering how we got that on int33[irq1] and still handled the keyboard.



Sign In or Register to comment.