Need assembly help

If you have questions about any aspect of QBasic programming, or would like to help fellow programmers solve their problems, check out this board!

Moderators: Pete, Mods

Post Reply
User avatar
seaBiscuit$
Coder
Posts: 45
Joined: Sun Nov 26, 2006 2:00 pm
Location: Champaign, Illinois

Need assembly help

Post by seaBiscuit$ » Fri Dec 29, 2006 5:04 pm

I've read some tutorials on using assembly in QB, and I was wondering if anyone knew how to use a jump statement (like jne, jz, etc.) from DEBUG.EXE so it would jump to a relative address rather than an absolute one, so it could say something like: "jump if zero to the statement 5 bytes from here," rather than "jump if zero to the statement at 05B." I could write line labels and use an assembler, but I want to know how it could be done in DEBUG, just for the sake of learning.

moneo
Veteran
Posts: 451
Joined: Tue Jun 28, 2005 7:00 pm
Location: Mexico City, Mexico

Post by moneo » Fri Dec 29, 2006 6:19 pm

I've written in many assembly languages that had relative jumps (or branches), both conditional and unconditional.

Sorry, but I don't know assembler for the PC. So, the first question is does the PC assembler have relative jumps? If so, what is the format of such a jump instruction?

Given the answer to my two questions, then you should have no problem inserting a relative jump in the code with Debug.

Good luck and regards..... Moneo

User avatar
seaBiscuit$
Coder
Posts: 45
Joined: Sun Nov 26, 2006 2:00 pm
Location: Champaign, Illinois

Post by seaBiscuit$ » Sat Dec 30, 2006 12:18 pm

I've been looking and to the best of my newfound knowledge, only jmp will support relative addressing, and only jmp and call will support indirect addressing. I think that the programmer is supposed to know the exact offset where their program is being run from, so I might just have to find out the offset of my string. :x

I'm beginning to hate these Intel guys... :evil:

Later that day...

Alright, I found out that the first string created by QBasic has the offset of 32510, as long as it's not resized, so I guess I'll start from there.

relsoft
Coder
Posts: 24
Joined: Wed Jun 07, 2006 9:04 pm
Location: Philippines
Contact:

Post by relsoft » Wed Jan 03, 2007 9:48 am

Here:

http://rel.betterwebber.com/junk.php?id=15

You just have to make an *.808 file(just an ASM file with some headers for outpufiles). It parses ASM files and uses and newer version of DEBUG(it's in the package so don't worry). Even makes your calls for you. :*) You can even do comments. It's made by my friend LOJ.


Here's an example of an 808 file

Code: Select all

.OUTPUT AFSPRT
.OUTSUB AF.SpriteTrans
.OUTSTR Asm.SpriteTrans$
.DEFINT A-Z
.OUTFRM Hex
.BYVAL ON
.DIM DESTSEG%,X%,Y%
.DIM SPRITESEGMENT%,SPRITEOFFSET%

;SUB RELSPRITETrans(BYVAL DESTSEG%,BYVAL X%,BYVAL Y%,BYVAL SPRITESEGMENT%,BYVAL SPRITEOFFSET%)
;STACK
;DEST SEG       =14
;X              =12  
;Y              =10
;SPRITESEGMENT  =8
;SPRITOFFSET    =6
;RET SEG        =4
;RET OFF        =2
;BP             =0
;DS             =-2
;BLANK REG      =-4
;WIDTH/8        =-6
;HEIGHT         =-8
;320-CLP_WIDTH  =-10    '0Ah

PUSH DS
MOV DX,SPRITESEGMENT%
MOV DS,DX	        	;POINT ADDRESS OF SPRITE TO DS
MOV DX,DESTSEG%
MOV ES,DX           		;POINT ADDRESS OF DEST TO ES
MOV SI, SPRITEOFFSET%            ;WE ARE NOW ON THE WIDTH OF THE SPRITE W=(ARRAY(0)/8)-1
MOV BX,[SI]         		;WIDTH*8
XOR AX,AX           		;ZERO OUT BLANK REG

