ld bc,(hl)

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
User avatar
777
Manic Miner
Posts: 512
Joined: Fri Jun 26, 2020 11:23 am
Location: sw uk

Re: ld bc,(hl)

Post by 777 »

neither works for me
i started programming the spectrum when i was 8 :-

1 plot rnd*255,rnd*175
2 goto 1
User avatar
Alessandro
Dynamite Dan
Posts: 1910
Joined: Wed Nov 15, 2017 11:10 am
Location: Messina, Italy
Contact:

Re: ld bc,(hl)

Post by Alessandro »

I understood I was making confusion between the value stored in the register and the location the register was pointing at - again... :oops:

@777 , finally I also managed to run your code, but just like you, I see an empty box on the upper right part of the screen and nothing else. Which kind of effect are you trying to achieve? Maybe if you explain it, it could be of help.
User avatar
777
Manic Miner
Posts: 512
Joined: Fri Jun 26, 2020 11:23 am
Location: sw uk

Re: ld bc,(hl)

Post by 777 »

the box is supposed to animate (spin)
i started programming the spectrum when i was 8 :-

1 plot rnd*255,rnd*175
2 goto 1
User avatar
Morkin
Bugaboo
Posts: 3266
Joined: Mon Nov 13, 2017 8:50 am
Location: Bristol, UK

Re: ld bc,(hl)

Post by Morkin »

Funny how you're trying to make something spin, using ZX Spin... :lol:

Firstly as already suggested, to make it compile in ZX Spin you'll need to replace:

Code: Select all

ld bc,(hl)
with

Code: Select all

ld c,(hl)
inc hl
ld b,(hl)
And delete the next

Code: Select all

inc hl
...instruction, as you've already incremented it once.

Same with the LD DE, (HL) I guess (but with LD E and D rather than LD C and B)

I've absolutely no idea what this bit is:

Code: Select all

sync:	
		ld a,r				; padding instruction
		in a,(c)
		cp e
		jp nz,sync
Try getting rid of this.

I've always wanted to learn how to do vector graphics in asm but I think it's quite an advanced topic, I really haven't got my head round the concepts yet.
My Speccy site: thirdharmoniser.com
User avatar
777
Manic Miner
Posts: 512
Joined: Fri Jun 26, 2020 11:23 am
Location: sw uk

Re: ld bc,(hl)

Post by 777 »

it still wont work if you add those instructions. and if you delete the sync it spins but it crashes all the graphics.
i started programming the spectrum when i was 8 :-

1 plot rnd*255,rnd*175
2 goto 1
User avatar
MonkZy
Manic Miner
Posts: 279
Joined: Thu Feb 08, 2018 1:01 pm

Re: ld bc,(hl)

Post by MonkZy »

@777

The sync routine is the floating bus hack developed by Steve Wetherill.

https://blog.stevewetherill.com/2022/02 ... -1986.html

Scroll down to the Sidwize section.

This routine will hang forever if it is ran on a 128k machine.
User avatar
Spud
Manic Miner
Posts: 375
Joined: Sun Nov 12, 2017 8:50 pm
Contact:

Re: ld bc,(hl)

Post by Spud »

I don't know about that sync thing and it freezes ZX Spin emulating a 48. For simiplicity, just replace with a halt

Code: Select all

sync:	
		;ld a,r				; padding instruction
		;in a,(c)
		;cp e
		;jp nz,sync
		
		halt
and for the illegal instruction problems:

Code: Select all

Edge_Loop:
		push bc				; preserve B for loop
		ld c,(hl)			; B = ypos1 C = xpos1
		inc hl
		ld b,(hl)
		inc hl
		ld e,(hl)			; D = ypos2 E = xpos2
		inc hl
		ld d,(hl)	
		inc hl
		push hl				; preserve edge pointer
		call Draw_Line
		pop hl
  		pop bc
		djnz Edge_Loop

Code: Select all

Erase_Loop:
		push bc				; preserve B for loop
		ld c,(hl)			; B = ypos1 C = xpos1
		inc hl
		ld b,(hl)
		inc hl
		ld e,(hl)			; D = ypos2 E = xpos2
		inc hl
		ld d,(hl)
		inc hl
		push hl				; preserve edge pointer
		call Erase_Line
		pop hl
  		pop bc
		djnz Erase_Loop

and this results in a spinning cube on screen, albeit with some corruption - perhaps the erasing loop is wrong.

Here is the full code fo convenience:

Code: Select all

	org 50000
Endless_Loop:
		ld hl,Edge_Data
		ld b,18
Frame_Loop:
		push bc				; preserve B for loop
	
		ld b,12
		push hl
Edge_Loop:
		push bc				; preserve B for loop
		ld c,(hl)			; B = ypos1 C = xpos1
		inc hl
		ld b,(hl)
		inc hl
		ld e,(hl)			; D = ypos2 E = xpos2
		inc hl
		ld d,(hl)	
		inc hl
		push hl				; preserve edge pointer
		call Draw_Line
		pop hl
  		pop bc
		djnz Edge_Loop
		
		ld bc,$40ff			; Steve Wetherill floating bus frame sync from Sidewize
		ld e,%00111010			; red ink on white paper
sync:	
		;ld a,r				; padding instruction
		;in a,(c)
		;cp e
		;jp nz,sync
		
		halt

		
		ld b,12
		pop hl
Erase_Loop:
		push bc				; preserve B for loop
		ld c,(hl)			; B = ypos1 C = xpos1
		inc hl
		ld b,(hl)
		inc hl
		ld e,(hl)			; D = ypos2 E = xpos2
		inc hl
		ld d,(hl)
		inc hl
		push hl				; preserve edge pointer
		call Erase_Line
		pop hl
  		pop bc
		djnz Erase_Loop

		
		pop bc
		djnz Frame_Loop
		jp Endless_Loop
		ret	




; Plot routine
; B = Y pixel position
; C = X pixel position
;
Plot:                   CALL Get_Pixel_Address          ; Get screen address in HL, pixel position (0 to 7) in A
                        LD BC,Plot_Point                ; Address of point lookup table
                        ADD A,C                         ; Add pixel position to get entry in table
                        LD C,A
                        LD A,(BC)                       ; Get pixel data from table
                        OR (HL)                         ; OR with screen data
                        LD (HL),A                       ; Write back to screen
                        RET
 
 
; Unplot routine
; B = Y pixel position
; C = X pixel position
;
Unplot:                 CALL Get_Pixel_Address          ; Same as Plot...
                        LD BC,Unplot_Point
                        ADD A,C
                        LD C,A
                        LD A,(BC)
                        AND (HL)                        ; AND with screen data
                        LD (HL),A
                        RET


; Draw Line routine
; B = Y pixel position 1
; C = X pixel position 1
; D = Y pixel position 2
; E = X pixel position 2
;
Draw_Line:              LD A,D                          ; Check whether we are going to be drawing up
                        CP B
                        JR NC,Draw_Line_1
 
                        PUSH BC                         ; If we are, then this neat trick swaps BC and DE
                        PUSH DE                         ; using the stack, forcing the line to be always
                        POP BC                          ; drawn downwards
                        POP DE
 
