## 3D Chess 2K18

The place for codemasters or beginners to talk about programming any language for the Spectrum.
arkannoyed
Manic Miner
Posts: 374
Joined: Mon Feb 05, 2018 9:56 am

### Re: 3D Chess 2K18

d2010 wrote:
Wed Apr 17, 2019 10:20 am
VIEWport music
https://youtu.be/RdQ_unzeFy4

arkannoyed wrote:
Fri Feb 15, 2019 3:17 pm
I am interested to know if the source makes an sense to anyone perhaps more familiar with source code listings?

I generally comment mine extremely badly or not at all. I'm probably not alone in the fact that when you write something, it reads just fine to you without lengthy explanations. I do appreciate however, that the older I get, the more helpful the comments are when I revisit some past projects.

If any parts do need further explanation, then I will oblige of course.
I think I feel rather queezy now! Eugh!
0 x

arkannoyed
Manic Miner
Posts: 374
Joined: Mon Feb 05, 2018 9:56 am

### Re: 3D Chess 2K18

Part 7: Print the Line

So, all of the construction of the line is now done and its there in HL and DE in a form that the following routines can interpret and print in the correct form.

First, we retrieve the Screen address to print to and swap it with the Left hand side data, so a single instruction handles that;

Code: Select all

``````print_line:
ex (sp),hl                        ;put HL Left buffer on stack and retrieve screen address
ld b,l                            ;save SCReen address LO byte``````
We also save the position of HL at the centre for doing the Left side in B

The masking is done by the Least Significant Bit (LSB) being detected and inverted (reset). In the case of the Right sided data, its already in the correct direction to print quite easily and calculate a mask on the fly as follows, whilst also checking whether we're doing 1 or 2 bytes.

Code: Select all

``````right:
ld a,e                            ;test if E=00
or a                              ;
jr z,r_yes                        ;if E>00 then just copy D to screen.
r_no:
ld (hl),d                         ;put full byte on screen, no need to mask
inc l                             ;next L to far right byte
ld d,e                            ;swap E into D so the routine that follows masks E instead
r_yes:
dec d                             ;and
and d                             ;print D
ld e,a                            ;
xor d                             ;
and (hl)                          ;merge with SCReen contents
or e                              ;
ld (hl),a                         ;place on SCReen

ld l,b                            ;restore SCReen address LO byte``````
The Left side data is residing on the stack, so we get it into DE. The problem is that its been created in reverse form, backwards. As we're at the centre of the line though and the first bit to place is at BIT 7 of H, then we just work our way left one bit at a time until we reach the last and then invert it and return after again restoring the screen address to the centre.

Code: Select all

``````get_lhs:
pop de                            ;LHS data retrieve from stack
ld c,80h                          ;left bit mask set +1 right so that DEC L happens
left:
rlc c                             ;next left bit
jr nc,left_ovr
dec l
left_ovr:
ex de,hl                          ;swap data into HL
add hl,hl                         ;propagate MSB
ex de,hl                          ;swap back to SCReen in HL, data in DE
sbc a,a                           ;apply carry
xor (hl)                          ;XOR screen contents
and c                             ;mask current bit
xor (hl)                          ;XOR screen again to write the bit
ld (hl),a                         ;place byte
ld a,d                            ;check if data finished
or e                              ;
jr nz,left                        ;loop if not
left_end:
ld a,(hl)                         ;change the last bit to 0
xor c                             ;
ld (hl),a                         ;

ld l,b                            ;restore SCReen address
ret                               ;``````
And that Ladies and Gentlemen is it! I could post the Graphics data next, though thats kind of pointless, so maybe just a link to the file or the asm. Any preferences? Any questions?
0 x

arkannoyed
Manic Miner
Posts: 374
Joined: Mon Feb 05, 2018 9:56 am

### Re: 3D Chess 2K18

I need a lie down!
0 x

arkannoyed
Manic Miner
Posts: 374
Joined: Mon Feb 05, 2018 9:56 am

### Re: 3D Chess 2K18

I knew this process would be useful!

I've just corrected the problem with losing bits in the Long Lines routine by changing at what point L gets its data by placing the instruction LD L,A at the start;

Code: Select all

``````data_line:
ld l,a                            ;put data into L in case of Long Line so we don't lose any bits on the 4 shift cycle
jr c,long_line
mini_ln_tst:
cp 3eh
jr c,bit5_test
inc ixl
bit5_test:
ld e,00h                          ;set the outer bytes to 00
ld l,e                            ;L=00

