Jump to content

Photo

Disassembling the Educational System Master Cartridge


77 replies to this topic

#1 tschak909 ONLINE  

tschak909

    River Patroller

  • 3,145 posts
  • Location:USA

Posted Fri May 1, 2015 3:32 PM

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



#2 Xuel OFFLINE  

Xuel

    Dragonstomper

  • 740 posts
  • Location:US

Posted Fri May 1, 2015 4:51 PM

Here's a quick disassembly using dis:

 

Attached File  esmc.zip   31.95KB   141 downloads

 

There's actually only 2K used in the cartridge. I used this one from Atarimania.



#3 tschak909 ONLINE  

tschak909

    River Patroller

  • Topic Starter
  • 3,145 posts
  • Location:USA

Posted Fri May 1, 2015 9:57 PM

Thank you! Am going to pour over this, tonight.

-Thom

#4 Rybags OFFLINE  

Rybags

    Gridrunner

  • 16,020 posts
  • Location:Australia

Posted Fri May 1, 2015 10:17 PM

$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.



#5 tschak909 ONLINE  

tschak909

    River Patroller

  • Topic Starter
  • 3,145 posts
  • Location:USA

Posted Fri May 1, 2015 10:47 PM

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.



#6 tschak909 ONLINE  

tschak909

    River Patroller

  • Topic Starter
  • 3,145 posts
  • Location:USA

Posted Sat May 2, 2015 9:17 AM

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



#7 tschak909 ONLINE  

tschak909

    River Patroller

  • Topic Starter
  • 3,145 posts
  • Location:USA

Posted Sat May 2, 2015 1:52 PM

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


#8 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • 14,421 posts
  • Location:United Kingdom

Posted Sat May 2, 2015 2:17 PM

The display list is just using two mode F lines between every mode 2 line as vertical spacing. $700 is all zeros.

#9 tschak909 ONLINE  

tschak909

    River Patroller

  • Topic Starter
  • 3,145 posts
  • Location:USA

Posted Sun May 3, 2015 11:59 AM

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



#10 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • 14,421 posts
  • Location:United Kingdom

Posted Sun May 3, 2015 12:22 PM

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.

#11 tschak909 ONLINE  

tschak909

    River Patroller

  • Topic Starter
  • 3,145 posts
  • Location:USA

Posted Sun May 3, 2015 12:55 PM

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



#12 kenjennings OFFLINE  

kenjennings

    Dragonstomper

  • 789 posts
  • Me + sio2pc-usb + 70 old floppies
  • Location:Florida, USA

Posted Sun May 3, 2015 2:23 PM

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.



#13 tschak909 ONLINE  

tschak909

    River Patroller

  • Topic Starter
  • 3,145 posts
  • Location:USA

Posted Sun May 3, 2015 2:27 PM

$0600 is also used as a temporary (1 page) buffer for the IRQ routine, the bytes stored there have already been EOR'ed.



#14 Bryan OFFLINE  

Bryan

    Quadrunner

  • 10,927 posts
  • Cruise Elroy = 4DB7
  • Location:Chesaning, MI

Posted Sun May 3, 2015 2:37 PM

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.



#15 tschak909 ONLINE  

tschak909

    River Patroller

  • Topic Starter
  • 3,145 posts
  • Location:USA

Posted Sun May 3, 2015 2:41 PM

The character set is a copy of the system character set, with some characters patched at initialization:

 

1GnsLjH.png



#16 tschak909 ONLINE  

tschak909

    River Patroller

  • Topic Starter
  • 3,145 posts
  • Location:USA

Posted Sun May 3, 2015 2:48 PM

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)



#17 tschak909 ONLINE  

tschak909

    River Patroller

  • Topic Starter
  • 3,145 posts
  • Location:USA

Posted Sun May 3, 2015 2:57 PM

@kenjennings @flashjazzcat, re the color registers, yeah, that does make sense.

 

-Thom



#18 tschak909 ONLINE  

tschak909

    River Patroller

  • Topic Starter
  • 3,145 posts
  • Location:USA

Posted Sun May 3, 2015 4:38 PM

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



#19 David_P OFFLINE  

David_P

    Dragonstomper

  • 931 posts
  • Location:Canada

Posted Sun May 3, 2015 5:04 PM

A machine with 256K should have enough RAM to buffer one side of a tape.



#20 tschak909 ONLINE  

tschak909

    River Patroller

  • Topic Starter
  • 3,145 posts
  • Location:USA

Posted Sun May 3, 2015 5:07 PM

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



#21 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • 14,421 posts
  • Location:United Kingdom

Posted Sun May 3, 2015 5:19 PM

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?

#22 tschak909 ONLINE  

tschak909

    River Patroller

  • Topic Starter
  • 3,145 posts
  • Location:USA

Posted Sun May 3, 2015 6:12 PM

assuming, yeah.

 

-Thom



#23 tschak909 ONLINE  

tschak909

    River Patroller

  • Topic Starter
  • 3,145 posts
  • Location:USA

Posted Sun May 3, 2015 6:13 PM

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



#24 Rybags OFFLINE  

Rybags

    Gridrunner

  • 16,020 posts
  • Location:Australia

Posted Sun May 3, 2015 6:59 PM

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 by Rybags, Sun May 3, 2015 7:00 PM.


#25 JamesD OFFLINE  

JamesD

    Quadrunner

  • 8,433 posts
  • Location:Flyover State

Posted Sun May 3, 2015 10:27 PM

Isn't the tape set up to be stopped periodically anyway?






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users