+Random Terrain Posted December 18, 2015 Share Posted December 18, 2015 I've been using SpiceWare's tip below while updating the Seaweed Assault code, but I just remembered what he posted at the bottom, that it might work differently with bB. I thought I should ask to make sure that nothing is different when using the tip with batari Basic. If it's also more efficient when using bB, I should mention it on the bB page. Using >= in assembly should be more efficient than >. A >= check only needs to worry about the state of C. test: cmp #70 bcc Skip ;C is set if Greater Than or Equal To 70 ; >= 70 logic here Skip: While a > check needs to worry about C and Z. test: cmp #69 bcc Skip ; C is clear if Less Than 69 beq Skip ; Z is set if Equal To 69 ; > 69 logic here Skip: It's possible bB is written in a way that makes > more efficient than >=. Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted December 18, 2015 Share Posted December 18, 2015 How about providing the output assembler listing of if statements with all 4 scenarios ">", "<",">=" and "<=" so we can check? Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted December 18, 2015 Author Share Posted December 18, 2015 How about providing the output assembler listing of if statements with all 4 scenarios ">", "<",">=" and "<=" so we can check? Good idea. Is this all you need or do you need the whole list file? __Main_Loop a = a + 1 if a = 10 then b = 42 if a > 10 then b = 42 if a >= 10 then b = 42 if a < 10 then b = 42 if a <= 10 then b = 42 goto __Main_Loop 1625 f45d .__Main_Loop 1626 f45d ; __Main_Loop 1627 f45d 1628 f45d . 1629 f45d ; 1630 f45d 1631 f45d . 1632 f45d ; 1633 f45d 1634 f45d .L00 ; a = a + 1 1635 f45d 1636 f45d e6 d6 INC a 1637 f45f . 1638 f45f ; 1639 f45f 1640 f45f .L01 ; if a = 10 then b = 42 1641 f45f 1642 f45f a5 d6 LDA a 1643 f461 c9 0a CMP #10 1644 f463 d0 04 BNE .skipL01 1645 f465 .condpart0 1646 f465 a9 2a LDA #42 1647 f467 85 d7 STA b 1648 f469 .skipL01 1649 f469 . 1650 f469 ; 1651 f469 1652 f469 .L02 ; if a > 10 then b = 42 1653 f469 1654 f469 a9 0a LDA #10 1655 f46b c5 d6 CMP a 1656 f46d b0 04 BCS .skipL02 1657 f46f .condpart1 1658 f46f a9 2a LDA #42 1659 f471 85 d7 STA b 1660 f473 .skipL02 1661 f473 . 1662 f473 ; 1663 f473 1664 f473 .L03 ; if a >= 10 then b = 42 1665 f473 1666 f473 a5 d6 LDA a 1667 f475 c9 0a CMP #10 1668 f477 90 04 BCC .skipL03 1669 f479 .condpart2 1670 f479 a9 2a LDA #42 1671 f47b 85 d7 STA b 1672 f47d .skipL03 1673 f47d . 1674 f47d ; 1675 f47d 1676 f47d .L04 ; if a < 10 then b = 42 1677 f47d 1678 f47d a5 d6 LDA a 1679 f47f c9 0a CMP #10 1680 f481 b0 04 BCS .skipL04 1681 f483 .condpart3 1682 f483 a9 2a LDA #42 1683 f485 85 d7 STA b 1684 f487 .skipL04 1685 f487 . 1686 f487 ; 1687 f487 1688 f487 .L05 ; if a <= 10 then b = 42 1689 f487 1690 f487 a9 0a LDA #10 1691 f489 c5 d6 CMP a 1692 f48b 90 04 BCC .skipL05 1693 f48d .condpart4 1694 f48d a9 2a LDA #42 1695 f48f 85 d7 STA b 1696 f491 .skipL05 1697 f491 . 1698 f491 ; 1699 f491 1700 f491 . 1701 f491 ; 1702 f491 1703 f491 .L06 ; goto __Main_Loop 1704 f491 4c 5d f4 jmp .__Main_Loop 1705 f494 if ECHOFIRST 2824 bytes of ROM space left Here it is with a variable replacing the number: __Main_Loop a = a + 1 if a = c then b = 42 if a > c then b = 42 if a >= c then b = 42 if a < c then b = 42 if a <= c then b = 42 goto __Main_Loop 1625 f45d .__Main_Loop 1626 f45d ; __Main_Loop 1627 f45d 1628 f45d . 1629 f45d ; 1630 f45d 1631 f45d . 1632 f45d ; 1633 f45d 1634 f45d .L00 ; a = a + 1 1635 f45d 1636 f45d e6 d6 INC a 1637 f45f . 1638 f45f ; 1639 f45f 1640 f45f .L01 ; if a = c then b = 42 1641 f45f 1642 f45f a5 d6 LDA a 1643 f461 c5 d8 CMP c 1644 f463 d0 04 BNE .skipL01 1645 f465 .condpart0 1646 f465 a9 2a LDA #42 1647 f467 85 d7 STA b 1648 f469 .skipL01 1649 f469 . 1650 f469 ; 1651 f469 1652 f469 .L02 ; if a > c then b = 42 1653 f469 1654 f469 a5 d8 LDA c 1655 f46b c5 d6 CMP a 1656 f46d b0 04 BCS .skipL02 1657 f46f .condpart1 1658 f46f a9 2a LDA #42 1659 f471 85 d7 STA b 1660 f473 .skipL02 1661 f473 . 1662 f473 ; 1663 f473 1664 f473 .L03 ; if a >= c then b = 42 1665 f473 1666 f473 a5 d6 LDA a 1667 f475 c5 d8 CMP c 1668 f477 90 04 BCC .skipL03 1669 f479 .condpart2 1670 f479 a9 2a LDA #42 1671 f47b 85 d7 STA b 1672 f47d .skipL03 1673 f47d . 1674 f47d ; 1675 f47d 1676 f47d .L04 ; if a < c then b = 42 1677 f47d 1678 f47d a5 d6 LDA a 1679 f47f c5 d8 CMP c 1680 f481 b0 04 BCS .skipL04 1681 f483 .condpart3 1682 f483 a9 2a LDA #42 1683 f485 85 d7 STA b 1684 f487 .skipL04 1685 f487 . 1686 f487 ; 1687 f487 1688 f487 .L05 ; if a <= c then b = 42 1689 f487 1690 f487 a5 d8 LDA c 1691 f489 c5 d6 CMP a 1692 f48b 90 04 BCC .skipL05 1693 f48d .condpart4 1694 f48d a9 2a LDA #42 1695 f48f 85 d7 STA b 1696 f491 .skipL05 1697 f491 . 1698 f491 ; 1699 f491 1700 f491 . 1701 f491 ; 1702 f491 1703 f491 .L06 ; goto __Main_Loop 1704 f491 4c 5d f4 jmp .__Main_Loop Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted December 18, 2015 Share Posted December 18, 2015 RT, that is absolutely what is going on but it's the underlying 6502 design that is more efficient in one direction: (Note: Your code otuput shows that ">=" is more efficient than ">", not the other way around). bcc is "<" so in the first example we're running the target code only if the inverse is true (>=) bcs is is the inverse of bcc but they are not equal (pardon the pun), we've basically got two instructions that say "<" and ">=" Now if we want logic for "<=" or ">" we have to add another branch instruction beq ("=") to build it so it's always better to go with ">=" instead of ">" and "<" instead of "<=" when you have the option. Compiler optimizations usually take advantage of the architecture too; here is a For loop example is from Virtual World BASIC (bB may have similar optimizations): The for loop that uses step has three extra instructions over the for loop that does not use step - I was able to add the optimization because step requires multiple instructions (must use the accumulator to add or subtract compared to inc) as well as bounds checking to keep the for loop from falling through which also isn't necessary without the step kepword: L_43 ;---assignments & functions: _43 for i= 91 to 13 step -2 lda #91; -- Init For Loop sta i; -- Init For Loopl0_For_Loop_STARTL_43 L_44 ;---assignments & functions: _44 for j = 7 to 12 lda #7; -- Init For Loop sta j; -- Init For Loopl1_For_Loop_STARTL_44 ;.... looped code here L_46 ;---assignments & functions: _46 next j,i l1_For_Loop_END_checkL_44 lda j cmp #12 bcs l1_For_Loop_ENDL_44 inc j jmp l1_For_Loop_STARTL_44l1_For_Loop_ENDL_44; done with loop l0_For_Loop_END_checkL_43 lda i cmp #13 beq l0_For_Loop_ENDL_43 bcc l0_For_Loop_ENDL_43 sec sbc #2 bcc l0_For_Loop_ENDL_43; kick out if step value overflows sta i jmp l0_For_Loop_STARTL_43l0_For_Loop_ENDL_43; done with loop Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted December 18, 2015 Author Share Posted December 18, 2015 Thanks. I just added another version to my post that uses another variable instead of a number. Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted December 18, 2015 Share Posted December 18, 2015 With bB there is always one comparison and one branch no matter if you use ">", ">=" or "<", "<=" so there are no size/speed optimisations to be had by choosing one over the other. 3 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted December 18, 2015 Author Share Posted December 18, 2015 With bB there is always one comparison and one branch no matter if you use ">", ">=" or "<", "<=" so there are no size/speed optimisations to be had by choosing one over the other. Thanks. I'll go put a version of what you said on the bB page right now before I forget in case anyone wonders about it in the future. I'll also stop changing if-thens in the Seaweed Assault code. That will save me some time. Here is the link: randomterrain.com/atari-2600-memories-batari-basic-commands.html#note_simple_comparison 1 Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted December 19, 2015 Share Posted December 19, 2015 With bB there is always one comparison and one branch no matter if you use ">", ">=" or "<", "<=" so there are no size/speed optimisations to be had by choosing one over the other. That's pretty cool, I see from the code RT posted bB juxtaposes the operands to reduce the number of instructions used in Spice's example; here's the initial example code, and then again replaced with this optimization: test: lda c cmp b bcc Skip ; c is Less Than b (carry flag) beq Skip ; c is Equal To b (zero flag) ; c>b logic here Skip: becomes: test: lda b cmp c bcs Skip ; b >= c (otherwise c>b) ; c> b logic here Skip: vwB is using SpiceWare's double branch instructions from the first example:) Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.