123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- ;uses 19 bytes of RAM, 4 bytes of stack space
- ;#define speed
- #define tmp OP1+14
- #define head tmp+1
- #define head_lag tmp+3
- #macro advanceVAT()
- #ifdef speed
- ;17cc saved per iteration
- ;8 bytes vs a 3 byte call (but no 8-byte subroutine)
- ld bc,-6
- add hl,bc
- sbc a,a ;HL<=FE66, so carry flag is set
- sub (hl)
- ld c,a
- add hl,bc
- #else
- call advance_VAT ;preserves DE
- #endif
- #endmacro
- sortVAT:
- #ifdef nointerrupt
- di
- #endif
- ld hl,(progPtr)
- isort_main:
- _:
- ld (head_lag),hl
- ld d,h
- ld e,l
- advanceVAT()
- ld (head),hl
- #ifdef speed
- ;11 bytes, 29cc or 46cc. avg=29.06640625cc
- ld a,(pTemp)
- cp l
- jr nz,$+7
- ld a,(pTemp+1)
- cp h
- ret z
- #else
- ;adds 8 bytes, 55cc
- ld bc,(pTemp) ;Need to verify that we haven't reached the end of the progVAT
- or a ;
- sbc hl,bc ;
- ret z ;
- add hl,bc ;
- #endif
- call cmpVAT
- ld hl,(head)
- jr nc,-_
- ;if it makes it here, then (head) needs to be inserted into the previous part of the VAT
- ;We might be able to speed it up a little more if I also grab the next element
- ; If (head_advance) is bigger than (head), then no need to start the search from the beginning
- ld de,tmp
- #ifdef speed
- ldd
- ldd
- ldd
- ldd
- ldd
- ldd
- ld b,0
- ld c,(hl)
- lddr
- ldd
- #else
- ld bc,6
- lddr
- ld c,(hl)
- inc c
- lddr
- #endif
- ld hl,(progPtr)
- _:
- push hl
- #ifdef speed
- ;+5 bytes, -11cc
- ld bc,-6
- add hl,bc
- ld de,tmp-6
- call cmpVAT_stepin
- #else
- ex de,hl
- ld hl,tmp
- call cmpVAT
- #endif
- pop hl
- jr c,+_
- advanceVAT()
- jp -_
- _:
- ;HL is where to insert
- ld de,(head)
- or a
- sbc hl,de
- ld b,h
- ld c,l
- ld hl,-6
- add hl,de
- ld a,l
- sub a,(hl)
- ld l,a
- jr nc,$+4
- dec h
- or a
- inc de
- ex de,hl
- #ifdef speed
- call fastldir
- #else
- ldir
- #endif
- ;begin at DE, copy tmp. First need size of tmp
- ld hl,tmp-6
- ld c,(hl)
- sbc hl,bc
- ld a,c
- ldir
- #ifdef speed
- ldi
- ldi
- ldi
- ldi
- ldi
- ldi
- ldi
- add a,7
- #else
- ld c,7
- add a,c
- ldir
- #endif
- ld hl,(head_lag)
- ld c,a
- ld a,l
- sub c
- ld l,a
- jp nc,isort_main
- dec h
- jp isort_main
- #ifndef speed
- advance_VAT:
- ld bc,-6
- add hl,bc
- sbc a,a ;HL<=FE66, so carry flag is set
- sub (hl)
- ld c,a
- add hl,bc
- ret
- #endif
- cmpVAT:
- ;if @HL>=@DE, return nc
- ld bc,-6
- add hl,bc
- ex de,hl
- add hl,bc
- cmpVAT_stepin:
- ld a,(de)
- cp (hl)
- jr nc,first_longer
- ;the second name is longer.
- ld c,a
- _:
- dec hl
- dec de
- ld a,(de)
- cp (hl)
- ret nz
- dec c
- jr nz,-_
- scf
- ret
- first_longer:
- ;the first name is longer, so load c with the size of the second name
- ld c,(hl)
- _:
- dec hl
- dec de
- ld a,(de)
- cp (hl)
- ret nz
- dec c
- jr nz,-_
- ret
- #ifdef speed
- fastldir:
- ;copy BC bytes from HL to DE
- ;breaks even at 26 bytes
- ; 5% faster than LDIR with 35 bytes
- ;10% faster than LDIR with 48 bytes
- ;15% faster than LDIR with 91 bytes
- ;20% faster than LDIR with 635 bytes
- ;max is ~ 20.8% faster than LDIR
- ;Cost: 104+16N+10ceiling(N/16)
- push hl
- ; push af
- xor a
- sub c
- and 15 ;change to n-1
- add a,a
- ld hl,ldirloop
- add a,l
- ld l,a
- #if (ldirloop>>8)!=(_ldirloop_end>>8)
- jr nc,$+3 ;these aren't needed if the ldirloop doesn't cross a 256 byte boundary. Can save 12cc on the above timings and 3 bytes.
- inc h ;
- #endif
- ; pop af
- ex (sp),hl
- ret
- ldirloop:
- ;n=16, (number of LDI instructions, use qty of 4,8,16,32,64)
- ldi
- ldi
- ldi
- ldi
- ldi
- ldi
- ldi
- ldi
- ldi
- ldi
- ldi
- ldi
- ldi
- ldi
- ldi
- _ldirloop_end:
- ldi
- jp pe,ldirloop
- ret
- #endif
- #undefine tmp
- #undefine head
- #undefine head_lag1
|