It is currently Mon Aug 21, 2017 1:16 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 24 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sat Jul 08, 2017 1:53 am 
Offline

Joined: Tue Apr 11, 2006 4:08 am
Posts: 229
I have a problem with simplifying some code. I would like to minimize the size of this code, but the functionality must be identical:

Code:
LEV_Check:

   LDA Variable
   CMP #1
   BNE No_01
   LDA #$02
   STA SPR_X
   JMP LEV01
No_01:
   LDA Variable
   CMP #2
   BNE No_02
   LDA #$02
   STA SPR_X
   JMP LEV02
No_02:
   LDA Variable
   CMP #3
   BNE No_03
   LDA #$02
   STA SPR_X
   JMP LEV03
No_03:
   LDA Variable
   CMP #4
   BNE No_04
   LDA #$02
   STA SPR_X
   JMP LEV04
No_04:
   LDA Variable
   CMP #5
   BNE No_05
   LDA #$02
   STA SPR_X
   JMP LEV05
No_05:
   LDA Variable
   CMP #6
   BNE No_06
   LDA #$02
   STA SPR_X
   JMP LEV06
No_06:
   LDA Variable
   CMP #7
   BNE No_07
   LDA #$02
   STA SPR_X
   JMP LEV07
No_07:
   LDA Variable
   CMP #8
   BNE No_08
   LDA #$02
   STA SPR_X
   JMP LEV08
No_08:
   LDA Variable
   CMP #9
   BNE No_09
   LDA #$02
   STA SPR_X
   JMP LEV09
No_09:
   LDA Variable
   CMP #10
   BNE No_10
   LDA #$02
   STA SPR_X
   JMP LEV10
No_10:
   LDA Variable
   CMP #11
   BNE No_11
   LDA #$02
   STA SPR_X
   JMP LEV11
No_11:
   LDA Variable
   CMP #12
   BNE No_12
   LDA #$02
   STA SPR_X
   JMP LEV12
No_12:
   LDA Variable
   CMP #13
   BNE No_13
   LDA #$02
   STA SPR_X
   JMP LEV13
No_13:
   LDA Variable
   CMP #14
   BNE No_14
   LDA #$02
   STA SPR_X
   JMP LEV14
No_14:
   LDA Variable
   CMP #15
   BNE No_15
   LDA #$02
   STA SPR_X
   JMP LEV15
No_15:
   LDA Variable
   CMP #16
   BNE No_16
   LDA #$02
   STA SPR_X
   JMP LEV16
No_16:
   LDA Variable
   CMP #17
   BNE No_17
   LDA #$02
   STA SPR_X
   JMP LEV17
No_17:
   LDA Variable
   CMP #18
   BNE No_18
   LDA #$02
   STA SPR_X
   JMP LEV18
No_18:
   LDA Variable
   CMP #19
   BNE No_19
   LDA #$02
   STA SPR_X
   JMP LEV19
No_19:
   LDA Variable
   CMP #20
   BNE No_20
   LDA #$02
   STA SPR_X
   JMP LEV20
No_20:
   LDA Variable
   CMP #21
   BNE No_21
   LDA #$02
   STA SPR_X
   JMP LEV21
No_21:
   LDA Variable
   CMP #22
   BNE No_22
   LDA #$02
   STA SPR_X
   JMP LEV22
No_22:
   LDA Variable
   CMP #23
   BNE No_23
   LDA #$02
   STA SPR_X
   JMP LEV23
No_23:
   LDA Variable
   CMP #24
   BNE No_24
   LDA #$02
   STA SPR_X
   JMP LEV24
No_24:
   LDA Variable
   CMP #25
   BNE No_25
   LDA #$02
   STA SPR_X
   JMP LEV25
No_25:
   LDA Variable
   CMP #26
   BNE No_26
   LDA #$02
   STA SPR_X
   JMP LEV26
No_26:
   LDA Variable
   CMP #27
   BNE No_27
   LDA #$02
   STA SPR_X
   JMP LEV27
No_27:
   LDA Variable
   CMP #28
   BNE No_28
   LDA #$02
   STA SPR_X
   JMP LEV28