Draw_Line_1:            CALL Get_Pixel_Address          ; Get screen address in HL, pixel position (0-7) in A
;
; At this point we have
;  A = Pixel position (0-7)
; HL = Screen address of the start point
; BC = Start coordinate (B=Y1, C=X1)
; DE = End coordinates  (D=Y2, E=X2)
;
                        LD IX,Plot_Point                ; Point to the Plot_Point table
                        ADD A,IXL                       ; Add the pixel position to get entry in table
                        LD IXL,A
 
                        LD A,D                          ; Calculate the line height in B (Y2-Y1)
                        SUB B
                        LD B,A
         
                        LD A,E                          ; Calculate the line width in C (X2-X1)
                        SUB C
                        JR C,Draw_Line_X1               ; If carry set (negative result) then we are drawing from right to left
;
; This bit of code mods the main loop for drawing left to right
;
                        LD C,A                          ; Store the line width
                        LD A,0x2C                       ; Code for INC L
                        LD (Draw_Line_Q1_M3),A          ; Mod the code
                        LD (Draw_Line_Q2_M3),A
                        LD A,0x0A                       ; Code for RRC D (CB 0A)
                        JR Draw_Line_X2                 ; Skip the next bit
;
; This bit of code mods the main loop for drawing right to left
;
Draw_Line_X1:           NEG                             ; The width of line is negative, so make it positive again
                        LD C,A                          ; Store the line width
                        LD A,0x2D                       ; Code for DEC L
                        LD (Draw_Line_Q1_M3),A
                        LD (Draw_Line_Q2_M3),A
                        LD A,0x02                       ; Code for RLC D (CB 02)
;
; We've got the basic information at this point
;
Draw_Line_X2:           LD (Draw_Line_Q1_M2 + 1),A      ; A contains the code for RLC D or RRC D, so make the mods
                        LD (Draw_Line_Q2_M2 + 1),A
                        LD D,(IX+0)                     ; Get the pixel data from the Point_Plot table
                        LD A,B                          ; Check if B and C are 0
                        OR C
                        JR NZ,Draw_Line_Q               ; There is a line to draw, so skip to the next bit
                        LD A,(HL)                       ; Here we've got a single point line, so plot and return
                        OR D
                        LD (HL),A
                        RET
;
; At this point
; HL = Screen address of the start point
;  B = Line height
;  C = Line width
;  D = Pixel data
;
Draw_Line_Q:            LD A,B                          ; Work out which diagonal we are on
                        CP C
                        JR NC,Draw_Line_Q2
;
; This bit of code draws the line where B<C (more horizontal than vertical)
;
Draw_Line_Q1:           LD A,C
                        LD (Draw_Line_Q1_M1 + 1),A      ; Self-mod the code again to store the line width
                        LD C,B
                        LD B,A
                        LD E,C                          ; Calculate the error value
                        SRL E
Draw_Line_Q1_L:         LD A,(HL)                       ; Plot the pixel
                        OR D
                        LD (HL),A
                        LD A,E
                        SUB C
                        LD E,A
                        JR NC,Draw_Line_Q1_M2
Draw_Line_Q1_M1:        ADD A,0                         ; Add the line height (previously stored; self modifying code)
                        LD E,A
                        CALL Pixel_Address_Down
Draw_Line_Q1_M2:        RRC D                           ; Rotate the pixel right or left; more self-modifying code
                        JR NC,Draw_Line_Q1_S
Draw_Line_Q1_M3:        INC L                           ; If we get a carry then move to adjacent screen address; more self modifying code
Draw_Line_Q1_S:         DJNZ Draw_Line_Q1_L             ; Loop until the line is drawn
                        RET
;
; This bit draws the line where B>=C (more vertical than horizontal, or diagonal)
;
Draw_Line_Q2:           LD (Draw_Line_Q2_M1 + 1),A
                        LD E,C                          ; Calculate the error value
                        SRL E
Draw_Line_Q2_L:         LD A,(HL)                       ; Plot the pixel
                        OR D
                        LD (HL),A
                        LD A,E                          ; Get the error value
                        SUB C                           ; Add the line length to it (X2-X1)
                        JR NC,Draw_Line_Q2_S            ; Skip the next bit if we don't get a carry
Draw_Line_Q2_M1:        ADD A,0                         ; Add the line height (previously stored; self modifying code)
Draw_Line_Q2_M2:        RRC D                           ; Rotates the pixel right with carry
                        JR NC,Draw_Line_Q2_S
Draw_Line_Q2_M3:        INC L                           ; If we get a carry then move to adjacent screen address; more self modifying code
Draw_Line_Q2_S:         LD E,A                          ; Store the error value back in
                        CALL Pixel_Address_Down         ; And also move down
                        DJNZ Draw_Line_Q2_L
                        RET
 
; Erase Line routine
; B = Y pixel position 1
; C = X pixel position 1
; D = Y pixel position 2
; E = X pixel position 2
;
Erase_Line:             LD A,D                          ; Check whether we are going to be drawing up
                        CP B
                        JR NC,Erase_Line_1
 
                        PUSH BC                         ; If we are, then this neat trick swaps BC and DE
                        PUSH DE                         ; using the stack, forcing the line to be always
                        POP BC                          ; drawn downwards
                        POP DE
 
Erase_Line_1:           CALL Get_Pixel_Address          ; Get screen address in HL, pixel position (0-7) in A
;
; At this point we have
;  A = Pixel position (0-7)
; HL = Screen address of the start point
; BC = Start coordinate (B=Y1, C=X1)
; DE = End coordinates  (D=Y2, E=X2)
;
                        LD IX,Unplot_Point              ; Point to the Unplot_Point table
                        ADD A,IXL                       ; Add the pixel position to get entry in table
                        LD IXL,A
 
                        LD A,D                          ; Calculate the line height in B (Y2-Y1)
                        SUB B
                        LD B,A
         
                        LD A,E                          ; Calculate the line width in C (X2-X1)
                        SUB C
                        JR C,Erase_Line_X1              ; If carry set (negative result) then we are drawing from right to left
;
; This bit of code mods the main loop for drawing left to right
;
                        LD C,A                          ; Store the line width
                        LD A,0x2C                       ; Code for INC L
                        LD (Erase_Line_Q1_M3),A         ; Mod the code
                        LD (Erase_Line_Q2_M3),A
                        LD A,0x0A                       ; Code for RRC D (CB 0A)
                        JR Erase_Line_X2                ; Skip the next bit
;
; This bit of code mods the main loop for drawing right to left
;
Erase_Line_X1:          NEG                             ; The width of line is negative, so make it positive again
                        LD C,A                          ; Store the line width
                        LD A,0x2D                       ; Code for DEC L
                        LD (Erase_Line_Q1_M3),A
                        LD (Erase_Line_Q2_M3),A
                        LD A,0x02                       ; Code for RLC D (CB 02)
