Autor
| Code optimization
| ARTRAG msx master Mensajes: 1802 | Publicado: Febrero 08 2008, 00:48   | ps
my new code is untested and for sure buggy
| | Metalbrain msx friend Mensajes: 15 | Publicado: Febrero 08 2008, 01:05   | Quote:
|
jp 2f
1: ld c,a
[...]
2: ld a,(ix+0) ; 127 == fine
cp 127
jp nz,1b
|
Hmmm... I see you insist on using that 127...
Then you can do this instead:
jp 2f
1:
[...]
2: ld a,(ix+0) ; 127 == fine
ld c,a
inc a
jp p,1b
OTOH, your new code seems to just add a new layer of complexity with the extra pointers. | | ARTRAG msx master Mensajes: 1802 | Publicado: Febrero 08 2008, 09:39   | Sorry, only now I full understand your suggestion
I'll move to the use of 128 as delimiter
| | ARTRAG msx master Mensajes: 1802 | Publicado: Febrero 08 2008, 11:00   | I tried a third way...
this time the storage of the frames is a bit more efficient, but I cannot avoid resorting to IX...
(again the code is untested)
psect npct,global,size=06000h
framex0:
dw p0
db 0,2
db 0,2
db 128
frame0:
dw p1
db 5,1
db 4,1
db 3,1
db 2,1
db 1,1
db 128
p0:
db 18,19
db 20,21
p1:
db 147,147,147,147,147
_frames:
dw framex0,frame0
global _map_w
;de dest_addr in the room
;bc nframe;
global __npctplot
__npctplot:
push ix
push de
ld hl,_frames
add hl,bc
add hl,bc
ld e,(hl)
inc hl
ld d,(hl)
db 0xdd
ld l,e
db 0xdd
ld h,d ; ora ix punta alla frame corrente
ld e,(ix+0)
ld d,(ix+1)
inc ix
inc ix ; de punta ai dati
pop hl ; hl punta alla destinazione in room
jp 2f ; SHARED_LOOP
;de source_addr;
;bc dest_addr in the room
;stack nframe
global __npctrest
__npctrest:
push ix
ex de,hl
pop af ; get return address
pop de ; get nframe
push af ; put return address
push hl ; save source_addr
ld hl,_frames
add hl,de
add hl,de
ld e,(hl)
inc hl
ld d,(hl) ; de punta alla frame corrente
db 0xdd
ld l,e
db 0xdd
ld h,d ; ora ix punta alla frame corrente
pop de ; de punta alla source in buffer
ld h,b
ld l,c ; ora hl punta alla destination in room
jp 2f
; SHARED_LOOP
1: push hl
ld c,a
ld b,0
add hl,bc ; dest
ld c,(ix+1) ; len
ex de,hl
ldir
ex de,hl
pop hl
ld bc,(_map_w)
add hl,bc
inc ix
inc ix
2: ld a,(ix+0) ; 128 == fine
and a
jp p, 1b
pop ix
ret
;de source_addr in the room
;bc dest_addr;
;stack nframe
global __npctgrab
__npctgrab:
push ix
ex de,hl
pop af ; get return address
pop de ; get nframe
push af ; put return address
push hl ; save source_addr
ld hl,_frames
add hl,de
add hl,de
ld e,(hl)
inc hl
ld d,(hl) ; de punta alla frame corrente
db 0xdd
ld l,e
db 0xdd
ld h,d ; ora ix punta alla frame corrente
pop hl ; hl punta alla source in room
ld d,b
ld e,c ; de punta alla destination in frame buffer
jp 2f
1: push hl
ld c,a
ld b,0
add hl,bc ; source
ld c,(ix+1) ; len
ldir
pop hl
ld bc,(_map_w)
add hl,bc
inc ix
inc ix
2: ld a,(ix+0) ; 128 == fine
and a
jp p, 1b
pop ix
ret
Any proposal ?
BTW
Is there a simple way to add with SIGN a byte to a word ?
In case, by storing as offset the difference of the current offset with the previous,
I could avoid the couple of push hl/pop hl in the inner loop.
The fact is that the difference can be negative so I need to add with SIGN a byte
to a word using less cycles of a push/pop couple
| | ARTRAG msx master Mensajes: 1802 | Publicado: Febrero 08 2008, 11:27   | Forget my last idea, I should subtract both offset and length...
It seems too much t be a real saving
| | ARTRAG msx master Mensajes: 1802 | Publicado: Febrero 08 2008, 12:05   | I fixed a mess with the IX pointers and the frame structure
psect npct,global,size=06000h
framex0:
dw p0
db 0,2
db 0,2
db 128
frame0:
dw p1
db 5,1
db 4,1
db 3,1
db 2,1
db 1,1
db 128
p0:
db 18,19
db 20,21
p1:
db 147,147,147,147,147
_frames:
dw framex0,frame0
global _map_w
;de dest_addr in the room
;bc nframe;
global __npctplot
__npctplot:
push ix
push de
ld hl,_frames
add hl,bc
add hl,bc
ld e,(hl)
inc hl
ld d,(hl)
db 0xdd
ld l,e
db 0xdd
ld h,d ; ora ix punta alla frame corrente
ld e,(ix+0)
ld d,(ix+1)
pop hl ; hl punta alla destinazione in room
jp 2f ; SHARED_LOOP
;de source_addr;
;bc dest_addr in the room
;stack nframe
global __npctrest
__npctrest:
push ix
ex de,hl
pop af ; get return address
pop de ; get nframe
push af ; put return address
push hl ; save source_addr
ld hl,_frames
add hl,de
add hl,de
ld e,(hl)
inc hl
ld d,(hl) ; de punta alla frame corrente
db 0xdd
ld l,e
db 0xdd
ld h,d ; ora ix punta alla frame corrente
pop de ; de punta alla source in buffer
ld h,b
ld l,c ; ora hl punta alla destination in room
jp 2f
; SHARED_LOOP
1: push hl
ld c,a
ld b,0
add hl,bc ; dest
ld c,(ix+1) ; len
ex de,hl
ldir
ex de,hl
pop hl
ld bc,(_map_w)
add hl,bc
2: inc ix
inc ix
ld a,(ix+0) ; 128 == fine
and a
jp p, 1b
pop ix
ret
;de source_addr in the room
;bc dest_addr;
;stack nframe
global __npctgrab
__npctgrab:
push ix
ex de,hl
pop af ; get return address
pop de ; get nframe
push af ; put return address
push hl ; save source_addr
ld hl,_frames
add hl,de
add hl,de
ld e,(hl)
inc hl
ld d,(hl) ; de punta alla frame corrente
db 0xdd
ld l,e
db 0xdd
ld h,d ; ora ix punta alla frame corrente
pop hl ; hl punta alla source in room
ld d,b
ld e,c ; de punta alla destination in frame buffer
jp 2f
1: push hl
ld c,a
ld b,0
add hl,bc ; source
ld c,(ix+1) ; len
ldir
pop hl
ld bc,(_map_w)
add hl,bc
2: inc ix
inc ix
ld a,(ix+0) ; 128 == fine
and a
jp p, 1b
pop ix
ret
| | ro msx guru Mensajes: 2353 | Publicado: Febrero 08 2008, 14:55   | When I have complex datatables I often use a mix of HL and IX to point to data. I try to make my tables logical for the code so that I don't have to use lotsa INC/DEC HL commands. Whenever I have to get or put data with an offset greater than 2 bytes I will use the IX.
For example
ld hl,table
ld ix,table
ld a(hl)
and 1
jp z,loop
inc hl
ld c(hl)
inc hl
ld b(hl)
inc hl
xor a
and b
jp nz,loop2
inc (hl)
ld a(ix+5)
or c
dec hl
dec hl
ld (hl)a
ret
(this is just some nonsence code to illustrate my point)
| | ARTRAG msx master Mensajes: 1802 | Publicado: Febrero 08 2008, 15:38   | Thanks, I'll think about it.
The fact is that ldir uses hl,de and bc,
so I have almost no escape in using IX
as pointer to the data structure
| | Heca msx friend Mensajes: 1 | Publicado: Febrero 08 2008, 18:34   | Using the first frame structure
framex1:
db 0,2,18,19 ; X offset of line 0, length of line 0, data, data ect
db 0,2,20,21; X offset of line 1, length of line 1, data, data ect
db 127 ; end of the frame
frame0:
db 5,1,147
db 4,1,147
db 3,1,147
db 2,1,147
db 1,1,147
db 127
etc
_frames:
dw framex1,frame0,frame1,frame2,frame3,frame4,frame5, etc etc
(not tested)
;de dest_addr in the room
;bc nframe;
global __npctplot
__npctplot:
ld hl,_frames
add hl,bc
add hl,bc
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
ld bc,0
ld a, (hl)
loop:
ex de,hl
add hl,bc
push hl ;save dest
ld b,0
ld c,a
add hl,bc
ex de,hl
inc hl
ld c, (hl)
inc hl
ldir
ld bc, (_map_w)
ld a, (hl)
cmp 127
pop de ;restore dest
jr nz, loop
ret
Removing IX op, is a little bit faster i think.
For other routines, i can't see what they're supposed to do.
| | ARTRAG msx master Mensajes: 1802 | Publicado: Febrero 08 2008, 20:11   | Good one !!My respect !
Thanks!
| | ARTRAG msx master Mensajes: 1802 | Publicado: Febrero 08 2008, 23:18   | @Heca
the other two routines are used to copy teh background under the frame from the room to a buffer (grab) and from the buffer to the room (restore)
in this way you can do large SW sprites, using this loop
1) grab the background
2) put the frame
2bis) display the room on the screen
3) restore the background
4) change coordinates and frame
5) go to 1)
| | ARTRAG msx master Mensajes: 1802 | Publicado: Febrero 08 2008, 23:32   | This version has been debugged and is fully working,
about Heca's code for npcplot, it is faster, but I do not know how to speed up
the other two functions using Heca's data structure
psect npct,global,size=06000h
framex0:
dw p0
db 0,2
db 0,2
db 128
frame0:
dw p1
db 5,1
db 4,1
db 3,1
db 2,1
db 1,1
db 128
p0:
db 18,19,20,21
p1:
db 147,147,147,147,147
_frames:
dw framex0,frame0
global _map_w
;de dest_addr in the room
;bc nframe;
global __npctplot
__npctplot:
push ix
ld hl,_frames
add hl,bc
add hl,bc
ld c,(hl)
inc hl
ld b,(hl)
; ld ix,bc
db 0xdd
ld l,c
db 0xdd
ld h,b ; ora ix punta alla frame corrente
ex de,hl ; hl punta alla destinazione in room
ld e,(ix+0) ; de punta ai dati della frame
ld d,(ix+1)
jp 2f ; SHARED_LOOP
;de source_addr;
;bc dest_addr in the room
;stack nframe
global __npctrest
__npctrest:
ex de,hl
pop af ; get return address
pop de ; get nframe
push af ; put return address
push ix
push hl ; save source_addr
ld hl,_frames
add hl,de
add hl,de
ld e,(hl)
inc hl
ld d,(hl) ; de punta alla frame corrente
; ld ix,bc
db 0xdd
ld l,e
db 0xdd
ld h,d ; ora ix punta alla frame corrente
pop de ; de punta alla source in buffer
ld h,b
ld l,c ; ora hl punta alla destination in room
jp 2f
; SHARED_LOOP
1: push hl
ld c,a
ld b,0
add hl,bc ; dest
ld c,(ix+1) ; len
ex de,hl
ldir
ex de,hl
pop hl
ld bc,(_map_w)
add hl,bc
2: inc ix
inc ix
ld a,(ix+0) ; 128 == fine
and a
jp p, 1b
pop ix
ret
;de source_addr in the room
;bc dest_addr;
;stack nframe
global __npctgrab
__npctgrab:
ex de,hl
pop af ; get return address
pop de ; get nframe
push af ; put return address
push ix
push hl ; save source_addr
ld hl,_frames
add hl,de
add hl,de
ld e,(hl)
inc hl
ld d,(hl) ; de punta alla frame corrente
; ld ix,bc
db 0xdd
ld l,e
db 0xdd
ld h,d ; ora ix punta alla frame corrente
pop hl ; hl punta alla source in room
ld d,b
ld e,c ; de punta alla destination in frame buffer
jp 2f
1: push hl
ld c,a
ld b,0
add hl,bc ; source
ld c,(ix+1) ; len
ldir
pop hl
ld bc,(_map_w)
add hl,bc
2: inc ix
inc ix
ld a,(ix+0) ; 128 == fine
and a
jp p, 1b
pop ix
ret
| |
| |
| |