How do I Create my own thread handler

Started by www.:).com, November 05, 2010, 07:53:14 PM

Previous topic - Next topic

clive

Quote from: www.:).com
Do you happen to know how many bytes can make up an instruction?

Yes, but it depends, the x86 uses a variable length instruction encoding. I can compute the length, but it is a non-trivial task.

Now normally when moving blocks of instructions around, one puts a label in front, and behind the block, and then computes the delta. Object files typically contain metadata describing the length of blocks of instructions.

Perhaps you should review the topics of assemblers, disassemblers and machine code, and perhaps linkers and loaders.

Observe that instructions are encoded with different sizes, depending on the opcode, and operand(s)

00401450                    _AddProcRef:                ; Xref 004065DF 0040669D 00406938 004069F9
00401450                                                ;      00406D96 00406DD0
00401450 A1444C4100             mov     eax,[_ProcRefList]
00401455 85C0                   test    eax,eax
00401457 7465                   jz      loc_004014BE
00401459 8B0D44104100           mov     ecx,[_ProcRefMax]
0040145F 8B15404C4100           mov     edx,[_ProcRefCount]
00401465 3BD1                   cmp     edx,ecx
00401467 7570                   jnz     loc_004014D9
00401469 53                     push    ebx
0040146A 56                     push    esi
0040146B 57                     push    edi
0040146C 8D0409                 lea     eax,[ecx+ecx]
0040146F 68A8124100             push    offset off_004112A8 ; 'AddProcRef(),NewProcRefList',000h
00401474 6A0A                   push    0Ah
00401476 50                     push    eax
00401477 A344104100             mov     [_ProcRefMax],eax
0040147C E87FFBFFFF             call    _allocate
00401481 8BD8                   mov     ebx,eax
00401483 A1404C4100             mov     eax,[_ProcRefCount]
00401488 8B35444C4100           mov     esi,[_ProcRefList]
0040148E 8BFB                   mov     edi,ebx
00401490 8D0C80                 lea     ecx,[eax+eax*4]
00401493 D1E1                   shl     ecx,1
00401495 8BC1                   mov     eax,ecx
00401497 C1E902                 shr     ecx,2
0040149A F3A5                   rep     movsd
0040149C 8BC8                   mov     ecx,eax
0040149E 83E103                 and     ecx,3
004014A1 F3A4                   rep     movsb
004014A3 8B0D444C4100           mov     ecx,[_ProcRefList]
004014A9 51                     push    ecx
004014AA E8A1FBFFFF             call    _release
004014AF 83C410                 add     esp,10h
004014B2 8BC3                   mov     eax,ebx
004014B4 A3444C4100             mov     [_ProcRefList],eax
004014B9 5F                     pop     edi
004014BA 5E                     pop     esi
004014BB 5B                     pop     ebx
004014BC EB1B                   jmp     loc_004014D9

004014BE                    loc_004014BE:               ; Xref 00401457
004014BE 8B1544104100           mov     edx,[_ProcRefMax]
004014C4 68C4124100             push    offset off_004112C4 ; 'AddProcRef(),ProcRefList',000h
004014C9 6A0A                   push    0Ah
004014CB 52                     push    edx
004014CC E82FFBFFFF             call    _allocate
004014D1 83C40C                 add     esp,0Ch
004014D4 A3444C4100             mov     [_ProcRefList],eax
004014D9                    loc_004014D9:               ; Xref 00401467 004014BC
004014D9 85C0                   test    eax,eax
004014DB 7453                   jz      loc_00401530
004014DD 8B0D404C4100           mov     ecx,[_ProcRefCount]
004014E3 668B542404             mov     dx,[esp+4]
004014E8 8D0C89                 lea     ecx,[ecx+ecx*4]
004014EB 66891448               mov     [eax+ecx*2],dx
004014EF A1404C4100             mov     eax,[_ProcRefCount]
004014F4 8B0D444C4100           mov     ecx,[_ProcRefList]
004014FA 8B542408               mov     edx,[esp+8]
004014FE 8D0480                 lea     eax,[eax+eax*4]
00401501 89544102               mov     [ecx+eax*2+2],edx
00401505 8B44240C               mov     eax,[esp+0Ch]
00401509 50                     push    eax
0040150A E851FBFFFF             call    _strmalloc
0040150F 8B0D404C4100           mov     ecx,[_ProcRefCount]
00401515 8B15444C4100           mov     edx,[_ProcRefList]
0040151B 83C404                 add     esp,4
0040151E 8D0C89                 lea     ecx,[ecx+ecx*4]
00401521 89444A06               mov     [edx+ecx*2+6],eax
00401525 A1404C4100             mov     eax,[_ProcRefCount]
0040152A 40                     inc     eax
0040152B A3404C4100             mov     [_ProcRefCount],eax
00401530                    loc_00401530:               ; Xref 004014DB
00401530 C3                     ret
It could be a random act of randomness. Those happen a lot as well.