jr nc,bit4_test-1
bit5_set:
jr bit4_res+1
long_line:
and 0e0h                          ;mask upper 3 bits E0h
ld e,a                            ;into E
lllp_00:
ld a,(ix+00h)                     ;get White data
and c                             ;mask with B/W component
xor (ix+0feh)                     ;apply Black data switch
ld d,h                            ;roll result from H into D. Pass 1 is null
add hl,hl                         ;propagate 3 bits in L
ld h,a                            ;B/W result into A
inc ixl                           ;next
djnz lllp_00                      ;loop x 4
jr print_line                     ;second byte here is 07=RLCA
bit4_test:
jr nc,bit4_res                    ;if bit ='0' then the data for BWRL is in the 4 bits remaining in A
bit4_set:
rrca                              ;re-use bit to fill BIT 7, creating a left orientated mask
and c                             ;mask with C BW byte to create 5 bit overlay mask of ccccc000
xor d                             ;create the Black or White Left and Right buffer bytes
bit4_res:
ld d,a                            ;load Right buffer
ld h,a                            ;load Left buffer``````
0 x

arkannoyed
Manic Miner
Posts: 374
Joined: Mon Feb 05, 2018 9:56 am

### Re: 3D Chess 2K18

0 x

arkannoyed
Manic Miner
Posts: 374
Joined: Mon Feb 05, 2018 9:56 am

### Re: 3D Chess 2K18

Lastly, I need to send thanks to Einar, as he wrote the original initialisation routine that sets the board at the game start. It's only had very minor changes applied since as far as I can remember. The routine is totally separate to the board build/ display one and is 40 bytes. It does have a bug, in that it swaps the White King and Queens places with one another. So far, I haven't dedicated much time to trying to correct it or come up with an alternative, though I'm sure it can be done in fewer bytes.

Code: Select all

``````init_board:
ld de,0ffc0h
ld b,d
ld c,d
ld hl,data_17
ib_loop1:
ld a,(hl)
dec a
ld (bc),a
ldi
jr nz,ib_loop1
dec e
ld b,20h
ib_loop2:
ld (de),a
inc e
djnz ib_loop2

ret                   ;23 bytes
data_17:
db 05h,07h,09h,0bh,0dh,09h,07h,05h
db 03h,03h,03h,03h,03h,03h,03h,03h,01h``````
0 x

Einar Saukas
Manic Miner
Posts: 953
Joined: Wed Nov 15, 2017 2:48 pm

### Re: 3D Chess 2K18

arkannoyed wrote:
Wed Apr 17, 2019 12:21 pm
Lastly, I need to send thanks to Einar, as he wrote the original initialisation routine that sets the board at the game start.
You are welcome!

arkannoyed wrote:
Wed Apr 17, 2019 12:21 pm
It does have a bug, in that it swaps the White King and Queens places with one another.
Ops!!!
0 x

arkannoyed
Manic Miner
Posts: 374
Joined: Mon Feb 05, 2018 9:56 am

### Re: 3D Chess 2K18

Nevermind!

I do have a working version I knocked together in 41 bytes, but ideally I'd love 38, as theres 38 bytes spare between the end of the routine and the board matrix. However chances are I'll find somewhere to save a byte in the code at some point anyway in which case something bigger should fit.!
0 x

arkannoyed
Manic Miner
Posts: 374
Joined: Mon Feb 05, 2018 9:56 am

### Re: 3D Chess 2K18

Ch-ch-ch-ch Changes!

I suppose I'll have to do the whole damn post again! Grrrrrr!

Only 1 byte improvement actually with a change to the square calculating routine allowing a saving in the routine that sets the counter for piece height.
Now down to 484 bytes.
0 x

arkannoyed
Manic Miner
Posts: 374
Joined: Mon Feb 05, 2018 9:56 am

### Re: 3D Chess 2K18

Oh bugger, there goes another one!

Saved another byte in the same routine, so now 483 bytes

by changing the routine to this;

Code: Select all

``````get_height:
ld e,c                         ;DE points to the current square
ld a,(de)                      ;get the piece we need in A
ld b,a                         ;save temp in B
rra                            ;/2
ld e,a                         ;DE points to the heights table
ld a,(de)                      ;get the piece height
ld e,b                         ;E now holds the current piece
ld b,a                         ;B=height
ld ix,0fe44h                   ;IX = Graphics data entry address``````
Or this, does the same thing;

Code: Select all

``````get_height:
ld e,c                         ;DE points to the current square
ld a,(de)                      ;get the piece we need in A
rra                            ;/2
ld e,a                         ;DE points to the heights table
ld a,(de)                      ;get the piece height
rl e                           ;put back th B/W bit into E
ld b,a                         ;B=height``````
0 x