No_28:
   LDA Variable
   CMP #29
   BNE No_29
   LDA #$02
   STA SPR_X
   JMP LEV29
No_29:
   LDA Variable
   CMP #30
   BNE No_30
   LDA #$02
   STA SPR_X
   JMP LEV30
No_30:
   LDA Variable
   CMP #31
   BNE No_31
   LDA #$02
   STA SPR_X
   JMP LEV31
No_31:
   LDA Variable
   CMP #32
   BNE No_32
   LDA #$02
   STA SPR_X
   JMP LEV32
No_32:
   LDA Variable
   CMP #33
   BNE No_33
   LDA #$02
   STA SPR_X
   JMP LEV33
No_33:
   LDA Variable
   CMP #34
   BNE No_34
   LDA #$02
   STA SPR_X
   JMP LEV34
No_34:
   LDA Variable
   CMP #35
   BNE No_35
   LDA #$02
   STA SPR_X
   JMP LEV35
No_35:
   LDA Variable
   CMP #36
   BNE No_36
   LDA #$02
   STA SPR_X
   JMP LEV36
No_36:
   LDA Variable
   CMP #37
   BNE No_37
   LDA #$02
   STA SPR_X
   JMP LEV37
No_37:
   LDA Variable
   CMP #38
   BNE No_38
   LDA #$02
   STA SPR_X
   JMP LEV38
No_38:
   LDA Variable
   CMP #39
   BNE No_39
   LDA #$02
   STA SPR_X
   JMP LEV39
No_39:
   LDA Variable
   CMP #40
   BNE No_40
   LDA #$02
   STA SPR_X
   JMP LEV40
No_40:
   LDA Variable
   CMP #41
   BNE No_41
   LDA #$02
   STA SPR_X
   JMP LEV41
No_41:
   LDA Variable
   CMP #42
   BNE No_42
   LDA #$02
   STA SPR_X
   JMP LEV42
No_42:
   LDA Variable
   CMP #43
   BNE No_43
   LDA #$02
   STA SPR_X
   JMP LEV43
No_43:
   LDA Variable
   CMP #44
   BNE No_44
   LDA #$02
   STA SPR_X
   JMP LEV44
No_44:
   LDA Variable
   CMP #45
   BNE No_45
   LDA #$02
   STA SPR_X
   JMP LEV45
No_45:
   LDA Variable
   CMP #46
   BNE No_46
   LDA #$02
   STA SPR_X
   JMP LEV46
No_46:
   LDA Variable
   CMP #47
   BNE No_47
   LDA #$02
   STA SPR_X
   JMP LEV47
No_47:
   LDA Variable
   CMP #48
   BNE No_48
   LDA #$02
   STA SPR_X
   JMP LEV48
No_48:
   LDA Variable
   CMP #49
   BNE No_49
   LDA #$02
   STA SPR_X
   JMP LEV49
No_49:
   LDA Variable
   CMP #50
   BNE No_50
   LDA #$02
   STA SPR_X
   JMP LEV50
No_50:
   LDA Variable
   CMP #51
   BNE No_51
   LDA #$02
   STA SPR_X
   JMP LEV51
No_51:
   LDA Variable
   CMP #52
   BNE No_52
   LDA #$02
   STA SPR_X
   JMP LEV52
No_52:
   LDA Variable
   CMP #53
   BNE No_53
   LDA #$02
   STA SPR_X
   JMP LEV53
No_53:
   LDA Variable
   CMP #54
   BNE No_54
   LDA #$02
   STA SPR_X
   JMP LEV54
No_54:
   LDA Variable
   CMP #55
   BNE No_55
   LDA #$02
   STA SPR_X
   JMP LEV55
No_55:
   LDA Variable
   CMP #56
   BNE No_56
   LDA #$02
   STA SPR_X
   JMP LEV56
No_56:
   LDA Variable
   CMP #57
   BNE No_57
   LDA #$02
   STA SPR_X
   JMP LEV57