;
; We've got the basic information at this point
;
Erase_Line_X2:          LD (Erase_Line_Q1_M2 + 1),A     ; A contains the code for RLC D or RRC D, so make the mods
                        LD (Erase_Line_Q2_M2 + 1),A
                        LD D,(IX+0)                     ; Get the pixel data from the Unplot_Point table
                        LD A,B                          ; Check if B and C are 0
                        OR C
                        JR NZ,Erase_Line_Q              ; There is a line to draw, so skip to the next bit
                        LD A,(HL)                       ; Here we've got a single point line, so plot and return
                        AND D
                        LD (HL),A
                        RET
;
; At this point
; HL = Screen address of the start point
;  B = Line height
;  C = Line width
;  D = Pixel data
;
Erase_Line_Q:           LD A,B                          ; Work out which diagonal we are on
                        CP C
                        JR NC,Erase_Line_Q2
;
; This bit of code draws the line where B<C (more horizontal than vertical)
;
Erase_Line_Q1:          LD A,C
                        LD (Erase_Line_Q1_M1 + 1),A     ; Self-mod the code again to store the line width
                        LD C,B
                        LD B,A
                        LD E,C                          ; Calculate the error value
                        SRL E
Erase_Line_Q1_L:        LD A,(HL)                       ; Unplot the pixel
                        AND D
                        LD (HL),A
                        LD A,E
                        SUB C
                        LD E,A
                        JR NC,Erase_Line_Q1_M2
Erase_Line_Q1_M1:       ADD A,0                         ; Add the line height (previously stored; self modifying code)
                        LD E,A
                        CALL Pixel_Address_Down
Erase_Line_Q1_M2:       RRC D                           ; Rotate the pixel right or left; more self-modifying code
                        JR C,Erase_Line_Q1_S            ; Note the change here from the Draw_Line routine
Erase_Line_Q1_M3:       INC L                           ; If we get no carry then move to adjacent screen address; more self modifying code
Erase_Line_Q1_S:        DJNZ Erase_Line_Q1_L            ; Loop until the line is drawn
                        RET
;
; This bit draws the line where B>=C (more vertical than horizontal, or diagonal)
;
Erase_Line_Q2:          LD (Erase_Line_Q2_M1 + 1),A
                        LD E,C                          ; Calculate the error value
                        SRL E
Erase_Line_Q2_L:        LD A,(HL)                       ; Unplot the pixel
                        AND D
                        LD (HL),A
                        LD A,E                          ; Get the error value
                        SUB C                           ; Add the line length to it (X2-X1)
                        JR NC,Erase_Line_Q2_S           ; Skip the next bit if we don't get a carry
Erase_Line_Q2_M1:       ADD A,0                         ; Add the line height (previously stored; self modifying code)
Erase_Line_Q2_M2:       RRC D                           ; Rotates the pixel right with carry
                        JR C,Erase_Line_Q2_S            ; Note the change here from the Draw_Line routine
Erase_Line_Q2_M3:       INC L                           ; If we get no carry then move to adjacent screen address; more self modifying code
Erase_Line_Q2_S:        LD E,A                          ; Store the error value back in
                        CALL Pixel_Address_Down         ; And also move down
                        DJNZ Erase_Line_Q2_L
                        RET

;; GET BUFFER PIXEL ADDRESS
;; B=y-pos C=x-pos 
;; Returns: HL=Adress of pixel A=Byte of the pixel

Get_Buffer_Address:

	ld l,0        ;
	ld h,b        ; B contains the Y-POS
	srl h         ;
	rr l          ;
	srl h         ;
	rr l          ; Shifts right 3x, then OR's low byte with 11100000 
	srl h         ;
	rr l          ; divide by 8?
	ld a,h        ;
	or 224        ; 11100000
	ld h,a        ;

 	ld a,c        ; C contains the X-POS
 	rra           ;
 	rra           ; divide by 8
 	rra           ;
 	and 31        ; 00011111 - strip out rolled in carry bytes
 	or l          ;
 	ld l,a        ;
 	ld a,c        ;
 	and 7         ; 00000111
 	ret           ;


; Get screen address
; B = Y pixel position
; C = X pixel position
; Returns address in HL and pixel position within character in A
;
Get_Pixel_Address:      LD A,B                          ; Calculate Y2,Y1,Y0
                        AND %00000111                   ; Mask out unwanted bits
                        OR %01000000                    ; Set base address of screen
                        LD H,A                          ; Store in H
                        LD A,B                          ; Calculate Y7,Y6
                        RRA                             ; Shift to position
                        RRA
                        RRA
                        AND %00011000                   ; Mask out unwanted bits
                        OR H                            ; OR with Y2,Y1,Y0
                        LD H,A                          ; Store in H
                        LD A,B                          ; Calculate Y5,Y4,Y3
                        RLA                             ; Shift to position
                        RLA
                        AND %11100000                   ; Mask out unwanted bits
                        LD L,A                          ; Store in L
                        LD A,C                          ; Calculate X4,X3,X2,X1,X0
                        RRA                             ; Shift into position
                        RRA
                        RRA
                        AND %00011111                   ; Mask out unwanted bits
                        OR L                            ; OR with Y5,Y4,Y3
                        LD L,A                          ; Store in L
                        LD A,C
                        AND 7
                        RET

; Move HL down one pixel line
;
Pixel_Address_Down:     INC H                           ; Go down onto the next pixel line
                        LD A,H                          ; Check if we have gone onto next character boundary
                        AND 7
                        RET NZ                          ; No, so skip the next bit
                        LD A,L                          ; Go onto the next character line
                        ADD A,32
                        LD L,A
                        RET C                           ; Check if we have gone onto next third of screen
                        LD A,H                          ; Yes, so go onto next third
                        SUB 8
                        LD H,A
                        RET
 
; Note that the functions above only work if each of these tables are in a byte boundary
;
Plot_Point:             DB %10000000,%01000000,%00100000,%00010000,%00001000,%00000100,%00000010,%00000001
Unplot_Point:           DB %01111111,%10111111,%11011111,%11101111,%11110111,%11111011,%11111101,%11111110
 
Plot_Line_LHS:          DB %11111111,%01111111,%00111111,%00011111,%00001111,%00000111,%00000011,%00000001
Plot_Line_RHS:          DB %10000000,%11000000,%11100000,%11110000,%11111000,%11111100,%11111110,%11111111

Edge_Data:

;;;EDGE DATA


;;;FRAME #1 0 degrees
     defb 164,7,231,7
     defb 231,7,231,74
     defb 231,74,164,74
     defb 164,74,164,7
     defb 218,21,178,21
     defb 178,21,178,61
     defb 178,61,218,61
     defb 218,61,218,21
     defb 164,7,178,21
     defb 231,7,218,21
     defb 231,74,218,61
     defb 164,74,178,61

