3D Chess 2K18

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

Re: 3D Chess 2K18

Post by arkannoyed » Wed Apr 17, 2019 10:38 am

d2010 wrote:
Wed Apr 17, 2019 10:20 am
VIEWport music
https://youtu.be/RdQ_unzeFy4
:x
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

User avatar
arkannoyed
Manic Miner
Posts: 365
Joined: Mon Feb 05, 2018 9:56 am

Re: 3D Chess 2K18

Post by arkannoyed » Wed Apr 17, 2019 10:49 am

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:
           ld a,d                            ;mask
           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

User avatar
arkannoyed
Manic Miner
Posts: 365
Joined: Mon Feb 05, 2018 9:56 am

Re: 3D Chess 2K18

Post by arkannoyed » Wed Apr 17, 2019 10:50 am

I need a lie down! :?
0 x

User avatar
arkannoyed
Manic Miner
Posts: 365
Joined: Mon Feb 05, 2018 9:56 am

Re: 3D Chess 2K18

Post by arkannoyed » Wed Apr 17, 2019 10:56 am

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
           add a,a
           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

           add a,a
           jr nc,bit4_test-1
bit5_set:
           add a,d
           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

User avatar
arkannoyed
Manic Miner
Posts: 365
Joined: Mon Feb 05, 2018 9:56 am

Re: 3D Chess 2K18

Post by arkannoyed » Wed Apr 17, 2019 11:30 am

0 x

User avatar
arkannoyed
Manic Miner
Posts: 365
Joined: Mon Feb 05, 2018 9:56 am

Re: 3D Chess 2K18

Post by arkannoyed » 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. 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

User avatar
Einar Saukas
Manic Miner
Posts: 937
Joined: Wed Nov 15, 2017 2:48 pm

Re: 3D Chess 2K18

Post by Einar Saukas » Wed Apr 17, 2019 3:37 pm

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

User avatar
arkannoyed
Manic Miner
Posts: 365
Joined: Mon Feb 05, 2018 9:56 am

Re: 3D Chess 2K18

Post by arkannoyed » Wed Apr 17, 2019 3:53 pm

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.! :D
0 x

User avatar
arkannoyed
Manic Miner
Posts: 365
Joined: Mon Feb 05, 2018 9:56 am

Re: 3D Chess 2K18

Post by arkannoyed » Thu Apr 18, 2019 10:24 am

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

User avatar
arkannoyed
Manic Miner
Posts: 365
Joined: Mon Feb 05, 2018 9:56 am

Re: 3D Chess 2K18

Post by arkannoyed » Thu Apr 18, 2019 10:56 am

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

Post Reply