It is currently Wed Nov 22, 2017 5:20 pm

All times are UTC - 7 hours



Forum rules


Related:



Post new topic Reply to topic  [ 49 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
 Post subject: Re: C/++ for the SNES
PostPosted: Sun Nov 16, 2014 2:39 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7272
Location: Chexbres, VD, Switzerland
Quote:
The problem with pure ASM is that no matter how much you comment it, if you leave and come back a few months later, the code will be almost unreadable. Much like commentless Perl, and very much not like well-written C++.

I must say I disagree with this one. Assembly has a lot of problems (if it didn't, high level language would never have been invented !), however, I don't think it is unreadable at all. Of course if you do comments like that :
Code:
ldx #$02  ; Load $02 into x

Then yes it's going to be totally unreadable. However if you have high level comments and never comment anything low level because it's obvious by looking at the code, then it'll be perfectly understandable.

As for people who says assembly is not a problem, again I disagree. It has the following inconvenients :
  • Slow developpement time, you have to write a lot of instructions to do something conceptually simple
  • You have to loose a lot of time deciding which register will hold what, and think again if somehow the program is better by changing this choice at a later time
  • 65xxx requires a lot of Temp variables (usually you'll need at least ~6 of them), and those are a nightmare. It's so easy to have them overwritten in a subroutine call, and this is extremely tedious to debug. I try to always comment which Temp variables I use, but this is not always up to date
  • Very error prone, I have almost never developped a function that worked as expected on the 1st try. This is true with computer science in general, but in assembly it's much more than with high level language
  • Although the CISC design of 6502 makes it relatively easy to write proper code, when you suddently run out of registers because you'd like to have that Z 3rd index registers, things will go really harsh as this means a lot of saving/loading to zeropage temp variables, loosing a lot of developpement time for something that is not conceptually complex
  • Not portable : If you want to port your project to another platform, you are forced into an entiere rewrite. Also it's much easier to convert from one HLL to another HLL than from one assembly to another assembly. Even changing the assembler itself for the same platform (e.g. switching from WLA-DX to CA65) can be almost impossible without a complete rewrite !

This doesnt' mean that assembly is not a good solution, it's just that it has it's inconvenients. As for C.
Quote:
Bigger problems come from C always casting to int when a type is shorter, lack of rotate operations (compilers have to guess when those are usable), etc.

I agree. This casting to int is the #1 problem : In 6502's case that'd force the int size to 8, but it has to be mimumum 16. Therefore for the code :
Code:
char a = whathever();
char b = whathever2();
char c = a+b;

This means the C standard imposes 16 bit add for the 3rd line, even if if could be done in 8-bit. OK in this particular cases it can easily be optimized, but in some cases this won't be the case.

Another problem is the assumption that all variables are on the stack. In theory it's easy to draw a function graph and to eliminate this problem, but the interupts and the existance of function pointers makes this completely impossible. I think SDCC somehow managed to fix this problem, unfortunately this compiler is much too complex for me to understand anything about it's inner working.

The combination of those 2 problems (16-bit default and variable stacking) makes it impossible for ANSI C to be ever efficient for the 65xxx. (pehaps for the 65816 it gets a little better, though). It could be possible for non-ANSI C to work, but then we'd as well invent another language.

Now there is some other HLL solutions worth mentionning :
  • ATALAN programming language - designed specifically for being efficient for 65xx. I have no idea how good it is, but looking like an interesting HLL solution
  • Virtual machines.
    Since with compiled HLLs your execution time is going to be bloated anyways, VMs does that but at least they keep the code size small. So if your execution time will be bloated, at least your ROM size won't, unlike what CC65 produces. You could even have a smaller ROM than what pure assembly would have lead to ! On 6502.org I've heard about
    • Forth (they seem to be very fond of it)
    • PLASMA
    • AcheronVM

I haven't tried any of these so I can't comment how good/bad they are. They look interesting, and should be relatively easy to port for the 65816.


Top
 Profile  
 
 Post subject: Re: C/++ for the SNES
PostPosted: Sun Nov 16, 2014 9:21 am 
Offline

Joined: Wed May 19, 2010 6:12 pm
Posts: 2366
Can't you just use absolute addressing when you run out of dp registers?


Top
 Profile  
 
 Post subject: Re: C/++ for the SNES
PostPosted: Sun Nov 16, 2014 9:28 am 
Offline

Joined: Fri May 13, 2011 7:36 pm
Posts: 143
Kannagi wrote:
The assembler is difficult to understand, because when I read the source code, I see that the variables are little to name it, unwanted little keyword, and the code is compressed and has not Indent style.

Having much more experience with higher level languages, when I program in ASM I tend to use descriptive variable and label names and indent code to show code flow. Helps me cope.

Code:
; Copy 6 blocks of $100 bytes
        ldx #$06
        *
            ; Copy $100 bytes
            ldy #$00
            *
                lda ($00),Y
                sta ($02),Y
                iny
            bne -
           
            ; Advance each pointer by $100
            inc $01
            inc $03
           
            dex
        bne --


Top
 Profile  
 
 Post subject: Re: C/++ for the SNES
PostPosted: Sun Nov 16, 2014 12:20 pm 
Offline

Joined: Wed May 19, 2010 6:12 pm
Posts: 2366
Quote:
You really do have to micro-optimize the living hell out of SNES ASM.


???

You mean to tell me, you don't get the job done by relocating memory, or replacing subroutines with macros?


Top
 Profile  
 
 Post subject: Re: C/++ for the SNES
PostPosted: Sun Nov 16, 2014 1:02 pm 
Offline

Joined: Thu Aug 12, 2010 3:43 am
Posts: 1589
byuu wrote:
Fun exercise for the reader: try and do muls.l #23,d0 (signed multiply) on the 65816.
Try that on the 68000 as well, it lacks that instruction (only the original 16×16→32 multiplication is present in the 68000).

But yeah, it's not like the 68000 doesn't have its fair share of weird things, just look at this (real code):
Code:
    swap    d7                          ; Generate VDP command used to set
    clr.w   d7                            ; the current address
    swap    d7
    add.l   d7, d7
    add.l   d7, d7
    lsr.w   #2, d7
    or.w    #$4000, d7
    swap    d7
Or for a less common but even more unreadable case:
Code:
    moveq   #0, d5                      ; Get left half of row
    move.w  (a6)+, d5
    lsl.l   #4, d5                      ; Expand it from four pixels to eight
    lsr.w   #4, d5                        ; pixels (scale horizontally)
    lsl.l   #8, d5
    lsr.w   #4, d5
    lsr.b   #4, d5
    move.l  d5, d4
    lsl.l   #4, d4
    or.l    d4, d5
    move.l  d5, (a5)+                   ; Store expanded pixels (twice so it
    move.l  d5, (a5)+                     ; scales vertically too)

The trick is to document every single operation (to a higher granurality than you'd do in C, mind you), and document what they're supposed to do. This will help you figure out what the code is doing even if the code is a total mess, since the comment is telling you what it's meant to be.


Top
 Profile  
 
 Post subject: Re: C/++ for the SNES
PostPosted: Mon Nov 17, 2014 6:14 pm 
Offline

Joined: Mon Mar 27, 2006 5:23 pm
Posts: 1339
> sta $211B; xba; sta $211B; lda #$17; sta $211C; lda $2134

Shoot, forgot the PPU MUL was signed. At any rate, you get the idea. The 680x0 has a lot more flexibility and registers available.

> The trick is to document every single operation (to a higher granurality than you'd do in C, mind you), and document what they're supposed to do

I do this, it doesn't help me.

But, okay. A lot of you disagree with me and that's fine. Whatever it is with my brain, coming back to ASM code I haven't touched in months is a disaster. I certainly did not want to abandon a year's worth of work on DKJM, and six month's worth on BL. If you guys can resume ASM work after a long period, then I am very impressed and jealous.


Top
 Profile  
 
 Post subject: Re: C/++ for the SNES
PostPosted: Mon Nov 17, 2014 11:09 pm 
Offline

Joined: Wed May 19, 2010 6:12 pm
Posts: 2366
Something I've been wondering about lately is how do you handle object memory slots on the 68000? With the 65816, all you have to do is move the direct page, and access the memory directly. With the 68000 you'd have to do all kinds of crazy register juggling.


Top
 Profile  
 
 Post subject: Re: C/++ for the SNES
PostPosted: Mon Nov 17, 2014 11:17 pm 
Offline

Joined: Thu Aug 12, 2010 3:43 am
Posts: 1589
You just do relative addressing (e.g. 4(a0) will be the address at register a0 + 4, you can even do stuff like 2(a0,d0.w) which would be the address at a0 + d0 + 2). Also huh, wouldn't the direct page method be wasteful on the SNES? I really doubt you need 256 bytes to store data for an object (and not aligning to a page would negate all benefits), unless I'm misunderstanding something. I know that I can get away with just 16 bytes per object generally, a few more if the game is rather complex but point stands.


Top
 Profile  
 
 Post subject: Re: C/++ for the SNES
PostPosted: Tue Nov 18, 2014 12:34 am 
Offline

Joined: Wed May 19, 2010 6:12 pm
Posts: 2366
Quote:
I know that I can get away with just 16 bytes per object generally.


Really? I'm curious in how you're able to get by with just 16 bytes.


Top
 Profile  
 
 Post subject: Re: C/++ for the SNES
PostPosted: Tue Nov 18, 2014 2:58 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7272
Location: Chexbres, VD, Switzerland
Quote:
Fun exercise for the reader: try and do muls.l #23,d0 (signed multiply) on the 65816.

As long as there is enough bits for the result, signed and unsigned multiply are equivalent.


Top
 Profile  
 
 Post subject: Re: C/++ for the SNES
PostPosted: Tue Nov 18, 2014 4:09 am 
Offline

Joined: Thu Aug 12, 2010 3:43 am
Posts: 1589
psycopathicteen wrote:
Quote:
I know that I can get away with just 16 bytes per object generally.


Really? I'm curious in how you're able to get by with just 16 bytes.

Code:
ObjType:        rs.b 1      ; 1 byte
ObjFlags:       rs.b 1      ; 1 byte
ObjX:           rs.w 1      ; 2 bytes
ObjY:           rs.w 1      ; 2 bytes
ObjSpeedX:      rs.w 1      ; 2 bytes
ObjSpeedY:      rs.w 1      ; 2 bytes

That's 10 bytes. Add some stuff that depends on the game and you'll get to a number that's around 16. The way I handle the objects means that I don't need to stick to powers of two anyway (only word alignment), so even if I end up with e.g 18 bytes it's not going to result in me having to waste space in padding.

Of course maybe you meant something else, but honestly the description is so vague I have to guess =P

Bregalad wrote:
Quote:
Fun exercise for the reader: try and do muls.l #23,d0 (signed multiply) on the 65816.

As long as there is enough bits for the result, signed and unsigned multiply are equivalent.

Why does the 68000 have separate MULU and MULS then? (both always have enough bits for the result since the operation is 16-bit × 16-bit → 32-bit)


Top
 Profile  
 
 Post subject: Re: C/++ for the SNES
PostPosted: Tue Nov 18, 2014 4:51 am 
Offline

Joined: Sun May 11, 2014 8:36 am
Posts: 77
Location: France
Sik wrote:
Code:
ObjType:        rs.b 1      ; 1 byte
ObjFlags:       rs.b 1      ; 1 byte
ObjX:           rs.w 1      ; 2 bytes
ObjY:           rs.w 1      ; 2 bytes
ObjSpeedX:      rs.w 1      ; 2 bytes
ObjSpeedY:      rs.w 1      ; 2 bytes

Why put the speed on 2 bytes ? a speed of 256 or more would be huge (especially 60 Hz).


Top
 Profile  
 
 Post subject: Re: C/++ for the SNES
PostPosted: Tue Nov 18, 2014 4:53 am 
Offline

Joined: Thu Aug 12, 2010 3:43 am
Posts: 1589
It's 8.8 fixed point actually (so 0x100 actually means 1 pixel per frame, not 256). Yes, I know the coordinates don't have a fractional part stored into them, but I have a way to fake subpixel accuracy while otherwise keeping everything pure integer.


Top
 Profile  
 
 Post subject: Re: C/++ for the SNES
PostPosted: Tue Nov 18, 2014 10:25 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7272
Location: Chexbres, VD, Switzerland
Quote:
Why does the 68000 have separate MULU and MULS then? (both always have enough bits for the result since the operation is 16-bit × 16-bit → 32-bit)

The only difference is sign extension because the result has more bits than the products.
If it was 16x16 -> 16, or 32x32->32, both would be strictly the same.


Top
 Profile  
 
 Post subject: Re: C/++ for the SNES
PostPosted: Tue Nov 18, 2014 10:46 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19246
Location: NE Indiana, USA (NTSC)
Sik wrote:
I have a way to fake subpixel accuracy while otherwise keeping everything pure integer.

Interesting. How do you go about handling less precision in displacement than in velocity? Do you add 1 if the subpixel portion of the speed is less than some pseudorandom value?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 49 posts ]  Go to page Previous  1, 2, 3, 4  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: Google [Bot] and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group