;;;FRAME #2 5 degrees
     defb 162,8,229,6
     defb 229,6,229,75
     defb 229,75,162,73
     defb 162,73,162,8
     defb 220,20,180,21
     defb 180,21,180,60
     defb 180,60,220,61
     defb 220,61,220,20
     defb 162,8,180,21
     defb 229,6,220,20
     defb 229,75,220,61
     defb 162,73,180,60

;;;FRAME #3 10 degrees
     defb 161,9,226,5
     defb 226,5,226,76
     defb 226,76,161,72
     defb 161,72,161,9
     defb 222,20,182,21
     defb 182,21,182,60
     defb 182,60,222,61
     defb 222,61,222,20
     defb 161,9,182,21
     defb 226,5,222,20
     defb 226,76,222,61
     defb 161,72,182,60

;;;FRAME #4 15 degrees
     defb 160,10,223,4
     defb 223,4,223,77
     defb 223,77,160,71
     defb 160,71,160,10
     defb 224,19,184,21
     defb 184,21,184,60
     defb 184,60,224,62
     defb 224,62,224,19
     defb 160,10,184,21
     defb 223,4,224,19
     defb 223,77,224,62
     defb 160,71,184,60

;;;FRAME #5 20 degrees
     defb 160,11,219,4
     defb 219,4,219,77
     defb 219,77,160,70
     defb 160,70,160,11
     defb 225,19,186,22
     defb 186,22,186,59
     defb 186,59,225,62
     defb 225,62,225,19
     defb 160,11,186,22
     defb 219,4,225,19
     defb 219,77,225,62
     defb 160,70,186,59

;;;FRAME #6 25 degrees
     defb 160,12,216,3
     defb 216,3,216,78
     defb 216,78,160,69
     defb 160,69,160,12
     defb 227,18,188,22
     defb 188,22,188,59
     defb 188,59,227,63
     defb 227,63,227,18
     defb 160,12,188,22
     defb 216,3,227,18
     defb 216,78,227,63
     defb 160,69,188,59

;;;FRAME #7 30 degrees
     defb 160,13,211,3
     defb 211,3,211,78
     defb 211,78,160,68
     defb 160,68,160,13
     defb 229,18,191,22
     defb 191,22,191,59
     defb 191,59,229,63
     defb 229,63,229,18
     defb 160,13,191,22
     defb 211,3,229,18
     defb 211,78,229,63
     defb 160,68,191,59

;;;FRAME #8 35 degrees
     defb 160,14,207,2
     defb 207,2,207,79
     defb 207,79,160,67
     defb 160,67,160,14
     defb 230,17,193,22
     defb 193,22,193,59
     defb 193,59,230,64
     defb 230,64,230,17
     defb 160,14,193,22
     defb 207,2,230,17
     defb 207,79,230,64
     defb 160,67,193,59

;;;FRAME #9 40 degrees
     defb 161,15,202,2
     defb 202,2,202,79
     defb 202,79,161,66
     defb 161,66,161,15
     defb 232,16,195,22
     defb 195,22,195,59
     defb 195,59,232,65
     defb 232,65,232,16
     defb 161,15,195,22
     defb 202,2,232,16
     defb 202,79,232,65
     defb 161,66,195,59

;;;FRAME #10 45 degrees
     defb 162,16,198,2
     defb 198,2,198,79
     defb 198,79,162,66
     defb 162,66,162,16
     defb 233,16,198,22
     defb 198,22,198,59
     defb 198,59,233,66
     defb 233,66,233,16
     defb 162,16,198,22
     defb 198,2,233,16
     defb 198,79,233,66
     defb 162,66,198,59

;;;FRAME #11 50 degrees
     defb 163,16,193,2
     defb 193,2,193,79
     defb 193,79,163,65
     defb 163,65,163,16
     defb 234,15,200,22
     defb 200,22,200,59
     defb 200,59,234,66
     defb 234,66,234,15
     defb 163,16,200,22
     defb 193,2,234,15
     defb 193,79,234,66
     defb 163,65,200,59

;;;FRAME #12 55 degrees
     defb 165,17,188,2
     defb 188,2,188,79
     defb 188,79,165,64
     defb 165,64,165,17
     defb 235,14,202,22
     defb 202,22,202,59
     defb 202,59,235,67
     defb 235,67,235,14
     defb 165,17,202,22
     defb 188,2,235,14
     defb 188,79,235,67
     defb 165,64,202,59

;;;FRAME #13 60 degrees
     defb 166,18,184,3
     defb 184,3,184,78
     defb 184,78,166,63
     defb 166,63,166,18
     defb 235,13,204,22
     defb 204,22,204,59
     defb 204,59,235,68
     defb 235,68,235,13
     defb 166,18,204,22
     defb 184,3,235,13
     defb 184,78,235,68
     defb 166,63,204,59

;;;FRAME #14 65 degrees
     defb 168,18,179,3
     defb 179,3,179,78
     defb 179,78,168,63
     defb 168,63,168,18
     defb 235,12,207,22
     defb 207,22,207,59
     defb 207,59,235,69
     defb 235,69,235,12
     defb 168,18,207,22
     defb 179,3,235,12
     defb 179,78,235,69
     defb 168,63,207,59

;;;FRAME #15 70 degrees
     defb 170,19,176,4
     defb 176,4,176,77
     defb 176,77,170,62
     defb 170,62,170,19
     defb 235,11,209,22
     defb 209,22,209,59
     defb 209,59,235,70
     defb 235,70,235,11
     defb 170,19,209,22
     defb 176,4,235,11
     defb 176,77,235,70
     defb 170,62,209,59

;;;FRAME #16 75 degrees
     defb 171,19,172,4
     defb 172,4,172,77
     defb 172,77,171,62
     defb 171,62,171,19
     defb 235,10,211,21
     defb 211,21,211,60
     defb 211,60,235,71
     defb 235,71,235,10
     defb 171,19,211,21
     defb 172,4,235,10
     defb 172,77,235,71
     defb 171,62,211,60

;;;FRAME #17 80 degrees
     defb 173,20,169,5
     defb 169,5,169,76
     defb 169,76,173,61
     defb 173,61,173,20
     defb 234,9,213,21
     defb 213,21,213,60
     defb 213,60,234,72
     defb 234,72,234,9
     defb 173,20,213,21
     defb 169,5,234,9
     defb 169,76,234,72
     defb 173,61,213,60

;;;FRAME #18 85 degrees
     defb 175,20,166,6
     defb 166,6,166,75
     defb 166,75,175,61
     defb 175,61,175,20
     defb 233,8,215,21
     defb 215,21,215,60
     defb 215,60,233,73
     defb 233,73,233,8
     defb 175,20,215,21
     defb 166,6,233,8
     defb 166,75,233,73
     defb 175,61,215,60

