Code: Select all
ld h,10h
loop:
add hl,hl
jr nc,loop
sub h
add a,b
Code: Select all
ld h,10h
loop:
add hl,hl
jr nc,loop
sub h
add a,b
Wow! Yes, I have not tried it, but this surely works. As you say, HL is recovered so we can play with it. Never thought of H being used for this.arkannoyed wrote: ↑Tue May 28, 2019 12:43 pm ...or a little cheeky -1 byte
Code: Select all
ld h,10h loop: add hl,hl jr nc,loop sub h add a,b
Code: Select all
; compensate + prioritize piece valuation(6B)
skiato add a, $20 ; A: 00pppppp, compensate=K+1, pih
ld h,a
evacol ld a, e ; A: 0rrr0ccc
; these two values below can be tuned for different opening schemes
if feamod>0
add a, 2 ; A: 0rrr0ccc
and 5 ; A: 00000ccc
else
inc a ; A: 0rrr0ccc
and 4 ; A: 00000cc0 (weight: 0,0,0,4,4,4,4,0)
endif
; ranks weight (ranks weight is 8..1, aiming for board's end)
evarnk add hl,hl
add a,h ;
ld h,00h
add hl,hl
add hl,hl
add hl,hl
sub h ; A: 0ppppxww (x=p+r)
Code: Select all
org $7F88 ; pawn: $22x4=$84
; piece, move type, vector list delta address (18B)
; move type / 0 / 0 / pawn straight / pawn diagonal / DDDD (real radius + 7)
movlis
pawgen defb $28, $E3 ; pawn straight
defb $18, $E7 ; pawn capture
org $7F8C
knigen defb $08, $EA ;
org $7F90
bisgen defb $0E, $E5 ; bishop
org $7F94
roogen defb $0E, $E0 ; rook
org $7F9C
quegen defb $0E, $E0 ; queen
defb $0E, $E5 ;
org $7FD8
kingen defb $08, $E0 ; king: $($16+$20)x4=$D8
defb $08, $E5 ;
Code: Select all
org $7FE0 ; vectors start at: $7FE0 (arbitrary)
; (y, x) move delta pairs (16B)
veclis
strvec defb $FF, $01 ; +0, straight vectors
defb $10, $F0 ; +3, straight pawn, last half line
org $7FE5
diavec defb $0F, $11 ; +5, diagonal vectors
defb $EF, $F1 ; +7, diagonal pawn
org $7FEA
knivec defb $E1, $F2 ; +10, knight vectors
defb $12, $21 ; knight moves listed clockwise
defb $1F, $0E ;
defb $EE, $DF ;
Let me look into it. I'll let you know. Any help is more than welcome.arkannoyed wrote: ↑Fri May 31, 2019 9:10 am Just another thought, expanding upon the previous improvement in size. Would this work by extending the use of HL a bit further?
Saves another few bytes (I think?!)Code: Select all
; compensate + prioritize piece valuation(6B) skiato add a, $20 ; A: 00pppppp, compensate=K+1, pih ld h,a evacol ld a, e ; A: 0rrr0ccc ; these two values below can be tuned for different opening schemes if feamod>0 add a, 2 ; A: 0rrr0ccc and 5 ; A: 00000ccc else inc a ; A: 0rrr0ccc and 4 ; A: 00000cc0 (weight: 0,0,0,4,4,4,4,0) endif ; ranks weight (ranks weight is 8..1, aiming for board's end) evarnk add hl,hl add a,h ; ld h,00h add hl,hl add hl,hl add hl,hl sub h ; A: 0ppppxww (x=p+r)
I took your idea and with a little tuning it seems to make things even smaller:reeagbo wrote: ↑Fri May 31, 2019 10:59 pmLet me look into it. I'll let you know. Any help is more than welcome.arkannoyed wrote: ↑Fri May 31, 2019 9:10 am Just another thought, expanding upon the previous improvement in size. Would this work by extending the use of HL a bit further?
Saves another few bytes (I think?!)Code: Select all
; compensate + prioritize piece valuation(6B) skiato add a, $20 ; A: 00pppppp, compensate=K+1, pih ld h,a evacol ld a, e ; A: 0rrr0ccc ; these two values below can be tuned for different opening schemes if feamod>0 add a, 2 ; A: 0rrr0ccc and 5 ; A: 00000ccc else inc a ; A: 0rrr0ccc and 4 ; A: 00000cc0 (weight: 0,0,0,4,4,4,4,0) endif ; ranks weight (ranks weight is 8..1, aiming for board's end) evarnk add hl,hl add a,h ; ld h,00h add hl,hl add hl,hl add hl,hl sub h ; A: 0ppppxww (x=p+r)
Code: Select all
; compensate + prioritize piece valuation(6B)
skiato ld h, $20 ; prepare H for later rotation and use for A
add a, h ; A: 00pppppp, compensate=K+1, pih
rlca ; leave space for square weight
rlca ; A: pppppp00, piece addition is 5 bits
ld b, a ; B: piece addition value
evacol ld a, e ; A: 0rrr0ccc
; these two values below can be tuned for different opening schemes
if feamod>0
add a, 2 ; A: 0rrr0ccc
and 5 ; A: 00000ccc
else
inc a ; A: 0rrr0ccc
and 4 ; A: 00000cc0 (weight: 0,0,0,4,4,4,4,0)
endif
; ranks weight (ranks weight is 8..1, aiming for board's end)
evarnk add hl, hl ; HL: 00100000 0rrr0ccc (before)
add hl, hl ;
add hl, hl ; HL: 000000rr r0ccc000 (after)
sub h ; A: 00000cww (w=r+c)
add a, b ; total value: pieces + weight
reeagbo wrote: ↑Sun Jun 02, 2019 10:51 amI took your idea and with a little tuning it seems to make things even smaller:
Many thanks! This is from now on the arkannoyed patch!Code: Select all
; compensate + prioritize piece valuation(6B) skiato ld h, $20 ; prepare H for later rotation and use for A add a, h ; A: 00pppppp, compensate=K+1, pih rlca ; leave space for square weight rlca ; A: pppppp00, piece addition is 5 bits ld b, a ; B: piece addition value evacol ld a, e ; A: 0rrr0ccc ; these two values below can be tuned for different opening schemes if feamod>0 add a, 2 ; A: 0rrr0ccc and 5 ; A: 00000ccc else inc a ; A: 0rrr0ccc and 4 ; A: 00000cc0 (weight: 0,0,0,4,4,4,4,0) endif ; ranks weight (ranks weight is 8..1, aiming for board's end) evarnk add hl, hl ; HL: 00100000 0rrr0ccc (before) add hl, hl ; add hl, hl ; HL: 000000rr r0ccc000 (after) sub h ; A: 00000cww (w=r+c) add a, b ; total value: pieces + weight
Code: Select all
genlis
bacata ; backup attack board in reverse order, used in evaluation (13B)
ld l, $FF ; (H)L = $80FF (boaata-1), H always $80
ld de, boaopo + $78 ; DE: same thing, 1B passed end of board
bacloo inc hl ; HL: increase 16b counter to hop to next page
dec e ; E: decrease 8b counter to hit Z flag
ld a, (hl) ; load attack status
ld (hl), 0 ; clear attack status, no alternative!
ld (de), a ; backup attack status
jr nz, bacloo ; loop down to square $00
; exit values: DE=$8200, HL=$8177
Code: Select all
; prepare environment (4B)
inc d ; D= $83= canlih
xor a ; reset
ld (de), a ; cantot= 0
ld b, l ; B= L = 77, SQUARE COUNT
Code: Select all
; read piece from board (4B)
squloo ld h, boasth ; H: board base ++
ld l, b ; point at current loop square
ld a, (hl) ; read piece from board
; get move type and pointer to move list (6B)
squgon dec h ; H(L)= movlih, moves vector base ++
add a, a ; x4, each piece vector is 4B long
add a, a ;
ld l, a ; (H)L points at the move vector now
Code: Select all
ld d, 2 ; 2 submoves per piece
subloo ; byte 1 - move type (5B)
ld a, (hl) ; move type loaded
or a ; =cp 0, 2nd move type not used case
; black/empty: move type=0 leads here
jr z, squexi ; ---v exit: square is done
ld e, a ; E: MOVE TYPE (B,C,D used here)
; byte 2 - movlis delta (3B)
inc hl ; next piece sub-entry
push hl ; Save HL for 2nd loop
ld l, (hl) ; pointer to move delta
Code: Select all
bisgen defb $0E, $E5 ; bishop
Code: Select all
vecloo ; vector read (8B)
ld c, b ; TARGET SQUARE init
ld a, (hl) ; vector delta
or a ; =cp 0
jr z, vecexi ; ---v exit: vectors end with 0, next sq.
push hl ; save current delta
push de ; save move type + radius
; E: variable radius within loop
ld d, a ; D: store delta within loop
Code: Select all
org $7FE5
diavec defb $0F, $11 ; +5, diagonal vectors
defb $EF, $F1 ; +7, diagonal pawn
Code: Select all
celloo ; prepare x88 check (7B)
ld a, d ; delta loaded
add a, c ; current target (sq. + delta)
ld c, a ; current target
and $88 ; 0x88, famous OOB trick
jr nz, vecnex ; ---v exit: OOB, next vector
; read target square (3B)
inc h ; H(L)= $80 = boasth ++
ld l, c ; point at target square
ld a, (hl) ; read target square content
; mark attacked ### str. pawn marked attacked
inc h ; H(L)= $81 = boaath ++
ld (hl), h ; mark attacked ($81)
dec h ; H(L)= $80 = boasth ++
dec h ; H(L)= $79= movlih ++
Code: Select all
dec h ; H(L)= $79= movlih ++
; target is white (4B)
bit 5, a ; is it white?, pih
jr nz, vecnex ; ---v exit: WHITE b4=1, next vector
; target not white (3B)
or a ; =cp 0, is it empty?, pih
jr z, taremp ; if not 0, it's black: legal, no go on
tarbla ; target is black (7B)
bit 5, e ; special move: pawn straight check
jr nz, vecnex ; ---v exit: no straight capture, next vector
ld e, a ; make radius=0 (=<8 in code, canonical: ld e, 0)
call legadd ;
taremp ; target is empty (14B)
bit 4, e ; special move: pawn on capture check
jr nz, vecnex ; ---v exit: no diagonal without capture, next vector
dec e ; decrease radius
legadj
bit 3, e ; if radius < 8 (Cb3=0), radius limit
jr nz, celloo ; ---^ cell loop
Code: Select all
vecnex ; next vector preparation (5B)
pop de ; DE: recover move type + radius
pop hl ; HL: recover current vector
inc hl ; HL: next vector
jr vecloo ; ---^ vector loop
Code: Select all
vecexi ; next square preparation (5B)
pop hl ; HL: recover pointer to sub-move list
inc hl ; HL: next byte, point at 2nd sub-move
dec d ; 2 sub-move iterations loop control
jr nz, subloo ; if not 2nd iteration, repeat loop
; end of loop (2B)
squexi djnz squloo ; ---^ squares loop
ret
Code: Select all
kincas ld l, a ; save A (can't use push AF, flags lost)
add a, b ; A: 0rrr0xxx + 000ppppp (uncolored white p.)
cp $AA ; king($36) at E1($74)= $AA, pih
ld a, l ; recover A
jr nz, kinend ; if no match, skip adding legal move
ld c, $72 ; E1-C1 move, rook's move missing
call legadd ; add king's move
ld c, $76 ; E1-G1 move, rook's move missing
call legadd ; add king's move and go on with king's moves
kinend
Code: Select all
genpw2 add a, b ; piece square + move type
and %11111000 ; masked with relevant bits
cp $88 ; $28(str.pawn)+$60(rnk 6) ### univocal
jr nz, skppw2 ; if not, skip
inc e ; increase radius: 1 -> 2
skppw2
There is no other way, I guess.
...you missed out the "with a maniacal obsession" part...arkannoyed wrote: ↑Tue Jun 04, 2019 9:35 am It may seem incredibly difficult, but its nothing more than a case of carefully going through parts of any routine and working out the mechanics of whatevers going on. Then armed with that info its possible to find more efficient ways of achieving the same goal
Well, yeah, that too. Best avoided, but I know only too well that if I obsess over saving a byte somewhere, when the code just looks 'wrong' it can become a bowel shatteringly intense experienceMorkin wrote: ↑Tue Jun 04, 2019 1:34 pm...you missed out the "with a maniacal obsession" part...arkannoyed wrote: ↑Tue Jun 04, 2019 9:35 am It may seem incredibly difficult, but its nothing more than a case of carefully going through parts of any routine and working out the mechanics of whatevers going on. Then armed with that info its possible to find more efficient ways of achieving the same goal
Just joking obviously, it'll be great to see the eventual collision between graphics and code.
Code: Select all
celloo ; prepare x88 check (7B)
ld a, d ; delta loaded
add a, c ; current target (sq. + delta)
ld c, a ; current target [does the result need to go into C?]
and $88 ; 0x88, famous OOB trick
jr nz, vecnex ; ---v exit: OOB, next vector
; read target square (3B)
inc h ; H(L)= $80 = boasth ++
ld l, c ; point at target square [could the result of ld a,d, add a,c go straight into L?]
ld a, (hl) ; read target square content
; mark attacked ### str. pawn marked attacked
inc h ; H(L)= $81 = boaath ++
ld (hl), h ; mark attacked ($81)
dec h ; H(L)= $80 = boasth ++
dec h ; H(L)= $79= movlih ++
Very good one. I had a quick glance and it seems like we could save a byte there. As you say we could (in theory) use L directly instead of C. Let me test it and I´ll get back early next week. We would need to start changing thing ever before, from celloo tag and on.arkannoyed wrote: ↑Thu Jun 06, 2019 11:26 am Just wondering if it needs to be the case in this routine that you don't apply the result into L directly as opposed to C then L. Does it need to be saved into C for use elsewhere, as I can't find it.
Might be missing something though, as is often the case.Code: Select all
celloo ; prepare x88 check (7B) ld a, d ; delta loaded add a, c ; current target (sq. + delta) ld c, a ; current target [does the result need to go into C?] and $88 ; 0x88, famous OOB trick jr nz, vecnex ; ---v exit: OOB, next vector ; read target square (3B) inc h ; H(L)= $80 = boasth ++ ld l, c ; point at target square [could the result of ld a,d, add a,c go straight into L?] ld a, (hl) ; read target square content ; mark attacked ### str. pawn marked attacked inc h ; H(L)= $81 = boaath ++ ld (hl), h ; mark attacked ($81) dec h ; H(L)= $80 = boasth ++ dec h ; H(L)= $79= movlih ++
Best case would be 351,but I need to verify this last change. "genmov" is very sensitive to changes. It took me ages to make it work.arkannoyed wrote: ↑Thu Jun 06, 2019 3:20 pm Do you have any projection yet as to what sort of size its going to be down to now? Sub 350 bytes?