RevEng Posted July 15, 2019 Share Posted July 15, 2019 As a side project, I've been working on a rudimentary terminal program for the 7800. Some day I see the 7800 as being capable of downloading game binaries directly from online sources, or alternate media like a savekey. Games could even download their own updates, and run them from RAM. To avoid having to parse something like the A78 header with the 6502, I've come up with a succinct embedable header. The header doesn't need to actually be in the code path, but will only spoil the X register if it is. [edit - old version of the header has been removed. See the spec for the correct info] A device with a bios and semi-persistent ram might even scan certain memory locations for a BEAD header, or check the start of an inserted SaveKey, and offer to run the binary. Hoping that sharing this info might stoke some imagination. 3 Quote Link to comment Share on other sites More sharing options...
+sramirez2008 Posted July 15, 2019 Share Posted July 15, 2019 5 minutes ago, RevEng said: Some day I see the 7800 as being capable of downloading game binaries directly from online sources, or alternate media like a savekey. This would be awesome! 1 1 Quote Link to comment Share on other sites More sharing options...
CPUWIZ Posted July 16, 2019 Share Posted July 16, 2019 8 hours ago, RevEng said: Some day I see the 7800 as being capable of downloading game binaries directly from online sources 5 Quote Link to comment Share on other sites More sharing options...
TailChao Posted July 16, 2019 Share Posted July 16, 2019 (edited) I like this idea, but have similar concerns with the current draft as with the *.a78 header. In particular, I don't think there should be any ambiguity with what the payload is (RAM-resident executable, Fixed 16K - 32K ROM image, etc.) and what's up with Pokey. The latter is a real issue, as Pokeys are being dropped all over the address space willy-nilly. We need clear indication as to if a Pokey is included and where it is. Nintendo's embedded headers used in the GameBoy are a good reference. These are detailed enough to clearly describe a cartridge's contents, but still simple enough to parse on an 8-Bit CPU without much fuss. More importantly, there's a good distinction between hardware description and software features. Something like a double bead : $BE,$AD,$FM,$BE,$AD,$SS ...or an extended bead : $BE,$AD,$FM,$18,$90,$xx,$SS,[data] where the $18,$90 is a clc,bcc to skip over more fields. These could give more information such as the payload size(s) or clarify features. Where $FM specifies the payload features and mapper (if any), something like : %FFFF.... == %VHX? \- V == AtariVox - H == High Score Cartridge - X == XM - ...etc %....MMMM \- %1111 == Executable Payload (i.e. load into RAM and run in place) - %0000 == Mapperless 16K - 32K - %0001 == Mapperless 48K - %0010 == SUPER - %1000 == Activision - %1001 == Absolute - ...etc The $SS could be a type-specific field. So this would be tied to $FM's %MMMM and give more information about what features exclusive to that mapper are used. Addendum : How about *.b78 as an extension? Edited July 16, 2019 by TailChao 1 Quote Link to comment Share on other sites More sharing options...
RevEng Posted July 16, 2019 Author Share Posted July 16, 2019 3 hours ago, TailChao said: I like this idea, but have similar concerns with the current draft as with the *.a78 header. In particular, I don't think there should be any ambiguity with what the payload is (RAM-resident executable, Fixed 16K - 32K ROM image, etc.) and what's up with Pokey. The latter is a real issue, as Pokeys are being dropped all over the address space willy-nilly. We need clear indication as to if a Pokey is included and where it is. I should have spelled it out, but the intention was for pokey to be strictly pokey@450, which has become a homebrew standard of sorts. For this header to have meaning, we need a platform with RAM or equivalent, like XM, MPC, CPUWIZ's other cart formats - and $450 is common to all of those. It's trivial to modify commercial games to use pokey@450 instead of 4000, so even those could be bead'ized. (though fitting the bead in would be a bit more work) I like the double-bead idea, with the base bead giving basic platform info, and extended beads giving future (hopefully esoteric) hardware options. That way first gen bead hardware might still be able to load software that specifies an extended bead, by simply ignoring it. On your suggestions for payload... with this header I'm not trying to do away with a78 headers for emulators. Rather I want to make it easier to load 7800 homebrew executables on real hardware, from sources that aren't trivial to seek through. I don't think the extended payload would be worth the extra parsing, when the reality is that we're not likely to see homebrew in Activision or Absolute formats. We're not having to prep AtariVox, controllers, etc., so they're not needed in BEAD. XM is covered by it's constituent peripherals in the current base bead. I think keeping the base bead features limited to a single byte, supporting foreseeable hardware, is key. I'm ok that this trades away some theoretical flexibility. I think it's more important for bead support to be cheap, both codewise and romwise. 1 Quote Link to comment Share on other sites More sharing options...
Trebor Posted July 16, 2019 Share Posted July 16, 2019 18 minutes ago, RevEng said: ...It's trivial to modify commercial games to use pokey@450 instead of 4000... Trivial meaning already done. ? 1 Quote Link to comment Share on other sites More sharing options...
TailChao Posted July 16, 2019 Share Posted July 16, 2019 Ah, thanks for the clarification I did get the impression this was just intended as a simple executable header, but it's always a little difficult to not try and cover all use cases. That considered, not having any indication as to where the data are going is a source of concern, as... On 7/15/2019 at 1:22 PM, RevEng said: A device with a bios and semi-persistent ram might even scan certain memory locations for a BEAD header, or check the start of an inserted SaveKey, and offer to run the binary. ...this could even be a stock unit with just a modified BIOS and SaveKey. The particular scenario I'm thinking of is running manufacturing tests and pulling data from the SaveKey into the 7800's internal RAM or even the cartridge's EXRAM, but this might be a bit too much. So with the desire to keep BEAD a tiny executable descriptor - I'd only move the "reserved" bits of F1 to the MSBs (since these might become significant enough to BIT / bmi / bvs over) and formally add the option to put a build tag or description after the BEAD. Effectively : $BE,$AD,[F1],$18,$90,[SS],"My Program (05/21/1984) v3",0 This way information which doesn't have to be in the filename (if any) can stay out, and if you're going to use the same binary for both BEAD-loading and ROM-ing it's a little more convenient to track. 1 hour ago, RevEng said: I think keeping the base bead features limited to a single byte, supporting foreseeable hardware, is key. I'm ok that this trades away some theoretical flexibility. I think it's more important for bead support to be cheap, both codewise and romwise. Agreed. 1 Quote Link to comment Share on other sites More sharing options...
RevEng Posted July 16, 2019 Author Share Posted July 16, 2019 1 hour ago, TailChao said: That considered, not having any indication as to where the data are going is a source of concern, as... ...this could even be a stock unit with just a modified BIOS and SaveKey. The particular scenario I'm thinking of is running manufacturing tests and pulling data from the SaveKey into the 7800's internal RAM or even the cartridge's EXRAM, but this might be a bit too much. Indirectly the start location is there, but it's just not covering your scenarios. e.g. 16k would start at C000, 32K would start at 8000, etc. So maybe some ram segments could be added to the formats? ; %00000nnn : 0=16k 1=32k 2=48k 3=128k 4=144k 5=@1800 6=@2200 7=@4000 The loads into ram segments would't have the 6502 vectors, so in that case the bead loader would just jump to the start of the segment. I'm also thinking that a segment load would as long as the natural segment length, if loaded from savekey. (since there's no EOF) Moving the reserved bit to MSB works for me. I also like the extended bead with descriptor string. [edit - Just considering if there should be a way to mark a bead as non-executable (ie. for data) and then string beads together. It would be neat, but too much scope creep.] Quote Link to comment Share on other sites More sharing options...
TailChao Posted July 17, 2019 Share Posted July 17, 2019 Hmm, I'd actually pull it back a little. How about this? $BE,$AD,[F1],$18,$90,[SS],"Description",0,... F1 : %vHYPRDSS \- v == Reserved (set to '0') - H == High Score Cartridge - Y == Yamaha - P == Pokey - R == ROF - DSS == Data Type and Size \- %000 : 16K @ $C000 - $FFFF - %001 : 32K @ $8000 - $FFFF - %010 : 48K @ $4000 - $FFFF - %011 : reserved - %100 : 4K @ $1800 - $27FF - %101 : reserved - %110 : 16K @ $4000 - $7FFF - %111 : reserved 16 hours ago, RevEng said: The loads into ram segments would't have the 6502 vectors, so in that case the bead loader would just jump to the start of the segment. I'm also thinking that a segment load would as long as the natural segment length, if loaded from savekey. (since there's no EOF) Yeah, each bead's size is given by the header - so creating a string of beads wouldn't require a directory. I do like this flexibility in storing the beads. Since the header can be executed-over, I'd think all beads should support this as an entry point - whether or not they actually have vectors for the 6502. 16 hours ago, RevEng said: [edit - Just considering if there should be a way to mark a bead as non-executable (ie. for data) and then string beads together. It would be neat, but too much scope creep.] Marking a bead as non-executable would be a nice feature, but once we start getting into arbitrary data it's going to require arbitrary payload sizes. I'd recommend keeping the beads as-is for now, and then if non-executable beads are desired in the future, they can be implemented using the "v" bit and perhaps a double-bead header. Quote Link to comment Share on other sites More sharing options...
RevEng Posted July 17, 2019 Author Share Posted July 17, 2019 Agreed all around! Any objection to swapping the reserved bit at %101, and the %100 segment? That way the 2 available reserved bits can be later used for either a full format or a segment, without splitting the nice grouping of formats and segments. When I get a chance I'll write up the spec at 7800.8bitdev.org, and update the first post here too. Quote Link to comment Share on other sites More sharing options...
TailChao Posted July 17, 2019 Share Posted July 17, 2019 Cool! 1 hour ago, RevEng said: Any objection to swapping the reserved bit at %101, and the %100 segment? That way the 2 available reserved bits can be later used for either a full format or a segment, without splitting the nice grouping of formats and segments. If you mean like this... - DSS == Data Type and Size \- %000 : 16K @ $C000 - $FFFF - %001 : 32K @ $8000 - $FFFF - %010 : 48K @ $4000 - $FFFF - %011 : reserved - %100 : 4K @ $1800 - $27FF - %101 : 16K @ $4000 - $7FFF - %110 : reserved - %111 : reserved ...that's totally fine. As long as the RAM / EXRAM targets are clearly separated from the 16K / 32K / 48K types I'm happy :) 1 hour ago, RevEng said: When I get a chance I'll write up the spec at 7800.8bitdev.org, and update the first post here too. Great, I'll put bead dispatch support on my BupSystem grocery list - with the *.b78 extension if that's okay. The feature list for v0.9.6.0 is currently locked (should be released in early August), but this shouldn't be too much effort to add later. Hopefully when later arrives there'll be some beads to test with! Quote Link to comment Share on other sites More sharing options...
RevEng Posted July 17, 2019 Author Share Posted July 17, 2019 I was thinking more like this... - DSS == Data Type and Size \- %000 : 16K @ $C000 - $FFFF - %001 : 32K @ $8000 - $FFFF - %010 : 48K @ $4000 - $FFFF - %011 : reserved - %100 : reserved - %101 : 4K @ $1800 - $27FF - %110 : 16K @ $4000 - $7FFF - %111 : reserved ...so at some point the middle reserved values can either become 2 formats, 1 format+1 segment, or 2 segments. (Without mixing up our grouping of formats and segments.) The b78 extension sounds good. The test beads shouldn't be a problem, for full format types anyway. The first place I'm putting them is in 7800basic, so I can just recompile any of the code samples or games. I'm also planning to work on a reference loader, targeting XM hardware. Quote Link to comment Share on other sites More sharing options...
TailChao Posted July 17, 2019 Share Posted July 17, 2019 1 hour ago, RevEng said: I was thinking more like this...so at some point the middle reserved values can either become 2 formats, 1 format+1 segment, or 2 segments. (Without mixing up our grouping of formats and segments.) Works for me! 1 Quote Link to comment Share on other sites More sharing options...
RevEng Posted July 18, 2019 Author Share Posted July 18, 2019 Ok, I took a first whack at the spec. Let me know if you have any input. Also let me know how (under what name) I can credit you in the doc! Quote Link to comment Share on other sites More sharing options...
TailChao Posted July 18, 2019 Share Posted July 18, 2019 Looks good so far! A few observations : In the Minimal BEAD Header section : "DSS types that don't have memory covering the 6502 reset vector will begin execution from the bead header" - it should be clarified that even BEADs with reset vectors should allow the use of their header as an entry point. In the Extended BEAD Header section : "It should be noted that the $18,$90 bytes are the 6502 CLS and BCC opcodes..." should be "...CLC and BCC..." Nitpick : We're using BEAD, Bead, and bead to refer to the header - should probably just stick with one (I vote for BEAD). I don't think any credit is required but using my handle is fine. One thought for future expansion, the description string is using a clc/bcc hop over its content. We could use different hops (sec/bcs, LDA#0/beq etc.) for different types of data. Might be helpful for when arbitrary nonexecutable blocks arrive. Quote Link to comment Share on other sites More sharing options...
RevEng Posted July 18, 2019 Author Share Posted July 18, 2019 Thanks for the typo catch, and the nitpick - I'll stick with BEAD. I'm not sold on the requirement that the reset vector should be ignored when present... it would certainly make it harder to convert commercial games to bead. It also adds friction to adoption by homebrewers. The reset vector adds a small bit of handling code, but I think it's worth it. Quote Link to comment Share on other sites More sharing options...
TailChao Posted July 19, 2019 Share Posted July 19, 2019 22 hours ago, RevEng said: I'm not sold on the requirement that the reset vector should be ignored when present... it would certainly make it harder to convert commercial games to bead. It also adds friction to adoption by homebrewers. Ah, I'm not saying the reset vectors should be ignored completely - but rather it would be polite for BEAD software to support both entry points. At most it's going to add three more bytes for a jmp $hhll or jmp ($hhll), and then the software could know whether it was started from a loader (and allow dropping back to your terminal / shell) or run directly from a cold start. Of course, this could just be more feature creep Quote Link to comment Share on other sites More sharing options...
RevEng Posted July 19, 2019 Author Share Posted July 19, 2019 Ok, I compromised on the point a bit... DSS types that don't have memory covering the 6502 reset vector will begin execution from the BEAD header. For executables with DSS types that do cover the reset vector, it's strongly encouraged that code execution beginning at the header location works correctly, as some BEAD loader implementations may not begin execution at the reset vector address. ...that way deviations are on the BEAD executable creator. I've updated the spec with the mentioned updates so far. I have minimal BEAD headers in 7800basic already for the non-segment formats, but I'm going to upgrade that to an extended header, and also work on some minimal loader reference implementations. I think we're done, but if you or anyone else has more suggestions, feel free to fire away. Quote Link to comment Share on other sites More sharing options...
TailChao Posted July 20, 2019 Share Posted July 20, 2019 Good compromise. 21 hours ago, RevEng said: I think we're done, but if you or anyone else has more suggestions, feel free to fire away. I gave the specification another read, everything is very clear and it covers our current use cases. Approved 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.