But I don't really understand what's wrong with my addition. It relies on the principle that a/255 + b/255 = (a+b)/255, so just using 'add' to add the numbers as 16bit integers should work, or am I totally wrong with this?
And the Multiplication: (a/255)*(b/255) = a*b, so shifting 8 bits left should give (a*b)/255, so calculating the 32bit result and using bit 8-24 should provide the result, or is this wrong again? Maybe i just don't understand fixed-point numbers correctelly
What I said earlier is not becouse I don't believe you, I just want to know why it won't work, so that i can avoid it in my other programs.
EDIT: and for the signed part: for the multiplication and division, the sign of the result should be the XOR result of the sign of the 2 arguments, right?
Isn't there anybody who can help me with fixed-point math? I can't find anything useful on google, but I think that almost every advanced asm programmer has used fixed-point math.
Or is everybody just to busy with the axe programming competition so that nobady has time to help other people?
Hi, I am trying to port a simple 3D engine from GML to z80, but I can't get it to work I think my fixed-point math routines aren't doing what they are supposed to do. Can enybody please help with that?
This is what it should do: (speed so low becouse of the recording software. The engine itself renders very efficiently)
And what i got is just an emty screen, while the camera is 5 units away, facing the target, and everything between 1 and 256 units should be visible.
The math currently being unsigned might be one problem, but i couldn't find any 16bit signed fixed-point routines with google.
Spoiler For assembly InitView routine:
InitView: ;call once every frame, before 3DTo2D ;IN: The engine's vars ;OUT: vars are initialised ;DESTROYS: a, bc, de, hl ld bc, (xto) ld de, (xfrom) call SubFP ld (xto), de ld bc, (yto) ld de, (yfrom) call SubFP ld (yto), de ld bc, (zto) ld de, (zfrom) call SubFP ld (zto), de ld bc, (xto) call MulFP push de ;1 ld bc, (yto) call MulFP ld h, d \ ld l, e pop bc ;0 add hl, bc push hl ;1 ld bc, (zto) call MulFP ld h, d \ ld l, e pop de ;0 add hl, de call sqrtFP ld d, h \ ld e, l ld hl, (xto) push de ;1 call DivFP pop de ;0 ld (xto), hl push de ;1 ld hl, (yto) call DivFP pop de ;0 ld (yto), hl ld hl, (zto) call DivFP ld (zto), hl ld bc, (xto) ld hl, (xup) call MulFP push de ;1 ld bc, (yto) ld hl, (yup) call MulFP ld h, d \ ld l, e pop bc ;0 push bc ;1 add hl, bc pop hl ;0 push hl ;1 ld bc, (zto) ld hl, (zup) call MulFP pop hl ;0 add hl, de ld bc, (xto) push hl ;1 call MulFP ld bc, (xup) call SubFP ld (xup), de ld bc, (yto) pop hl ;0 push hl ;1 call MulFP ld bc, (yup) call SubFP ld (yup), de ld bc, (zto) pop hl ;0 call MulFP ld bc, (zup) call SubFP ld (zup), de ld a, (angle) ld b, 40 add a, b call SinA push hl ;1 ld a, (angle) call SinA pop de ;0 call DivFP push hl ;1 ld hl, (xup) ld b, h \ ld c, l call MulFP push de ;2 ld hl, (yup) ld b, h \ ld c, l call MulFP pop hl ;1 add hl, de push hl ;2 ld hl, (zup) ld b, h \ ld c, l call MulFP pop hl ;1 add hl, de call SqrtFP pop bc ;0 call MulFP push de ;1 ld hl, (xup) call divFP ld (xup), hl pop de ;0 push de ;1 ld hl, (yup) call DivFP ld (yup), hl pop de ;0 ld hl, (zup) call DivFP ld (zup), hl ld hl, (yup) ld bc, (zto) call MulFP push de ;1 ld hl, (zup) ld bc, (yto) call MulFP pop hl ;0 call SubFP ld (xcross), de ld hl, (zup) ld bc, (xto) call MulFP push de ;1 ld hl, (xup) ld bc, (zto) call MulFP pop hl ;0 call SubFP ld (ycross), de ld hl, (xup) ld bc, (yto) call MulFP push de ;1 ld hl, (yup) ld bc, (xto) call MulFP pop hl ;0 call SubFP ld (zcross), de ret
Spoiler For assembly 3DTo2D routine:
3DTo2D: ;IN: xpoint, ypoint and zpoint vars ;OUT: screenx and screeny are set to the onscreen coordinates for the point ;Will not work if InitView wasn't called before this routine ;DESTROYS: a, bc, de, hl ld a, 0 ld (valid), a ld bc, (xpoint) ld de, (xfrom) call SubFP ld (xpoint), de ld bc, (ypoint) ld de, (yfrom) call SubFP ld (ypoint), de ld bc, (zpoint) ld de, (zfrom) call SubFP ld (zpoint), de ld hl, (xpoint) ld bc, (xto) call MulFP push de ;1 ld hl, (ypoint) ld bc, (yto) call MulFP pop hl ;0 add hl, de push hl ;1 ld hl, (zpoint) ld bc, (zto) call MulFP pop hl ;0 add hl, de push hl ;1 ld a, l ld c, a ld a, (min_range) ld b, a ld a, c cp b jp c, Invalid ld c, a ld a, (max_range) ld b, a ld a, c cp b jp nc, Invalid ld a, 1 ld (valid), a ld hl, (xpoint) ld bc, (xcross) call MulFP push de ;2 ld hl, (ypoint) ld bc, (ycross) call MulFP pop hl ;1 add hl, de push hl ;2 ld hl, (zpoint) ld bc, (zcross) call MulFP pop hl ;1 add hl, de pop de ;0 push de ;1 call DivFP ld (screenx), hl ld hl, (xpoint) ld bc, (xup) call MulFP push de ;2 LD HL, (ypoint) ld bc, (yup) call MulFP pop hl ;1 add hl, de push hl ;2 ld hl, (zpoint) ld bc, (zup) call MulFP pop hl ;1 add hl, bc pop de ;0 call DivFP ld (screeny), hl ld hl, $0100 ld de, (screenx) add hl, de ld bc, $5F00 call MulFP ld (screenx), de ld hl, $0100 ld de, (screeny) add hl, de ld bc, $4100 call MulFP ld (screeny), de ret Invalid: pop bc ret
Spoiler For assembly math routines:
Mul8b: ;Multiplies 2 8bit numbers ;IN: h and e ;OUT: h * e in hl ;DESTROYS: hl, b, d ld d, 0 ld l, d ld b, 8 _Mul_8b_loop: add hl, hl jr nc, _Mul_8b_skip add hl, de _Mul_8b_skip: djnz _Mul_8b_loop ret
SqrtA: LD (Asqr),A SRL A JR DataOver Asqr: .DB 0 Bsqr: .DB 0 Csqr: .DB 0 DataOver: LD (Bsqr),A LD B,A LD (Csqr),A iterate: LD A,(Bsqr) ld b, a LD a,(Asqr) LD D,A LD E,B divideDbyEreturnA: RL D RLA SUB E JR nc,$+3 ADD A,E LD E,A LD A,D CPL push af ;1 LD a,(Bsqr) ld b, a pop af ;0 ADD A,B SRL A LD (Bsqr),A LD a,(Bsqr) ld b, a LD A,(Csqr) DEC A CP B JR z,done push af ;1 LD (Csqr),a ld b, a pop af ;0 JR iterate done: LD A,(Bsqr) RET
Div16By8: ;divides a 16-bit number by an 8-bit number ;IN: hl and d ;OUT: hl = hl/d, remainder = a ;DESTROYS: a, b, c, d, hl xor a ld b, 16 _D16b8Loop: add hl, hl rla jr c, _D16b8Overflow cp d jr c, _D16b8Skip _D16b8Overflow: sub b inc l _D16b8Skip: djnz _D16b8Loop ret
SubFP: ;substracts 2 16-bit fixed-point numbers ;IN: bc, de ;OUT: bc - de in de ;DESTROYS: a, de ld a, b sub d ld d, a ld a, c sub e ld a, e ret
MulFP: ;Multiplies 2 16bit fixed-point numbers ;IN: hl, bc ;OUT: hl * bc in de ;DESTROYS: hl, bc, de ld e, b push hl ;1 push bc ;2 call Mul8b pop bc ;1 pop hl ;0 push de ;1 ld h, l ld e, c call Mul8b pop hl ;0 ld e, d ld d, l ret
;adding fixed-point numbers: ;load one of the numbers in hl, and the other in an other 16-bit register. ;then, do: add hl, <register>
DivFP: ;IN: hl, de ;OUT: hl = hl / de ld a, h ld h, l ld l, 0 call Div24by16 ret
Div24by16: push hl ;INPUTS: ahl = dividend de = divisor ;1 pop ix ;OUTPUTS: ahl = quotient de = divisor ;0 ld hl,0 ld b,24 _Div24by16loop: add ix,ix rla adc hl,hl jr c,_Div24by16setbit or a sbc hl,de add hl,de jr c,_Div24by16skip _Div24by16setbit: or a sbc hl,de inc ix _Div24by16skip: djnz _Div24by16loop push ix ;1 pop hl ;0 ret
SinA: ;calculates the sine of a as a fixed point number ;IN: a ;OUT: hl = sin(a) LD H, 0 LD L, A LD DE, sine_table ADD HL, DE LD A, (HL) INC HL LD H, (HL) LD L, A RET sine_table: .DW $0000, $0004, $0009, $000D, $0012, $0016, $001B, $001F, $0024 .DW $0028, $002C, $0031, $0035, $003A, $003E, $0042, $0047, $004B .DW $004F, $0053, $0058, $005C, $0060, $0064, $0068, $006C, $0070 .DW $0074, $0078, $007C, $0080, $0084, $0088, $008B, $008F, $0093 .DW $0096, $009A, $009E, $00A1, $00A5, $00A8, $00AB, $00AF, $00B2 .DW $00B5, $00B8, $00BB, $00BE, $00C1, $00C4, $00C7, $00CA, $00CC .DW $00CF, $00D2, $00D4, $00D7, $00D9, $00DB, $00DE, $00E0, $00E2 .DW $00E4, $00E6, $00E8, $00EA, $00EC, $00ED, $00EF, $00F1, $00F2 .DW $00F3, $00F5, $00F6, $00F7, $00F8, $00F9, $00FA, $00FB, $00FC .DW $00FD, $00FE, $00FE, $00FF, $00FF, $00FF, $0100, $0100, $0100
SqrtFP: ;IN: hl ;OUT: hl = sqrt(hl) ld a, h call SqrtA ld h, a ld a, l call SqrtA ld l, a ret
Has enybody got some routines for this on their hard drive (you will get credits for it) or can enybody gelp me with writing my own?
BTW: I added the exe for if enybody wants to try the engine itself (sorry for the ones withouth windows, but GM can only compile exe's)
EDIT: I forgot to say the controls: use z, q, s and d to walk and turn
Feature request: step by step debugging (like ti flash debugger)
This is looking great (and the screenshot looks much like pindurTI, btw)
EDIT: when i posted this, i first got a database error saying it wasn't posted succesfully, then an error saying i've already submited this post. Strange...
The only way I got TI-connect back to work, was by borrowing a calc from my friend, backup all programs, reset the full memory, and downgrading to 2.40, and TI-connect worked again
I've tryed that for abouth 30 times now. I know TI-connect
EDIT: I can't even downgrade: When I try to send an other OS, My calc says that there was an error, and I should press any key to turn it of. DOES THAT MEAN I CAN'T DOWNLOAD ANYTHING ON MY CALC ANYMORE?
yea, but not like this. to me, this always happens: TI-connect can't find the divice OR: ti-divice detected, but couldn't get status But now, it connects as it should, and when I send something to it, it starts the transfer, interrupts the transfer and says 'ti-device detected, but couldn't get status'. I never had this with my previous OS
EDIT: now it says 'transfer failed, a retry may be succesfull', but a retry isn't sucessfull, nor a 10th retry...