Sam Trenholme's webpage
This article was posted to the Usenet group alt.hackers in 1995; any technical information is probably outdated.

fun with ROMs (was Re: Video Fader)

Article: 8902 of alt.hackers
From: Ralf Brown <>
Newsgroups: alt.hackers
Subject: fun with ROMs (was Re: Video Fader)
Date: 20 Oct 1995 11:23:37 GMT
Organization: Just me and my PC....
Lines: 184
Approved: :devorppA
Message-ID: 308648a6@ralf
Summary: :yrammuS
Keywords: :sdrowyeK
In-Reply-To: <4621gh$>
Originator: ralf@B.GP.CS.CMU.EDU
Status: RO

In article <4621gh$>,
(Kevin Horton) wrote:
}Obhack: I'm trying to program my own game on the Coleco Vision.  To
}program games on an essentially un-documented machine, you must first
}get to know it.  I built an adapter that plugs into my EPROM programmer
}that allows me to read CV carts.  It works great on my 'test carts',
}    [using adapter to read CV BIOS ROM]
}Bingo!  I have data!  I successfully read the
}ROM out and replace it back into my CV.  I then dis-assemble the code and
}found out all the interrupt vectors! ;-)

I just did something similar, but no hardware required, and I didn't even
have to open up the modem.

ObHack: disassembling the EPROM on my new Sportster Vi to find undocumented
AT commands.

Step 0: Some years ago, someone had mentioned a "poke" command
which turned
  an older version of a Sportster into a Courier (same motherboard, different
  price range...) -- ATGW<nnn>,<nn>.  So I tried ATGR<nnn>
  and got back 16
  lines like

    0000:0000    FF00 000F 0429 C000 10A7 C000 10AC C000

  Hmm, segmented addresses....	Sure enough, ATGR1000:1000 and ATGR1100:0000
  spit out the same values.  ATI7 reports a 256K EPROM, so not suprisingly,
  there is valid data from C000:0000 on up.  And the hex dump sure looked
  like 80x86 code, so I entered a few bytes into DEBUG and got back valid
  code.  All right, we've got an 8018x or 386EX in real mode!  (The strings
  in the ROM showed the processor to be an 80188)

Step 1: Copy the modem's RAM and ROM.  Create a file with copy/paste and
  search/replace (Emacs' narrow-to-region command came in very handy here)
  with all the ATGR commands to output the first 64K of the address space
  and C000:0000 to F000:FFFF.  Stuff this to the modem using RBcomm's
  command and log the results to a file.

Step 2: Massage the captured data.  After a few passes of regex
  search/replace, the data was in a format that could be fed into DEBUG.
  Add the appropriate DEBUG commands to beginning and end of the file, then

    DEBUG sportrom.rom <sportrom.txt >nul

  Bingo!  A binary of the modem's ROM.

Step 3: Start peeking at the ROM with "strings", Turbo Debugger, etc.
  As it turns out, there is no way to alter the modem's memory, so it is no
  longer possible to turn a Sportster into the more expensive Courier.

Step 4: post the list of undocumented commands :-)

Sportster Vi / Courier HST undocumented commands

AT commands:
 g= [addr]	  : dump 100h memory locations starting at hex addr [0] (bytes)
 gb [addr]	  : dump 100h I/O ports starting at hex address [0]
 gi [addr]	  : read I/O port at hex addr [0] and return value in hex
 gn		  : set ?? flag
 go<addr>,<val>   : output hex value to I/O port at hex address [0]
 gr [addr]	  : dump 100h memory locations starting at hex addr [0] (words)
 gu		  : nop
 gx [addr]
 gy [addr]
 g<4 hex digits>
 g<8 hex digits>
 r		  : set ?? flag
 rs99?		  : print copyright string
 usr		  : print out credits
 y5		  : [checks something on phone line]
 y6		  : same as ATI6
 y7		  : check signal quality (only while connected)
 y8		  : dump compression dictionary (receive)
 y9		  : dump compression dictionary (xmit)
 y11		  : prints "Freq	 Level", plus listing if connected
 y12		  : prints "Recv	 Xmit", plus listing if connected
 y14		  : prints "000,000,018,007,010,000"
 ~S?		  : print serial number
 ~S=		  : set serial number  (lost on next ATZ or power cycle)

 #MFR?		  : print modem manufacturer's name
 #MDL?		  : print modem model string
 #REV?		  : print revision string
 #VBQ?		  : print buffer sizes
 #VCI?		  : print modem ID string
 #VBT?		  :
 #VBT=?		  : list valid values (0-40)
 #VBT=<n>   :
 #BDR?		  :
 #BDR=?		  : print valid values (0,1,2,4,8,16,24)
 #BDR=<n>   :
 #VBS?		  :
 #VBS=?		  : list valid values (2,3,4)
 #VBS=<n>   :
 #VLS?		  :
 #VLS=?		  : list valid values (0,1,2,3,4)
 #VLS=<n>   :
 #VRA		  : NOP
 #VRN		  : NOP
 #VSD?		  :
 #VSD=?		  : list valid values (0,1)
 #VSD=<n>   :
 #VSK		  : NOP
 #VSP?		  :
 #VSP=?		  : list valid values (0-255)
 #VSP=<n>   :
 #VSR?		  :
 #VSR=?		  : list valid values (8000)
 #VSR=<n>   :
 #CID?		  :
 #CID=?		  : list valid values (0,1,2)
 #CID=<n>   :
 #VSS?		  :
 #VSS=?		  : list valid values (0,1,2,3)
 #VSS=<n>   :
 #VTD?		  :
 #VTD=?		  : list valid values (3F,3F,3F)
 #VTD=<n>   :
 #VTM		  :
 #VTS=[n,n]	  :
 #VTS=[n,n,n]	  :
 #VTS={n,n}	  :
 #VTS={n,n,n}	  :


(must follow +fclass in same command?)
 +fpi="case-sensitive literal"
 +fli="case-sensitive literal"

(disabled on Sportster, available on some other models)
 c0		  : disable transmitter (modem is receive-only)
 c1		  : enable transmitter
 k0		  : modem clock in call-duration mode
 k1		  : modem clock in real-time mode
 &L0		  : normal phone line (doc. for Courier)
 &L1		  : leased line (doc. for Courier)

My employer will | I'net:	 Fido: Ralf Brown 1:129/26.1
deny knowing of  | "Man is the only kind of varmint sets his own trap,
this message...  | it, then steps in it." -- John Steinbeck,

Back to index