Results 1 to 27 of 27

Thread: Inline assembly

  1. #1
    Guest

    Post

    Anyone know any good inline assembly functions, grahics or otherwise?

  2. #2
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Check this baby out: (I wrote this yesterday)
    Code:
    #include <iostream>
    
    #if _MSC_VER < 1100
    #error Unlikely to work on another compiler...
    #endif
    
    using namespace std;
    
    void sound(long lFreq, long lDuration);
    
    int main() {
    	for(int j = 1; j < 5; j++) {
    		for(int i = 1; i < 5; i++) {
    			sound(1046 / i, 10);
    			sound(988 / i, 10);
    			sound(880 / i, 10);
    			sound(784 / i, 10);
    			sound(699 / i, 10);
    			sound(659 / i, 10);
    			sound(587 / i, 10);
    			sound(523 / i, 10);
    		}
    	}
    	return 0;
    }
    
    void sound(long lFreq, long lDuration) {
    	__asm {
    		; Setting up
    		mov ebx,	lDuration
    		mov edi,	lFreq
    
    		in  al,		61h		// Read current port mode B
    		mov cl,		al		// Save current mode
    		or	al,		3		// Switch on speaker and timer
    		out 61h,	al
    		mov al,		0b6h	// Set for channel 2
    		out 43h,	al		// Command register
    		mov dx,		14h
    		mov ax,		4f38h	// Frequency divisor
    		div di
    		out 42h,	al		// Low byte of frequency
    		mov al,		ah
    		out 42h,	al		// High byte of frequency
    		
    		; Delay
    		mov	ax,		91		// Multiplier
    		mul	bx
    		mov	bx,		500
    		div	bx
    		mov	bx,		ax		// Save result
    		mov	ah,		0		// Read time
    		int	1ah
    		add	dx,		bx
    		mov	bx,		dx
    
    		// Cycle until time's up
    Cycle:	int	1ah
    		cmp	dx,		bx		// Has time gone?
    		ja Break			// If we miss it somehow...exit anyway
    		jne	Cycle			// Loop round again
    
    Break:	in	al,		61h		// Read mode of port B
    		mov	al,		cl		// Previous mode
    		and	al,		0fch
    		out	61h,	al		// Restore mode
    	}
    }
    Just call sound(frequency, duration in 1/100sec). It makes a tone on the PC's internal speaker
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  3. #3
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892

    Cool Cool inline assembly!

    My favorite!
    WOO! No #includes!
    Code:
    #define ASMERROR_SUCCESS					0x00
    #define ASMERROR_FUNCTION_NOT_SUPPORTED		0x01
    #define ASMERROR_VOLUME_LOCKED				0xB1
    #define ASMERROR_VOLUME_NOT_REMOVABLE		0xB2
    #define ASMERROR_EJECT_REQUEST_FAILED		0xB5
    
    short AsmEjectDrive(char DriveLetter)
    {
    	short ReturnValue = ASMERROR_SUCCESS;
    	short DriveNumber = (short) DriveLetter - (DriveLetter>=65 && DriveLetter<=90 ? 64 : 96);
    	
    	__asm {
    		push ax
    		push bx					// Preserve registers for later
    		push cx
    
    		mov ax, 440Dh			// Generic IOCTL operation
    		mov bx, DriveNumber 	// BX register requires drive NUMBER (not letter)
    		mov cx, 849h			// Device operation -> eject something removable!
    		int 21h					// Yep, it's the 21h interrupt we know and love
    		
    		jnc success				// No carry flag? WOO! Success!
    		
    		mov ReturnValue, ax		// Carry flag? DRATS! Failure. AX (ErrorCode)->ReturnValue
    success:
    		pop cx
    		pop bx					// Restore registers (they were preserved)
    		pop ax
    	}
    	
    	// By now, either the drive ejected itself and ReturnValue remained
    	// ASMERROR_SUCCESS, or it didn't and ReturnValue became one of the
    	// error codes #defined above... Good enough by us! Return it.
    	return ReturnValue;
    }
    
    void main()
    {
    	AsmEjectDrive('E'); // Guess what this does...
    }
    It returns one of the error code things defined on the top.

  4. #4
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Well, my hard disk just flew out of its caddy . I think it's time for an asm competition...
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  5. #5
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892
    Well I don't really know any cool assembly functions.
    This one for ejecting your "hard drive", I stole from MSDN when nobody was looking.
    Oh, here's one from around my HD somewhere...
    Let's say you don't want a whole huge #include just for a poor little clrscr() - solution:
    Use this!
    Code:
    void clrscr()
    {
    	__asm {
    		push ax
    		push es
    		push di // Save all the junky registers
    		push cx
    		
    		mov ax, 0xB800 // Put the video-card address 0xB800 in AX
    		mov es, ax // ...so that we can move it to ES
    		xor di, di // Set DI to zero (start clearing the screen from the zeroest point)
    		mov cx, 2000 // We want to clear 2000 chars (80x25)
    		mov ax, 20h // Clear with the character 20h (space)
    		rep stosw // Store 20h in ES:DI (video:changing location) 2000 times, thus CLRSCRing
    
    		pop cx
    		pop di // Take 'em back
    		pop es
    		pop ax
    	}
    }
    It's been long, it might not work, you'll get over it.

  6. #6
    Guest
    <ahem> speaking of ASM, paste this into an ASM file, and compile it.
    incase you dont get a chance to try this totaly kewl program, it makes your moniter in full-screen mode, then makes cool fire effect...

    =)
    it has nothing to do with what your talking about, I just thought I would include it(BTW the compiled executable is only 1.92kb)
    Code:
       .MODEL SMALL   ; Data segment < 64K, code segment < 64K
       .STACK 200H    ; Set up 512 bytes of stack space
       .386
    
    ; ===========================================================================
      .DATA
    
    CR        EQU 13
    LF        EQU 10
    
    BufferX   EQU 320                       ; Width of screen buffer
    BufferY   EQU 104                       ; Height of screen buffer
    
    AllDone   DB CR, LF, "That was:"
              DB CR, LF
              DB CR, LF, "         FFFFFFFFF    IIIIIII     RRRRRRRRR        EEEEEEEEE         !  "
              DB CR, LF, "          FFF           III        RRR   RRR        EEE             !!! "
              DB CR, LF, "          FFF           III        RRR   RRR        EEE            !!!!!"
              DB CR, LF, "          FFF           III        RRRRRRRR         EEE            !!!!!"
              DB CR, LF, "          FFFFFFF       III        RRRRRRRR         EEEEEEEE       !!!!!"
              DB CR, LF, "          FFF           III        RRR  RRR         EEE             !!! "
              DB CR, LF, "          FFF           III        RRR   RRR        EEE                 "
              DB CR, LF, "          FFF           III        RRR    RRR       EEE             !!! "
              DB CR, LF, "         FFFFF        IIIIIII     RRRR    RRRR     EEEEEEEEE        !!! "
              DB CR, LF
              DB CR, LF
    
    Buffer    DB BufferX * BufferY DUP (?) ; The screen buffer
    
    Seed      DW 3749h                     
    INCLUDE PALETTE.DAT                    ; The palette, generated with
                                           ; Autodesk Animator, and a simple
                                           ; Pascal program.
    
    ; ===========================================================================
       .CODE
    
    InitializeMCGA   PROC
       MOV   AX, 0A000h
       MOV   ES, AX                        ; ES now points to the VGA
    
       MOV   AH, 00H                       ; Set video mode
       MOV   AL, 13H                       ; Mode 13h
       INT   10H                           ; We are now in 320x200x256
       RET            
    InitializeMCGA   ENDP
    
    ; ---------------------------------------------------------------------------
    
    SetUpPalette     PROC
       MOV   SI, OFFSET Palette            ; SI now points to the palette
       MOV   CX, 768                       ; Prepare for 768 OUTs
       MOV   DX, 03C8H                     ; Palette WRITE register
       XOR   AL, AL                        ; Start at color 0
       CLI                                 ; Disable interrupts
       OUT   DX, AL                        ; Send value
       CLD                                 ; Forward direction
       INC   DX                            ; Now use palette DATA register
       REP   OUTSB                         ; 768 multiple OUTs
       STI                                 ; Enable interrupts
       RET
    SetupPalette     ENDP
    
    ; ---------------------------------------------------------------------------
    
    ; This procedure was picked up from comp.lang.asm.x86 - many thanks to the
    ; unknown author.
    
    Random           PROC
       MOV   AX, Seed                      ; Move the seed value into AX
       MOV   DX, 8405H                     ; Move 8405H into DX
       MUL   DX                            ; Put 8405H x Seed into DX:AX
       INC   AX                            ; Increment AX
       MOV   Seed, AX                      ; We have a new seed
       RET
    Random           ENDP
    
    ; ---------------------------------------------------------------------------
    
    DrawScreen       PROC
       MOV   SI, OFFSET Buffer             ; Point SI to the start of the buffer
       XOR   DI, DI                        ; Start drawing at 0, 0
       MOV   BX, BufferY - 4               ; Miss the last four lines from the
                                           ; buffer.  These lines will not look
                                           ; fire-like at all
    Row:
       MOV   CX, BufferX SHR 1             ; 160 WORDS
       REP   MOVSW                         ; Move them
       SUB   SI, 320                       ; Go back to the start of the array row
       MOV   CX, BufferX SHR 1             ; 160 WORDS
       REP   MOVSW                         ; Move them
       DEC   BX                            ; Decrease the number of VGA rows left
       JNZ   Row                           ; Are we finished?
       RET
    DrawScreen       ENDP
    
    ; ---------------------------------------------------------------------------
    
    AveragePixels    PROC
       MOV   CX, BufferX * BufferY - BufferX * 2  ; Alter all of the buffer,
                                                  ; except for the first row and
                                                  ; last row
       MOV   SI, OFFSET Buffer + 320              ; Start from the second row
    
    Alter:
       XOR   AX, AX                        ; Zero out AX
       MOV   AL, DS:[SI]                   ; Get the value of the current pixel
       ADD   AL, DS:[SI+1]                 ; Get the value of pixel to the right
       ADC   AH, 0
       ADD   AL, DS:[SI-1]                 ; Get the value of pixel to the left
       ADC   AH, 0
       ADD   AL, DS:[SI+BufferX]           ; Get the value of the pixel underneath
       ADC   AH, 0
       SHR   AX, 2                         ; Divide the total by four
    
       JZ    NextPixel                     ; Is the result zero?
       DEC   AX                            ; No, so decrement it by one
    
    NextPixel:
       MOV   DS:[SI-BufferX], AL           ; Put the new value into the array
       INC   SI                            ; Next pixel
       DEC   CX                            ; One less to do
       JNZ   Alter                         ; Have we done them all?
       RET
    AveragePixels    ENDP
    
    ; ---------------------------------------------------------------------------
    
    TextMode         PROC
       MOV   AH, 00H                       ; Set video mode
       MOV   AL, 03H                       ; Mode 03h
       INT   10H                           ; Enter 80x25x16 mode
    
       MOV   DX, OFFSET AllDone            ; DS:DX points to the ending message
       MOV   AH, 09H
       INT   21H                           ; Display the ending message
       RET
    TextMode         ENDP
    
    ; ---------------------------------------------------------------------------
    
    Start:
       MOV   AX, @DATA
       MOV   DS, AX                        ; DS now points to the data segment.
    
       CALL  InitializeMCGA
       CALL  SetUpPalette
    
    MainLoop:
       CALL  AveragePixels
    
       MOV   SI, OFFSET Buffer + BufferX * BufferY - BufferX SHL 1
       ; SI now points to the start of the second last row
       MOV   CX, BufferX SHL 1             ; Prepare to get BufferX x 2 random #s
    
    BottomLine:
       CALL   Random                       ; Get a random number
       MOV    DS:[SI], DL                  ; Use only the low byte of DX - ie,
       INC    SI                           ; the number will be 0 --> 255
       DEC    CX                           ; One less pixel to do
       JNZ    BottomLine                   ; Are we done yet?
    
       CALL  DrawScreen                    ; Copy the buffer to the VGA
    
       MOV   AH, 01H                       ; Check for keypress
       INT   16H                           ; Is a key waiting in the buffer?
       JZ    MainLoop                      ; No, keep on going
    
       MOV   AH, 00H                       ; Yes, so get the key
       INT   16H
    
       CALL  TextMode
       MOV   AH, 4CH
       MOV   AL, 00H
       INT   21H                           ; Return to DOS
    END Start
    Ok, you called my bluff, you saw an INCLUDE in there,
    put this in a file called pallete.dat

    Code:
    ; This file was generated externally by a high level language, and a
    ; copy of Autodesk Animator.  This file is only needed by FIRE!.ASM
    ; during assembly, and is not required for FIRE!.EXE to run.
    
    
    Palette DB    0,  0,  0,  0,  0,  6,  0,  0,  6,  0,  0,  7,  0,  0,  8,  0,  0,  8,  0,  0,  9,  0,  0, 10
            DB    2,  0, 10,  4,  0,  9,  6,  0,  9,  8,  0,  8, 10,  0,  7, 12,  0,  7, 14,  0,  6, 16,  0,  5
            DB   18,  0,  5, 20,  0,  4, 22,  0,  4, 24,  0,  3, 26,  0,  2, 28,  0,  2, 30,  0,  1, 32,  0,  0
            DB   32,  0,  0, 33,  0,  0, 34,  0,  0, 35,  0,  0, 36,  0,  0, 36,  0,  0, 37,  0,  0, 38,  0,  0
            DB   39,  0,  0, 40,  0,  0, 40,  0,  0, 41,  0,  0, 42,  0,  0, 43,  0,  0, 44,  0,  0, 45,  0,  0
            DB   46,  1,  0, 47,  1,  0, 48,  2,  0, 49,  2,  0, 50,  3,  0, 51,  3,  0, 52,  4,  0, 53,  4,  0
            DB   54,  5,  0, 55,  5,  0, 56,  6,  0, 57,  6,  0, 58,  7,  0, 59,  7,  0, 60,  8,  0, 61,  8,  0
            DB   63,  9,  0, 63,  9,  0, 63, 10,  0, 63, 10,  0, 63, 11,  0, 63, 11,  0, 63, 12,  0, 63, 12,  0
            DB   63, 13,  0, 63, 13,  0, 63, 14,  0, 63, 14,  0, 63, 15,  0, 63, 15,  0, 63, 16,  0, 63, 16,  0
            DB   63, 17,  0, 63, 17,  0, 63, 18,  0, 63, 18,  0, 63, 19,  0, 63, 19,  0, 63, 20,  0, 63, 20,  0
            DB   63, 21,  0, 63, 21,  0, 63, 22,  0, 63, 22,  0, 63, 23,  0, 63, 24,  0, 63, 24,  0, 63, 25,  0
            DB   63, 25,  0, 63, 26,  0, 63, 26,  0, 63, 27,  0, 63, 27,  0, 63, 28,  0, 63, 28,  0, 63, 29,  0
            DB   63, 29,  0, 63, 30,  0, 63, 30,  0, 63, 31,  0, 63, 31,  0, 63, 32,  0, 63, 32,  0, 63, 33,  0
            DB   63, 33,  0, 63, 34,  0, 63, 34,  0, 63, 35,  0, 63, 35,  0, 63, 36,  0, 63, 36,  0, 63, 37,  0
            DB   63, 38,  0, 63, 38,  0, 63, 39,  0, 63, 39,  0, 63, 40,  0, 63, 40,  0, 63, 41,  0, 63, 41,  0
            DB   63, 42,  0, 63, 42,  0, 63, 43,  0, 63, 43,  0, 63, 44,  0, 63, 44,  0, 63, 45,  0, 63, 45,  0
            DB   63, 46,  0, 63, 46,  0, 63, 47,  0, 63, 47,  0, 63, 48,  0, 63, 48,  0, 63, 49,  0, 63, 49,  0
            DB   63, 50,  0, 63, 50,  0, 63, 51,  0, 63, 52,  0, 63, 52,  0, 63, 52,  0, 63, 52,  0, 63, 52,  0
            DB   63, 53,  0, 63, 53,  0, 63, 53,  0, 63, 53,  0, 63, 54,  0, 63, 54,  0, 63, 54,  0, 63, 54,  0
            DB   63, 54,  0, 63, 55,  0, 63, 55,  0, 63, 55,  0, 63, 55,  0, 63, 56,  0, 63, 56,  0, 63, 56,  0
            DB   63, 56,  0, 63, 57,  0, 63, 57,  0, 63, 57,  0, 63, 57,  0, 63, 57,  0, 63, 58,  0, 63, 58,  0
            DB   63, 58,  0, 63, 58,  0, 63, 59,  0, 63, 59,  0, 63, 59,  0, 63, 59,  0, 63, 60,  0, 63, 60,  0
            DB   63, 61,  0, 63, 61,  0, 63, 61,  0, 63, 62,  0, 63, 62,  0, 63, 62,  0, 63, 62,  0, 63, 63,  0
            DB   63, 63,  1, 63, 63,  2, 63, 63,  3, 63, 63,  4, 63, 63,  5, 63, 63,  6, 63, 63,  7, 63, 63,  8
            DB   63, 63,  9, 63, 63, 10, 63, 63, 10, 63, 63, 11, 63, 63, 12, 63, 63, 13, 63, 63, 14, 63, 63, 15
            DB   63, 63, 16, 63, 63, 17, 63, 63, 18, 63, 63, 19, 63, 63, 20, 63, 63, 21, 63, 63, 21, 63, 63, 22
            DB   63, 63, 23, 63, 63, 24, 63, 63, 25, 63, 63, 26, 63, 63, 27, 63, 63, 28, 63, 63, 29, 63, 63, 30
            DB   63, 63, 31, 63, 63, 31, 63, 63, 32, 63, 63, 33, 63, 63, 34, 63, 63, 35, 63, 63, 36, 63, 63, 37
            DB   63, 63, 38, 63, 63, 39, 63, 63, 40, 63, 63, 41, 63, 63, 42, 63, 63, 42, 63, 63, 43, 63, 63, 44
            DB   63, 63, 45, 63, 63, 46, 63, 63, 47, 63, 63, 48, 63, 63, 49, 63, 63, 50, 63, 63, 51, 63, 63, 52
            DB   63, 63, 52, 63, 63, 53, 63, 63, 54, 63, 63, 55, 63, 63, 56, 63, 63, 57, 63, 63, 58, 63, 63, 59
            DB   63, 63, 60, 63, 63, 61, 63, 63, 62, 63, 63, 63, 63, 63, 60, 63, 63, 61, 63, 63, 62, 63, 63, 63

  7. #7
    Guest
    Does anyone have any asm functions for plotting s pixel, and drawing a line and rectangle?

  8. #8
    Guest
    Ok i found a bunch of functions in asm, but the ones that have a variable thats a "byte" dont seem to work. What i mean by byte is...

    void pixel(int x, int y, byte color)

    Any ideas?

  9. #9
    Guest
    How is it used?

    and does it give an error as to say why it doesnt work??

  10. #10
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892
    Here's the definition:
    Code:
    typedef __int8 byte;
    Good luck!

  11. #11
    Guest
    This is the function...

    void pixel(int x, int y, byte color)
    {
    asm mov ax, 0A000h
    asm mov es, ax
    asm mov bx, x
    asm mov dx, y
    asm xchg dh, dl
    asm mov al, color
    asm mov di, dx
    asm shr di, 2
    asm add di, dx
    asm add di, bx
    asm stosb
    }

    Do you see anything wrong in it?

  12. #12
    Guest
    I dont really know how ASM works in C++, but I dont think you need the asm in front of everything.

  13. #13
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    The syntax is:
    Code:
    asm statement
    or
    Code:
    asm {
        statements
    }
    In Visual C++, though, you need to use __asm rather than asm.

    PS: Dennis - I'm back on YM now, if you wanted to talk.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  14. #14
    Guest
    If you didnt notice, i have "asm" in front of everything.

  15. #15
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Yeah - I was just clarifying for Dennis...
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  16. #16
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892
    I don't see anything wrong with that code.
    Is it not working?

  17. #17
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    It didn't work on my copy of VC++5...until I added this to the top of the file:
    Code:
    #ifndef asm
    #define asm __asm
    #endif
    That should work for most compilers, since they usually add a __ to proprietary things.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  18. #18
    Guest
    Well i think i got past that byte problem, but now im getting this error...

    Error: 286/287 instructions not enabled in function pixel(int, int, unsigned char)

    Any ideas?

  19. #19
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    What compiler / error number?
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  20. #20
    Guest
    I figured it out, i have to compile with the 286 instructions tirned on. It was all my fault, i should have looked at the switches sooner. Thanks though. One more questions, does anyone know how to draw a line, square and circle?

  21. #21
    Guest
    Or if you dont know any could you transfer these into inline assembly for me, thanks.

    Code:
    void line(int x1, int y1, int x2, int y2, byte color)
    {
    	int i, dx, dy, sdx, sdy, dxabs, dyabs, x, y, px, py;
    
    	dx = x2 - x1;
    	dy = y2 - y1;
    	dxabs = abs(dx);
    	dyabs = abs(dy);
    	sdx = sgn(dx);
    	sdy = sgn(dy);
    	x = dyabs>>1;
    	y = dxabs>>1;
    	px = x1;
    	py = y1;
    
    	VGA[(py<<8)+(py<<6)+px]=color;
    
    	if(dxabs >= dyabs)
    	{
    		for(i = 0; i < dxabs; i++)
    		{
    			y+=dyabs;
    			if(y >= dxabs)
    			{
    				y-+dxabs;
    				py+=sdy;
    			}
    			px+=sdx;
    			pixel(px, py, color);
    		}
    	}
    
    	else
    	{
    		for(i = 0; i < dyabs; i++)
    		{
    			x+=dxabs;
    			if(x >= dyabs)
    			{
    				x-=dyabs;
    				px+=sdx;
    			}
    			py+=sdy;
    			pixel(px, py, color);
    		}
    	}
    }

    Code:
    void rect(int left, int top, int right, int bottom, byte color)
    {
    	word top_offset, bottom_offset, i, temp;
    
    	if(top>bottom)
    	{
    		temp=top;
    		top=bottom;
    		bottom=temp;
    	}
    	if(left>right)
    	{
    		temp=left;
    		left=right;
    		right=temp;
    	}
    
    	top_offset=(top<<8)+(top<<6);
    	bottom_offset=(bottom<<8)+(bottom<<6);
    
    	for(i=left; i<=right; i++)
    	{
    		VGA[top_offset+i]=color;
    		VGA[bottom_offset+i]=color;
    	}
    
    	for(i=top_offset; i<=bottom_offset; i+=SCREEN_WIDTH)
    	{
    		VGA[left+i]=color;
    		VGA[right+i]=color;
    	}
    }

    Code:
    void rectFill(int left, int top, int right, int bottom, byte color)
    {
    	word top_offset, bottom_offset, i, temp, width;
    
    	if(top>bottom)
    	{
    		temp=top;
    		top=bottom;
    		bottom=temp;
    	}
    	if(left>right)
    	{
    		temp=left;
    		left=right;
    		right=temp;
    	}
    
    	top_offset=(top<<8)+(top<<6)+left;
    	bottom_offset=(bottom<<8)+(bottom<<6)+left;
    	width=right-left+1;
    
    	for(i=top_offset; i<=bottom_offset; i+=SCREEN_WIDTH)
    	{
    		memset(&VGA[i], color, width);
    	}
    }

  22. #22
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892
    I really hope this doesn't work, because that would mean I know asm!
    Code:
    void line(int x1, int y1, int x2, int y2, byte color)
    {
    	// Changed dx to d_x (dx->register name) and dy to d_y (to look good)
    	int i, d_x, d_y, sdx, sdy, dxabs, dyabs, x, y, px, py;
    	asm {
    //		d_x = x2 - x1;
    		mov d_x,x2
    		sub d_x,x1
    
    //		dy = y2 - y1;
    		mov d_y,y2
    		sub d_y,y1
    
    //		dxabs = abs(d_x);
    //		sdx = sgn(d_x);
    		mov dxabs,d_x
    		mov sdx,1
    		cmp dxabs,0
    		jge no_neg_d_x
    		neg dxabs
    		mov sdx,-1
    no_neg_d_x:
    
    //		dyabs = abs(d_y);
    //		sdy = sgn(dy);
    		mov dyabs,d_y
    		mov sdy,1
    		cmp dyabs,0
    		jge no_neg_d_y
    		neg dyabs
    		mov sdy,-1
    no_neg_d_y:
    
    //		x = dyabs>>1;
    		mov x,dyabs shr 1
    
    //		y = dxabs>>1;
    		mov y,dxabs shr 1
    
    //		px = x1;
    		mov px,x1
    
    //		py = y1;
    		mov py,y1
    
    //		VGA[(py<<8)+(py<<6)+px]=color;
    		mov ax,A000h
    		mov es,ax
    		mov di,x1
    		add di,y1 shl 6
    		add di,y1 shl 8
    		mov al,color
    		stosb
    
    //		if(dxabs >= dyabs)
    		cmp dxabs,dyabs
    		jl else_label
    //		{
    //			for(i = 0; i < dxabs; i++)
    			mov cx,dxabs
    for_label:
    //			{
    //				y+=dyabs;
    				add y,dyabs
    
    //				if(y >= dxabs)
    				cmp y,dxabs
    				jl end_inner_if_label
    //				{
    //					y-=dxabs;
    					sub y,dxabs
    
    //					py+=sdy;
    					add py,sdy
    //				}
    end_inner_if_label:
    //				px+=sdx;
    				add px,sdx
    
    //				pixel(px, py, color);
    		// NOTE: Standard ASM method------>
    				push px		// Delete these 4 lines if it's
    				push py		// MASM32
    				push color
    				call pixel
    		// NOTE: MASM32 method------------>
    				invoke pixel,px,py,color // Delete this line if it's not MASM32
    			dec cx
    			jnz for_label
    //			}
    		jmp end_if_label
    //		} else {
    else_label:
    //			for(i = 0; i < dyabs; i++)
    			mov cx,dyabs
    other_for_label:
    //			{
    //				x+=dxabs;
    				add x,dxabs
    
    //				if(x >= dyabs)
    				cmp x,dyabs
    				jl end_other_inner_if_label
    //				{
    //					x-=dyabs;
    					sub x,dyabs
    
    //					px+=sdx;
    					add px,sdx
    //				}
    end_other_inner_if_label:
    //				py+=sdy;
    				add py,sdy
    
    //				pixel(px, py, color);
    		// NOTE: Standard ASM method------>
    				push px		// Delete these 4 lines if it's
    				push py		// MASM32
    				push color
    				call pixel
    		// NOTE: MASM32 method------------>
    				invoke pixel,px,py,color // Delete this line if it's not MASM32
    			dec cx
    			jnz other_for_label
    //			}
    //		}
    end_if_label:
    } }

  23. #23
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892
    Same goes for this code, I hope it doesn't work!
    Code:
    void rect(int left, int top, int right, int bottom, byte color)
    {
    	word top_offset, bottom_offset; //, i, temp; ("i" and "temp" not needed in asm)
    
    	__asm {
    //		if(top>bottom)
    		cmp top,bottom
    		jle end_first_if
    //		{
    //			temp=top;
    //			top=bottom;
    //			bottom=temp;
    			xchg top,bottom
    //		}
    end_first_if:
    //		if(left>right)
    		cmp left,right
    		jle end_second_if
    //		{
    //			temp=left;
    //			left=right;
    //			right=temp;
    			xchg left,right
    //		}
    end_second_if:
    		
    //		top_offset=(top<<8)+(top<<6);
    		mov top_offset,top shl 8
    		add top_offset,top shl 6
    
    //		bottom_offset=(bottom<<8)+(bottom<<6);
    		mov bottom_offset,bottom shl 8
    		add bottom_offset,bottom shl 6
    		
    		// The following 2 lines are necessary for VGA, and aren't taking from C++ code:
    		mov ax,A000h
    		mov es,ax
    		// The above 2 lines, yadda yadda yadda
    		
    		// In the C++ statements below, there are numerous VGA[?] = color
    		// "color" doesn't change so let's put it in AL once, to save lots of time.
    		mov al,color
    
    //		for(i=left; i<=right; i++)
    		mov cx,right
    		sub cx,left
    //		{
    first_for_label:
    //			VGA[top_offset+i]=color;
    			mov di,top_offset
    			add di,cx
    			add di,left // because cx=i-left
    			stosb
    
    //			VGA[bottom_offset+i]=color;
    			mov di,bottom_offset
    			add di,cx
    			add di,left // same reason as above
    			stosb
    //		}
    		dec cx
    		jnz first_for_label
    
    //		for(i=top_offset; i<=bottom_offset; i+=SCREEN_WIDTH)
    		mov cx,bottom_offset
    		sub cx,top_offset
    //		{
    second_for_label:
    //			VGA[left+i]=color;
    			mov di,left
    			add di,cx
    			add di,top_offset
    			stosb
    
    //			VGA[right+i]=color;
    			mov di,left
    			add di,cx
    			add di,bottom_offset
    			stosb
    //		}
    		sub cx,SCREEN_WIDTH
    		cmp cx,0
    		jle second_for_label
    	}
    }

  24. #24
    Guest
    ok, i have a function and i want to return the value that in the register AL, how would i do that?

  25. #25
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Two ways:
    Code:
    long myfunc(long in) {
        long retval;
        asm {
            mov eax, in
            mov retval, eax
        }
        return retval;
    }
    ...or...
    Code:
    long myfunc(long in) {
        asm {
            mov eax, in
        }
    }
    In the second case it automatically returns the value. In 32bit C/C++, the return value is always stored in EAX.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  26. #26
    Guest
    The problem with that is im using dos so i cant use 32-bit registers.

  27. #27
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Umph...

    Try using AX then, for the return value. Keep in mind, though, that AH and AL are the high and low bytes of AX, and EAX is AX and an extra 16 bits.

    Although, I think using it that way should work normally even in 32bit code, as long as nothing too big gets put through.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width