;;;Bytes = 648
Perhaps this helps a little. Tested on ZX Spin emulating a 48K/
roganjosh
Drutt
Posts: 21
Joined: Fri Aug 13, 2021 5:57 pm

Re: ld bc,(hl)

Post by roganjosh »

MonkZy wrote: Sun May 01, 2022 9:23 am @777

The sync routine is the floating bus hack developed by Steve Wetherill.

https://blog.stevewetherill.com/2022/02 ... -1986.html

Scroll down to the Sidwize section.

This routine will hang forever if it is ran on a 128k machine.
To expand on this - not all emulators will successfully handle code that relies on the floating bus method. Those that don't will likely hang. A hang will also happen if your (777) code hasn't set up the attribute byte you're testing for. I don't know what category ZX Spin falls into as far as the floating bus is concerned. As @spud suggests, a halt is sometimes a perfectly adequate alternative.

Alan
User avatar
bobs
Microbot
Posts: 107
Joined: Thu Dec 28, 2017 8:26 am
Location: UK
Contact:

Re: ld bc,(hl)

Post by bobs »

I’ve only looked at the original code, so could be completely wrong, but could the corruption be down to the location of the following look-up tables?

I’m not sure what ‘in a byte boundary’ means, but the code only adjusts the low byte to address them, so they can’t straddle a high-byte boundary.

Code: Select all

; Note that the functions above only work if each of these tables are in a byte boundary
;
Plot_Point:             DB %10000000,%01000000,%00100000,%00010000,%00001000,%00000100,%00000010,%00000001
Unplot_Point:           DB %01111111,%10111111,%11011111,%11101111,%11110111,%11111011,%11111101,%11111110
 
Plot_Line_LHS:          DB %11111111,%01111111,%00111111,%00011111,%00001111,%00000111,%00000011,%00000001
Plot_Line_RHS:          DB %10000000,%11000000,%11100000,%11110000,%11111000,%11111100,%11111110,%11111111
User avatar
MonkZy
Manic Miner
Posts: 279
Joined: Thu Feb 08, 2018 1:01 pm

Re: ld bc,(hl)

Post by MonkZy »

@777 I have just realised you are working from some code I wrote on an old thread, complete with my cryptic annotations :oops: , at least I had credited Steve Wetherill in the notes. :D

That code was pretty botched and messy. I used floating bus to see if I could do the cube draw in one frame. I could not.

@roganjosh is correct that you need to set a block of 3 attributes with a specific colour to trigger the jp nz and exit the loop. Use halt and optimise later.

@bobs is correct that the lookup table must be positioned so the the address low byte does not exceed 255.
User avatar
777
Manic Miner
Posts: 512
Joined: Fri Jun 26, 2020 11:23 am
Location: sw uk

Re: ld bc,(hl)

Post by 777 »

thank you all, its getting better. i did think that there was another problem with this code and not just that ld instruction problem. it there a way of positioning the box without altering all the data frames? if i can move it into the middle of the screen, this may stop the glitches, as from experience this routine doesnt like too be to far across the screen in the x position
i started programming the spectrum when i was 8 :-

1 plot rnd*255,rnd*175
2 goto 1
User avatar
777
Manic Miner
Posts: 512
Joined: Fri Jun 26, 2020 11:23 am
Location: sw uk

Re: ld bc,(hl)

Post by 777 »

i managed to get it to work while trying something else. i wanted to move it in the x position. it stays in the same place but gets rid of the glitches. odd. still dont know how to move it to another part of the screen, though. i also tried it with sub but sbc seem less flickery. heres what i added

Code: Select all

ld a,100
sbc a,c	

Code: Select all

	org 50000
Endless_Loop:
		ld hl,Edge_Data
		ld b,18
Frame_Loop:
		push bc				; preserve B for loop
	
		ld b,12
		push hl
Edge_Loop:
		push bc				; preserve B for loop
		ld c,(hl)
ld a,100
sbc a,c			; B = ypos1 C = xpos1
		inc hl
		ld b,(hl)
		inc hl
		ld e,(hl)	
ld a,100
sbc a,e		; D = ypos2 E = xpos2
		inc hl
		ld d,(hl)	
		inc hl
		push hl				; preserve edge pointer
		call Draw_Line
		pop hl
  		pop bc
		djnz Edge_Loop
		
		ld bc,$40ff			; Steve Wetherill floating bus frame sync from Sidewize
		ld e,%00111010			; red ink on white paper
sync:	
		;ld a,r				; padding instruction
		;in a,(c)
		;cp e
		;jp nz,sync
		
		halt

		
		ld b,12
		pop hl
Erase_Loop:
		push bc				; preserve B for loop
		ld c,(hl)

ld a,100
sbc a,c			; B = ypos1 C = xpos1
		inc hl
		ld b,(hl)
		inc hl
		ld e,(hl)	

ld a,100
sbc a,e		; D = ypos2 E = xpos2
		inc hl
		ld d,(hl)
		inc hl
		push hl				; preserve edge pointer
		call Erase_Line
		pop hl
  		pop bc
		djnz Erase_Loop

		
		pop bc
		djnz Frame_Loop
		jp Endless_Loop
		ret	




; Plot routine
; B = Y pixel position
; C = X pixel position
;
Plot:                   CALL Get_Pixel_Address          ; Get screen address in HL, pixel position (0 to 7) in A
                        LD BC,Plot_Point                ; Address of point lookup table
                        ADD A,C                         ; Add pixel position to get entry in table
                        LD C,A
                        LD A,(BC)                       ; Get pixel data from table
                        OR (HL)                         ; OR with screen data
                        LD (HL),A                       ; Write back to screen
                        RET
 
 
; Unplot routine
; B = Y pixel position
; C = X pixel position
;
Unplot:                 CALL Get_Pixel_Address          ; Same as Plot...
                        LD BC,Unplot_Point
                        ADD A,C
                        LD C,A
                        LD A,(BC)
                        AND (HL)                        ; AND with screen data
                        LD (HL),A
                        RET


; Draw Line routine
; B = Y pixel position 1
; C = X pixel position 1
; D = Y pixel position 2
; E = X pixel position 2
;
Draw_Line:              LD A,D                          ; Check whether we are going to be drawing up
                        CP B
                        JR NC,Draw_Line_1
 
                        PUSH BC                         ; If we are, then this neat trick swaps BC and DE
                        PUSH DE                         ; using the stack, forcing the line to be always
                        POP BC                          ; drawn downwards
                        POP DE
 
Draw_Line_1:            CALL Get_Pixel_Address          ; Get screen address in HL, pixel position (0-7) in A
;
; At this point we have
;  A = Pixel position (0-7)
; HL = Screen address of the start point
; BC = Start coordinate (B=Y1, C=X1)
; DE = End coordinates  (D=Y2, E=X2)
;
                        LD IX,Plot_Point                ; Point to the Plot_Point table
                        ADD A,IXL                       ; Add the pixel position to get entry in table
                        LD IXL,A
 
                        LD A,D                          ; Calculate the line height in B (Y2-Y1)
                        SUB B
                        LD B,A
         
                        LD A,E                          ; Calculate the line width in C (X2-X1)
                        SUB C
                        JR C,Draw_Line_X1               ; If carry set (negative result) then we are drawing from right to left
