Big step in confirmation of pin manipulations working on kazzo.

Able to read PRG-ROM flash chip's manf and device ID from commandline.

New dictionaries io and nes along with firmware files to support.
now have io_reset, nes_init, and snes_init io.c functions
nes.c functions including discrete_exp0_prgrom_wr and emulate_nes_cpu_rd.

New dictionary.c/.h for host to make dictionary calls easier including
setting proper return data lengths based on opcode.

adding nop command to pinport.h

AVR Memory Usage
----------------
Device: atmega164a

Program:    2960 bytes (18.1% Full)
(.text + .data + .bootloader)

Data:         53 bytes (5.2% Full)
(.data + .bss + .noinit)
This commit is contained in:
Paul Molloy 2016-11-27 00:18:46 -06:00
parent 94ea3fd474
commit 7d00145431
21 changed files with 953 additions and 249 deletions

View File

@ -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

View File

@ -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();
}

View File

@ -3,7 +3,12 @@
#include <avr/io.h>
#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

View File

@ -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();

148
firmware/source/nes.c Normal file
View File

@ -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;
}

15
firmware/source/nes.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _nes_h
#define _nes_h
#include <avr/io.h>
#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

View File

@ -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.
*/

View File

@ -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<<LED)

View File

@ -1,7 +1,6 @@
#include "usb.h"
#include "pinport.h"
//USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]);
/* This function is called when the driver receives a SETUP transaction from
@ -48,9 +47,9 @@ typedef struct setup_packet{
uint8_t bmRequestType; //contains endpoint
uint8_t bRequest; //designates dictionary of opcode
uint8_t opcode; //wValueLSB (little endian)
uint8_t wValueMSB; //expansion byte
uint8_t wIndexLSB; //operand LSB
uint8_t wIndexMSB; //operand MSB
uint8_t miscdata; //wValueMSB
uint8_t operandLSB; //wIndexLSB
uint8_t operandMSB; //wIndexMSB
uint16_t wLength;
}setup_packet;
@ -90,15 +89,15 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) {
break;
case PP_OPCODE_8BOP_MIN ... PP_OPCODE_8BOP_MAX:
rv[0] = pinport_opcode_8b_operand(
spacket->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;

View File

@ -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

Binary file not shown.

114
host/source/dictionary.c Normal file
View File

@ -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;
}

29
host/source/dictionary.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef _dictionary_h
#define _dictionary_h
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <libusb.h>
//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

View File

@ -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;

View File

@ -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

View File

@ -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;

56
shared/shared_dict_io.h Normal file
View File

@ -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

69
shared/shared_dict_nes.h Normal file
View File

@ -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

View File

@ -144,11 +144,17 @@
#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
#define LED_OFF 67

View File

@ -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

View File

@ -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