SHR BX,3                        ;DIV WIDTH BY 8
MOV DX,[SI+2]   		;SAVE HEIGHT
PUSH AX         		;PUSH IT TO STACK

PUSH BX         ;SAVE WIDTH
ADD SI,4       ;SI NOW POINTS TO 1ST COLOR OF SPRITE ARRAY
PUSH DX         ;PUSH HEIGHT
PUSH AX         ;FOR 320-WIDTH

;NOTE!!!!  AFTER THE CLIPS
;AX=X     CLIPPED
;CX=Y     CLIPPED
;BX=WIDTH   NEW
;DX=HEIGHT  NEW

        MOV AX,X%               ;X VALUE
        CMP AX,319d             ;GET OUT IF X > 319
JG LBL_END_IT                   ;ELSE
        CMP AX,0                ;X<0 THEN
        JL LBL_CLIP_LEFT        ;CLIP OUR X VALUE
LBL_POST_CLIP_LEFT:

        MOV CX,Y%               ;Y VALUE
        CMP CX,199d             ;GET OUT IF Y > 199
JG LBL_END_IT                   ;ELSE
        CMP CX,0                ;Y<0 THEN
        JL LBL_CLIP_TOP         ;CLIP OUR Y VALUE
LBL_POST_CLIP_TOP:

;OK HERE'S THE SCORE: AX=X,CX=Y,DX=HEIGHT,BX=WIDTH  ALL CLIPPED TOP AND LEFT
;NOW LETS CLIP IT TO THE RIGHT

        ADD BX,AX               ;ADD X TO WIDTH AND SEE IF ITS OVER  *BX IS DESTROYED
        CMP BX,319d             ;IF X+WIDTH > 319 ;TOO RIGHT THEN CROP IT
        JG  LBL_CLIP_RIGHT      ;ELSE CONTINUE     
        SUB BX,AX               ;RESTORE BX SINCE IT WAS DESTROYED
LBL_POST_CLIP_RIGHT:

;NOW LETS CLIP IT DOWN

        ADD DX,CX               ;ADD Y TO HEIGHT AND SEE IF ITS OVER  *DX IS DESTROYED
        CMP DX,199d             ;IF Y+HEIGHT > 199 ;TOO LOW THEN CROP IT
        JG  LBL_CLIP_DOWN       ;ELSE CONTINUE     
        SUB DX,CX               ;RESTORE DX SINCE IT WAS DESTROYED
LBL_POST_CLIP_DOWN:


;WHEW!!!!!!!!! THAT WAS DISORIENTING!!!!!!!!
;BUT ALL VARIABLES ARE EITHER CLIPPED OR CROPPED NOW   ;-)
;AX=X,CX=Y,BX=WIDTH,DX=HEIGHT



MOV [BP-8],BX   ;DAMN FULL OF AGI'S HERE :(    SAVE BX

;LET US NOW CALCULATE  THE OFFSET NORMALLY
;SHIFT LEFT  8 Y VALUE (Y*256)
XCHG CH, CL      
MOV BX,320d

MOV DI,CX       ;SAVE Y VALUE TO DX
SUB BX,[BP-8]

SHR DI,2        ;SHIFT RIGHT TO DIVIDE DI BY 64
ADD DI,CX       ;Y*64+Y*256=Y*320  :)
MOV [BP-0A],BX   ;SAVE 320-WIDTH TO STACK

ADD DI,AX       ;DEST OFFSET(X,Y)=Y*320+X


;DI=Y*320+X

MOV BX,[BP-8]   ;RESTORE BX

LBL_MAIN_SPR_LOOP:

MOV CX,BX               ;PUT CLIPPED WIDTH TO COUNTER