;
; This bit of code mods the main loop for drawing left to right
;
                        LD C,A                          ; Store the line width
                        LD A,0x2C                       ; Code for INC L
                        LD (Draw_Line_Q1_M3),A          ; Mod the code
                        LD (Draw_Line_Q2_M3),A
                        LD A,0x0A                       ; Code for RRC D (CB 0A)
                        JR Draw_Line_X2                 ; Skip the next bit
;
; This bit of code mods the main loop for drawing right to left
;
Draw_Line_X1:           NEG                             ; The width of line is negative, so make it positive again
                        LD C,A                          ; Store the line width
                        LD A,0x2D                       ; Code for DEC L
                        LD (Draw_Line_Q1_M3),A
                        LD (Draw_Line_Q2_M3),A
                        LD A,0x02                       ; Code for RLC D (CB 02)
;
; We've got the basic information at this point
;
Draw_Line_X2:           LD (Draw_Line_Q1_M2 + 1),A      ; A contains the code for RLC D or RRC D, so make the mods
                        LD (Draw_Line_Q2_M2 + 1),A
                        LD D,(IX+0)                     ; Get the pixel data from the Point_Plot table
                        LD A,B                          ; Check if B and C are 0
                        OR C
                        JR NZ,Draw_Line_Q               ; There is a line to draw, so skip to the next bit
                        LD A,(HL)                       ; Here we've got a single point line, so plot and return
                        OR D
                        LD (HL),A
                        RET
;
; At this point
; HL = Screen address of the start point
;  B = Line height
;  C = Line width
;  D = Pixel data
;
Draw_Line_Q:            LD A,B                          ; Work out which diagonal we are on
                        CP C
                        JR NC,Draw_Line_Q2
;
; This bit of code draws the line where B<C (more horizontal than vertical)
;
Draw_Line_Q1:           LD A,C
                        LD (Draw_Line_Q1_M1 + 1),A      ; Self-mod the code again to store the line width
                        LD C,B
                        LD B,A
                        LD E,C                          ; Calculate the error value
                        SRL E
Draw_Line_Q1_L:         LD A,(HL)                       ; Plot the pixel
                        OR D
                        LD (HL),A
                        LD A,E
                        SUB C
                        LD E,A
                        JR NC,Draw_Line_Q1_M2
Draw_Line_Q1_M1:        ADD A,0                         ; Add the line height (previously stored; self modifying code)
                        LD E,A
                        CALL Pixel_Address_Down
Draw_Line_Q1_M2:        RRC D                           ; Rotate the pixel right or left; more self-modifying code
                        JR NC,Draw_Line_Q1_S
Draw_Line_Q1_M3:        INC L                           ; If we get a carry then move to adjacent screen address; more self modifying code
Draw_Line_Q1_S:         DJNZ Draw_Line_Q1_L             ; Loop until the line is drawn
                        RET
;
; This bit draws the line where B>=C (more vertical than horizontal, or diagonal)
;
Draw_Line_Q2:           LD (Draw_Line_Q2_M1 + 1),A
                        LD E,C                          ; Calculate the error value
                        SRL E
Draw_Line_Q2_L:         LD A,(HL)                       ; Plot the pixel
                        OR D
                        LD (HL),A
                        LD A,E                          ; Get the error value
                        SUB C                           ; Add the line length to it (X2-X1)
                        JR NC,Draw_Line_Q2_S            ; Skip the next bit if we don't get a carry
Draw_Line_Q2_M1:        ADD A,0                         ; Add the line height (previously stored; self modifying code)
Draw_Line_Q2_M2:        RRC D                           ; Rotates the pixel right with carry
                        JR NC,Draw_Line_Q2_S
Draw_Line_Q2_M3:        INC L                           ; If we get a carry then move to adjacent screen address; more self modifying code
Draw_Line_Q2_S:         LD E,A                          ; Store the error value back in
                        CALL Pixel_Address_Down         ; And also move down
                        DJNZ Draw_Line_Q2_L
                        RET
 
; Erase Line routine
; B = Y pixel position 1
; C = X pixel position 1
; D = Y pixel position 2
; E = X pixel position 2
;
Erase_Line:             LD A,D                          ; Check whether we are going to be drawing up
                        CP B
                        JR NC,Erase_Line_1
 
                        PUSH BC                         ; If we are, then this neat trick swaps BC and DE
                        PUSH DE                         ; using the stack, forcing the line to be always
                        POP BC                          ; drawn downwards
                        POP DE
 
Erase_Line_1:           CALL Get_Pixel_Address          ; Get screen address in HL, pixel position (0-7) in A
;
; At this point we have
;  A = Pixel position (0-7)
; HL = Screen address of the start point
; BC = Start coordinate (B=Y1, C=X1)
; DE = End coordinates  (D=Y2, E=X2)
;
                        LD IX,Unplot_Point              ; Point to the Unplot_Point table
                        ADD A,IXL                       ; Add the pixel position to get entry in table
                        LD IXL,A
 
                        LD A,D                          ; Calculate the line height in B (Y2-Y1)
                        SUB B
                        LD B,A
         
                        LD A,E                          ; Calculate the line width in C (X2-X1)
                        SUB C
                        JR C,Erase_Line_X1              ; If carry set (negative result) then we are drawing from right to left
;
; This bit of code mods the main loop for drawing left to right
;
                        LD C,A                          ; Store the line width
                        LD A,0x2C                       ; Code for INC L
                        LD (Erase_Line_Q1_M3),A         ; Mod the code
                        LD (Erase_Line_Q2_M3),A
                        LD A,0x0A                       ; Code for RRC D (CB 0A)
                        JR Erase_Line_X2                ; Skip the next bit
;
; This bit of code mods the main loop for drawing right to left
;
Erase_Line_X1:          NEG                             ; The width of line is negative, so make it positive again
                        LD C,A                          ; Store the line width
                        LD A,0x2D                       ; Code for DEC L
                        LD (Erase_Line_Q1_M3),A
                        LD (Erase_Line_Q2_M3),A
                        LD A,0x02                       ; Code for RLC D (CB 02)
;
; We've got the basic information at this point
;
Erase_Line_X2:          LD (Erase_Line_Q1_M2 + 1),A     ; A contains the code for RLC D or RRC D, so make the mods
                        LD (Erase_Line_Q2_M2 + 1),A
                        LD D,(IX+0)                     ; Get the pixel data from the Unplot_Point table
                        LD A,B                          ; Check if B and C are 0
                        OR C
                        JR NZ,Erase_Line_Q              ; There is a line to draw, so skip to the next bit
                        LD A,(HL)                       ; Here we've got a single point line, so plot and return
                        AND D
                        LD (HL),A
                        RET