No_57:
   LDA Variable
   CMP #58
   BNE No_58
   LDA #$02
   STA SPR_X
   JMP LEV58
No_58:
   LDA Variable
   CMP #59
   BNE No_59
   LDA #$02
   STA SPR_X
   JMP LEV59
No_59:
   LDA Variable
   CMP #60
   BNE No_60
   LDA #$02
   STA SPR_X
   JMP LEV60
No_60:
   LDA Variable
   CMP #61
   BNE No_61
   LDA #$02
   STA SPR_X
   JMP LEV61
No_61:
   LDA Variable
   CMP #62
   BNE No_62
   LDA #$02
   STA SPR_X
   JMP LEV62
No_62:
   LDA Variable
   CMP #63
   BNE No_63
   LDA #$02
   STA SPR_X
   JMP LEV63
No_63:
   LDA Variable
   CMP #64
   BNE No_64
   LDA #$02
   STA SPR_X
   JMP LEV64
No_64:
   RTS


Top
 Profile  
 
PostPosted: Sat Jul 08, 2017 2:15 am 
Offline

Joined: Tue Oct 06, 2015 10:16 am
Posts: 493
- you don't need to "lda variable" more than once, cmp does not change A
- lda #2; sta spr_x happens in every option except 64, so make that its own check at the start


Top
 Profile  
 
PostPosted: Sat Jul 08, 2017 3:26 am 
Offline

Joined: Tue Feb 07, 2017 2:03 am
Posts: 214
Code:
LEV_Check:
   LDX Variable
   CPX #64
   BEQ _exit
   LDA #$02
   STA SPR_X
   LDA LvlFuncPtrTableLo,x
   STA $100
   LDA LvlFuncPtrTableHi,x
   STA $101
   JMP ($100)
_exit
   RTS
LvlFuncPtrTableLo
   .byte <LEV01,<LEV02,<LEV03,<LEV04,<LEV05,<LEV06,<LEV07(..snip...),<LEV63
LvlFuncPtrTableHi
   .byte >LEV01,>LEV02,>LEV03,>LEV04,>LEV05,>LEV06,>LEV07(..snip...),>LEV63


Top
 Profile  
 
PostPosted: Sat Jul 08, 2017 5:36 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2924
Location: Tampere, Finland
Obvious first step when you have repetitive code like that (in ca65 syntax):
Code:
.repeat 64, i
   LDA Variable
   CMP #i+1
   BNE :+
   LDA #$02
   STA SPR_X
   JMP .ident(.sprintf("LEV%02d", i+1))
   :
.endrepeat

This doesn't reduce the size of the binary, but makes the code much more readable and maintainable. Next step is to refactor the code to minimize code size, as shown by Oziphantom (his example is not 100% functionally equivalent, though, but shows the main idea).

EDIT: Had "i" instead of "i+1".

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Last edited by thefox on Sat Jul 08, 2017 6:50 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Sat Jul 08, 2017 5:45 am 
Offline

Joined: Tue Feb 07, 2017 2:03 am
Posts: 214
oh yeah, ooppss
Code:
LEV_Check:
   LDX Variable
   CPX #65
   BCS _exit
   LDA #$02
   STA SPR_X
   LDA LvlFuncPtrTableLo,x
   STA $100
   LDA LvlFuncPtrTableHi,x
   STA $101
   JMP ($100)
_exit
   RTS
LvlFuncPtrTableLo
   .byte <LEV01,<LEV02,<LEV03,<LEV04,<LEV05,<LEV06,<LEV07(..snip...),<LEV63
LvlFuncPtrTableHi
   .byte >LEV01,>LEV02,>LEV03,>LEV04,>LEV05,>LEV06,>LEV07(..snip...),>LEV63


Top
 Profile  
 
PostPosted: Sat Jul 08, 2017 1:34 pm 
Offline

Joined: Wed Nov 30, 2016 4:45 pm
Posts: 83
Location: Southern California
Do adjust the table for being 1-based rather than 0-based though.

A way to do it without variables is to put the address on the stack and use the RTS as the jump itself, not just the default return:
Code:
   LDA  LvlFuncPtrTableHi,x    ; (high byte first)
   PHA
   LDA  LvlFuncPtrTableLo,x
   PHA
