04-22-2003, 10:47 AM
Here:
Notes. Your BX indexing technique is slow. ;*) as compared to a di/si inc.
PutF uses your BX indexing technique and PutF2 uses the standard Inc Si/Di.
Here's the one which is faster:
To test:
Notes. Your BX indexing technique is slow. ;*) as compared to a di/si inc.
PutF uses your BX indexing technique and PutF2 uses the standard Inc Si/Di.
Code:
MODEL MEDIUM,BASIC
.STACK 30H
.386
.CODE
;SUB RelPutF(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 ;REAL WIDTH
;320-WIDTH =-4 ;FOR SPEEDIER LOOP NO SUB
;DS:SI =SPRITE SEG:SPRITE OFF
;ES:DI =DEST SEG:DEST OFF
align 2
PUBLIC RelPutF
RelPutF PROC
PUSH BP
mov bp,sp
sub sp,4
mov [bp-2],ds ;save ds
mov es,[bp+14] ;layer
mov ds,[bp+8] ;spr seg
mov si,[bp+6] ;spr off
mov dx,[si] ;wid
mov ax,[si+2] ;height
add si,4
shr dx,3 ;wid\8
;calc offset
mov cx,[bp+10] ;y
xchg ch,cl ;Y*256
mov di,cx ;save
shr di,2 ;Y*64
add di,cx ;Y*64+Y*256=320
add di,[bp+12] ;Offset=Y*320+X
;notes:
;Al = Hieght
;dx = Wid
;bx = free
;cx = free
mov cx,320
sub cx,dx
mov [bp-4],cx ;save to stack
Yloop:
xor bx,bx
mov cx,dx ;save wid
Xloop:
mov ah,[si+bx]
or ah,ah
jz skip
mov es:[di+bx],ah
skip:
inc bx
dec cx
jnz Xloop
add si,bx
add bx,[bp-4]
add di,bx
dec al
jnz Yloop
mov ds,[bp-2]
ADD SP,4
POP BP ;RESTORE BP
RET 10
RelPutF ENDP
END
Here's the one which is faster:
Code:
MODEL MEDIUM,BASIC
.STACK 30H
.386
.CODE
;SUB RelPutF2(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 ;REAL WIDTH
;320-WIDTH =-4 ;FOR SPEEDIER LOOP NO SUB
;DS:SI =SPRITE SEG:SPRITE OFF
;ES:DI =DEST SEG:DEST OFF
align 2
PUBLIC RelPutF2
RelPutF2 PROC
PUSH BP
mov bp,sp
sub sp,4
mov [bp-2],ds ;save ds
mov es,[bp+14] ;layer
mov ds,[bp+8] ;spr seg
mov si,[bp+6] ;spr off
mov dx,[si] ;wid
mov bx,[si+2] ;height
add si,4
shr dx,3 ;wid\8
;calc offset
mov cx,[bp+10] ;y
xchg ch,cl ;Y*256
mov di,cx ;save
shr di,2 ;Y*64
add di,cx ;Y*64+Y*256=320
add di,[bp+12] ;Offset=Y*320+X
;notes:
;Ax = free
;dx = Wid
;bx = Height
;cx = free
mov cx,320
sub cx,dx
mov [bp-4],cx ;save to stack
Yloop:
mov cx,dx ;save wid
Xloop:
mov al,[si]
inc si
or al,al
jz skip
mov es:[di],al
skip:
inc di
dec cx
jnz Xloop
add di,[bp-4]
dec bx
jnz Yloop
mov ds,[bp-2]
ADD SP,4
POP BP ;RESTORE BP
RET 10
RelPutF2 ENDP
END
To test:
Code:
DECLARE SUB RelPutF (BYVAL DESTSEG%, BYVAL X%, BYVAL Y%, BYVAL SPRITESEGMENT%, BYVAL SPRITEOFFSET%)
DECLARE SUB RelPutF2 (BYVAL DESTSEG%, BYVAL X%, BYVAL Y%, BYVAL SPRITESEGMENT%, BYVAL SPRITEOFFSET%)
DEFINT A-Z
DIM Vpage(31999) AS INTEGER
'Test Vars
DIM PutTestMem AS SINGLE
DIM PutTestMem2 AS SINGLE
DIM PutTestVid AS SINGLE
DIM PutTestVid2 AS SINGLE
CLS
SCREEN 13
W = 15
H = 15
Layer = VARSEG(Vpage(0))
Size = ((W + 1) * (H + 1) + 4) \ 2
DIM Array(Size) AS INTEGER
FOR I = 0 TO H
FOR J = 0 TO W
PSET (J, I), (I OR J) + 150
NEXT
NEXT
GET (0, 0)-(W, H), Array
SprSeg = VARSEG(Array(0))
SprOff = VARPTR(Array(0))
TIMER ON
T# = TIMER
FOR n& = 1 TO 500000
RelPutF Layer, 100, 100, SprSeg, SprOff
NEXT
PutTestMem = n& / (TIMER - T#)
T# = TIMER
FOR n& = 1 TO 500000
RelPutF2 Layer, 100, 100, SprSeg, SprOff
NEXT
PutTestMem2 = n& / (TIMER - T#)
'VIDEO
T# = TIMER
FOR n& = 1 TO 500000
RelPutF &HA000, 100, 100, SprSeg, SprOff
NEXT
PutTestVid = n& / (TIMER - T#)
T# = TIMER
FOR n& = 1 TO 500000
RelPutF2 &HA000, 100, 100, SprSeg, SprOff
NEXT
PutTestVid2 = n& / (TIMER - T#)
CLS
SCREEN 0
WIDTH 80
PRINT STR$(PutTestMem) + " For PutF aka [Si/di+bx] trick (Base mem)"
PRINT STR$(PutTestMem2) + " For PutF2 aka inc si/di (Base mem)"
PRINT STR$(PutTestVid) + " For PutF aka [Si/di+bx] trick (Video mem)"
PRINT STR$(PutTestVid2) + " For PutF2 aka inc si/di (Video mem)"
C$ = INPUT$(1)
CLS
SCREEN 0
END