;
; At this point
; HL = Screen address of the start point
;  B = Line height
;  C = Line width
;  D = Pixel data
;
Erase_Line_Q:           LD A,B                          ; Work out which diagonal we are on
                        CP C
                        JR NC,Erase_Line_Q2
;
; This bit of code draws the line where B<C (more horizontal than vertical)
;
Erase_Line_Q1:          LD A,C
                        LD (Erase_Line_Q1_M1 + 1),A     ; Self-mod the code again to store the line width
                        LD C,B
                        LD B,A
                        LD E,C                          ; Calculate the error value
                        SRL E
Erase_Line_Q1_L:        LD A,(HL)                       ; Unplot the pixel
                        AND D
                        LD (HL),A
                        LD A,E
                        SUB C
                        LD E,A
                        JR NC,Erase_Line_Q1_M2
Erase_Line_Q1_M1:       ADD A,0                         ; Add the line height (previously stored; self modifying code)
                        LD E,A
                        CALL Pixel_Address_Down
Erase_Line_Q1_M2:       RRC D                           ; Rotate the pixel right or left; more self-modifying code
                        JR C,Erase_Line_Q1_S            ; Note the change here from the Draw_Line routine
Erase_Line_Q1_M3:       INC L                           ; If we get no carry then move to adjacent screen address; more self modifying code
Erase_Line_Q1_S:        DJNZ Erase_Line_Q1_L            ; Loop until the line is drawn
                        RET
;
; This bit draws the line where B>=C (more vertical than horizontal, or diagonal)
;
Erase_Line_Q2:          LD (Erase_Line_Q2_M1 + 1),A
                        LD E,C                          ; Calculate the error value
                        SRL E
Erase_Line_Q2_L:        LD A,(HL)                       ; Unplot the pixel
                        AND D
                        LD (HL),A
                        LD A,E                          ; Get the error value
                        SUB C                           ; Add the line length to it (X2-X1)
                        JR NC,Erase_Line_Q2_S           ; Skip the next bit if we don't get a carry
Erase_Line_Q2_M1:       ADD A,0                         ; Add the line height (previously stored; self modifying code)
Erase_Line_Q2_M2:       RRC D                           ; Rotates the pixel right with carry
                        JR C,Erase_Line_Q2_S            ; Note the change here from the Draw_Line routine
Erase_Line_Q2_M3:       INC L                           ; If we get no carry then move to adjacent screen address; more self modifying code
Erase_Line_Q2_S:        LD E,A                          ; Store the error value back in
                        CALL Pixel_Address_Down         ; And also move down
                        DJNZ Erase_Line_Q2_L
                        RET

;; GET BUFFER PIXEL ADDRESS
;; B=y-pos C=x-pos 
;; Returns: HL=Adress of pixel A=Byte of the pixel

Get_Buffer_Address:

	ld l,0        ;
	ld h,b        ; B contains the Y-POS
	srl h         ;
	rr l          ;
	srl h         ;
	rr l          ; Shifts right 3x, then OR's low byte with 11100000 
	srl h         ;
	rr l          ; divide by 8?
	ld a,h        ;
	or 224        ; 11100000
	ld h,a        ;

 	ld a,c        ; C contains the X-POS
 	rra           ;
 	rra           ; divide by 8
 	rra           ;
 	and 31        ; 00011111 - strip out rolled in carry bytes
 	or l          ;
 	ld l,a        ;
 	ld a,c        ;
 	and 7         ; 00000111
 	ret           ;


; Get screen address
; B = Y pixel position
; C = X pixel position
; Returns address in HL and pixel position within character in A
;
Get_Pixel_Address:      LD A,B                          ; Calculate Y2,Y1,Y0
                        AND %00000111                   ; Mask out unwanted bits
                        OR %01000000                    ; Set base address of screen
                        LD H,A                          ; Store in H
                        LD A,B                          ; Calculate Y7,Y6
                        RRA                             ; Shift to position
                        RRA
                        RRA
                        AND %00011000                   ; Mask out unwanted bits
                        OR H                            ; OR with Y2,Y1,Y0
                        LD H,A                          ; Store in H
                        LD A,B                          ; Calculate Y5,Y4,Y3
                        RLA                             ; Shift to position
                        RLA
                        AND %11100000                   ; Mask out unwanted bits
                        LD L,A                          ; Store in L
                        LD A,C                          ; Calculate X4,X3,X2,X1,X0
                        RRA                             ; Shift into position
                        RRA
                        RRA
                        AND %00011111                   ; Mask out unwanted bits
                        OR L                            ; OR with Y5,Y4,Y3
                        LD L,A                          ; Store in L
                        LD A,C
                        AND 7
                        RET

; Move HL down one pixel line
;
Pixel_Address_Down:     INC H                           ; Go down onto the next pixel line
                        LD A,H                          ; Check if we have gone onto next character boundary
                        AND 7
                        RET NZ                          ; No, so skip the next bit
                        LD A,L                          ; Go onto the next character line
                        ADD A,32
                        LD L,A
                        RET C                           ; Check if we have gone onto next third of screen
                        LD A,H                          ; Yes, so go onto next third
                        SUB 8
                        LD H,A
                        RET
 
; Note that the functions above only work if each of these tables are in a byte boundary
;
Plot_Point:             DB %10000000,%01000000,%00100000,%00010000,%00001000,%00000100,%00000010,%00000001
Unplot_Point:           DB %01111111,%10111111,%11011111,%11101111,%11110111,%11111011,%11111101,%11111110
 
Plot_Line_LHS:          DB %11111111,%01111111,%00111111,%00011111,%00001111,%00000111,%00000011,%00000001
Plot_Line_RHS:          DB %10000000,%11000000,%11100000,%11110000,%11111000,%11111100,%11111110,%11111111

Edge_Data:

;;;EDGE DATA


;;;FRAME #1 0 degrees
     defb 164,7,231,7
     defb 231,7,231,74
     defb 231,74,164,74
     defb 164,74,164,7
     defb 218,21,178,21
     defb 178,21,178,61
     defb 178,61,218,61
     defb 218,61,218,21
     defb 164,7,178,21
     defb 231,7,218,21
     defb 231,74,218,61
     defb 164,74,178,61

;;;FRAME #2 5 degrees
     defb 162,8,229,6
     defb 229,6,229,75
     defb 229,75,162,73
     defb 162,73,162,8
     defb 220,20,180,21
     defb 180,21,180,60
     defb 180,60,220,61
     defb 220,61,220,20
     defb 162,8,180,21
     defb 229,6,220,20
     defb 229,75,220,61
     defb 162,73,180,60

;;;FRAME #3 10 degrees
     defb 161,9,226,5
     defb 226,5,226,76
     defb 226,76,161,72
     defb 161,72,161,9
     defb 222,20,182,21
     defb 182,21,182,60
     defb 182,60,222,61
     defb 222,61,222,20
     defb 161,9,182,21
     defb 226,5,222,20
     defb 226,76,222,61
     defb 161,72,182,60