MichaelW

Mouse driver function 2 hides the mouse cursor and function 3 gets the button status and mouse position. Since you are referring to mouse-driver functions, I assume that you will be depending on a mouse driver to interface with the mouse, and that by "custom mouse" you mean a custom mouse cursor.

For the text modes the mouse driver provides a way to control how the cursor affects the appearance of the character under it. For the graphics modes the mouse driver provides a relatively simple way to define and use a custom cursor, but note that the cursor must fit in a 16x16-pixel block for the most commonly used display modes.

The mouse driver also provides a method for a user program to effectively hook into the mouse hardware interrupt. This method will work better than the separate thread that you are proposing, and it is much, much easier to implement.
eschew obfuscation

www.:).com

#18
O, i didn't know that, and Thanks for correcting me I thought it was the other way around function 01 hid the cursor and 02 showed it.

MichaelW

The attachment does not attempt to implement a custom cursor, but it does show how a mouse-driver interrupt subroutine can be implemented and basically how it works.
eschew obfuscation

MichaelW

This code implements a custom cursor, consisting of a single pixel to keep it simple.

;=========================================================================
.model small, c
.386
include support.asm
.stack
;=========================================================================
.data
;=========================================================================
    prevx     dw 0
    prevy     dw 0
    backcolor dw 0
;=========================================================================
.code
;=========================================================================

;---------------------------------------------------------------
; These procedures assume that the VGA is operating in mode 13h,
; and that ES has been loaded with the segment address of the
; graphics display buffer.
;---------------------------------------------------------------

GetPixel_13 proc uses bx cx dx x:WORD,y:WORD

    mov ax, y         ; pixel byte address = y*320+x
    mov cx, 320
    mul cx
    mov bx, ax
    add bx, x
    xor ah, ah
    mov al, es:[bx]
    ret

GetPixel_13 endp

SetPixel_13 proc uses ax bx cx dx x:WORD,y:WORD,color:WORD

    mov ax, y         ; pixel byte address = y*320+x
    mov cx, 320
    mul cx
    mov bx, ax
    add bx, x
    mov ax, color
    mov es:[bx], al
    ret

SetPixel_13 endp

;=========================================================================

MouseInit proc

    mov ax, 3533h
    int 21h
    mov ax, es
    test ax, ax
    jnz @F
    ret
  @@:
    xor ax,ax
    int 33h
    test ax, ax
    jnz @F
    ret
  @@:
    mov ax, 12
    mov cx, 1    ; set only mask bit 0, cursor position changed
    push cs
    pop es
    mov dx, InterruptSub
    int 33h
    mov ax, 1
    ret

MouseInit endp

;=========================================================================

InterruptSub proc

    push ds
    push es
    push ss
    pop ds
    push 0A000h
    pop es

    ;--------------------------------------------------------------
    ; Convert the virtual-screen x coordinate (0-639) to a display
    ; pixel coordinate (0-319). For mode 13h the virtual-screen y
    ; coordinate (0-199) requires no conversion.
    ;--------------------------------------------------------------

    shr cx, 1

    ;------------------------------------------------------------
    ; Erase the cursor by restoring the saved background at the
    ; previous cursor position, save the current coordinates for
    ; the next cycle, save the background at the new position,
    ; and draw the cursor at the new position.
    ;------------------------------------------------------------

    invoke SetPixel_13, prevx, prevy, backcolor
    mov prevx, cx
    mov prevy, dx
    invoke GetPixel_13, cx, dx
    mov backcolor, ax
    invoke SetPixel_13, cx, dx, 1

    pop es
    pop ds
    retf

InterruptSub endp

;=========================================================================
.startup
;=========================================================================

    mov ax, 13h
    int 10h
    call MouseInit
    print hexword$(ax),13,10
    call waitkey

;=========================================================================
.exit
end
eschew obfuscation

dedndave

the default cursor for video mode 13h is big and clunky - lol
here is one i created for that mode   :U
you may want to replace the F6 and FE values with your own palette values of black and white