LBL_SPRITE_LOOP:                ;X LOOP

        MOV AL,DS:[SI]             ;MOV COLOR
        
        OR  AL,AL               ;IF C<>0 THEN
                        
        JZ LBL_SKIP_ZERO           ;ELSE
           AND AL,0F            ;GET COLOR TRANS OFFSET FOR SPRITE
           MOV AH,ES:[DI]
           AND AH,0F            ;GET COLOR TRANS FOR BUFFER/SCREEN
           ADD AH,AL            ;ADD THEM 2GETHER
           SHR AH,01            ;DIV BY TWO TO AVERAGE D COLORS
           SUB AL,DS:[SI]       ;BASE COLOR
           NEG AL

           ADD AL,AH            ;ADD AVE PIX TO BASE COLOR
                                ;SPECIAL THANKS TO CGI JOE FOR HIS TUTE :)

           MOV ES:[DI],AL       ;PLOT IT

LBL_SKIP_ZERO:

        
        DEC CX
        INC SI                  ;NEXT OFFSET
        INC DI

        CMP CX,0
JNE   LBL_SPRITE_LOOP

ADD DI, [BP-0A]                   ;ADD TO DI OUR 320-CLP_WIDTH
ADD SI,[BP-4]                   ;CORRECTOR POINT TO NEXT ROW

DEC DX

JNZ  LBL_MAIN_SPR_LOOP



LBL_END_IT:

ADD SP,8
POP DS      ;RESTORE DS

END


LBL_CLIP_LEFT:
        NEG AX          ;NEGATE AX AX=-AX=+AX
        SUB BX,AX       ;SUBRACT CLIPPED WIDTH TO REAL WIDTH
        JLE LBL_END_IT  ;IF AX<=0 THEN ENDIT SINCE ITS TOOLEFT TO SEE A COL OF PIX ;)
        ADD SI,AX       ;ADD OUR AX TO SI(POINT TO CLIPPED X OFFSET
                        ;BX IS OUR NEW CLIPPED WIDTH
        MOV [BP-4],AX   ;SAVE IT TO STACK FOR SKIPPING CHECK PURPOSES
        
        XOR AX,AX       ;ZERO IS OUR X COORD
JMP LBL_POST_CLIP_LEFT



LBL_CLIP_TOP:
        NEG CX          ;NEGATE CX CX=-CX=+CX
        SUB DX,CX       ;SUBRACT CLIPPED HEIGHT TO REAL HEIGHT
                        ;DX IS OUR NEW CLIPPED HEIGHT
        JLE LBL_END_IT  ;IF CX<=0 THEN ENDIT SINCE ITS TOOLEFT TO SEE A ROW OF PIX ;)

     LBL_HEIGHT_LOOP:
        ;ADD OUR REAL WIDTH TO SI(POINT TO CLIPPED Y OFFSET)
        ADD SI, [BP-6] 
        DEC CX
     JNZ LBL_HEIGHT_LOOP        ;LOOP IT UNTIL WE GET TO RIGHT Y OFFSET
                                ;CX=0 ZERO IS OUR Y COORD
JMP LBL_POST_CLIP_TOP


LBL_CLIP_RIGHT:
       SUB BX,320d      ;SUBTRACT X+WIDTH WITH 319  TRUST ME NO NEGS HERE :)
                        ;BX NOW IS CLIPPED RIGHT
       ADD [BP-4],BX    ;ADD IT TO THE CHECKER AS OUR SPR DATA IS IN COLUMN MAJOR ORDER
       MOV BX,320d      ;CORRECT BX TO  CLIPX2+1
       SUB BX,AX        ;SUBTRACT AX TO BX TO CORRECT WIDTH (0 TO 319)
JMP LBL_POST_CLIP_RIGHT

LBL_CLIP_DOWN:
       ADD CX,DX        ;ADD THE HEIGHT TO Y
       SUB CX,200d      ;CORRECT IT
       SUB DX,CX        ;CROP OUR HEIGHT
       MOV CX,Y%        ;RESTORE Y
JMP LBL_POST_CLIP_DOWN
Hello. :*)

User avatar
seaBiscuit$
Coder
Posts: 45
Joined: Sun Nov 26, 2006 2:00 pm
Location: Champaign, Illinois

Post by seaBiscuit$ » Wed Jan 03, 2007 10:50 am

Thanks for that! QBasic was doing crazy things with my string, so I had given up on that. Scratch is fantastic! 8)

Post Reply