tschak909 Posted May 1, 2015 Share Posted May 1, 2015 I want to open up a small thread, deconstructing the Educational Master System cartridge, AKA the Dorsett Talk&Teach Master Cartridge. It's definitely an interesting chunk of code, thus far. The cartridge itself is a 4K cartridge, that loads into $B800 ... very interesting, actually, as this definitely checks out to the earlier design of Colleen managing everything including cartridges in 4K banks. $B800, some basic initialization code, clearing console switches, clearing and setting P/M registers based on rom table values, and setting up POKEY values (starting at AUDF1) based again on ROM table values...more to look at here.. The OS is most definitely bypassed, and POKEY is being bit-banged manually to decode the data coming in off the tape... 1 Quote Link to comment Share on other sites More sharing options...
Xuel Posted May 1, 2015 Share Posted May 1, 2015 Here's a quick disassembly using dis: esmc.zip There's actually only 2K used in the cartridge. I used this one from Atarimania. 1 Quote Link to comment Share on other sites More sharing options...
tschak909 Posted May 2, 2015 Author Share Posted May 2, 2015 Thank you! Am going to pour over this, tonight. -Thom Quote Link to comment Share on other sites More sharing options...
Rybags Posted May 2, 2015 Share Posted May 2, 2015 $B800 would be 2K... the memory management by hw inside the computer is such that 8K of system Ram still drops off the memory map. Exception of course is the likes of Mac-65 with the bankswitching that allows selectively deselecting the entire cart if the setting + requested address is right. Often it'll be the case that smaller than 8K Roms will replicate across the cart address space. I remember getting Gridrunner as an 8K file then looked into it and found identical 4K copies, so I just chopped the executable in half. Strange that a cart such as this would bitbang and not utilize the OS... stuff like that lends to the theory that some software might have been developed before the OS was ready. Quote Link to comment Share on other sites More sharing options...
tschak909 Posted May 2, 2015 Author Share Posted May 2, 2015 Yes, 2K, derp! It's very compact, not much more than a Pokey IRQ handler, some tables, and some initialization code. It doesn't use the OS because the OS tape routines are block oriented. The Dorsett tapes were stream oriented, very similar to MODEM transmission, where the text/commands and voice are synchronized together. Listen to the raw tape data (e.g. on Atariwiki), and you'll hear it's fairly continuous, with intermittent gaps. The effective transmission speed is about 450 bits per second, from what I'm seeing... The original Dorsett tapes were Kansas City Standard at 300 bps. Quote Link to comment Share on other sites More sharing options...
tschak909 Posted May 2, 2015 Author Share Posted May 2, 2015 Interesting, I see a bit of code at $B820, which writes $69 to POTGO... Is the POT counter being used as a cycle timer, here? And wtf? They turn right around, grab a value from the table, and write it to VCOUNT. WTF? CHBASE seems to sit at $0C00 after initialization. PMBASE seems to sit at $0800 after initialization. It looks like, we have four tables, which put info into GTIA (2), POKEY, and ANTIC respectively: $BD8C $BD6D both set GTIA registers $BD79 sets POKEY registers $BD82 sets ANTIC registers (yes, there is overlap, byte saving feature it looks like) Tables are read backwards. VIMIRQ is set to $B99C . I suspect the majority of the tape decoding is happening here. $B840 sets up vectors to copy the system character set at $E000 to $0C00, ultimately executed by a pair of recursive subroutine calls which copy the data. Immediately after the copy, it looks like certain characters are patched according to another table in ROM (probably for descenders, the edu cartridge uses IRG mode 3) (it never ceases to amaze me, while I step through code in a debugger, some of the crazy weird tricks used...) -Thom Quote Link to comment Share on other sites More sharing options...
tschak909 Posted May 2, 2015 Author Share Posted May 2, 2015 Traced through where the display starts to show the initial screen, display list is in ROM, and a wee bit funky: Altirra> .dumpdlist BD0B: mode F @ 0700 BD0E: mode F BD0F: mode 2 @ 0820 BD12: mode F @ 0700 BD15: mode F BD16: mode 2 @ 0840 BD19: mode F @ 0700 BD1C: mode F BD1D: mode 2 @ 0860 BD20: mode F @ 0700 BD23: mode F BD24: mode 2 @ 0880 BD27: mode F @ 0700 BD2A: mode F BD2B: mode 2 @ 08A0 BD2E: mode F @ 0700 BD31: mode F BD32: mode 2 @ 08C0 BD35: mode F @ 0700 BD38: mode F BD39: mode 2 @ 08E0 BD3C: mode F @ 0700 BD3F: mode F BD40: mode 2 @ 0900 BD43: mode F @ 0700 BD46: mode F BD47: mode 2 @ 0920 BD4A: mode F @ 0700 BD4D: mode F BD4E: mode 2 @ 0940 BD51: mode F @ 0700 BD54: mode F BD55: mode 2 @ 0960 BD58: mode F @ 0700 BD5B: mode F BD5C: mode 2 @ 0980 BD5F: mode F @ 0700 BD62: mode F BD63: mode 2 @ 09A0 BD66: mode F @ 0700 BD69: waitvbl BD00 ANTIC Status: Altirra> .antic DMACTL = 2d : narrow missiles players 2-line dlist CHACTL = 00 : DLIST = bd0b HSCROL = 00 VSCROL = 00 PMBASE = 08 CHBASE = 0c NMIEN = 00 : NMIST = 5f : vbi PENH/V = 00 00 GTIA status: Altirra> .gtia Player 0: color = d4, pos = 40, size=3, data = ff Player 1: color = d4, pos = 60, size=3, data = ff Player 2: color = d4, pos = 80, size=3, data = ff Player 3: color = d4, pos = a0, size=3, data = ff Missile 0: color = d4, pos = 00, size=0, data = 00 Missile 1: color = d4, pos = 00, size=0, data = 00 Missile 2: color = d4, pos = 00, size=0, data = 00 Missile 3: color = d4, pos = 00, size=0, data = 00 Playfield colors: 84 | 84 0a 84 00 PRIOR: 08 (pri= 8 , normal) VDELAY: 00 GRACTL: 03, player DMA, missile DMA CONSOL: 08 set <-> 0f input, speaker collision registers omitted and finally, POKEY: Altirra> .pokey AUDF1: a0 AUDC1: a0 Output: 1 (228 cycles until fire) (passive: 256 cycles) AUDF2: 0b AUDC2: a0 Output: 1 (767 cycles until fire) (passive: 2983 cycles) AUDF3: ce AUDC3: a0 Output: 1 AUDF4: 05 AUDC4: a0 Output: 0 AUDCTL: 78, 17-bit poly, 1.79 ch1, 1.79 ch3, ch1+ch2, ch3+ch4, 64KHz SKCTL: 13 SERIN: 00 SEROUT: ff (done) shift register ff (0: done) IRQEN: c0, break key, keyboard IRQST: b7, keyboard, sertrans ALLPOT: 00 Command line: negated Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted May 2, 2015 Share Posted May 2, 2015 The display list is just using two mode F lines between every mode 2 line as vertical spacing. $700 is all zeros. Quote Link to comment Share on other sites More sharing options...
tschak909 Posted May 3, 2015 Author Share Posted May 3, 2015 Yeah, but I wonder why? Is it to keep the number of cycles stolen somewhat consistent? Why not use blank instructions? maybe less color register messing needed when changing screens? -Thom Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted May 3, 2015 Share Posted May 3, 2015 You can't necessarily use blank line instructions since these take the COLBK colour. They may have wanted to use a different border colour at some stage. Quote Link to comment Share on other sites More sharing options...
tschak909 Posted May 3, 2015 Author Share Posted May 3, 2015 and they do..so.. ok. Looks like the IRQ routine set up is where the data decoding happens. The data is read from SERIN when ready (thanks to SKSTAT) and is subsequently EOR'ed $FF, to invert the bits. I assume as a primitive form of obfusication, but it does check out with the engineering notes that specified that Dorsett tapes must have $FF's written immediately from the leader... -Thom Quote Link to comment Share on other sites More sharing options...
kenjennings Posted May 3, 2015 Share Posted May 3, 2015 Yeah, but I wonder why? Is it to keep the number of cycles stolen somewhat consistent? Why not use blank instructions? maybe less color register messing needed when changing screens? Yes, and what FJC said... Probably to space out the text while keeping the text and gaps color consistent. Mode F and mode 2 use the same color registers for border (COLBAK) vs the "background" of the playfield (COLPF2). Most other text and map modes and the blank line instructions use COLBAK for the playfield background, so if it used one of those mode instructions then the spacer gaps between mode 2 lines would have a different "background" than the text lines. Quote Link to comment Share on other sites More sharing options...
tschak909 Posted May 3, 2015 Author Share Posted May 3, 2015 $0600 is also used as a temporary (1 page) buffer for the IRQ routine, the bytes stored there have already been EOR'ed. Quote Link to comment Share on other sites More sharing options...
Bryan Posted May 3, 2015 Share Posted May 3, 2015 It's possible some of the hardware writes are left over from an older memory map (although Antic can't be moved...). It's cool to see weird stuff like this. 1 Quote Link to comment Share on other sites More sharing options...
tschak909 Posted May 3, 2015 Author Share Posted May 3, 2015 The character set is a copy of the system character set, with some characters patched at initialization: 1 Quote Link to comment Share on other sites More sharing options...
tschak909 Posted May 3, 2015 Author Share Posted May 3, 2015 Also, as may have been gleaned before, the output display is 32 characters by 13 lines, definitely a throw-back to some earlier hardware-only system. (416 bytes) Quote Link to comment Share on other sites More sharing options...
tschak909 Posted May 3, 2015 Author Share Posted May 3, 2015 @kenjennings @flashjazzcat, re the color registers, yeah, that does make sense. -Thom Quote Link to comment Share on other sites More sharing options...
tschak909 Posted May 3, 2015 Author Share Posted May 3, 2015 It just hit me like a ton of bricks. I could write a routine to read data streamed off the tape, BUT... (1) due to the initialization required to get POKEY into a usable state to bit bang the data, I am concerned that there would be conflicts trying to utilize CIO at the same time to write out the serialized data to disk. Am I too paranoid? (2) There isn't enough RAM to put an entire side of a tape into memory. In fact, it would probably be just over the limit, and stopping the tape to flush a part of memory out of disk, in the middle of a flurry of data would undoubtedly introduce jitter into the output (this format _literally_ has no error correction! it's akin to a streamed MODEM transmission at about 450 baud) decisions, decisions... nonetheless, I will try to write something that can decode the data off the tape. -Thom Quote Link to comment Share on other sites More sharing options...
+David_P Posted May 3, 2015 Share Posted May 3, 2015 A machine with 256K should have enough RAM to buffer one side of a tape. 1 Quote Link to comment Share on other sites More sharing options...
tschak909 Posted May 3, 2015 Author Share Posted May 3, 2015 dealing with ram expansions will be a sticky point. the code inside the pokey IRQ is very tricky, and bytes need to be serviced as quickly as possible to avoid overrun. Having to juggle a bank switching mechanism in there may blow the cycle count right out of the water. -Thom Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted May 3, 2015 Share Posted May 3, 2015 You're looking at accessing an indexed table of PORTB values (INC BANK / LDX BANK / LDA TABLE,X / STA PORTB) every 16K which you previously built when interrogating the RAM expansion. Is it that tight? Quote Link to comment Share on other sites More sharing options...
tschak909 Posted May 4, 2015 Author Share Posted May 4, 2015 assuming, yeah. -Thom Quote Link to comment Share on other sites More sharing options...
tschak909 Posted May 4, 2015 Author Share Posted May 4, 2015 in the end, I'm doing this just to try and decode the data... if worse comes to worse, i'll just read it right out of page 6, and start doing my forensic analysis based on that. -Thom Quote Link to comment Share on other sites More sharing options...
Rybags Posted May 4, 2015 Share Posted May 4, 2015 (edited) Leader and IRG tone is all 1 on tape, possibly EOR #$FF is just to turn that to zero which would make program logic easier. Though a trail of leader won't generate SERIN data. A write to VCOUNT is sort of strange, but might just be test code inadvertantly left in the program. I've used such dummy writes before, it can be handy in a Ram based program - to turn the write off you just point to an unused register location. An easier way to capture all the data might be just get the audio track into an editor. Then split it into chunks you know will fit in memory, ensuring you do the cut at a gap in the data. Though doing bankswitching to fit in a larger Ram machine shouldn't be a problem. Tape is so slow that even bit-banging you're still receiving bits at about 1/3rd the rate a byte comes in over standard disk. Edited May 4, 2015 by Rybags Quote Link to comment Share on other sites More sharing options...
JamesD Posted May 4, 2015 Share Posted May 4, 2015 Isn't the tape set up to be stopped periodically anyway? 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.