; mode 13h cursor
;
; width = 7
; height = 12
;
; 0 = x
; F6 = black
; FE = white
;
CBMEXI  DW      0F6h,0,0,0,0,0,0
        DW      0F6h,0F6h,0,0,0,0,0
        DW      0F6h,0FEh,0F6h,0,0,0,0
        DW      0F6h,0FEh,0FEh,0F6h,0,0,0
        DW      0F6h,0FEh,0FEh,0FEh,0F6h,0,0
        DW      0F6h,0FEh,0FEh,0FEh,0FEh,0F6h,0
        DW      0F6h,0FEh,0FEh,0FEh
        DW      0FEh,0FEh,0F6h
        DW      0F6h,0FEh,0FEh,0FEh,0FEh,0F6h,0
        DW      0F6h,0F6h,0F6h,0FEh,0FEh,0F6h,0
        DW      0,0,0,0F6h,0FEh,0FEh,0F6h
        DW      0,0,0,0F6h,0F6h,0F6h,0

my notes say the height is 11 pixels
but i see 12 lines of data - not sure why that is - lol
i may have decided not to use the bottom line of data

www.:).com

Thanks, and as for the 12 lines filled in when there are only to be 11 is the last a black line? Because when I set pixels on the screen for some reason there is one black pixel to the right of where I set the pixel. Do you happen to know why it does this or is it what I use to run them (dosbox)?

dedndave

without seeing the code - no

yes - the bottom line is (partially) black
any location in the bitmap that contains a 0 is not z-buffered and over-written by a cursor pixel
i.e., the current pixel values at those locations are left unmodified
otherwise, all the F6 locations are black cursor pixels and all the FE locations are white cursor pixels

it has been a long time since i have written any code for mode 13h
perhaps the table needs to be defined as one more line than is declared in the mouse cursor set function
i don't recall

i do seem to recall that word values are used so that the high byte may serve as the actual z-buffer

as i said...
Quotemy notes say the height is 11 pixels
but i see 12 lines of data - not sure why that is - lol
i may have decided not to use the bottom line of data
try using 12 lines of data and telling the function you want a cursor of 11 lines height

www.:).com

Well i'm wondering why it puts a black pixel next to it. Here is some code i wrote that simply sets the entire screen to green. After that it sets the first pixel to blue and if you look closely there is a black pixel next to it. If you would like to test it assemble it using ml.exe and link16.exe in masm32\bin directory. I would not run it in real dos because for some reason when i assembled it it would not change back to text mode. wonder why? I recommend using dosbox at: http://www.dosbox.com/



; Question for masm form
.model small
.stack
.data
.code
AppMain:
    mov ax, 00a000h      ; mov segment of 13h video memory in to es for quick reference
    mov es, ax

    mov ax, 13h      ; switch the video mode to 13h -- 320 X 200, 256 colors
    int 10h

    mov ax, 2      ; move the vga color for green into ax
    mov di, 0      ; reset di to 0 so wee can fill the whole screen

    FillScreen:      ;Shows that this is were we fill the screen
    mov es:[di], ax      ; put the color ax into di
    inc di      ; increment di by 1
    cmp di, 64000      ; see if di is at byte 64000 because we fill whole screen (320 * 200 = 64000)
    jne FillScreen      ; cheak to see if we have filled screen if so continue with rest of program

    ; Set first pixel to blue
    mov ax, 1      ; set the regester i use for color to blue
    mov di, 0      ; set the regester i use for pixel positioning to 0 -- first pixel
    mov es:[di], ax      ; set the pixel

    mov ah, 07      ; Wait for key press
    int 21h

    mov ax, 03      ; switch video mode back to 80 X 25 -- text mode
    int 10h

    mov ax, 4c00h      ; Exit to dos
    int 21h
end AppMain


MichaelW

Quote from: www.:).com on November 07, 2010, 03:00:06 PM
I would not run it in real dos because for some reason when i assembled it it would not change back to text mode. wonder why?

It does switch back to text mode, but since the code does not pause after the switch, you can't see it (or at least I can't the way I'm executing it). Try adding this code after the mode switch:

    mov ax, 40h     ;
    mov es, ax      ; load segment address of BIOS data area into ES
    mov bx, 49h     ; load offset address of current video mode into BX
    mov dl, es:[bx] ; get the value into DL
    add dl, 30h     ; anticipating a one-digit value, convert to decimal digit
    mov ah, 2       ; and display it
    int 21h

    mov ah, 07      ; Wait for key press
    int 21h


Dave,

I was interested to see what your cursor looked like, but I don't understand the definition or how it's supposed to be used. For mode 13h a 7x11 cursor should occupy 77 bytes in the display buffer, not 84 words. For the mouse driver Set Graphics Cursor Block Function (9), you specify the cursor as two 16x16 bit masks, 32 words total.

eschew obfuscation

www.:).com

Quote from: MichaelW on November 07, 2010, 04:46:55 PM
Dave,

