diff --git a/board-package-source/bootloaders/cathy3k/microcade-bootloader-game.hex b/board-package-source/bootloaders/cathy3k/microcade-bootloader-game.hex index 2ce4f24..186b55f 100644 --- a/board-package-source/bootloaders/cathy3k/microcade-bootloader-game.hex +++ b/board-package-source/bootloaders/cathy3k/microcade-bootloader-game.hex @@ -7,7 +7,7 @@ :107460000FBE31962F010895E0E0F0E085919491F0 :10747000019608958AE28BB98BEA34D01092890084 :107480008AEF8093880082E080936F0083E080938E -:107490008100EDE5F7E785913AD0E936E1F781E043 +:107490008100E7E5F7E785913AD0E336E1F781E04F :1074A0008093D7008AE482BF1092D8001092E20045 :1074B0001092DA001092E10080E808D019BC1EBAE0 :1074C0001092E00066D489E057D481E98093D80017 @@ -18,49 +18,49 @@ :107510008DB587FFFDCF8EB508958FE08221E9F705 :10752000F3DFE3E6F6E090EB5C98892FF0DF80E193 :10753000EEDF5C9A8191EBDF83E68E278F77D1F7C0 -:107540009395983B89F708952E9858982D98E3E6DF -:10755000F1E094FC36C097FC4DC092FE08959684ED -:107560009920D1F3F894C089D78520E030E080E0FD -:1075700090E4AFEFBFEF119689199040E0F72D012D -:10758000BD4F8D0127FD13C0E0E0F8E011928EE7BA -:10759000819392E4E11791939AE508F092E4E33441 -:1075A000C9F781931082BCDFFE0121969DDF91DF38 -:1075B000F90100D520583F4F040D151D9A9411F77D -:1075C0000FC28301282D60906C0170906B0143D035 -:1075D00019F48823C1F70895380188243CD0C9F5EF -:1075E00080916A01821709F4830160906E017090A6 -:1075F0006D01F4CF80E8982E60906E0170906D015F -:107600002AD059F48823B1F708959FEF96FC03C060 -:1076100095FE089591E097FB890E662477248301F7 -:10762000222719D0B1F48823A1F380916A0136F0A2 -:10763000881650F4821730F0213003C0881520F4EA -:10764000281710F48301282F60906E0170906D014F -:10765000E8CF3801822EF30147DF3BDFC3E6D1E0FC -:10766000E6E5F7E709908591081621F4ED35D1F7A5 -:107670000880801049CFC9E02EDFCA95E9F7D0E134 -:1076800094FC55C097FC37C095FE1AC0C3E6D2E003 -:10769000E3E6F6E098E088E78E0F00840192E817B1 -:1076A000E1F7884F09900192E817E1F7C858DF4FDA -:1076B0009A9589F732DFC85FD340C33E49F749C086 -:1076C000C3E6D6E0EBE5FAE098E08E2F885702900B -:1076D0000086E817E1F738960A900292E817E1F77A -:1076E0003897C857D0409A9581F717DFC850DC4FBC -:1076F000C33E41F72EC0A3EEB6E0E3E6F6E09AE023 -:10770000C6E00D9080818025807F802582958193C1 -:10771000A336B90709F4B2E0E336F90709F4F2E059 -:10772000E336FC0771F7F9DEDA9529F712C0A3EE0C -:10773000B9E0E3E6FAE092E00E90829180258F7046 -:10774000802582958083E336F907B1F7E6DEDA9586 -:1077500071F78827089541524455424F59D5F08D0D -:1077600014A1C881CFD9F1AF000000FFFFCFCFFF38 -:10777000FFFFFFCFCFFFFF0000FE067E7E06FE4626 -:10778000565616FE0656461EFE3F61E9E3FFE3EB42 -:0A779000E3FFE3EBE3FFE16B3F00D2 -:10779A001201100102000008412336000100000016 -:1077AA00000109023E0002010080320904000001C2 -:1077BA000202010005240010010424020405240623 -:1077CA000001070582030800FF09040100020A00FC -:1077DA0000000705040210000107058302100001DA +:107540009395983B89F70895E3E6F1E094FC36C003 +:1075500097FC4DC092FE089596849920D1F3F8943B +:10756000C089D78520E030E080E090E4AFEFBFEF46 +:10757000119689199040E0F72D01BD4F8D0127FD2F +:1075800013C0E0E0F8E011928EE7819392E4E117F6 +:1075900091939AE508F092E4E334C9F7819310825D +:1075A000BFDFFE012196A0DF94DFF90103D520584B +:1075B0003F4F040D151D9A9411F712C28301282D17 +:1075C00060906C0170906B0143D019F48823C1F76F +:1075D0000895380188243CD0C9F580916A0182174A +:1075E00009F4830160906E0170906D01F4CF80E822 +:1075F000982E60906E0170906D012AD059F4882306 +:10760000B1F708959FEF96FC03C095FE089591E0B1 +:1076100097FB890E662477248301222719D0B1F4C1 +:107620008823A1F380916A0136F0881650F48217FE +:1076300030F0213003C0881520F4281710F483019E +:10764000282F60906E0170906D01E8CF3801822E76 +:10765000F3014ADF3EDFC3E6D1E0E0E5F7E709905A +:107660008591081621F4E735D1F7088080104CCFBA +:10767000C9E031DFCA95E9F7D0E194FC55C097FC29 +:1076800037C095FE1AC0C3E6D2E0E3E6F6E098E024 +:1076900088E78E0F00840192E817E1F7884F099080 +:1076A0000192E817E1F7C858DF4F9A9589F735DF5F +:1076B000C85FD340C33E49F749C0C3E6D6E0EBE517 +:1076C000FAE098E08E2F885702900086E817E1F7DD +:1076D00038960A900292E817E1F73897C857D040D9 +:1076E0009A9581F71ADFC850DC4FC33E41F72EC090 +:1076F000A3EEB6E0E3E6F6E09AE0C6E00D90808106 +:107700008025807F802582958193A336B90709F46F +:10771000B2E0E336F90709F4F2E0E336FC0771F76B +:10772000FCDEDA9529F712C0A3EEB9E0E3E6FAE051 +:1077300092E00E90829180258F70802582958083C3 +:10774000E336F907B1F7E9DEDA9571F7882708958E +:1077500041524455424F59D5F08D14A1C881CFD91B +:10776000F1AF000000FFFFCFCFFFFFFFFFCFCFFF44 +:10777000FF0000FE067E7E06FE46565616FE0656A4 +:10778000461EFE3F61E9E3FFE3EBE3FFE3EBE3FFCC +:04779000E16B3F006A +:10779400120110010200000841233600010000001C +:1077A400000109023E0002010080320904000001C8 +:1077B4000202010005240010010424020405240629 +:1077C4000001070582030800FF09040100020A0002 +:1077D40000000705040210000107058302100001E0 :1078000011241FBE04B714BE88E18093600010925B :1078100060008EEF9AE09EBF8DBF222433242101A9 :107820003101410180E88AC00F928F939F931F928C @@ -83,13 +83,13 @@ :107930001F909F918F910FBE0F90189580936100BB :1079400010926100B1E0B5BF82E085BF81E985B9E1 :1079500087EE84B91DB8769A10BA83EF81BB8CE2AA -:107960008BB98FE38AB980E58CBDBDBDA0E0EAE9A3 +:107960008BB98FE38AB980E58CBDBDBDA0E0E4E9A9 :10797000F7E705900D92A035E1F71D92BB30E9F7CE :1079800001FD06C000FF04C07F9B02C06DDD41F514 -:1079900071DD789460DE71F0ABE9B7E0E9E6F7E716 -:1079A00090E105900D929A95E1F7A059BF4FE93902 +:1079900071DD78945DDE71F0ABE9B7E0E3E6F7E71F +:1079A00090E105900D929A95E1F7A059BF4FE33908 :1079B000B9F7B7DD4FD02CDD80915201807861F4AA -:1079C0008FB18095807F66991C9B8460982E1DDE08 +:1079C0008FB18095807F66991C9B8460982E1ADE0B :1079D0008110BADD92FC02C0332062F745DD51F31D :1079E000F89489EB7FDD81E08093E00010926F00D6 :1079F00010928100109285001092840081E085BF72 @@ -104,8 +104,8 @@ :107A800011F4C3DFFACF8C34C1F38035B1F38437FE :107A900021F484E4C8DF80E004C1813611F489E573 :107AA00000C1813429F4B1DF582EAFDF482EE5CF75 -:107AB000803711F483E5F5C0833539F4E6E5F7E75F -:107AC0008591B1DFED35E1F7EDC0863521F481E335 +:107AB000803711F483E5F5C0833539F4E0E5F7E765 +:107AC0008591B1DFE735E1F7EDC0863521F481E33B :107AD000AADF89E3E6C0863781F481E3669B8E5F87 :107AE0001C9B8F5FA0DF81E47C9B885F7D9B8C5F0C :107AF0007E9B8E5F7F9B8F5FD4C08837C1F485DF0C diff --git a/board-package-source/bootloaders/cathy3k/microcade-bootloader-menu.hex b/board-package-source/bootloaders/cathy3k/microcade-bootloader-menu.hex index 80027a1..feacc53 100644 --- a/board-package-source/bootloaders/cathy3k/microcade-bootloader-menu.hex +++ b/board-package-source/bootloaders/cathy3k/microcade-bootloader-menu.hex @@ -7,7 +7,7 @@ :107460000FBE31962F010895E0E0F0E085919491F0 :10747000019608958AE28BB98BEA34D01092890084 :107480008AEF8093880082E080936F0083E080938E -:107490008100EDE5F7E785913AD0E936E1F781E043 +:107490008100E7E5F7E785913AD0E336E1F781E04F :1074A0008093D7008AE482BF1092D8001092E20045 :1074B0001092DA001092E10080E808D019BC1EBAE0 :1074C0001092E00066D489E057D481E98093D80017 @@ -18,49 +18,49 @@ :107510008DB587FFFDCF8EB508958FE08221E9F705 :10752000F3DFE3E6F6E090EB5C98892FF0DF80E193 :10753000EEDF5C9A8191EBDF83E68E278F77D1F7C0 -:107540009395983B89F708952E9858982D98E3E6DF -:10755000F1E094FC36C097FC4DC092FE08959684ED -:107560009920D1F3F894C089D78520E030E080E0FD -:1075700090E4AFEFBFEF119689199040E0F72D012D -:10758000BD4F8D0127FD13C0E0E0F8E011928EE7BA -:10759000819392E4E11791939AE508F092E4E33441 -:1075A000C9F781931082BCDFFE0121969DDF91DF38 -:1075B000F90100D520583F4F040D151D9A9411F77D -:1075C0000FC28301282D60906C0170906B0143D035 -:1075D00019F48823C1F70895380188243CD0C9F5EF -:1075E00080916A01821709F4830160906E017090A6 -:1075F0006D01F4CF80E8982E60906E0170906D015F -:107600002AD059F48823B1F708959FEF96FC03C060 -:1076100095FE089591E097FB890E662477248301F7 -:10762000222719D0B1F48823A1F380916A0136F0A2 -:10763000881650F4821730F0213003C0881520F4EA -:10764000281710F48301282F60906E0170906D014F -:10765000E8CF3801822EF30147DF3BDFC3E6D1E0FC -:10766000E6E5F7E709908591081621F4ED35D1F7A5 -:107670000880801049CFC9E02EDFCA95E9F7D0E134 -:1076800094FC55C097FC37C095FE1AC0C3E6D2E003 -:10769000E3E6F6E098E088E78E0F00840192E817B1 -:1076A000E1F7884F09900192E817E1F7C858DF4FDA -:1076B0009A9589F732DFC85FD340C33E49F749C086 -:1076C000C3E6D6E0EBE5FAE098E08E2F885702900B -:1076D0000086E817E1F738960A900292E817E1F77A -:1076E0003897C857D0409A9581F717DFC850DC4FBC -:1076F000C33E41F72EC0A3EEB6E0E3E6F6E09AE023 -:10770000C6E00D9080818025807F802582958193C1 -:10771000A336B90709F4B2E0E336F90709F4F2E059 -:10772000E336FC0771F7F9DEDA9529F712C0A3EE0C -:10773000B9E0E3E6FAE092E00E90829180258F7046 -:10774000802582958083E336F907B1F7E6DEDA9586 -:1077500071F78827089541524455424F59D5F08D0D -:1077600014A1C881CFD9F1AF000000FFFFCFCFFF38 -:10777000FFFFFFCFCFFFFF0000FE067E7E06FE4626 -:10778000565616FE0656461EFE3F61E9E3FFE3EB42 -:0A779000E3FFE3EBE3FFE16B3F00D2 -:10779A001201100102000008412336000100000016 -:1077AA00000109023E0002010080320904000001C2 -:1077BA000202010005240010010424020405240623 -:1077CA000001070582030800FF09040100020A00FC -:1077DA0000000705040210000107058302100001DA +:107540009395983B89F70895E3E6F1E094FC36C003 +:1075500097FC4DC092FE089596849920D1F3F8943B +:10756000C089D78520E030E080E090E4AFEFBFEF46 +:10757000119689199040E0F72D01BD4F8D0127FD2F +:1075800013C0E0E0F8E011928EE7819392E4E117F6 +:1075900091939AE508F092E4E334C9F7819310825D +:1075A000BFDFFE012196A0DF94DFF90103D520584B +:1075B0003F4F040D151D9A9411F712C28301282D17 +:1075C00060906C0170906B0143D019F48823C1F76F +:1075D0000895380188243CD0C9F580916A0182174A +:1075E00009F4830160906E0170906D01F4CF80E822 +:1075F000982E60906E0170906D012AD059F4882306 +:10760000B1F708959FEF96FC03C095FE089591E0B1 +:1076100097FB890E662477248301222719D0B1F4C1 +:107620008823A1F380916A0136F0881650F48217FE +:1076300030F0213003C0881520F4281710F483019E +:10764000282F60906E0170906D01E8CF3801822E76 +:10765000F3014ADF3EDFC3E6D1E0E0E5F7E709905A +:107660008591081621F4E735D1F7088080104CCFBA +:10767000C9E031DFCA95E9F7D0E194FC55C097FC29 +:1076800037C095FE1AC0C3E6D2E0E3E6F6E098E024 +:1076900088E78E0F00840192E817E1F7884F099080 +:1076A0000192E817E1F7C858DF4F9A9589F735DF5F +:1076B000C85FD340C33E49F749C0C3E6D6E0EBE517 +:1076C000FAE098E08E2F885702900086E817E1F7DD +:1076D00038960A900292E817E1F73897C857D040D9 +:1076E0009A9581F71ADFC850DC4FC33E41F72EC090 +:1076F000A3EEB6E0E3E6F6E09AE0C6E00D90808106 +:107700008025807F802582958193A336B90709F46F +:10771000B2E0E336F90709F4F2E0E336FC0771F76B +:10772000FCDEDA9529F712C0A3EEB9E0E3E6FAE051 +:1077300092E00E90829180258F70802582958083C3 +:10774000E336F907B1F7E9DEDA9571F7882708958E +:1077500041524455424F59D5F08D14A1C881CFD91B +:10776000F1AF000000FFFFCFCFFFFFFFFFCFCFFF44 +:10777000FF0000FE067E7E06FE46565616FE0656A4 +:10778000461EFE3F61E9E3FFE3EBE3FFE3EBE3FFCC +:04779000E16B3F006A +:10779400120110010200000841233600010000001C +:1077A400000109023E0002010080320904000001C8 +:1077B4000202010005240010010424020405240629 +:1077C4000001070582030800FF09040100020A0002 +:1077D40000000705040210000107058302100001E0 :1078000011241FBE04B714BE88E18093600010925B :1078100060008EEF9AE09EBF8DBF222433242101A9 :107820003101410180E88AC00F928F939F931F928C @@ -83,13 +83,13 @@ :107930001F909F918F910FBE0F90189580936100BB :1079400010926100B1E0B5BF82E085BF81E985B9E1 :1079500087EE84B91DB8769A10BA83EF81BB8CE2AA -:107960008BB98FE38AB980E58CBDBDBDA0E0EAE9A3 +:107960008BB98FE38AB980E58CBDBDBDA0E0E4E9A9 :10797000F7E705900D92A035E1F71D92BB30E9F7CE :1079800001FD06C0000004C07F9B02C06DDD41F513 -:1079900071DD789460DE71F0ABE9B7E0E9E6F7E716 -:1079A00090E105900D929A95E1F7A059BF4FE93902 +:1079900071DD78945DDE71F0ABE9B7E0E3E6F7E71F +:1079A00090E105900D929A95E1F7A059BF4FE33908 :1079B000B9F7B7DD4FD02CDD80915201807861F4AA -:1079C0008FB18095807F66991C9B8460982E1DDE08 +:1079C0008FB18095807F66991C9B8460982E1ADE0B :1079D0008110BADD92FC02C0332062F745DD51F31D :1079E000F89489EB7FDD81E08093E00010926F00D6 :1079F00010928100109285001092840081E085BF72 @@ -104,8 +104,8 @@ :107A800011F4C3DFFACF8C34C1F38035B1F38437FE :107A900021F484E4C8DF80E004C1813611F489E573 :107AA00000C1813429F4B1DF582EAFDF482EE5CF75 -:107AB000803711F483E5F5C0833539F4E6E5F7E75F -:107AC0008591B1DFED35E1F7EDC0863521F481E335 +:107AB000803711F483E5F5C0833539F4E0E5F7E765 +:107AC0008591B1DFE735E1F7EDC0863521F481E33B :107AD000AADF89E3E6C0863781F481E3669B8E5F87 :107AE0001C9B8F5FA0DF81E47C9B885F7D9B8C5F0C :107AF0007E9B8E5F7F9B8F5FD4C08837C1F485DF0C diff --git a/board-package-source/libraries/ArduboyFX/examples/basic-example/basic-example.ino b/board-package-source/libraries/ArduboyFX/examples/basic-example/basic-example.ino index 962849d..5e098e5 100644 --- a/board-package-source/libraries/ArduboyFX/examples/basic-example/basic-example.ino +++ b/board-package-source/libraries/ArduboyFX/examples/basic-example/basic-example.ino @@ -21,10 +21,6 @@ #include // required to access the FX external flash #include "fxdata/fxdata.h" // this file contains all references to FX data -//constant values -constexpr uint8_t FXlogoWidth = 115; -constexpr uint8_t FXlogoHeight = 16; - Arduboy2 arduboy; //assign values; diff --git a/board-package-source/libraries/ArduboyFX/examples/helloworld/helloworld.ino b/board-package-source/libraries/ArduboyFX/examples/helloworld/helloworld.ino index f2e7e7d..8e19078 100644 --- a/board-package-source/libraries/ArduboyFX/examples/helloworld/helloworld.ino +++ b/board-package-source/libraries/ArduboyFX/examples/helloworld/helloworld.ino @@ -20,7 +20,7 @@ #include #include -#include "fxdata\fxdata.h" +#include "fxdata/fxdata.h" Arduboy2Base arduboy; diff --git a/board-package-source/libraries/ArduboyFX/examples/loadGameState/fxdata/fxdata-data.bin b/board-package-source/libraries/ArduboyFX/examples/loadGameState/fxdata/fxdata-data.bin new file mode 100644 index 0000000..e69de29 diff --git a/board-package-source/libraries/ArduboyFX/examples/loadGameState/fxdata/fxdata-save.bin b/board-package-source/libraries/ArduboyFX/examples/loadGameState/fxdata/fxdata-save.bin new file mode 100644 index 0000000..f96c401 --- /dev/null +++ b/board-package-source/libraries/ArduboyFX/examples/loadGameState/fxdata/fxdata-save.bin @@ -0,0 +1 @@ +ÿÿ \ No newline at end of file diff --git a/board-package-source/libraries/ArduboyFX/examples/loadGameState/fxdata/fxdata.bin b/board-package-source/libraries/ArduboyFX/examples/loadGameState/fxdata/fxdata.bin new file mode 100644 index 0000000..7de9e36 --- /dev/null +++ b/board-package-source/libraries/ArduboyFX/examples/loadGameState/fxdata/fxdata.bin @@ -0,0 +1 @@ +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ \ No newline at end of file diff --git a/board-package-source/libraries/ArduboyFX/examples/loadGameState/fxdata/fxdata.h b/board-package-source/libraries/ArduboyFX/examples/loadGameState/fxdata/fxdata.h new file mode 100644 index 0000000..6aadb2b --- /dev/null +++ b/board-package-source/libraries/ArduboyFX/examples/loadGameState/fxdata/fxdata.h @@ -0,0 +1,14 @@ +#pragma once + +/**** FX data header generated by fxdata-build.py tool version 1.13 ****/ + +using uint24_t = __uint24; + +// Initialize FX hardware using FX::begin(FX_DATA_PAGE); in the setup() function. + +constexpr uint16_t FX_DATA_PAGE = 0xfff0; +constexpr uint24_t FX_DATA_BYTES = 0; + +constexpr uint16_t FX_SAVE_PAGE = 0xfff0; +constexpr uint24_t FX_SAVE_BYTES = 2; + diff --git a/board-package-source/libraries/ArduboyFX/examples/loadGameState/fxdata/fxdata.txt b/board-package-source/libraries/ArduboyFX/examples/loadGameState/fxdata/fxdata.txt new file mode 100644 index 0000000..fffc9bb --- /dev/null +++ b/board-package-source/libraries/ArduboyFX/examples/loadGameState/fxdata/fxdata.txt @@ -0,0 +1,4 @@ + + savesection //4K block save section. Any data below will be stored in save data area + + uint16_t 0xFFFF //game state end marker / start of unused space diff --git a/board-package-source/libraries/ArduboyFX/examples/loadGameState/loadGameState.ino b/board-package-source/libraries/ArduboyFX/examples/loadGameState/loadGameState.ino new file mode 100644 index 0000000..e2aa907 --- /dev/null +++ b/board-package-source/libraries/ArduboyFX/examples/loadGameState/loadGameState.ino @@ -0,0 +1,169 @@ +/* ***************************************************************************** + * FX gameState example v1.00 by Mr.Blinky Jan.2023 licenced under CC0 + * ***************************************************************************** + * + * This is a example showing how you can save and load game data to the FX flash + * chip. + * + * Before this example sketch is uploaded and run on the Arduboy FX, make sure + * the fxdata of this sketch has been built and uploaded to the Arduboy FX. + * + * If the Arduboy FX Arduino plugin has been installed you can simply choose the + * 'Build and upload Arduboy FX data' from the Arduino IDE Tools menu. Since the + * data has already been prebuild for this demo you may alsu choose the 'upload + * existing Arduboy FX data' option. + * + * Alternatively the fxdata.txt script file can be build using the fxdata-build.py + * Python script and the fxdata.bin file can be uploaded using the + * fxdata-upload.py, uploader-gui.py, or flash-writer.py (using the -d switch) + * Python scripts. + * + * ***************************************************************************** + * + * The FX library has two functions for saving and loading game data: + * + * uint8_t FX::loadGameState(uint8_t* gameState, size_t size) + * + * void FX::saveGameState(uint8_t* gameState, size_t size) + * + * loadGameState + * ------------- + * + * Loads previously saved game data. It returns 0 if there was no data to load + * or 1 if the data was successfully loaded. + * + * gameState is a pointer to an uint8_t array or to a structure in RAM containing + * your game data. When using a structure for the game data, the structure must be + * cast to an uint8_t array by putting (uint8_t*)& in front of the structures name. + * + * size is the size of the uint8_t array or structure in RAM and is usually + * determined by using the sizeof() operator. + * + * When there is no game data loaded (result 0), the contents of the gameState + * structure remains unchanged. + * + * saveGameState + * ------------- + * + * Saves game data into a 4K flash block that is uniquely assigned to a program. + * On the first save, data is saved at the beginning of the block. Any save + * after that will be appended after previously saved data as a simple method to + * reduce flash wear. Once the new data doesn't fit into the 4K block, the block + * is erased and the new data is stored at the beginning of the block again. + * when an erase is necessary this function takes a bit longer to execute. + * This process is fully transparent and you do not need to worry about it. + * It just explains why sometimes this function may take a bit more time then usual. + * + * gameState and size are the same parameters as for the loadSaveData function. + * + * initilizing FX chip when using save capabilities + * ------------------------------------------------ + * + * To let the FX library know your sketch makes use of save data the FX library + * must be initialized in setup with the following line: + * + * FX::begin(FX_DATA_PAGE, FX_SAVE_PAGE); + * + * The FX_DATA_PAGE, FX_SAVE_PAGE defines are defined in the fxdata.h file that + * will be created by the fxdata-build tool. + * + * creating a save data block + * -------------------------- + * + * In order to use the loadGameState and saveGameState functions, a save section + * must be added to the fxdata.txt file located in the fxdata folder in your + * sketch folder. this save section can be added by typing the word 'savesection' + * (without the quotes)on a line at the end of the fxdata.txt file. + * Any data defined after that will be written into the default save data file. + + * A minimum blank save data file can be generated by adding just two lines: + * + * savesection + * uint16_t 0xFFFF // No saved game state / end of game state + * + * Example of a predefined save data with 5 high scores: + * + * savesection + * uint16_t 30 //size of save data excluding length bytes + * uint16_t 50000 //high scores + * string "KVN" + * uint16_t 40000 + * string "MRB" + * uint16_t 30000 + * string "FLM" + * uint16_t 20000 + * string "VMP" + * uint16_t 10000 + * string "ADB" + * uint16_t 0xFFFF //end of save data / beginning of free space + * //not included in the save data length + * + * when there is a savesection in a fxdata.txt file, the fxbuild.by tool will + * generate 3 files: + * + * fxdata.bin this file is uploaded during development, when uploading + * a sketch through the Arduino IDE or using a emulator. + * It contains both the data and save sections. + * + * fxdata-data.bin contains only the data. This file is used when the sketch + * hexfile is made part of a flash image file. + * fxdata-save.bin contains only the save data. This file is used when the + * sketch hexfile is made part of a flash image file. + * + ******************************************************************************/ + +#include +#include +#include "fxdata/fxdata.h" //created by the fxdata-build.py python script. + +Arduboy2 arduboy; + +// First we create a structure that will contain all the relevant game data that +// needs to be saved. + +struct GameState +{ + char name[20]; // space for a text string + uint16_t count; // A counter that counts the number of times this sketch was +}; // run (and saved data) + +GameState gameState; // This creates the actual gameState in ram. + +void setup() { + arduboy.begin(); // initialize Arduboy. + + FX::begin(FX_DATA_PAGE, FX_SAVE_PAGE); // Initialize FX chip. When using FX save data, + // FX_SAVE_PAGE must also be passed on in FX::begin. + + if (!FX::loadGameState((uint8_t*) &gameState, sizeof(gameState))) // Load saveState from the 4K FX save data block. '(uint8_t*) &' is used + // here to cast a uint8_t pointer to the saveState structure. + { + // This code gets executed only when the function didn't load a saveState (function returned 0) + strcpy(gameState.name, "Hello World !!!"); // copy some introductory text to saveState.name + gameState.count = 1; // set count to 1 for 1st time this sketch is run. + } + else + { + // A previously saved gameState was loaded. + strcpy(gameState.name, "Save state loaded"); // change text + gameState.count ++; // increase the number of times this sketch was run. + } + + FX::saveGameState((uint8_t*) &gameState, sizeof(gameState)); //Save the game state to 4K FX save block + + arduboy.clear(); + arduboy.setCursor(0,32 - 8); + arduboy.print(gameState.name); + arduboy.setCursor(0,32 + 8); + arduboy.print("Number of times this\nsketch is run: "); + arduboy.print(gameState.count); + FX::display(); +} + +void loop() { + + if (!arduboy.nextFrame()) return; //waint for next frame + + if (arduboy.buttonsState()) arduboy.exitToBootloader(); // exit to bootloader. + +} diff --git a/board-package-source/libraries/ArduboyFX/library.properties b/board-package-source/libraries/ArduboyFX/library.properties index 336a8fa..aa30732 100644 --- a/board-package-source/libraries/ArduboyFX/library.properties +++ b/board-package-source/libraries/ArduboyFX/library.properties @@ -1,5 +1,5 @@ name=ArduboyFX -version=1.0.6 +version=1.0.7 author=Mr.Blinky maintainer=mstr.blinky@gmail.com sentence=The Arduboy FX library. diff --git a/board-package-source/libraries/ArduboyFX/src/ArduboyFX.cpp b/board-package-source/libraries/ArduboyFX/src/ArduboyFX.cpp index edfb0c8..b1ac43a 100644 --- a/board-package-source/libraries/ArduboyFX/src/ArduboyFX.cpp +++ b/board-package-source/libraries/ArduboyFX/src/ArduboyFX.cpp @@ -32,6 +32,25 @@ void FX::begin() void FX::begin(uint16_t developmentDataPage) { disableOLED(); + #ifdef ARDUINO_ARCH_AVR + const uint8_t* vector = FX_DATA_VECTOR_KEY_POINTER; + asm volatile( + "lpm r18, z+ \n" + "lpm r19, z+ \n" + "lpm r21, z+ \n" + "lpm r20, z+ \n" + "subi r18, 0x18 \n" + "sbci r19, 0x95 \n" + "brne .+2 \n" // skip if FX_DATA_VECTOR_KEY_POINTER != FX_VECTOR_KEY_VALUE + "movw %A[devdata], r20 \n" + "sts %[datapage]+0, %A[devdata] \n" + "sts %[datapage]+1, %B[devdata] \n" + : "+&z" (vector), + [devdata] "+&r" (developmentDataPage) + : [datapage] "" (&programDataPage) + : "r18", "r19", "r20", "r21" + ); + #else if (pgm_read_word(FX_DATA_VECTOR_KEY_POINTER) == FX_VECTOR_KEY_VALUE) { programDataPage = (pgm_read_byte(FX_DATA_VECTOR_PAGE_POINTER) << 8) | pgm_read_byte(FX_DATA_VECTOR_PAGE_POINTER + 1); @@ -40,6 +59,7 @@ void FX::begin(uint16_t developmentDataPage) { programDataPage = developmentDataPage; } + #endif wakeUp(); } @@ -47,6 +67,37 @@ void FX::begin(uint16_t developmentDataPage) void FX::begin(uint16_t developmentDataPage, uint16_t developmentSavePage) { disableOLED(); + #ifdef ARDUINO_ARCH_AVR + const uint8_t* vector = FX_DATA_VECTOR_KEY_POINTER; + asm volatile( + "lpm r18, z+ \n" + "lpm r19, z+ \n" + "lpm r21, z+ \n" + "lpm r20, z+ \n" + "subi r18, 0x18 \n" + "sbci r19, 0x95 \n" + "brne .+2 \n" // skip if FX_DATA_VECTOR_KEY_POINTER != FX_VECTOR_KEY_VALUE + "movw %A[devdata], r20 \n" + "sts %[datapage]+0, %A[devdata] \n" + "sts %[datapage]+1, %B[devdata] \n" + "lpm r18, z+ \n" + "lpm r19, z+ \n" + "lpm r21, z+ \n" + "lpm r20, z+ \n" + "subi r18, 0x18 \n" + "sbci r19, 0x95 \n" + "brne .+2 \n" // skip if FX_SAVE_VECTOR_KEY_POINTER != FX_VECTOR_KEY_VALUE + "movw %A[devsave], r20 \n" + "sts %[savepage]+0, %A[devsave] \n" + "sts %[savepage]+1, %B[devsave] \n" + : "+&z" (vector), + [devdata] "+&r" (developmentDataPage), + [devsave] "+&r" (developmentSavePage) + : [datapage] "" (&programDataPage), + [savepage] "" (&programSavePage) + : "r18", "r19", "r20", "r21" + ); + #else if (pgm_read_word(FX_DATA_VECTOR_KEY_POINTER) == FX_VECTOR_KEY_VALUE) { programDataPage = (pgm_read_byte(FX_DATA_VECTOR_PAGE_POINTER) << 8) | pgm_read_byte(FX_DATA_VECTOR_PAGE_POINTER + 1); @@ -63,6 +114,7 @@ void FX::begin(uint16_t developmentDataPage, uint16_t developmentSavePage) { programSavePage = developmentSavePage; } + #endif wakeUp(); } @@ -207,7 +259,6 @@ void FX::seekSave(uint24_t address) "adc %C[addr], r0 \n" :[addr] "+&r" (address) :[page] "" (&programSavePage) - :"r24" ); #else // C++ version for non AVR platforms address += (uint24_t)programSavePage << 8; @@ -406,6 +457,183 @@ void FX::readSaveBytes(uint24_t address, uint8_t* buffer, size_t length) readBytesEnd(buffer, length); } +uint8_t FX::loadGameState(uint8_t* gameState, size_t size) // ~54 bytes +{ + #ifdef ARDUINO_ARCH_AVR + uint8_t result asm("r24"); + asm volatile( + "ldi r22, 0 \n" //seekSave(0) + "ldi r23, 0 \n" + "ldi r24, 0 \n" + "call %x3 \n" //seekSave uses r20, r21, r22, r23, r24 + "movw r18, r26 \n" //save size + "movw r20, r30 \n" //save gameState + "0: \n" + "ldi r22,0 \n" //result = 0 + "1: \n" + "call %x4 \n" //readPendingUInt16 uses r24, r25 + "cp r24, r18 \n" + "cpc r25, r19 \n" + "brne 4f \n" //if (readPendingUInt16 != size) break + " \n" + "movw r26, r18 \n" //restore size + "movw r30, r20 \n" //restore gameState + "ldi r22, 0 \n" //result = 0 + "2: \n" //do + "call %x5 \n" // data = readPendingUint8 + "st z+, r24 \n" // addr = data + "sbiw r26, 1 \n" // size-- + "brne 2b \n" //until size == 0 + "ldi r22, 1 \n" //result = 1 + "rjmp 1b \n" //next + "4: \n" + "call %x6 \n" //readEnd + "mov r24, r22 \n" //return result + : [addr] "+&z" (gameState), + [size] "+&x" (size), + [val] "=&r" (result) + : "i" (seekSave), + "i" (readPendingUInt16), + "i" (readPendingUInt8), + "i" (readEnd) + : "r18", "r19", "r20", "r21" + ); + #else + seekSave(0); + uint8_t result = 0; + while (readPendingUInt16() == size) // if gameState size not equal, most recent gameState has been read or there is no gameState + { + for (uint16_t i = 0; i < size; i++) + { + uint8_t data = readPendingUInt8(); + gameState[i] = data; + } + { + result = 1; // signal gameState loaded + } + } + readEnd(); + #endif + return result; +} + +void FX::saveGameState(uint8_t* gameState, size_t size) // ~152 bytes locates free space in 4K save block and saves the GamesState. +{ // if there is not enough free space, the block is erased prior to saving + register size_t sz asm("r18") = size; + #ifdef ARDUINO_ARCH_AVR + asm volatile( + "ldi r26, 0 \n" //addr = 0 + "ldi r27, 0 \n" + "1: \n" + "movw r22, r26 \n" //uint24_t addr + "ldi r24, 0 \n" + "call %x2 \n" //seekSave uses r20, r21, r22, r23, r24 + "call %x3 \n" //readPendingLastUInt16 uses r24, r25 + "movw r22, r26 \n" //save addr + "adiw r26, 2 \n" //addr += 2 for size word + "add r26, r18 \n" //addr += size + "adc r27, r19 \n" + "cp r24, r18 \n" + "cpc r25, r19 \n" + "breq 1b \n" //readPendingLastUInt16 == size + " \n" + "subi r24, 0xFF \n" //if result of readPendingLastUInt16 != 0xFFFF + "sbci r25, 0xFF \n" + "brne 2f \n" //erase block + " \n" + "subi r26, lo8(4094+1) \n" + "sbci r27, hi8(4094+1) \n"// addr < 4094+1 (last two bytes in 4K block always 0xFF) + "movw r26, r22 \n"// addr -= size - 2 point to start of free space + "brcs 3f \n" + "2: \n" //erase 4K save block at addr + "call %x4 \n" //writeEnable + "ldi r20, 0 \n" + "lds r21, %[page]+0 \n" + "lds r22, %[page]+1 \n" + "ldi r24, %[erase] \n" //SFC_ERASE + "call %x5 \n" //seekCommand + "sbi %[fxport], %[fxbit] \n" //disable + "call %x6 \n" //waitWhileBusy + "ldi r26, 0 \n" //addr = 0 + "ldi r27, 0 \n" + "3: \n" + "ldi r23, 0xFC \n" // int8_t shiftstate = -4 + "4: \n" + "call %x4 \n" //writeEnable + "mov r20, r26 \n" //addr + "lds r21, %[page]+0 \n" + "add r21, r27 \n" + "lds r22, %[page]+1 \n" + "adc r22, r1 \n" + "ldi r24, %[write] \n" //SFC_WRITE + "call %x5 \n" //seekCommand + "5: \n" + "mov r24, r19 \n" + "sbrc r23, 1 \n" //if (shiftstate & 3 == 0) writebyte(size >> 8) + "mov r24, r18 \n" //if (shiftstate & 3 == 2) writebyte(size & 0xFF) + "sbrc r23, 0 \n" //else writeByte(gameState++); + "ld r24, z+ \n" //saveState + "call %x7 \n" //writeByte + "asr r23 \n" //shiftstate >>= 1 + "brcc .+4 \n" //if (shiftstate == -1) size-- + "subi r18, 1 \n" + "sbci r19, 0 \n" + "breq 6f \n" //size == 0 + " \n" + "adiw r26, 1 \n" //addr++ + "and r26, r26 \n" + "brne 5b \n" //while addr & 0xFF != 0 (not end of page) + "6: \n" + "sbi %[fxport], %[fxbit] \n" //disable + "call %x6 \n" //waitWhileBusy + "cp r18, r1 \n" + "cpc r19, r1 \n" + "brne 4b \n" //while size != 0 + :[state] "+&z" (gameState), + [size] "+&r" (sz) + : "" (seekSave), + "" (readPendingLastUInt16), + "" (writeEnable), + "" (seekCommand), + "" (waitWhileBusy), + "" (writeByte), + [fxport] "i" (_SFR_IO_ADDR(FX_PORT)), + [fxbit] "i" (FX_BIT), + [erase] "i" (SFC_ERASE), + [write] "i" (SFC_WRITE), + [page] "" (&programSavePage) + : "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27" + ); + #else + uint16_t addr = 0; + for(;;) // locate end of previous gameStates + { + seekSave(addr); + if (readPendingLastUInt16() != size) break; //found end of previous gameStates + addr += size + 2; + } + if ((addr + size) > 4094) //is there enough space left? last two bytes of 4K block must always be unused (0xFF) + { + eraseSaveBlock(0); // erase save block + waitWhileBusy(); // wait for erase to complete + addr = 0; // write saveState at the start of block + } + + while (size) + { + writeEnable(); + seekCommand(SFC_WRITE, (uint24_t)(programSavePage << 8) + addr); + do + { + writeByte(*gameState++); + if (--size == 0) break; + } + while ((uint8_t)++addr); // write bytes until end of a page + disable(); // start writing the (partial) page + waitWhileBusy(); // wait for page write to complete + } + #endif +} void FX::eraseSaveBlock(uint16_t page) { @@ -1062,7 +1290,6 @@ void FX::drawNumber(uint16_t n, int8_t digits) void FX::drawNumber(int32_t n, int8_t digits) { - asm volatile("dbg:\n"); if (n < 0) { n = -n; diff --git a/board-package-source/libraries/ArduboyFX/src/ArduboyFX.h b/board-package-source/libraries/ArduboyFX/src/ArduboyFX.h index 1209929..ed035eb 100644 --- a/board-package-source/libraries/ArduboyFX/src/ArduboyFX.h +++ b/board-package-source/libraries/ArduboyFX/src/ArduboyFX.h @@ -231,7 +231,7 @@ class FX static void seekDataArray(uint24_t address, uint8_t index, uint8_t offset, uint8_t elementSize); - static void seekSave(uint24_t address); // selects flashaddress of program save area for reading and starts the first read + static void seekSave(uint24_t address) __attribute__ ((noinline)); // selects flashaddress of program save area for reading and starts the first read static inline uint8_t readUnsafe() __attribute__((always_inline)) // read flash data without performing any checks and starts the next read. { @@ -273,7 +273,11 @@ class FX static void readSaveBytes(uint24_t address, uint8_t* buffer, size_t length); - static void eraseSaveBlock(uint16_t page); + static uint8_t loadGameState(uint8_t* gameState, size_t size) __attribute__ ((noinline)); //loads GameState from program exclusive 4K save data block. + + static void saveGameState(uint8_t* gameState, size_t size) __attribute__ ((noinline)); // Saves GameState in RAM to programes exclusive 4K save data block. + + static void eraseSaveBlock(uint16_t page); // erases 4K flash block static void writeSavePage(uint16_t page, uint8_t* buffer);