diff --git a/firmware/main.hex b/firmware/main.hex index 3250176..c2e6414 100644 --- a/firmware/main.hex +++ b/firmware/main.hex @@ -1,164 +1,187 @@ -:100000000C94E8000C94D1030C9405010C940501A8 -:100010000C9405010C9405010C9405010C94050148 -:100020000C9405010C9405010C9405010C94050138 -:100030000C9405010C9405010C9405010C94050128 -:100040000C9405010C9405010C9405010C94050118 -:100050000C9405010C9405010C9405010C94050108 -:100060000C9405010C9405010C9405010C940501F8 -:100070000C9405010C9405010C9405012101230148 -:10008000260128012B012D013001320135013701F4 -:1000900039013C013E014001420144014601480151 -:1000A0004A01BD01BD01BD01BD014C014E01500120 -:1000B0005201BD01BD01BD01BD01540156015801F0 -:1000C0005A015C015E016001620164016601680120 -:1000D0006A016C016E0170017201BD01BD01BD01BB -:1000E000BD0174017601BB0178017A017E018101B5 -:1000F000850188018E018B0187018A018D019001A4 -:1001000092019401960198019A019C019E01A0011F -:10011000A201A401A601A801AA01AC01AE01B0018F -:10012000B201BD01BD01BD01BD01B701B401B60100 -:10013000BA01CA01CE01CC01D001D601DD01DF0137 -:10014000E101E301ED01F0014402460248024A02E6 -:100150004C024E02500252025402560258025C02F5 -:10016000090212000101008096090400000000004D -:10017000000012011001FF000008C016DC0500029B -:10018000010200011E0349004E004C0020005200F5 -:100190006500740072006F002D00500072006F0047 -:1001A00067002A0349006E00660069006E0069005E -:1001B000740065004E00650073004C006900760015 -:1001C000650073002E0063006F006D0004030904D6 -:1001D00011241FBECFEFD4E0DEBFCDBF11E0A0E001 -:1001E000B1E0E0E2FAE002C005900D92A230B10762 -:1001F000D9F711E0A2E0B1E001C01D92A533B1072B -:10020000E1F70E94E5040C940E050C94000011B86F -:100210008FEF82B914B885B917B888B98AB18471DB -:100220008AB98BB18B6E8BB950985898089590E02D -:100230008B35910508F0A1C0FC01E25CFF4F0C94E6 -:10024000080511B895C08FEF81B992C012B890C05F -:100250008FEF82B98DC014B88BC08FEF84B988C07E -:1002600015B886C08FEF85B983C017B881C018B89C -:100270007FC08FEF88B97CC038987AC0389A78C030 -:10028000409876C0409A74C0399872C0399A70C04C -:1002900041986EC0419A6CC03A986AC03A9A68C058 -:1002A000429866C0429A64C03B9862C03B9A60C064 -:1002B00043985EC0439A5CC03C985AC03C9A58C070 -:1002C000449856C0449A54C03D9852C03D9A50C07C -:1002D00045984EC0459A4CC03E984AC03E9A48C088 -:1002E000469846C0469A44C03F9842C03F9A40C094 -:1002F000479A3EC08AB184718AB93AC08BB1847181 -:1003000002C08BB18B6E8BB933C0509831C05898F6 -:10031000509A2EC05098589A2BC05098589828C080 -:10032000519826C0519A24C0599822C0599A20C089 -:1003300053981EC0539A1CC05B981AC05B9A18C091 -:10034000559816C0559A14C05D9812C05D9A10C099 -:1003500056980EC0569A0CC05E980AC05E9A08C0A5 -:10036000579806C0579A04C05F9A02C05F9A5F9878 -:1003700080E00895479A4798FBCF81E8089590E080 -:10038000FC01E058F109EB30F105A0F5E756FF4F0D -:100390000C94080562B922C08FEF84B965B91EC0FC -:1003A0008FEF84B965B9479A479805C08FEF84B934 -:1003B00065B95F9A5F9814B811C061B90FC064B98C -:1003C0000DC067B90BC09AB1862F846189238AB9A1 -:1003D0008AB16B7E682B6AB901C068B980E0089564 -:1003E0009BB1862F846189238BB98BB16B7E682B7F -:1003F0006BB9F4CF82E80895813A61F0823AB9F09E -:10040000803A11F58FEF84B965B9479A479814B8C7 -:1004100042B916C08FEF84B965B9479A479814B8A6 -:1004200042B967FF02C041980BC0419A09C042B966 -:100430008FEF84B9603230F415B8479A479814B8F2 -:1004400080E0089565B9F9CF83E80895803B61F4B1 -:1004500022B98FEF84B945B9479A479865B95F9A31 -:100460005F9814B880E0089584E80895CF93DF93EF -:10047000EB0190E0805C91098C309105F8F48C558B -:100480009F4FFC010C94080580B113C083B111C0CB -:1004900086B10FC089B10DC082B10BC085B109C052 -:1004A00088B107C08BB105C081B103C084B101C060 -:1004B00087B1888380E003C08AB1FBCF85E8DF91F4 -:1004C000CF910895CF93FC01C081CC1FCC27CC1FC6 -:1004D0008181813079F582819FEF980F9E3718F4E2 -:1004E0000E94170128C09FE7980F9E3120F4648175 -:1004F0000E94BF0120C09FE5980F9E3028F44481E0 -:1005000065810E94FC0117C09FE4980F9E3030F473 -:100510002481458163810E9426020DC09FE3980FCC -:100520009E3358F463E071E00E943602809302012A -:10053000CF5F03C080E88093020122E031E0309376 -:100540001A01209319018C2FCF91089581E008950D -:10055000CF93DF9360911B01635067FDA4C080912E -:100560001801CCE0D0E0C81BD109C15EDE4F8091FC -:1005700017018D3209F085C0683009F092C083EC14 -:1005800080930B018AE58093010110920A01888112 -:10059000807621F0CE010E94620260C08A811092B2 -:1005A00014019981911106C01092150124E131E0E6 -:1005B00082E050C0953019F480931C013DC0963004 -:1005C000A9F59B81913019F482E791E004C0923043 -:1005D00041F480E691E090931A018093190182E141 -:1005E00021C09330F1F4811108C08CEC91E090931C -:1005F0001A018093190184E015C0813041F482EA28 -:1006000091E090931A01809319018AE20BC0823025 -:1006100041F484E891E090931A01809319018EE1EE -:1006200001C080E090E490930A0118C0983079F0FE -:10063000993031F480931E0124E131E080E00AC05A -:1006400081E09A3009F080E024E131E003C02EE13E -:1006500031E081E030931A01209319018F3F39F482 -:10066000988197FD8E8190E890930A0107C09F8141 -:10067000911104C09E81981708F4892F809300017E -:1006800010C080910A0187FF0CC0CE010E94A60213 -:100690008F3F21F48EE18093010103C081111092FC -:1006A000000110921B018091010184FF4DC08091D7 -:1006B00000018F3F09F448C0C82F893008F0C8E016 -:1006C0008C1B8093000180910B0198E8892780930F -:1006D0000B01CC2361F18091190190911A012091B5 -:1006E0000A0126FF12C0ACE0B1E02BE031E020951A -:1006F0003095280F391F4C2F4A0FF901EA0FFB1FC5 -:10070000E491ED934A13F9CF09C0ECE0F1E0DC018C -:100710002C2F2E0F3D9131932E13FCCF01962FEFEE -:100720002C0F820F911D90931A01809319016C2F49 -:100730008CE091E00E94CD03CC5FCC3019F08FEFBC -:1007400080930001C093010184E199B1947131F467 -:100750008150D9F710921C0110921601DF91CF91B0 -:100760000895E9E6F0E0808182608083E89A089548 -:10077000A82FB92F80E090E041E050EA609530E08A -:1007800009C02D9182279795879510F0842795278A -:10079000305EC8F36F5FA8F30895EADF8D939D93F1 -:1007A0000895CF93CFB7CF93DF93C3954C9BE9F7D1 -:1007B0004C9B0BC04C9B09C04C9B07C04C9B05C07D -:1007C0004C9B03C04C9B01C089C06F93C091180122 -:1007D000DD27C15EDE4F2F9365E54C9B03C02F9153 -:1007E0006F91E6CF0F931F934F9320E040E15F930B -:1007F00009B1047104FB27F93F9350E03BE039C095 -:10080000147140642F77012F5F5F1EC0406819B1DB -:1008100014712F7752501FC0406409B12F770471B3 -:10082000D1F15F5F00C023C0406219B12F7714710E -:1008300091F15F5F00C025C004711027515012F480 -:100840005D5F0000115027952C3F19B1C8F6147157 -:100850000127015027952C3FC8F64227499309B13B -:10086000047110274F73115027952C3FA8F6469519 -:10087000469519B1147179F00127015027952C3F45 -:1008800098F66B5A60F3315009B1B0F600C011E030 -:100890001CBB002717C03B503195C31BD04011E053 -:1008A0001CBB0881033CF9F00B34E9F020911601E0 -:1008B0001981110F1213EDCF093651F10D3211F0DC -:1008C000013E39F700931D013F915F914F911F91B8 -:1008D0000F912F916F91CCB3C0FD67CFDF91CF9176 -:1008E000CFBFCF91189520911D01222369F310915C -:1008F0001B01112339F534303AF130931B01209359 -:100900001701109118013BE0311B309318011CC0F6 -:1009100000911B010130B4F40AE53091010134FD6E -:1009200014C000930101CBE0D1E013C0052710E013 -:1009300000C000000BB91AC0052710E0221F1DC01F -:1009400010E021C04AE502C032ED432FC4E1D0E0FF -:1009500032E01AB114615C9A0BB11AB954E120E883 -:1009600065E320FF05270BB9279517951C3FF0F687 -:100970006695B8F7B1F720FF05270BB927951795AE -:100980001C3FD0F62795179517FF052700001C3F41 -:100990000BB9B0F629913A9519F70B7E10911C010D -:1009A000110FC651D0400BB911F01093160111E090 -:1009B0001CBB00611AB11B7E402F4B7E54E05A9540 -:1009C000F1F70BB91AB94BB97FCF2EE088E190E06F -:1009D0000FB6F894A895809360000FBE2093600036 -:1009E0000E94B103549A80E0815041F0A895EFE94C -:1009F000FFE03197F1F700C00000F6CF54980E9455 -:100A00000701519A599A7894A8950E94A802FCCFA0 -:100A1000EE0FFF1F0590F491E02D0994F894FFCF9D -:020A2000FF5A7B +:100000000C94D1000C94B1040C94EE000C94EE000E +:100010000C94EE000C94EE000C94EE000C94EE00A8 +:100020000C94EE000C94EE000C94EE000C94EE0098 +:100030000C94EE000C94EE000C94EE000C94EE0088 +:100040000C94EE000C94EE000C94EE000C94EE0078 +:100050000C94EE000C94EE000C94EE000C94EE0068 +:100060000C94EE000C94EE000C94EE000C94EE0058 +:100070000C94EE000C94EE000C94EE00C601C80146 +:10008000CB01CD01D001D201D501D701DA01DC01CC +:10009000DE01E101E301E501E701E901EB01ED0129 +:1000A000EF01C401C401C401C401F101F301F50170 +:1000B000F701C401C401C401C401F901FB01FD0140 +:1000C000FF01010203020502070209020B020D02F1 +:1000D0000F021102130215021702C401C401C40168 +:1000E000C40119021B021D021F022102250228025F +:1000F0002C022F02350232022E0231023402370264 +:1001000039023B023D023F024102430245024702DF +:1001100049024B024D024F0251025302550257024F +:100120005902C401C401C401C4015E025B025D0244 +:100130006102040309042A0349006E006600690095 +:100140006E006900740065004E00650073004C008D +:1001500069007600650073002E0063006F006D007B +:100160001E0349004E004C00200052006500740040 +:1001700072006F002D00500072006F0067001201C6 +:100180001001FF000008C016DC050002010200019A +:10019000090212000101008096090400000000001D +:1001A000000011241FBECFEFD4E0DEBFCDBF11E0B1 +:1001B000A0E0B1E0EEE8FBE002C005900D92A230B5 +:1001C000B107D9F711E0A2E0B1E001C01D92A5335B +:1001D000B107E1F70E9453010C94C5050C9400008F +:1001E00011B88FEF82B914B885B917B888B98AB138 +:1001F00084718AB98BB18B6E8BB95098589851988D +:10020000599A08950E94F000399A419A389A409874 +:100210003A9A429A3C9A449A3D9A459A3F9A479A0A +:1002200047988FEF84B915B8479A479814B812B811 +:1002300081B914B885B95998519A08950E94F0006F +:10024000399A419A3C9A449A3D9A459A509A589ABA +:100250003F9A479A4798579A5F9A5F988FEF84B969 +:1002600015B8479A479814B884B915B85F9A5F983B +:1002700014B812B881B914B885B95998519A08952B +:10028000813049F0813020F0823049F086E90895CC +:100290000E94F00002C00E94020180E008950E94C6 +:1002A0001E0180E008952EE088E190E00FB6F894FA +:1002B000A895809360000FBE209360000E948C037D +:1002C000549A20E040EA5FE004C0A895CA01019773 +:1002D000F1F72150D1F754980E94F0007894A89536 +:1002E0000E949303FCCF9FEF94B985B9479A479832 +:1002F00045B962B95898509A5098589A14B80895C8 +:10030000882311F080EA0895862F642F422F0E94DF +:10031000730180E00895509858984098419A429A05 +:1003200062B99FEF94B985B9479A479814B800000D +:10033000000087FF03C0409A419801C0409A000026 +:1003400000000000000083B14098419A0895CF93C7 +:10035000DF93E901803811F081EA06C0862F642F0F +:100360000E948B01888380E0DF91CF910895E82F70 +:10037000F0E0EB35F10540F4E25CFF4FEE0FFF1FBC +:100380000590F491E02D09948CE8089511B897C078 +:100390008FEF81B994C012B892C08FEF82B98FC02D +:1003A00014B88DC08FEF84B98AC015B888C08FEF9C +:1003B00085B985C017B883C018B881C08FEF88B9D8 +:1003C0007EC038987CC0389A7AC0409878C0409AED +:1003D00076C0399874C0399A72C0419870C0419AF9 +:1003E0006EC03A986CC03A9A6AC0429868C0429A05 +:1003F00066C03B9864C03B9A62C0439860C0439A11 +:100400005EC03C985CC03C9A5AC0449858C0449A1C +:1004100056C03D9854C03D9A52C0459850C0459A28 +:100420004EC03E984CC03E9A4AC0469848C0469A34 +:1004300046C03F9844C03F9A42C0479840C0479A40 +:100440003EC08AB184718AB93AC08BB1847102C04E +:100450008BB18B6E8BB933C0509831C05898509A7D +:100460002EC05098589A2BC05098589828C0519830 +:1004700026C0519A24C0599822C0599A20C0539836 +:100480001EC0539A1CC05B981AC05B9A18C055983E +:1004900016C0559A14C05D9812C05D9A10C0569847 +:1004A0000EC0569A0CC05E980AC05E9A08C0579853 +:1004B00006C0579A04C05F9A02C05F9A5F9880E0B6 +:1004C0000895479A479880E00895853891F18638D5 +:1004D00070F48238E9F0833828F48038B9F0813834 +:1004E00099F418C08338C1F0843871F41BC088387F +:1004F00031F1893828F48638F1F0873829F41DC0A5 +:10050000893839F18A3841F18DE8089562B922C0FD +:100510008FEF84B965B91EC08FEF84B965B9479A6A +:10052000479805C08FEF84B965B95F9A5F9814B892 +:1005300011C061B90FC064B90DC067B90BC08AB1F1 +:10054000962F946198239AB98AB16B7E862B8AB9CB +:1005500001C068B980E008958BB1962F946198230B +:100560009BB98BB16B7E862B8BB980E00895813A65 +:1005700071F0823AC9F0803A11F08EE808958FEF59 +:1005800084B965B9479A479814B842B917C08FEF34 +:1005900084B965B9479A479814B842B967FF02C051 +:1005A00041980CC0419A0AC042B9603248F48FEFBA +:1005B00084B9607865B9479A479814B880E008957F +:1005C0008FEF84B965B9479A479814B880E00895C9 +:1005D000803B11F08FE8089522B98FEF84B945B9B7 +:1005E000479A479865B95F9A5F9814B880E0089574 +:1005F000FB01853C59F1863C70F4823C09F1833C57 +:1006000028F4803CC9F0813CA9F418C0833CD1F0A7 +:10061000843C81F419C0883CF9F0893C28F4863C7C +:10062000B9F0873C39F416C08A3CD1F08A3CB0F06E +:100630008B3CD1F080E9089580B113C083B111C023 +:1006400086B10FC089B10DC082B10BC085B109C0A0 +:1006500088B107C08BB105C081B103C084B101C0AE +:1006600087B1808380E008958AB1808380E0089517 +:1006700081E008951F93FC0110E0808187FD11E067 +:100680008181823031F1833041F18130C9F582813D +:10069000803B28F4803A68F4803820F006C0803C23 +:1006A00068F012C00E94B7012CC064810E946502EC +:1006B00028C0658144810E94B70223C063814581BF +:1006C00024810E94E8021DC063E071E00E94F802EC +:1006D00013C082810E94400114C08281803830F4AE +:1006E0006581448123810E9480010BC06581448122 +:1006F00023E031E00E94A701809302011F5F03C045 +:1007000080E88093020182E091E090931A01809347 +:100710001901812F1F910895E9E6F0E08081826040 +:100720008083E89A08951F93CF93DF9360911B0114 +:10073000635067FDA5C080911801CCE0D0E0C81BD4 +:10074000D109C15EDE4F809117018D3209F085C05D +:10075000683009F093C083EC80930B018AE58093A5 +:10076000000110920A018881807641F0CE010E943A +:100770003A03282F8F3F09F45FC065C09A81109219 +:1007800014018981882321F41092150122E04DC0C3 +:10079000853019F490931C0147C08630B1F58B81E8 +:1007A000813019F48EE791E004C0823041F480E991 +:1007B00091E090931A018093190122E122C08330C5 +:1007C000F9F48A81882341F482E391E090931A013D +:1007D0008093190124E015C0813041F486E391E053 +:1007E00090931A01809319012AE20BC0823041F4E0 +:1007F00080E691E090931A01809319012EE101C0E7 +:1008000020E080E480930A011EC0883021F421E0BA +:100810008EE191E00CC0893019F490931E0104C060 +:100820008A3011F421E001C020E084E191E090934E +:100830001A018093190107C0888187FD2E8180E805 +:1008400080930A0106C08F81882319F48E81821754 +:1008500008F0822F8093010111C080910A0187FF67 +:100860000DC0CE010E9438038F3F21F48EE18093AA +:10087000000104C0882311F01092010110921B01A5 +:100880008091000184FF46C0809101018F3F09F4EF +:1008900041C0182F893008F018E0811B80930101B6 +:1008A00080910B0198E8892780930B01112321F196 +:1008B0002091190130911A0180910A0186FF0AC026 +:1008C000912FF901ACE0B1E084918D933196915074 +:1008D000D9F708C0912FD901ECE0F1E08D91819317 +:1008E0009150E1F7C90101961150810F911D1F5FD1 +:1008F00090931A01809319018CE091E0612F0E947E +:10090000AD04612F6C5F6C3019F08FEF80930101A3 +:100910006093000194E189B1847131F49150D9F769 +:1009200010921C0110921601DF91CF911F91089532 +:10093000A82FB92F80E090E041E050EA609530E0C8 +:1009400009C02D9182279795879510F084279527C8 +:10095000305EC8F36F5FA8F30895EADF8D939D932F +:100960000895CF93CFB7CF93DF93C3954C9BE9F70F +:100970004C9B0BC04C9B09C04C9B07C04C9B05C0BB +:100980004C9B03C04C9B01C089C06F93C091180160 +:10099000DD27C15EDE4F2F9365E54C9B03C02F9191 +:1009A0006F91E6CF0F931F934F9320E040E15F9349 +:1009B00009B1047104FB27F93F9350E03BE039C0D3 +:1009C000147140642F77012F5F5F1EC0406819B11A +:1009D00014712F7752501FC0406409B12F770471F2 +:1009E000D1F15F5F00C023C0406219B12F7714714D +:1009F00091F15F5F00C025C004711027515012F4BF +:100A00005D5F0000115027952C3F19B1C8F6147195 +:100A10000127015027952C3FC8F64227499309B179 +:100A2000047110274F73115027952C3FA8F6469557 +:100A3000469519B1147179F00127015027952C3F83 +:100A400098F66B5A60F3315009B1B0F600C011E06E +:100A50001CBB002717C03B503195C31BD04011E091 +:100A60001CBB0881033CF9F00B34E9F0209116011E +:100A70001981110F1213EDCF093651F10D3211F01A +:100A8000013E39F700931D013F915F914F911F91F6 +:100A90000F912F916F91CCB3C0FD67CFDF91CF91B4 +:100AA000CFBFCF91189520911D01222369F310919A +:100AB0001B01112339F534303AF130931B01209397 +:100AC0001701109118013BE0311B309318011CC035 +:100AD00000911B010130B4F40AE53091000134FDAE +:100AE00014C000930001CBE0D1E013C0052710E053 +:100AF00000C000000BB91AC0052710E0221F1DC05E +:100B000010E021C04AE502C032ED432FC4E1D0E03D +:100B100032E01AB114615C9A0BB11AB954E120E8C1 +:100B200065E320FF05270BB9279517951C3FF0F6C5 +:100B30006695B8F7B1F720FF05270BB927951795EC +:100B40001C3FD0F62795179517FF052700001C3F7F +:100B50000BB9B0F629913A9519F70B7E10911C014B +:100B6000110FC651D0400BB911F01093160111E0CE +:100B70001CBB00611AB11B7E402F4B7E54E05A957E +:0E0B8000F1F70BB91AB94BB97FCFF894FFCF3C +:020B8E005AFF0C :00000001FF diff --git a/firmware/source/io.c b/firmware/source/io.c index 27005c9..11bb70e 100644 --- a/firmware/source/io.c +++ b/firmware/source/io.c @@ -1,9 +1,42 @@ #include "io.h" +//================================================================================================= +// +// I/O operations +// This file includes all the io functions possible to be called from the io dictionary. +// +// See description of the commands contained here in shared/shared_dictionaries.h +// +//================================================================================================= + +/* Desc:Function takes an opcode which was transmitted via USB + * then decodes it to call designated function. + * shared_dict_io.h is used in both host and fw to ensure opcodes/names align + * Pre: Macros must be defined in firmware pinport.h + * opcode must be defined in shared_dict_io.h + * Post:function call complete. + * Rtn: SUCCESS if opcode found, ERR_UNKN_IO_OPCODE_ONLY if opcode not present. + */ +uint8_t io_opcode_only( uint8_t opcode ) +{ + switch (opcode) { + case IO_RESET: io_reset(); break; + case NES_INIT: nes_init(); break; + case SNES_INIT: snes_init(); break; + default: + //macro doesn't exist + return ERR_UNKN_IO_OPCODE_ONLY; + } + + return SUCCESS; + +} //pullup as many cart pins as possible //goal to be safe state for all hardware -void io_pullup() +//doesn't currently contain any checks to report error/success from +//this is intended to be the "reset" safest condition for the kazzo +void io_reset() { //pull up addr[7:0] bus _ADDR_IP(); @@ -18,10 +51,10 @@ void io_pullup() _CTL_HI(); //pull up aux port + //Aux port contains EXP /OE control + //pull up on EXP FF should disable FF ouput _AUX_IP(); _AUX_HI(); - //Aux port EXP /OE control - //pull up on EXP FF should disable FF ouput //EXP0 input no pullup //Lots of possibilities, ~safe bet it will have it's own pull-up/down if needed. @@ -32,4 +65,127 @@ void io_pullup() _EXP0_FLT(); //LED LAST displaying complete.. + //planning to have LED DIM at power on to signify kazzo is in default + //mostly all pins pulled up state. + //gives some insight to current state of kazzo since it doesn't reset itself + //or if kazzo does reset itself due to WDT dim LED can help detect that. + _LED_IP(); //DIM pulled up + //_LED_OP(); //BRIGHT full power + //boot with LED on/pulled up to differentiate bettwen BL/RUN + _LED_ON(); + } + +//NES cartridge interfacing setup +//set outputs as required +//latch address of $0000 +//disable NES cart memories +void nes_init() +{ + //start with a reset + //expecting user to do this but just to be sure + io_reset(); + + //enable control outputs and disable memories + //PRG-ROM + _ROMSEL_OP(); + _ROMSEL_HI(); + //WRAM (and state of m2 during first half of CPU cycle) + _M2_OP(); + _M2_LO(); + //CPU RD + _PRGRW_OP(); + _PRGRW_RD(); + + //other control pins are inputs, leave as IP pullup from reset + + //disable any CHR/VRAM memories with CHR /RD /WR + //prior to setting PPU A13 & /A13 which are /CE pins + //doing this helps ensure data bus is clear before + //using it for AHL clocking + _CSRD_OP(); + _CSRD_HI(); + _CSWR_OP(); + _CSWR_HI(); + + //memories are now disabled Data bus should be clear + + //setup AHL FF + _AHL_OP(); + _AHL_CLK(); + + //now meet conditions to call other macros + //setup address $0000 + _ADDRH_SET(0x00); + _ADDR_LO(); + + //default state of ADDR[7:0] + _ADDR_OP(); + + //default state data bus pulled up + _DATA_IP(); + _DATA_HI(); + + //turn LED off + _LED_OFF(); + //set as OP for future commands to utilize + _LED_OP(); + +} + + +//SNES cartridge interfacing setup +//set outputs as required +//latch address of $000000 +//disable cart memories +//reset high disables SRAM and puts INL carts in PRGM mode +void snes_init() +{ + //start with a reset + //expecting user to do this but just to be sure + io_reset(); + + //enable control outputs and disable memories + //ROM + _ROMSEL_OP(); + _ROMSEL_HI(); + _CSRD_OP(); + _CSRD_HI(); + _CSWR_OP(); + _CSWR_HI(); + + //disable SRAM and put cart in PRGM mode + _SRST_OP(); + _SRST_HI(); + + //other control pins are inputs or unused, leave as IP pullup from reset + + //memories are now disabled Data bus should be clear + + //setup AHL FF + _AHL_OP(); + _AHL_CLK(); + //setup AXL FF + _AXLOE_OP(); + _AXL_CLK(); + + //now meet conditions to call other macros + //setup address $000000 + _ADDRH_SET(0x00); + _ADDRX_SET(0x00); + _ADDR_LO(); + + //default state of ADDR[7:0] + _ADDR_OP(); + + //default state data bus pulled up + _DATA_IP(); + _DATA_HI(); + + //turn LED off + _LED_OFF(); + //set as OP for future commands to utilize + _LED_OP(); + +} + diff --git a/firmware/source/io.h b/firmware/source/io.h index 8bffa3c..fde8a1e 100644 --- a/firmware/source/io.h +++ b/firmware/source/io.h @@ -3,7 +3,12 @@ #include #include "pinport.h" +#include "shared_dictionaries.h" +#include "shared_errors.h" -void io_pullup(); +uint8_t io_opcode_only( uint8_t opcode ); +void io_reset(); +void nes_init(); +void snes_init(); #endif diff --git a/firmware/source/main.c b/firmware/source/main.c index 30ad199..b5ef775 100644 --- a/firmware/source/main.c +++ b/firmware/source/main.c @@ -37,13 +37,8 @@ int __attribute__((noreturn)) main(void) //reconnect to host usbDeviceConnect(); - //intialize i/o to pullup state - io_pullup(); - - //configure LED PORT/DDR - _LED_OP(); - //boot with LED on to differentiate bettwen BL/RUN - _LED_ON(); + //intialize i/o and LED to pullup state + io_reset(); //enable interrupts sei(); diff --git a/firmware/source/nes.c b/firmware/source/nes.c new file mode 100644 index 0000000..ff2caca --- /dev/null +++ b/firmware/source/nes.c @@ -0,0 +1,148 @@ +#include "nes.h" + +//================================================================================================= +// +// NES operations +// This file includes all the nes functions possible to be called from the nes dictionary. +// +// See description of the commands contained here in shared/shared_dictionaries.h +// +//================================================================================================= + +/* Desc:Function takes an opcode which was transmitted via USB + * then decodes it to call designated function. + * shared_dict_nes.h is used in both host and fw to ensure opcodes/names align + * Pre: Macros must be defined in firmware pinport.h + * opcode must be defined in shared_dict_nes.h + * Post:function call complete. + * Rtn: SUCCESS if opcode found, ERR_UNKN_NES_OPCODE_24BOP if opcode not present. + */ +uint8_t nes_opcode_24b_operand( uint8_t opcode, uint8_t addrH, uint8_t addrL, uint8_t data ) +{ + switch (opcode) { + case DISCRETE_EXP0_PRGROM_WR: + discrete_exp0_prgrom_wr( addrH, addrL, data ); + break; + default: + //macro doesn't exist + return ERR_UNKN_NES_OPCODE_24BOP; + } + + return SUCCESS; + +} + + +/* Desc:Function takes an opcode which was transmitted via USB + * then decodes it to call designated function. + * shared_dict_nes.h is used in both host and fw to ensure opcodes/names align + * Pre: Macros must be defined in firmware pinport.h + * opcode must be defined in shared_dict_nes.h + * Post:pointer to data updated with return value. + * Rtn: SUCCESS if opcode found, ERR_UNKN_NES_OPCODE_16BOP_8BRV if opcode not present. + */ +uint8_t nes_opcode_16b_operand_8b_return( uint8_t opcode, uint8_t addrH, uint8_t addrL, uint8_t *data ) +{ + switch (opcode) { + case EMULATE_NES_CPU_RD: + *data = emulate_nes_cpu_rd( addrH, addrL ); + break; + default: + //macro doesn't exist + return ERR_UNKN_NES_OPCODE_16BOP_8BRV; + } + + return SUCCESS; + +} + +/* Desc: Discrete board PRG-ROM only write, does not write to mapper + * PRG-ROM /WE <- EXP0 w/PU + * PRG-ROM /OE <- /ROMSEL + * PRG-ROM /CE <- GND + * PRG-ROM write: /WE & /CE low, /OE high + * mapper '161 CLK <- /ROMSEL + * mapper '161 /LOAD <- PRG R/W + * mapper '161 /LOAD must be low on rising edge of CLK to latch data + * This is a /WE controlled write with data latched on rising edge EXP0 + * Note:addrH bit7 has no effect (ends up on PPU /A13) + * /ROMSEL, M2, & PRG R/W signals untouched + * Pre: nes_init() setup of io pins + * Post:data latched by PRG-ROM, mapper register unaffected + * address left on bus + * data left on bus, but pullup only + * EXP0 left pulled up + * Rtn: None + */ +void discrete_exp0_prgrom_wr( uint8_t addrH, uint8_t addrL, uint8_t data ) +{ + _DATA_OP(); + DATA_OUT = addrH; + _AHL_CLK(); //addrH latched + DATA_OUT = data; + ADDR_OUT = addrL; + _EXP0_LO(); //Tas = 0ns, Tah = 30ns + _EXP0_PU(); //Twp = 40ns, Tds = 40ns, Tdh = 0ns + //16Mhz avr clk = 62.5ns period guarantees timing reqts + //Need to check with scope to make sure EXP0 P/U effective + _DATA_IP(); +} + + +/* Desc:Emulate NES CPU Read as best possible + * decode A15 from addrH to set /ROMSEL as expected + * float EXP0 + * toggle M2 as NES would + * insert some NOP's in to be slow like NES + * Note:not the fastest read operation + * Pre: nes_init() setup of io pins + * Post:address left on bus + * data bus left clear + * EXP0 left floating + * Rtn: None + */ +uint8_t emulate_nes_cpu_rd( uint8_t addrH, uint8_t addrL ) +{ + uint8_t read; //return value + + //m2 should be low as it aids in disabling WRAM + //this is also m2 state at beginging of CPU cycle + //all these pins should already be in this state, but + //go ahead and setup just to be sure since we're trying + //to be as accurate as possible + _EXP0_FLT(); //this could have been left pulled up + _M2_LO(); //start of CPU cycle + _ROMSEL_HI(); //trails M2 + _PRGRW_RD(); //happens just after M2 + + //set address bus + ADDR_OUT = addrL; + _ADDRH_SET(addrH); + + //couple NOP's to wait a bit + NOP(); + NOP(); + + //set M2 and /ROMSEL + if( addrH >= 0x80 ) { //addressing cart rom space + _M2_HI(); + _ROMSEL_LO(); //romsel trails M2 during CPU operations + } else { + _M2_HI(); + } + + //couple more NOP's waiting for data + NOP(); + NOP(); + NOP(); + NOP(); + + //latch data + read = DATA_IN; + + //return bus to default + _M2_LO(); + _ROMSEL_HI(); + + return read; +} diff --git a/firmware/source/nes.h b/firmware/source/nes.h new file mode 100644 index 0000000..963b170 --- /dev/null +++ b/firmware/source/nes.h @@ -0,0 +1,15 @@ +#ifndef _nes_h +#define _nes_h + +#include +#include "pinport.h" +#include "shared_dictionaries.h" +#include "shared_errors.h" + +uint8_t nes_opcode_only( uint8_t opcode ); +uint8_t nes_opcode_24b_operand( uint8_t opcode, uint8_t addrH, uint8_t addrL, uint8_t data ); +uint8_t nes_opcode_16b_operand_8b_return( uint8_t opcode, uint8_t addrH, uint8_t addrL, uint8_t *data ); +void discrete_exp0_prgrom_wr( uint8_t addrH, uint8_t addrL, uint8_t data ); +uint8_t emulate_nes_cpu_rd( uint8_t addrH, uint8_t addrL ); + +#endif diff --git a/firmware/source/pinport.c b/firmware/source/pinport.c index 67f5933..6ad4f0c 100644 --- a/firmware/source/pinport.c +++ b/firmware/source/pinport.c @@ -2,14 +2,14 @@ //This file was created based on pinport.h //the close relationship between these two files must be kept in mind when making changes. -//This file is also very dependent on shared_pinport.h -//the shared_pinport.h was generated from this file, so any changes here must be forwarded. +//This file is also very dependent on shared_dict_pinport.h +//the shared_dict_pinport.h was generated from this file, so any changes here must be forwarded. /* Desc:Function takes an opcode which was transmitted via USB * then decodes it to call designated macro. - * shared_pinport.h is used in both host and fw to ensure opcodes/names align + * shared_dict_pinport.h is used in both host and fw to ensure opcodes/names align * Pre: Macro must be defined in firmware pinport.h - * opcode must be defined in shared_pinport.h + * opcode must be defined in shared_dict_pinport.h * Post:Macro call complete. * Rtn: SUCCESS if opcode found, ERR_UNKN_PP_OPCODE_ONLY if opcode not present. */ @@ -284,14 +284,14 @@ void software_AHL_CLK() /* Desc:Function takes an opcode and 8bit operand which was transmitted via USB * then decodes it to call designated macro/function. - * shared_pinport.h is used in both host and fw to ensure opcodes/names align + * shared_dict_pinport.h is used in both host and fw to ensure opcodes/names align * Pre: Macro must be defined in firmware pinport.h - * opcode must be defined in shared_pinport.h + * opcode must be defined in shared_dict_pinport.h * data bus must be free and clear * control pins must be initialized * -FF latch /OE pins set as outputs * -FF CLK pins low ready for CLK - * See big CAUTION on shared_pinport.h for more details + * See big CAUTION on shared_dict_pinport.h for more details * ADDR_OP() expected to be set * Post:Macro/function called with operand * data bus left free and clear when possible @@ -370,16 +370,16 @@ uint8_t pinport_opcode_8b_operand( uint8_t opcode, uint8_t operand ) /* Desc:Function takes an opcode and 16bit operand which was transmitted via USB * then decodes it to call designated macro/function. * operandMSB is most significant byte, operandLSB is least significant - * shared_pinport.h is used in both host and fw to ensure opcodes/names align + * shared_dict_pinport.h is used in both host and fw to ensure opcodes/names align * Pre: Macros must be defined in firmware pinport.h - * opcode must be defined in shared_pinport.h + * opcode must be defined in shared_dict_pinport.h * data bus must be free and clear * control pins must be initialized * -FF latch /OE pins set as outputs * -FF CLK pins low ready for CLK * ADDR_OP() is expected to be set. * /ROMSEL and M2 expected to be OP. - * See big CAUTION on shared_pinport.h for more details + * See big CAUTION on shared_dict_pinport.h for more details * Post:Macro/function called with operand * data bus left free and clear when possible * -some opcodes diliberately drive the bus @@ -444,15 +444,15 @@ uint8_t pinport_opcode_16b_operand( uint8_t opcode, uint8_t operandMSB, uint8_t /* Desc:Function takes an opcode and 24bit operand which was transmitted via USB * then decodes it to call designated macro/function. * operandMSB is most signf byte, operandMID is center, operandLSB is least significant - * shared_pinport.h is used in both host and fw to ensure opcodes/names align + * shared_dict_pinport.h is used in both host and fw to ensure opcodes/names align * Pre: Macros must be defined in firmware pinport.h - * opcode must be defined in shared_pinport.h + * opcode must be defined in shared_dict_pinport.h * data bus must be free and clear * control pins must be initialized * -FF latch /OE pins set as outputs * -FF CLK pins low ready for CLK * ADDR_OP() is expected to be set. - * See big CAUTION on shared_pinport.h for more details + * See big CAUTION on shared_dict_pinport.h for more details * Post:Macro/function called with operand * data bus left free and clear when possible * -some opcodes may diliberately drive the bus @@ -488,10 +488,10 @@ uint8_t pinport_opcode_24b_operand( uint8_t opcode, uint8_t operandMSB, uint8_t /* Desc:Function takes an opcode and pointer to return value byte * then decodes it to retreive value. - * shared_pinport.h is used in both host and fw to ensure opcodes/names align + * shared_dict_pinport.h is used in both host and fw to ensure opcodes/names align * Pre: Macros must be defined in firmware pinport.h - * opcode must be defined in shared_pinport.h - * See big CAUTION on shared_pinport.h for more details + * opcode must be defined in shared_dict_pinport.h + * See big CAUTION on shared_dict_pinport.h for more details * Post:pointer updated to value designated by opcode. * Rtn: SUCCESS if opcode found, ERR_UNKN_PP_OPCODE_8BRV if opcode not present. */ diff --git a/firmware/source/pinport.h b/firmware/source/pinport.h index 6772d78..2c6f838 100644 --- a/firmware/source/pinport.h +++ b/firmware/source/pinport.h @@ -174,6 +174,8 @@ void software_AXL_CLK(); // Easier to add them than take them out maybe..? //Current rule is _ goes with () type macro +// used for a very short delay +#define NOP() do { __asm__ __volatile__ ("nop"); } while (0) //============================ //ADDR[7:0] PORTA @@ -323,7 +325,7 @@ void software_AXL_CLK(); #define EXP0 PD0 //NES EXP0 controls a number of varying flash cart features... #define FC_APU PD0 //FC Audio in cart from 2A03 APU #define TDO PD0 //CPLD JTAG on INL-ROM NES/FC boards released after ~Oct2016 -#define S_RST PD0 //SNES /RESET pin used for CPLD prgm/play mode and SRAM CE +#define SRST PD0 //SNES /RESET pin used for CPLD prgm/play mode and SRAM CE #define LED PD1 //LED on INL retro prog-dumper #define EXP9 PD1 //NES dual purposed pin @@ -354,6 +356,11 @@ void software_AXL_CLK(); #define _EXP0_LO() _EXP0_lo(); _EXP0_op(); //Sets low then DDR to o/p #define _EXP0_PU() _EXP0_ip(); _EXP0_hi(); //maybe add some NOP() to allow time for pull up #define _EXP0_FLT() _EXP0_ip(); _EXP0_lo(); //Set to i/p w/o pullup +//SNES /RESET versions, more permissible for driving EXP0 to 5v as NES cart shouldn't be inserted +#define _SRST_IP() _EXP0_ip() +#define _SRST_OP() _EXP0_op() +#define _SRST_LO() _EXP0_lo() +#define _SRST_HI() _EXP0_hi() #define _LED_IP() AUX_DDR &= ~(1<opcode, spacket->wIndexLSB ); + spacket->opcode, spacket->operandLSB ); break; case PP_OPCODE_16BOP_MIN ... PP_OPCODE_16BOP_MAX: rv[0] = pinport_opcode_16b_operand( - spacket->opcode, spacket->wIndexMSB, spacket->wIndexLSB ); + spacket->opcode, spacket->operandMSB, spacket->operandLSB ); break; case PP_OPCODE_24BOP_MIN ... PP_OPCODE_24BOP_MAX: rv[0] = pinport_opcode_24b_operand( spacket->opcode, - spacket->wValueMSB, spacket->wIndexMSB, spacket->wIndexLSB ); + spacket->miscdata, spacket->operandMSB, spacket->operandLSB ); break; case PP_OPCODE_8BRV_MIN ... PP_OPCODE_8BRV_MAX: rv[0] = pinport_opcode_8b_return( spacket->opcode, &rv[1]); @@ -108,6 +107,33 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) { rv[0] = ERR_BAD_PP_OP_MINMAX; } break; //end of PINPORT + + case IO: + switch (spacket->opcode) { + case IO_OPCODE_ONLY_MIN ... IO_OPCODE_ONLY_MAX: + rv[0] = io_opcode_only( spacket->opcode ); + break; + default: //io opcode min/max definition error + rv[0] = ERR_BAD_IO_OP_MINMAX; + } + break; //end of IO + + case NES: + switch (spacket->opcode) { + case NES_OPCODE_24BOP_MIN ... NES_OPCODE_24BOP_MAX: + rv[0] = nes_opcode_24b_operand( spacket->opcode, + spacket->operandMSB, spacket->operandLSB, spacket->miscdata ); + break; + case NES_OPCODE_16BOP_8BRV_MIN ... NES_OPCODE_16BOP_8BRV_MAX: + rv[0] = nes_opcode_16b_operand_8b_return( spacket->opcode, + spacket->operandMSB, spacket->operandLSB, &rv[1]); + rlen++; + break; + default: //nes opcode min/max definition error + rv[0] = ERR_BAD_NES_OP_MINMAX; + } + break; //end of NES + default: //request (aka dictionary) is unknown rv[0] = ERR_UNKN_DICTIONARY; diff --git a/firmware/source/usb.h b/firmware/source/usb.h index 604dd81..d36b099 100644 --- a/firmware/source/usb.h +++ b/firmware/source/usb.h @@ -6,6 +6,10 @@ #include "usbdrv.h" #include "logic.h" #include "shared_dictionaries.h" +#include "shared_errors.h" +#include "pinport.h" +#include "io.h" +#include "nes.h" #endif diff --git a/host/inlretro.exe b/host/inlretro.exe index 39f7519..a0357e8 100644 Binary files a/host/inlretro.exe and b/host/inlretro.exe differ diff --git a/host/source/dictionary.c b/host/source/dictionary.c new file mode 100644 index 0000000..9f1be19 --- /dev/null +++ b/host/source/dictionary.c @@ -0,0 +1,114 @@ +#include "dictionary.h" + +/* Make dictionary calls simpler + * provide USBtransfer pointer with handle set to retro programmer + * provide dictionary as defined in shared_dictionaries.h (request) + * provide opcode from the dictionary (wValueLSB) + * provide 16bit addr used for usb transfer index (optional, can also send 8bits applied to wIndexLSB) + * provide miscdata optional to be used for wValueMSB + * + * makes call to usb_transfer after determining: + * endpoint direction + * data length + * + * debug print of call and return values + */ + +int dictionary_call( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr, uint8_t miscdata) +{ + transfer->request = dictionary; + transfer->wValueMSB = miscdata; + transfer->wValueLSB = opcode; + transfer->wIndexMSB = (addr>>8); + transfer->wIndexLSB = addr; + + //default IN for now reading back error codes from short commands + transfer->endpoint = USB_IN; + //default length of zero + transfer->wLength = 0; + + //return data buffer big enough for one data packet + uint8_t rbuf[8]; + rbuf[0] = 0xA5; + rbuf[1] = 0xC3; + rbuf[2] = 0xA5; + rbuf[3] = 0xC3; + rbuf[4] = 0xA5; + rbuf[5] = 0xC3; + rbuf[6] = 0xA5; + rbuf[7] = 0xC3; + transfer->data = rbuf; + + + debug("dictionary call dict:%d opcode:%d/%x addr:%x data:%x", dictionary, opcode, opcode, addr, miscdata); + switch (dictionary) { + case PINPORT: debug("dict: PINPORT"); + transfer->wLength = 1; + switch (opcode) { + case PP_OPCODE_ONLY_MIN ... PP_OPCODE_ONLY_MAX: + debug("PP_OPCODE_ONLY"); + break; + case PP_OPCODE_8BOP_MIN ... PP_OPCODE_8BOP_MAX: + debug("PP_OPCODE_8BOP"); + break; + case PP_OPCODE_16BOP_MIN ... PP_OPCODE_16BOP_MAX: + debug("PP_OPCODE_16BOP"); + break; + case PP_OPCODE_24BOP_MIN ... PP_OPCODE_24BOP_MAX: + debug("PP_OPCODE_24BOP"); + break; + case PP_OPCODE_8BRV_MIN ... PP_OPCODE_8BRV_MAX: + debug("PP_OPCODE_8BRV"); + transfer->wLength = 2; + break; + default: //pinport opcode min/max definition error + sentinel("bad PP opcode min/max err:%d",ERR_BAD_PP_OP_MINMAX); + } + break; //end of PINPORT + + case IO: debug("dict: IO"); + transfer->wLength = 1; + switch (opcode) { + case IO_OPCODE_ONLY_MIN ... IO_OPCODE_ONLY_MAX: + debug("IO_OPCODE_ONLY"); + break; + default: //io opcode min/max definition error + sentinel("bad IO opcode min/max err:%d",ERR_BAD_IO_OP_MINMAX); + } + break; //end of IO + + case NES: debug("dict: NES"); + transfer->wLength = 1; + switch (opcode) { + case NES_OPCODE_24BOP_MIN ... NES_OPCODE_24BOP_MAX: + debug("NES_OPCODE_24BOP"); + break; + case NES_OPCODE_16BOP_8BRV_MIN ... NES_OPCODE_16BOP_8BRV_MAX: + debug("NES_OPCODE_16BOP_8BRV"); + transfer->wLength = 2; + break; + default: //nes opcode min/max definition error + sentinel("bad NES opcode min/max err:%d",ERR_BAD_NES_OP_MINMAX); + } + break; //end of NES + + default: + //request (aka dictionary) is unknown + sentinel("unknown DICT err:%d",ERR_UNKN_DICTIONARY); + } + + + int xfr_cnt; + + xfr_cnt = usb_transfer( transfer ); + debug("xf: %d er: %d rv: %x, %x, %x, %x, %x, %x, %x",xfr_cnt, rbuf[0], rbuf[1], rbuf[2], rbuf[3], rbuf[4], rbuf[5], rbuf[6], rbuf[7]); + check(rbuf[0] == SUCCESS, "retro programmer had error: %d, dict:%d, opcode:%d/%x, addr:%x, data:%x",rbuf[0], dictionary, opcode, opcode, addr, miscdata) + //send command + + return 0; + +error: + printf("dictionary call went to error\n"); + return -1; + +} diff --git a/host/source/dictionary.h b/host/source/dictionary.h new file mode 100644 index 0000000..d7c6f2d --- /dev/null +++ b/host/source/dictionary.h @@ -0,0 +1,29 @@ +#ifndef _dictionary_h +#define _dictionary_h + +#include +#include +#include +#include +#include +#include + +//include prior to other file includes +//that way DEBUG can be turned on/off for this file alone +//uncomment to DEBUG this file alone +#define DEBUG +//"make debug" to get DEBUG msgs on entire program +#include "dbg.h" + +#include "usb_operations.h" +#include "shared_errors.h" +#include "shared_dictionaries.h" + +//uncomment to DEBUG this file alone +#define DEBUG +//"make debug" to get DEBUG msgs on entire program +#include "dbg.h" + +int dictionary_call( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr, uint8_t miscdata); + +#endif diff --git a/host/source/erase.c b/host/source/erase.c index cc3c3d4..f3cef7a 100644 --- a/host/source/erase.c +++ b/host/source/erase.c @@ -5,52 +5,14 @@ int erase_nes( USBtransfer *transfer ) debug("erasing"); - int xfr_cnt; - uint8_t rbuf[2]; - rbuf[0] = 0; - rbuf[1] = 0; - int i; - - transfer->endpoint = USB_IN; - transfer->request = PINPORT; - transfer->data = rbuf; - - uint8_t c[20]; - uint8_t o[20]; - - c[0] = LED_ON; - c[1] = ADDR_OP; - c[2] = DATA_IP; - c[3] = M2_OP; - c[4] = ROMSEL_OP; - c[5] = PRGRW_OP; - c[6] = CSRD_OP; - c[7] = CSWR_OP; - c[8] = AHL_OP; - c[9] = AXLOE_OP; - c[10] = AXL_CLK; - c[11] = ADDR_RD; - c[12] = ADDR_LO; - c[13] = ADDR_RD; - c[14] = LED_OFF; - c[15] = LED_OFF; - c[16] = LED_OFF; - c[17] = LED_OFF; - c[18] = LED_OFF; - c[19] = LED_OFF; - - for ( i = 0; i < 20; i++) { - transfer->wValueLSB = c[i]; - if (c[i] >= 0xc0) transfer->wLength = 2; - else transfer->wLength = 1; - xfr_cnt = usb_transfer( transfer ); - debug("xf: %d OP: %d/%x er: %d rv: %x",xfr_cnt, c[i], c[i], rbuf[0], rbuf[1]); - rbuf[0] = 0xAA; - rbuf[1] = 0; - - //send command - } - + //dict opcode addr data + dictionary_call( transfer, IO, IO_RESET, 0, 0); + dictionary_call( transfer, IO, NES_INIT, 0, 0); + dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0xAA); + dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x2AAA, 0x55); + dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0x90); + dictionary_call( transfer, NES, EMULATE_NES_CPU_RD, 0x8000, 0); + dictionary_call( transfer, NES, EMULATE_NES_CPU_RD, 0x8001, 0); return 0; diff --git a/host/source/erase.h b/host/source/erase.h index 1d890b1..b140863 100644 --- a/host/source/erase.h +++ b/host/source/erase.h @@ -18,6 +18,7 @@ #include "usb_operations.h" #include "shared_errors.h" #include "shared_dictionaries.h" +#include "dictionary.h" //uncomment to DEBUG this file alone #define DEBUG diff --git a/host/source/usb_operations.c b/host/source/usb_operations.c index 186a765..b31376f 100644 --- a/host/source/usb_operations.c +++ b/host/source/usb_operations.c @@ -33,6 +33,7 @@ libusb_device_handle * open_usb_device( libusb_context *context ) //returns 0 on success LIBUSB_ERROR code on failure //int libusb_init ( libusb_context ** context) int usb_init = libusb_init(&context); + debug("Initalized libusb"); check( usb_init == LIBUSB_SUCCESS, "Failed to initialize libusb: %s", libusb_strerror(usb_init)); //void libusb_set_debug ( libusb_context * ctx, int level ) @@ -51,7 +52,9 @@ libusb_device_handle * open_usb_device( libusb_context *context ) // Returns a list of USB devices currently attached to the system. // return value is number of devices plus one as list is null terminated, or LIBUSB_ERROR if negative. // Must free device list after done with it + debug("getting device list"); ssize_t dev_count = libusb_get_device_list( context, &device_list); + debug("got device list"); check( dev_count >= 0, "libusb unable to find any devices: %s", libusb_strerror(dev_count)); ssize_t i = 0; diff --git a/shared/shared_dict_io.h b/shared/shared_dict_io.h new file mode 100644 index 0000000..fa336e2 --- /dev/null +++ b/shared/shared_dict_io.h @@ -0,0 +1,56 @@ +#ifndef _shared_dict_io_h +#define _shared_dict_io_h + +//define dictionary's reference number in the shared_dictionaries.h file +//then include this dictionary file in shared_dictionaries.h +//The dictionary number is literally used as usb transfer request field +//the opcodes and operands in this dictionary are fed directly into usb setup packet's wValue wIndex fields + + +//============================================================================================= +//============================================================================================= +// IO DICTIONARY +// +// opcodes contained in this dictionary must be implemented in firmware/source/io.c +// +//============================================================================================= +//============================================================================================= + + + + + +//============================================================================================= +// OPCODES with no operand and no return value besides SUCCESS/ERROR_CODE +//============================================================================================= +// 0x00-0xFF +// Detect this opcode/operand setup with opcode between the following defines: +#define IO_OPCODE_ONLY_MIN 0x00 +#define IO_OPCODE_ONLY_MAX 0xFF +// +//============================================================================================= +//============================================================================================= + +//pullup as many cart pins as possible +//goal to be safe state for all hardware +//doesn't currently contain any checks to report error/success from +//this is intended to be the "reset" safest condition for the kazzo +//LED is pulled up (DIM) to help indicate this io state +//EXP FF is disabled due to pull up on /OE +#define IO_RESET 0x00 + + +//NES cartridge interfacing setup +//set outputs as required +//latch address of $0000 +//disable NES cart memories +#define NES_INIT 0x01 + +//SNES cartridge interfacing setup +//set outputs as required +//latch address of $000000 +//disable cart memories +//reset high disables SRAM and puts INL carts in PRGM mode +#define SNES_INIT 0x02 + +#endif diff --git a/shared/shared_dict_nes.h b/shared/shared_dict_nes.h new file mode 100644 index 0000000..afacde1 --- /dev/null +++ b/shared/shared_dict_nes.h @@ -0,0 +1,69 @@ +#ifndef _shared_dict_nes_h +#define _shared_dict_nes_h + +//define dictionary's reference number in the shared_dictionaries.h file +//then include this dictionary file in shared_dictionaries.h +//The dictionary number is literally used as usb transfer request field +//the opcodes and operands in this dictionary are fed directly into usb setup packet's wValue wIndex fields + + +//============================================================================================= +//============================================================================================= +// NES DICTIONARY +// +// opcodes contained in this dictionary must be implemented in firmware/source/nes.c +// +//============================================================================================= +//============================================================================================= + + +// OPCODES with no operand and no return value besides SUCCESS/ERROR_CODE + + + + +//============================================================================================= +// OPCODES WITH OPERAND and no return value besides SUCCESS/ERROR_CODE +//============================================================================================= +// 0x00-0x7F +// Detect this opcode/operand setup with opcode between the following defines: +#define NES_OPCODE_24BOP_MIN 0x00 +#define NES_OPCODE_24BOP_MAX 0x7F +// +//============================================================================================= +//============================================================================================= + + + + +//Discrete board PRG-ROM only write, does not write to mapper +//This is a /WE controlled write with data latched on rising edge EXP0 +//PRG-ROM /WE <- EXP0 w/PU +//PRG-ROM /OE <- /ROMSEL +//PRG-ROM /CE <- GND +//PRG-ROM write: /WE & /CE low, /OE high +//mapper '161 CLK <- /ROMSEL +//mapper '161 /LOAD <- PRG R/W +//wValueMSB: data +//wIndex: address +#define DISCRETE_EXP0_PRGROM_WR 0x00 + + +//============================================================================================= +// OPCODES WITH OPERAND AND RETURN VALUE plus SUCCESS/ERROR_CODE +//============================================================================================= +// +// +#define NES_OPCODE_16BOP_8BRV_MIN 0x80 +#define NES_OPCODE_16BOP_8BRV_MAX 0xFF +// +//============================================================================================= +//============================================================================================= + +//read from NES CPU ADDRESS +//set /ROMSEL, M2, and PRG R/W +//read from cartridge just as NES's CPU would +//nice and slow trying to be more like the NES +#define EMULATE_NES_CPU_RD 0x80 + +#endif diff --git a/shared/shared_dict_pinport.h b/shared/shared_dict_pinport.h index 0439948..a402a91 100644 --- a/shared/shared_dict_pinport.h +++ b/shared/shared_dict_pinport.h @@ -144,10 +144,16 @@ #define EXP0_op 59 #define EXP0_lo 60 //Don't call this assuming EXP0 DDR is set to o/p #define EXP0_hi 61 //Don't call this unless you're certain pin is 5v tolerant +//SNES versions uppercase as assuming 5v tolerance without NES cart +#define SRST_IP 58 +#define SRST_OP 59 +#define SRST_LO 60 +#define SRST_HI 61 //User options pull up, force low, and float #define EXP0_LO 62 //Sets low then DDR to o/p #define EXP0_PU 63 //maybe add some NOP(); to allow time for pull up #define EXP0_FLT 64 //Set to i/p w/o pullup + #define LED_IP 65 #define LED_OP 66 diff --git a/shared/shared_dictionaries.h b/shared/shared_dictionaries.h index 148cf2f..cbf86ce 100644 --- a/shared/shared_dictionaries.h +++ b/shared/shared_dictionaries.h @@ -5,12 +5,91 @@ //these numbers literally sent in usb control transfer in request field //the included dictionaries define opcodes and operands contained in transfer wValue wIndex fields //they also define expected data buffer sizes and contents. +// +//TODO eventually the host code should have access to these libraries during run time. +//that way character strings can be interpreted by parsing the dictionary .h file +//this would also allow for dictionary expansion after compilation of host code. +//However the kazzo fw would still need rebuilt to support dictionary expansion. +//Possible to take this one step further and remove dictionaries from host compiliation. +//that way you simply point the host to a dictionary directory at runtime. +//Perhaps utilizing a database of some sort would be better than directory of text/.h files. +//but since firmware build relies on dictionary definition at build time, perhaps the simplest +//solution of using those avr build .h files slurped up by host at run time is safest and easiest. +//having host capability to convert command string to the usb dict/opcode is the first +//step in having scripting support on host side. The thought above just expands it one +//step further making the dictionaries themselves operate as run time 'scripts'. +//don't define dictionary #0 as it is common to forget to define +//============================================================================================= +//============================================================================================= #define PINPORT 1 #include "shared_dict_pinport.h" //pinport dictionary has various commands giving low and mid level access to retro prog's i/o pins. //It also contains internal avr registers associated with the avr's io. //Access to other internal avr registers should be placed in other associated dictionaries. +//The opcodes in this dictionary should not have any cyclic effect such as pulsing /ROMSEL +//low to read data and then disabling taking /ROMSEL high again. These commands are intended +//to appear as a single change/edge to cartridge hardware. Only potential exception to this +//is AHL/AXL clocking which is used to latch values to FF's, that effectively is only one +//state change for the cartridge hardware. +// +// Many of the opcodes in the second half of this dictionary have the following rules: +// +// The opcodes that follow operate under some rules that you must adhere to if calling +// 1) Data bus should be free and clear when possible +// -DATA_IP() is default state +// -Be cognizant if you're driving the data bus +// many of these opcodes use the data bus to function. +// -Many of these opcodes will end up driving the data bus +// know when that'll happen and free bus when data retreived +// +// -Flipflops must be initialized +// this primarily means CLK pin must be OP and LO ready for CLK command +// -output of FF must be enabled to actually feed latched value on cart +// final pcb version will enable EXP FF after clocking. +// early pcb versions have FF /OE on separate pin not so automatic. +// +// -control pins must be initialized +// -enable OP on pins necessary to perform desire of command +// ie M2 and /ROMSEL must be OP if you're trying to change them with a command. +// +// -be cognizant of what pins are inputs and which are outputs +// ie driving PPU /A13 will be fed back to CIRAM /CE so it needs to be IP +// -if in doubt, leave it as input with pull up, atleast that shouldn't break anything +// +// -ADDR_OP is default state, these opcodes assume it to be set as it shouldn't conflict +// -/ROMSEL & M2 expected to be set as outputs +// +// +//============================================================================================= +//============================================================================================= + + +//============================================================================================= +//============================================================================================= +#define IO 2 +#include "shared_dict_io.h" +//io dictionary contains commands +//Scope of functions contained is intended to be general and generic not specific +//to the cartridge inserted. The closest these operations get to being cart/system +//specific is in setup for a system. Calling the cart/system setup contained here +//prepares kazzo for system specific commands. Once complete with system specifc +//commands come back here to 'deinitialize' access to that cartridge. +//commands in this dictionary are meant to estabilish baseline rules of i/o to +//support calling higher level system/cart specific functions. +//============================================================================================= +//============================================================================================= + + +//============================================================================================= +//============================================================================================= +#define NES 3 +#include "shared_dict_nes.h" +//nes dictionary contains commands +//These commands rely on io initialization from io dictionary prior to calling +//This library is intended to contain all NES related opcodes/commands +//============================================================================================= +//============================================================================================= #endif diff --git a/shared/shared_errors.h b/shared/shared_errors.h index b38073b..5fa816f 100644 --- a/shared/shared_errors.h +++ b/shared/shared_errors.h @@ -6,13 +6,19 @@ //greater than 128 are possible avr return codes #define ERR_UNKN_DICTIONARY 128 #define ERR_BAD_PP_OP_MINMAX 129 +#define ERR_BAD_IO_OP_MINMAX 130 +#define ERR_BAD_NES_OP_MINMAX 131 -#define ERR_UNKN_PP_OPCODE_ONLY 139 -#define ERR_UNKN_PP_OPCODE_8BOP 130 -#define ERR_UNKN_PP_OPCODE_16BOP 131 -#define ERR_UNKN_PP_OPCODE_24BOP 132 -#define ERR_UNKN_PP_OPCODE_8BRV 133 +#define ERR_UNKN_PP_OPCODE_ONLY 140 +#define ERR_UNKN_PP_OPCODE_8BOP 141 +#define ERR_UNKN_PP_OPCODE_16BOP 142 +#define ERR_UNKN_PP_OPCODE_24BOP 143 +#define ERR_UNKN_PP_OPCODE_8BRV 144 +#define ERR_UNKN_IO_OPCODE_ONLY 150 + +#define ERR_UNKN_NES_OPCODE_24BOP 160 +#define ERR_UNKN_NES_OPCODE_16BOP_8BRV 161 #endif