I was interested to see what your cursor looked like, but I don't understand the definition or how it's supposed to be used. For mode 13h a 7x11 cursor should occupy 77 bytes in the display buffer, not 84 words. For the mouse driver Set Graphics Cursor Block Function (9), you specify the cursor as two 16x16 bit masks, 32 words total.

Thanks, but i'm not shore I understand what you are saying.
- Remember I am a beginner(only understand the fundamentals).

dedndave

sorry guys
looking further at my code, i had implemented drawing and un-drawing the cursor myself - lol

give me a few minutes and i'll post the resultant exe   :P

dedndave

ok - here it is

to run sf1mg2.com:

the W parameter allows creation of the map to be viewed
so, at the command prompt type:
SF1MG2 W
the first time you run it, it will generate a map
however, if the map is already present, some text notes will appear
press O to see it generated again or V to view the one already generated
(pressing V does not allow you to view map generation, of course)

once you are in there, a map appears
you can move the mouse about and click to bring up the measurement calipers
clicking again starts a measurement and again ends it

when you are done playing with that (lol), press ESC to exit (twice if calipers have been used)
THEN, you will see the cursor that i posted earlier (it is only used for the exit menu - lol)

note: to get out of full screen mode after exit, press Alt-Enter

MichaelW

Quote from: www.:).com on November 07, 2010, 05:00:06 PM
Thanks, but i'm not shore I understand what you are saying.
- Remember I am a beginner(only understand the fundamentals).

I'm not sure what you are asking, but here is a quick demo of a user-defined cursor and the Set Graphics Cursor Block function:

;=========================================================================
.model small
.386
.stack
.data
    ;------------------------------------------------
    ; Define screen and cursor masks for a crosshair
    ; cursor. Cursor hot spot at 7,7.
    ;
    ; The mouse driver will AND the screen mask bits
    ; with the corresponding screen pixel bits and
    ; XOR the result with the cursor mask. In truth
    ; table form:
    ;
    ;  screen mask cursor mask resulting screen bit
    ;       0            0              0
    ;       0            1              1
    ;       1            0          unchanged
    ;       1            1          inverted
    ;
    ; Note that the masks bits are expanded as
    ; necessary for the current graphics mode.
    ; For example, for mode 13h each mask bit is
    ; expanded to 8 bits and these bits are then
    ; combined with the 8 attribute bits for the
    ; corresponding screen pixel.
    ;------------------------------------------------

                  ;0123456701234567
    screen_mask dw 1111111111111111b ;0
                dw 1111111111111111b ;1
                dw 1111111011111111b ;2
                dw 1111111011111111b ;3
                dw 1111111011111111b ;4
                dw 1111111011111111b ;5
                dw 1111111111111111b ;6
                dw 0000001110000001b ;7
                dw 1111111111111111b ;0
                dw 1111111011111111b ;1
                dw 1111111011111111b ;2
                dw 1111111011111111b ;3
                dw 1111111011111111b ;4
                dw 1111111111111111b ;5
                dw 1111111111111111b ;6
                dw 1111111111111111b ;7

    cursor_mask dw 0000000000000000b ;0
                dw 0000000000000000b ;1
                dw 0000000100000000b ;2
                dw 0000000100000000b ;3
                dw 0000000100000000b ;4
                dw 0000000100000000b ;5
                dw 0000000000000000b ;6
                dw 1111110001111110b ;7
                dw 0000000000000000b ;0
                dw 0000000100000000b ;1
                dw 0000000100000000b ;2
                dw 0000000100000000b ;3
                dw 0000000100000000b ;4
                dw 0000000000000000b ;5
                dw 0000000000000000b ;6
                dw 0000000000000000b ;7

;=========================================================================
.code
;=========================================================================

MouseInit proc
    mov ax, 3533h
    int 21h
    mov ax, es
    test ax, ax
    jnz @F
    ret
  @@:
    xor ax,ax
    int 33h
    test ax, ax
    jnz @F
    ret
  @@:
    mov ax, 1
    ret
MouseInit endp

;=========================================================================
.startup
;=========================================================================

    mov ax, 13h
    int 10h

    call MouseInit
    test ax, ax
    jz  @F

    mov ax, 9       ; Set Graphics Cursor Block
    mov bx, 7       ; hot spot x coordinate
    mov cx, 7       ; hot spot y coordinate
    push ds         ; ES:DX -> screen and cursor masks
    pop es
    mov dx, OFFSET screen_mask
    int 33h

    mov ax, 1       ; Show Cursor
    int 33h

  @@:

    mov ah, 07
    int 21h

;=========================================================================
.exit
end


eschew obfuscation