_exit
   RTS

and you'll save a few bytes of code too. Remember that RTS requires the 16-bit addr to be the target minus 1.

This is from section 11 entitled "Synthesizing instructions with RTS, RTI, and JSR" (intentionally written in that order) of my 6502 stacks treatise.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources


Top
 Profile  
 
PostPosted: Sat Jul 08, 2017 5:59 pm 
Offline

Joined: Tue Apr 11, 2006 4:08 am
Posts: 229
Oziphantom wrote:
oh yeah, ooppss
Code:
LvlFuncPtrTableLo
   .byte <LEV01,<LEV02,<LEV03,<LEV04,<LEV05,<LEV06,<LEV07(..snip...),<LEV63
LvlFuncPtrTableHi
   .byte >LEV01,>LEV02,>LEV03,>LEV04,>LEV05,>LEV06,>LEV07(..snip...),>LEV63



An error pops up - "syntax error in expression!" :( I use NESASM3.


Top
 Profile  
 
PostPosted: Sat Jul 08, 2017 6:09 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 9904
Location: Rio de Janeiro - Brazil
Use LOW() and HIGH () instead of < and >. You may need to use .db instead of .byte too, but I'm not sure.


Top
 Profile  
 
PostPosted: Sun Jul 09, 2017 3:36 am 
Offline

Joined: Tue Apr 11, 2006 4:08 am
Posts: 229
usage.txt from NESASM3 says:

Quote:
HIGH() - Returns the high byte of a value.

LOW() - Returns the low byte.

DB - Store one or more data bytes at the current location.

DW - Store data words.

BYTE - Same as DB.


I changed and should be fine, but.. Unfortunately again NESASM3 displays an error. "syntax error in expression!" :/



I may have described it incompletely. LEV01-64 are labels such as:

Code:
LEV01:

    ;some data here (like sprites, monsters etc, nametable change, map variables etc

RTS


"LEV_Check" is in infinite loop. Byte "Variable" will have a value of #$01 - #$64 randomly saved, and depending on what value it will write, then LEV_Check will run the corresponding JMP LEV01 to LEV64.


Top
 Profile  
 
PostPosted: Sun Jul 09, 2017 5:08 am 
Offline

Joined: Tue Feb 07, 2017 2:03 am
Posts: 214
can you post the code as you have it written, bit hard to tell what is wrong, also give us the exact error?

Although personally I would say ditch NESASM and get a real assembler. I recommend 64tass but it will need to to make your own NES header. Or if NESASM has a binary include you could abuse NESASM to just make the .nes file for you with the code and data built by 64tass.


Top
 Profile  
 
PostPosted: Sun Jul 09, 2017 8:46 am 
Offline
User avatar

Joined: Wed Sep 21, 2016 8:55 am
Posts: 53
Location: Calgary.Alberta,Canada
Most of us don't use NESASM so we don't know the syntax,you can also use words instead of high,low bytes


Code:
LEV_Check:
   LDA Variable
   CMP #64
   BEQ _exit
   LDA #$02
   STA SPR_X
   LDA Variable
   ASL
   TAX
   LDA LvlFuncPtrTable+0,x
   STA $00
   LDA LvlFuncPtrTable+1,x
   STA $01
   JMP ($00)
_exit
   RTS
LvlFuncPtrTable
   .dw LEV01,LEV02,LEV03,LEV04,LEV05,LEV06,LEV07(.All other function labels...),LEV63




sdm wrote:

I may have described it incompletely. LEV01-64 are labels such as:

Code:
LEV01:

    ;some data here (like sprites, monsters etc, nametable change, map variables etc

RTS


"LEV_Check" is in infinite loop. Byte "Variable" will have a value of #$01 - #$64 randomly saved, and depending on what value it will write, then LEV_Check will run the corresponding JMP LEV01 to LEV64.





Yes that's all fine sdm





If you want a low and high byte address table this needs to be done

Code:
LEV_Check:
   LDX Variable
   CPX #64
   BEQ _exit
   LDA #$02
   STA SPR_X
   LDA LvlFuncPtrTableLo,x
   STA $00
   LDA LvlFuncPtrTableHi,x
   STA $01
   JMP ($00)
_exit
   RTS
LvlFuncPtrTableLo
   .byte LOW(LEV01),LOW(LEV02),LOW(LEV03),LOW(LEV04),LOW(LEV05),LOW(LEV06),LOW(LEV07)(..ect...),LOW(LEV63)
LvlFuncPtrTableHi
   .byte HIGH(LEV01),HIGH(LEV02),HIGH(LEV03),HIGH(LEV04),HIGH(LEV05),HIGH(LEV06),HIGH(LEV07)(..ect...),HIGH(LEV63)


Top
 Profile  
 
PostPosted: Wed Jul 12, 2017 3:11 pm 
Offline

Joined: Tue Apr 11, 2006 4:08 am
Posts: 229
Thanks for the help.

NESASM3 probably has some limitations, for example:

Code:
   .dw LEV01,LEV02,LEV03,LEV04,LEV05,LEV06,LEV07,LEV08,LEV09,LEV10,LEV11,LEV12,LEV13,LEV14,LEV15,LEV16,LEV17,LEV18,LEV19,LEV20,LEV21 (ect)


Displays error "Syntax error in expression!"


Only then is done ok: (I also see the length of the label name does matter. 100 characters total on one line?)

Code:
   .dw LEV01,LEV02,LEV03,LEV04,LEV05,LEV06,LEV07,LEV08,LEV09,LEV10,LEV11,LEV12,LEV13,LEV14,LEV15,LEV16,LEV17,LEV18,LEV19,LEV20
   .dw LEV21,LEV22,LEV23,LEV24,LEV25,LEV26,LEV27,LEV28,LEV29,LEV30,LEV31,LEV32,LEV33,LEV34,LEV35,LEV36,LEV25,LEV26,LEV27,LEV28
(ect)


Top
 Profile  
 
PostPosted: Wed Jul 12, 2017 8:49 pm 
Offline

Joined: Wed Nov 30, 2016 4:45 pm
Posts: 83
Location: Southern California
Once again: You don't need to store the indirect address in variable space and use JMP(ind). Put the address on the stack and use the RTS as the jump itself, not just the default return:
Code:
   [...]
   LDA  LvlFuncPtrTableHi,x    ; (high byte first)
   PHA
   LDA  LvlFuncPtrTableLo,x
   PHA
_exit
   RTS

and you'll save 5-7 bytes of code too. Remember that RTS requires the 16-bit addr to be the target minus 1, so make that adjustment when you form the table.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources


Top
 Profile  
 
PostPosted: Wed Jul 12, 2017 10:26 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3451
Location: Indianapolis
Oziphantom wrote:
Or if NESASM has a binary include you could abuse NESASM to just make the .nes file for you with the code and data built by 64tass.


I'd recommend against that, because (even in the newest versions) of NESASM it behaves badly when you overflow an 8kB bank boundary (creates a malformed ROM and doesn't give any error or warning). Unfortunately many people still insist on using it (WHY :? ), so I still have to fiddle around with that kind of crap when I collaborate with anyone. I can say I've used worse assemblers though..


Top
 Profile  
 
PostPosted: Wed Jul 12, 2017 11:21 pm 
Offline

Joined: Tue Feb 07, 2017 2:03 am
Posts: 214
Yeah but Garth, they are having trouble making an array of Words, lets keep the -1, stack push tricks to latter yeah ;)

Memblers... it is the assembler that just keeps on giving.. between it and WLA-X in the SNES section, I'm thinking taking the time to find the NES tutorials, and doing a convert to TASS would save us a lot of help requests. As I guess once people learn this is the thing you type to do the thing, and they don't really understand it, getting them to move to another assembler is hard.. then they become so entrenched into it that all their code library is in its style that they just end up stuck in it... I can only imagine how many people find the tutorials hit some random garbage the old tools throw at them and just quit.. not even making it here to ask.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users 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