;;;FRAME #4 15 degrees
     defb 160,10,223,4
     defb 223,4,223,77
     defb 223,77,160,71
     defb 160,71,160,10
     defb 224,19,184,21
     defb 184,21,184,60
     defb 184,60,224,62
     defb 224,62,224,19
     defb 160,10,184,21
     defb 223,4,224,19
     defb 223,77,224,62
     defb 160,71,184,60

;;;FRAME #5 20 degrees
     defb 160,11,219,4
     defb 219,4,219,77
     defb 219,77,160,70
     defb 160,70,160,11
     defb 225,19,186,22
     defb 186,22,186,59
     defb 186,59,225,62
     defb 225,62,225,19
     defb 160,11,186,22
     defb 219,4,225,19
     defb 219,77,225,62
     defb 160,70,186,59

;;;FRAME #6 25 degrees
     defb 160,12,216,3
     defb 216,3,216,78
     defb 216,78,160,69
     defb 160,69,160,12
     defb 227,18,188,22
     defb 188,22,188,59
     defb 188,59,227,63
     defb 227,63,227,18
     defb 160,12,188,22
     defb 216,3,227,18
     defb 216,78,227,63
     defb 160,69,188,59

;;;FRAME #7 30 degrees
     defb 160,13,211,3
     defb 211,3,211,78
     defb 211,78,160,68
     defb 160,68,160,13
     defb 229,18,191,22
     defb 191,22,191,59
     defb 191,59,229,63
     defb 229,63,229,18
     defb 160,13,191,22
     defb 211,3,229,18
     defb 211,78,229,63
     defb 160,68,191,59

;;;FRAME #8 35 degrees
     defb 160,14,207,2
     defb 207,2,207,79
     defb 207,79,160,67
     defb 160,67,160,14
     defb 230,17,193,22
     defb 193,22,193,59
     defb 193,59,230,64
     defb 230,64,230,17
     defb 160,14,193,22
     defb 207,2,230,17
     defb 207,79,230,64
     defb 160,67,193,59

;;;FRAME #9 40 degrees
     defb 161,15,202,2
     defb 202,2,202,79
     defb 202,79,161,66
     defb 161,66,161,15
     defb 232,16,195,22
     defb 195,22,195,59
     defb 195,59,232,65
     defb 232,65,232,16
     defb 161,15,195,22
     defb 202,2,232,16
     defb 202,79,232,65
     defb 161,66,195,59

;;;FRAME #10 45 degrees
     defb 162,16,198,2
     defb 198,2,198,79
     defb 198,79,162,66
     defb 162,66,162,16
     defb 233,16,198,22
     defb 198,22,198,59
     defb 198,59,233,66
     defb 233,66,233,16
     defb 162,16,198,22
     defb 198,2,233,16
     defb 198,79,233,66
     defb 162,66,198,59

;;;FRAME #11 50 degrees
     defb 163,16,193,2
     defb 193,2,193,79
     defb 193,79,163,65
     defb 163,65,163,16
     defb 234,15,200,22
     defb 200,22,200,59
     defb 200,59,234,66
     defb 234,66,234,15
     defb 163,16,200,22
     defb 193,2,234,15
     defb 193,79,234,66
     defb 163,65,200,59

;;;FRAME #12 55 degrees
     defb 165,17,188,2
     defb 188,2,188,79
     defb 188,79,165,64
     defb 165,64,165,17
     defb 235,14,202,22
     defb 202,22,202,59
     defb 202,59,235,67
     defb 235,67,235,14
     defb 165,17,202,22
     defb 188,2,235,14
     defb 188,79,235,67
     defb 165,64,202,59

;;;FRAME #13 60 degrees
     defb 166,18,184,3
     defb 184,3,184,78
     defb 184,78,166,63
     defb 166,63,166,18
     defb 235,13,204,22
     defb 204,22,204,59
     defb 204,59,235,68
     defb 235,68,235,13
     defb 166,18,204,22
     defb 184,3,235,13
     defb 184,78,235,68
     defb 166,63,204,59

;;;FRAME #14 65 degrees
     defb 168,18,179,3
     defb 179,3,179,78
     defb 179,78,168,63
     defb 168,63,168,18
     defb 235,12,207,22
     defb 207,22,207,59
     defb 207,59,235,69
     defb 235,69,235,12
     defb 168,18,207,22
     defb 179,3,235,12
     defb 179,78,235,69
     defb 168,63,207,59

;;;FRAME #15 70 degrees
     defb 170,19,176,4
     defb 176,4,176,77
     defb 176,77,170,62
     defb 170,62,170,19
     defb 235,11,209,22
     defb 209,22,209,59
     defb 209,59,235,70
     defb 235,70,235,11
     defb 170,19,209,22
     defb 176,4,235,11
     defb 176,77,235,70
     defb 170,62,209,59

;;;FRAME #16 75 degrees
     defb 171,19,172,4
     defb 172,4,172,77
     defb 172,77,171,62
     defb 171,62,171,19
     defb 235,10,211,21
     defb 211,21,211,60
     defb 211,60,235,71
     defb 235,71,235,10
     defb 171,19,211,21
     defb 172,4,235,10
     defb 172,77,235,71
     defb 171,62,211,60

;;;FRAME #17 80 degrees
     defb 173,20,169,5
     defb 169,5,169,76
     defb 169,76,173,61
     defb 173,61,173,20
     defb 234,9,213,21
     defb 213,21,213,60
     defb 213,60,234,72
     defb 234,72,234,9
     defb 173,20,213,21
     defb 169,5,234,9
     defb 169,76,234,72
     defb 173,61,213,60

;;;FRAME #18 85 degrees
     defb 175,20,166,6
     defb 166,6,166,75
     defb 166,75,175,61
     defb 175,61,175,20
     defb 233,8,215,21
     defb 215,21,215,60
     defb 215,60,233,73
     defb 233,73,233,8
     defb 175,20,215,21
     defb 166,6,233,8
     defb 166,75,233,73
     defb 175,61,215,60

;;;Bytes = 648
i started programming the spectrum when i was 8 :-

1 plot rnd*255,rnd*175
2 goto 1
User avatar
bobs
Microbot
Posts: 107
Joined: Thu Dec 28, 2017 8:26 am
Location: UK
Contact:

Re: ld bc,(hl)

Post by bobs »

@777 You need to put the results of your new calculations back into the original registers, as currently they are left in A and are ignored.

Code: Select all

LD A, 100
SUB C
LD C, A
That’s going to mirror the position about 100 though, is that what you want? Offsetting it might be better?

Code: Select all

LD A, 50
ADD A, C
LD C, A
It also looks from your code that you still need to ensure that those lookup tables are aligned correctly to remove the glitches.
Post Reply