Rants from Vas https://rants.vastheman.com Take a hit with V-Real Tue, 13 Aug 2019 10:13:17 +0000 en-US hourly 1 https://wordpress.org/?v=4.9.10 Lifting a jinx? https://rants.vastheman.com/2019/08/13/jinx/ https://rants.vastheman.com/2019/08/13/jinx/#respond Tue, 13 Aug 2019 10:13:17 +0000 https://rants.vastheman.com/?p=332 The past decade has seen a substantial increase in rail freight in Australia. Capital investment like the Southern Sydney Freight Line and conversion of the Victorian North East line to 1435 mm standard gauge is paying off. Allied Pinnacle has a siding just south of Kensington station, and Southern Shorthaul Railroad (SSR) currently has the contract to deliver their wheat. SSR uses a pair of S class “bulldog nose” locomotives from the 1950s coupled back-to-back to operate this service. Right now they’re using S302 and S317, but they were using S312 earlier in the year.

S302 is named after the pioneer Edward Henty. Here it is at Kensington, in orange and grey livery:

S302 at Kensington

S317 was the last S class locomotive to be delivered, and was named after Sir John Monash. S317 has been involved in two major accidents: it was rebuilt after a head-on collision with X33 in 1967, and collided with the read of the Spirit of Progress at Barnawartha in 1982 killing the crew. Here it is at Kensington:

S317 at Kensington

Wait! What’s that below the cab window? It doesn’t have the old Sir John Monash nameplate any more. It seems to be named Jenny Molloy now! Who’s Jenny Molloy? Whoever she is, she definitely isn’t as well-known as Sir John Monash. She does have the same initials, though. Here’s a view of the nose:

S317 at Kensington

Interesting paintwork inside the horns, too. If anyone knows more about the renaming of S317 or who Jenny Molloy is, I’d love to hear about it. Did the old name have too many bad connotations? Was the new name intentionally selected to have the same initials? Does the new name lift a jinx?

https://rants.vastheman.com/2019/08/13/jinx/feed/ 0
The Q Factor https://rants.vastheman.com/2018/03/20/qfactor/ https://rants.vastheman.com/2018/03/20/qfactor/#respond Tue, 20 Mar 2018 11:27:27 +0000 https://rants.vastheman.com/?p=315 QSound logo screenIf you spent much time in video game arcades ’90s, you’re sure to have seen the QSound logo proudly displayed during the attract loop of games running on Capcom’s CPS-2 and ZN-1/ZN-1 hardware platforms, and heard the distinctive jingle. But What exactly is QSound? What does it actually do? Capcom was definitely keen to promote its inclusion, but did it really give an edge in any area besides marketing? Was it worth the licensing fees they undoubtedly paid, and the precious attract loop time they spent announcing it?

As implemented in Capcom’s arcade systems, QSound technology is provided by a digital signal processor (DSP) running an internal program that implements a sixteen-channel sample player/mixer. It produces 16-bit stereo output at just over 24 kHz. It supports 16-bit samples, but Capcom only ever used it with 8-bit sample ROMs. In addition to playing and mixing the channels, it applies “spatialisation” effects, intended to give the impression of a more expansive virtual sound stage. I know what you’re thinking: everything I’ve said so far sounds like marketing material, but what do the effects actually do, and does it actually work?

The most prominent effect you’ll hear is the way the QSound DSP handles stereo panning. Conventionally, panning just reduces the volume on one channel or the other. If you pan a sound hard left, it’s sent to the left speaker at full volume and silenced on the right speaker. As you pan towards the centre, the volume on the right speaker increases until you reach the centre position where the volume is equal on left and right speakers. Panning past the centre to the right reduces the volume on the left speaker.

Rather than simply adjusting the level, the QSound produces two components for each stereo output: one sent directly to the speaker, and the other passed through a digital filter. Panning controls the volume ratio of the component sent directly to the speaker and the filtered component. For the left output, when a sound is centred, the sound is sent directly to the speaker only. As you pan to the centre, the amount sent through the filter increases until you reach the centre, where the filtered component is about 2 dB lower than the direct component. Panning further to the right continues to increase the volume of the filtered component, and reduces the volume of the component sent directly to the speaker. When panned hard, it’s sent through the filter only. For what happens with the right stereo output, just reverse the directions. The pan tables are illustrated in the graph below.

QSound pan

That’s all well and good, we know that panning controls the ratio of filtered to unfiltered output rather than just adjusting volume, but what do the filters themselves do? Let’s start by looking at the filter used for the left stereo output:

QSound right-to-left

It has a fairly flat passband up to about 1 kHz, falls to about -5 dB at 2 kHz, a small peak at 3 kHz, and falls off rapidly from 5 kHz to the stop band at 6 kHz. Can you guess what this is for yet? This filter is supposed to simulate the sound your left ear hears from a sound source to your right. Low frequencies tend to diffract around obstacles, so they don’t have much directionality, midrange frequencies pass through your head fairly effectively, and high frequencies are basically blocked by your head. This is designed to give a more realistic impression of the position of a source on the virtual sound stage than simple panning.

The filter for the right stereo output, simulating what your right ear heard from a sound source on your left, is similar but not quite the same (perhaps the asymmetry is supposed to increase the realism):

QSound left-to-right

This is not the only effect applied by the QSound DSP, it’s just the most prominently audible one. It leaves the question of whether it actually works as intended. In my opinion, it works reasonably well if used effectively, provided the speaker setup has reasonable stereo separation, and the listener is in the sweet spot – easily achievable with headphones or a home stereo, but not in a noisy arcade with poor cabinet acoustics, not so much. Maybe it would work OK with a something like a Sega Blast City cabinet, specifically designed for stereo output. Some of the other QSound effects are less dependent on stereo separation, so they work better in typical arcades.

https://rants.vastheman.com/2018/03/20/qfactor/feed/ 0
TPG FTTB Settings https://rants.vastheman.com/2018/01/24/settings/ https://rants.vastheman.com/2018/01/24/settings/#comments Wed, 24 Jan 2018 06:52:16 +0000 https://rants.vastheman.com/?p=306 In case anyone else wants to configure third-party equipment for a TPG fibre-to-the-building service, here are the details. Below the fold are screenshots of the settings entered in the web-based configuration UI of an AVM FRITZ!Box. Note that the SIP password is not the same as your account password, and you’ll need to obtain this somehow. TPG doesn’t make this easy, but it is possible.

Internet connection

Modulation: VDSL2 17a (ITU G.993.2)
VPI: 1
VCI: 32
Encapsulation: PPPoE
Authentication: PAP
Username: your TPG username optionally followed by “@tpg.com.au”
Password: doesn’t matter – it isn’t actually verified (you can use your account password)

Phone service connection

Connection type: PVC
802.1q PCP tag:
(PBit or 802.1p traffic class)
5 (VO, voice with < 10 ms latency/jitter)
VPI: 1
VCI: 32
Encapsulation: routed bridge encapsulation
IPv4 configuration: DHCP

SIP connection settings

Registrar server: uni-v1.tpg.com.au
Proxy server: uni-v1.tpg.com.au
STUN server: none (disabled)
Connection type: SIP trunk
Telephone number: your telephone number including area code (ten digits)
Username: your telephone number including area code (ten digits)
Password: your SIP password (16 characters including uppercase and lowercase letters and digits)
Voice codecs: G.711 and G.729

Internet account settings for AVM FRITZ!Box

DSL settings

Telephone line settings for AVM FRITZ!Box

Line settings

Telephone number settings for AVM FRITZ!Box

SIP settings

https://rants.vastheman.com/2018/01/24/settings/feed/ 4
TPG: Just Don’t https://rants.vastheman.com/2018/01/20/tpg/ https://rants.vastheman.com/2018/01/20/tpg/#respond Fri, 19 Jan 2018 15:38:21 +0000 https://rants.vastheman.com/?p=298 Due to persistent issues with line quality, I switched an Internet connection from Internode ADSL2+ to TPG fibre to the building (FTTB). Although the connection quality is better, just about everything else about TPG is worse. I strongly recommend avoiding TPG. Problems include:

  • Error-prone signup process
  • Supplied modem/router is heavily compromised
  • Phone service is tied to compromised modem/router
  • No IPv6 support
  • Support staff very inconsistent
  • Good support staff hobbled by policy

My Internode connection had become very slow and unstable in hot, dry weather. Strangely it was fine in the rain, and even during flooding. It almost seemed like something needed to be damp to maintain an electrical connection. There’s no way to actually get these kinds of issues resolved, as the ISP and last mile provider will blame each other and the in-building wiring, and charge extortionate rates for technicians to be called out without actually solving the issues. The only other option I have for last mile is TPG. I’d been switching to Telstra LTE on bad days, and to be fair it’s actually not too bad at the moment. It seems to be pretty fast and stable, but I imagine that will get worse as more people start to use the network. But using LTE comes with a number of imitations, and it’s supposed to be my backup, not my day-to-day Internet connection.

Sadly, it seems that Internode may be going downhill since being acquired by TPG. After iiNet acquired Internode, they were allowed to operate independently for the most part. The call centre in Adelaide remained open, Internode continued to offer the same kinds of perks as before, including Usenet servers, Steam content mirrors, native IPv6 connectivity, and more. However, TPG has consolidated iiNet and Internode support and seems to be phasing out Internode perks. They’ve even started selling TPG nbn™ HFC (DOCSIS cable) under the Internode brand name, providing the same IPv4-only connection and obfuscated SIP phone service.

With the consolidation in the Australian ISP sector, there’s a big reduction in competition. TPG has merged with or acquired Soul, AAPT, Chariot, iiNet, Internode, TransACT, WestNet, PIPE, Westnet, and more. There doesn’t seem to be a good alternative at the moment. There may be an opportunity for an upstart ISP that understands what made “premium” ISPs like Internode successful in the first place.

Sign-up process

I initially tried signing up for the service through the web site, converting an existing dial-up account I’ve had for over a decade. At the end of the process, it gave me a red error message telling me there was a problem and to call customer service. Despite this, it still charged me the setup fee, and not the correct setup fee for the options I’d chosen. Also, there’s no option to choose the delivery address for the supplied modem/router through the web interface: it will always be sent to the billing address, not the service address. This means you need to get it from the billing address to the service address if they aren’t the same.

It took multiple calls to customer service over several weeks to get the incorrect setup fee refunded and get back to where I started again. The telephone support staff seem to vary substantially. Many of them don’t seem to be interested in actually getting issues resolved, and just want to read from a script. I also had support staff promise to call back, and then never do so.

After this, I tried my luck signing up over the phone. The saleswoman insisted that I needed to create a new account, and couldn’t convert my existing dial-up account over. She assured me that my existing TPG e-mail address could be transferred to the new account without any period where mail would be lost. It’s possible to specify a delivery address for the modem/router when signing up over the phone. However, after completing the sign-up process, I was transferred to support who informed me that there was no need to sign up for a new account at all, and it seems to be impossible to transfer the existing e-mail account to the new account without a multi-day period where e-mails will be lost. The call was recorded, so it’s on record that the saleswoman promised me something that they can’t deliver. This issue still hasn’t been resolved.

Supplied modem/router

TPG supplied a Huawei HG659 modem/router. This device is rather lacking in functionality. It lacks DECT base station functionality, it can’t function as a SIP gateway for multiple IP phones, it doesn’t support incoming VPN connections, and numerous other useful features are absent. On top of this, TPG supplies the device with crippled firmware. The predefined “admin” user account is limited to changing basic settings, and it’s not possible to create an account with full access. It’s possible to access some hidden settings (including authentication, encapsulation and VLAN settings) with a JavaScript debugger attack, but trying to access other settings this way drops you back to the login page. It’s completely impossible to access bandwidth settings and telephony settings, or to back up/restore settings.

The modem/router is pre-configured and has TR-069 permanently enabled on VLAN 6. This allows TPG to push configuration or firmware updates to the device at any time. This is a huge problem for stability and security. There’s no way to control if/when updates may be pushed, allowing your connections to be interrupted at any time. A poorly considered or malicious update could cause denial of service, DNS hijacking, communication interception, or a host of other issues. Flaws in TR-069 are actively exploited by the Mirai botnet as well as other malware.

TPG’s justification for this is that it makes it easy to TPG to fix configuration problems, and they make vague claims about doing it for “security” reasons. It’s true that it makes support simpler if the ISP can push out default configuration. However it comes with a massive security risk. They should acknowledge the security risks involved, and give the customer the ability to choose between convenience and security. The real motivation seems to be an effort to hide the SIP settings to prevent customers from using other SIP clients or IP phones. I really don’t understand TPG’s obsession with preventing the customer from using a SIP client of their choice.

It’s possible to put the modem/router into firmware recovery mode by holding the reset button (with a straightened paperclip) for twenty seconds, and then to load a different firmware image. However, Huawei doesn’t seem to distribute a standard firmware image, so you’d need to use a firmware image from another ISP, with its own customisations and potential security issues. If you don’t enable TR-069 after loading a different firmware image, you won’t be able to obtain the SIP settings, so the phone service still won’t be usable. However, if you do enable TR-069, TPG will just push out their firmware image along with the configuration, and you’ll be back where you started.

In summary, it’s impossible to get the modem/router into a clean state where you can fully control it and still use TPG’s phone service. The modem/router supplied by TPG must be treated as a hostile device on your network. As the customer, you can’t prevent malicious configuration or firmware updates being applied, and you can’t verify or change the device’s configuration.

Phone service inflexibility

TPG’s SIP phone service for FTTB customers is limited and inflexible. Unlike other SIP phone services, it’s only accessible from TPG’s network. The server uses the DNS name uni-v1.tpg.com.au which resolves to three private IPv4 addresses –,, and – accessible via VLAN 6. TPG requires use of the narrowband 8 kbps G.729 voice codec, which provides poor call quality. TPG also actively works to prevent customers from using their own IP phones.

TPG refuses to supply customers with SIP connection details, only pushing them out via TR069. The SIP username and password are different from the username and password used to access e-mail and other TPG services. It seems somewhat strange and pointless to require authentication at all, since the SIP server is only accessible on a TPG connection via a specific VLAN. It would be trivial to identify the customer by the origin of the connection. It seems to be nothing more than a way to force the customer to use the compromised modem/router supplied by TPG. (TPG actually does provide SIP settings for some services on this page. The aphone1 to aphone6 servers resolve to public IP addresses, but they are only accessible from TPG connections. However, there’s nothing to indicate which customers can use these settings – it’s definitely not applicable to FTTB services.)

It was previously possible to use a JavaScript debugger attack on the supplied Huawei modem/router to back up settings, and extract the SIP settings, including the password, from the resulting file. However, new firmware made that impossible. It would be possible to buy a VDSL DSLAM, emulate the SIP server, and steal the credentials that way, but this is prohibitively expensive. It may be possible to connect to VLAN 6 with a different modem/router, use software to emulate the TR-069 client, and obtain the VoIP settings that way. It may also be possible to open the supplied modem router, solder in a serial or JTAG header, and dump the Flash filesystem. Desoldering the Flash chips and dumping the data directly is another option. All of these options are a lot of work just to be able to use a service that you pay for, without having to allow a compromised device on your network.

There’s no way to unbundle the phone service from the Internet service. So if you decide that the risk of using a compromised modem/router is too high and the workarounds are too impractical, you’re still forced to pay for a phone service you can’t use.

All this effort to prevent customers from using SIP clients other than the supplied modem/router seems rather strange. There doesn’t seem to be a technical reason for it, as the service seems to use standard protocols, and customers who’ve managed to extract the details from their modem/router haven’t had issues using other SIP clients. The lack of any plausible explanation almost seems like TPG wants to have devices they control on customers’ networks for some malicious purpose.

The decision to require G.729 seems odd as well. With ever-increasing line speeds, a 32 kbps codec like G.726 shouldn’t be a problem. In particular, G.726 would allow lossless forwarding to cordless DECT handsets. Only allowing access from TPG’s network is also artificially limiting. Packets are cheap to forward – there’s no real reason not to allow access from other networks. It can still be limited to one or two concurrent calls and/or concurrent registrations. Call quality will suffer if there’s unpredictable latency or packet loss in the path, but the customer can deal with that.

NodePhone SIP service, ironically owned by TPG, can be used from anywhere on the Internet. I’ve successfully used it from as far away as Hong Kong and Shanghai with good results. Right now I’m using a NodePhone service over my TPG FTTB connection as it’s a better option than using a compromised modem/router.

Lack of password verification

TPG requires your VDSL modem to be configured to use PAP authentication. However, the password is not verified. They assume that by being physically patched to the DSLAM port, you are authorised to use the service. This isn’t a safe assumption. In most apartment buildings, tradesmen and/or residents can easily access the main distribution frame (MDF) and change the patches. For services with the DSLAM located in a roadside cabinet or telephone exchange, there are further points along the path where a technician could unintentionally or maliciously patch the DSLAM port assigned to you to another line.

This appears to be to make support simpler. If the password is not verified, a dummy password can be used in settings pre-configured or pushed out to the customer’s modem/router via TR-069, and support staff can walk a customer through the process of setting up a modem/router without either of them having to know the password. However, it’s another security hole, and given the metadata retention laws and the aggressive behaviour of copyright holders, it’s unwise to make it in any way simpler for someone to impersonate the customer.

Lax e-mail security

TPG’s mail servers support explicit and opportunistic SSL/TLS encryption. However, as of the time of writing, TPG’s relevant support pages don’t make any mention of enabling encryption, and the step-by-step guides for Apple Mail and Android phones show settings that will result in usernames, passwords, and mail contents being transmitted in plain text.

This shows blatant disregard for customers’ security. A customer following TPG’s instructions for configuring Apple Mail or an Android phone will expose their account name and password to anyone with the ability to sniff packets between them and TPG’s mail servers. On a public WiFi network, this includes anyone in the vicinity who can use packet capture software.

No IPv6 support

TPG does not officially support IPv6 and has no timeline for IPv6 rollout. There are rumours that they’re testing IPv6 with selected customers, but there’s no way to voluntarily join the test group. IPv6 is not a new technology. RFC 2460 was published in late 1998, almost twenty years ago. Microsoft began requiring applications to work in a pure IPv6 environment (no IPv4) for logo certification beginning with Windows Vista in 2006, over ten years ago. All major operating systems and most network equipment provides IPv6 support.

TPG is really behind here. Internode (now owned by TPG) has provided dual stack IPv4/IPv6 since 2008 (ten years ago), assigning a static /56 subnet and a dynamic /64 subnet to each connection. Even Telstra, not known for being on the cutting edge, has rolled out IPv6 for NBN and ADSL customers. With iiNet, you at least have the option of using a 6rd service to provide IPv6 connectivity, although it suffers from some limitations compared to a true dual stack deployment.

Phone support

The quality of service provided by the phone support staff varies enormously. You often need to work your way through multiple people before you reach someone who seems to actually care or be interested in helping. Even then, the staff are hobbled by processes and policies, and may not be able to really do much. I’ve experienced this multiple times with the support and engineering teams. One time, the guy said something to the effect of, “Well, I understand what you’re saying, but I don’t set the policy. The call’s recorded, I’ll mark this as a complaint, hopefully someone in Sydney will actually hear it.”

There are definitely some people at TPG who seem to want to do the right thing by the customers. Ace and Joy from support, in the unlikely event that you’re reading this, I’d like you to know I think you’re great. You’ve both got back to me when you said you would, tried to understand the issues I raised, and tried to get things resolved as well as you can. It’s not your fault TPG’s policies are hostile to the customer, or some of the other people on the support team don’t seem to care.

Closing thoughts

I’ve had TPG Internet accounts for over twenty years now. Back in the dial-up days, TPG was the ISP to beat. They provided national service at competitive rates, and it just worked with no fuss. Now everything’s a nightmare. It seems TPG wants to sell to people who just use their Internet connection for Facebook and YouTube. There’s definitely a market for that, but the trouble is they’ve absorbed the ISPs who catered for people who wanted a little more, and soon there may not be any other options left. It’s sad to see the Australian ISP landscape go this way.

https://rants.vastheman.com/2018/01/20/tpg/feed/ 0
Going Old-School https://rants.vastheman.com/2017/07/08/oldschool/ https://rants.vastheman.com/2017/07/08/oldschool/#comments Fri, 07 Jul 2017 18:27:31 +0000 https://rants.vastheman.com/?p=290 For lulz, I decided to rewrite MAME’s Intel 4004 CPU core and add support for most 4040 features. The new CPU core operates at the bus cycle level, and exposes most useful signals. It also uses lots of address spaces for all the different kinds of memory and I/O it supports (thanks OG). Some CPU core bugs were fixed along the way – notably intra-page jumps on page boundaries were broken.

One nice benefit we get from this is being able to hook up the I/O for the Bally/Nutting solid-state Flicker pinball prototype (supposedly the first microprocessor-controlled pinball machine) how the hardware actually worked. I also hooked up the playfield lamp matrix as outputs and the operator adjustments as machine configuration while I was at it. We need a proper thermal model of a lamp with PWM dimming support before that part can be declared perfect. (It previously used a hack, pulling the low bits of RC out of the CPU using the state interface. This worked due to a quirk of the game program, and there was no way to implement it properly without the 4004 CM-RAM signals being exposed.)

Possibly more interestingly, we can now emulate the Intel INTELLEC® 4/MOD 40 development system. There seem to be very few surviving examples of this system, but fortunately we’ve got monitor PROM dumps, and there’s some information floating around the web. It has interesting debugging features on the front panel. There’s a scanned manual, but the schematics are very poor quality. However, with some idea of how it works, it’s possible to work out what all the chips are supposed to be. That’s the fun part. Turning it into MAME code isn’t as much fun, but it’s doable.

The front panel looks like this:

That requires clickable artwork for the switches and outputs for the LEDs to get a usable experience (writing the MAME XML layout really isn’t fun). There’s a simple monitor in PROM, designed to be used with an ASCII teleprinter with paper tape reader and punch (e.g. a Teletype Model 33 ASR). MAME’s RS-232 video terminal will have to do as a substitute for that.

If you get bleeding edge MAME (i.e. built from source no more than a day or so old), you can try it out in emulation. Did you ever wonder how developers may have debugged 4004 code in the mid to late ’70s? Well even if you didn’t, now you can find out.

The front panel looks like this in emulation (without the explanatory labels), and by default MAME shows the video terminal below this:

All those LEDs are functional, and all those switches are clickable and visually reflect their current state.

So how would you actually use it in practice? That’s where this brief instruction manual on the MAMEdev wiki comes in. It’s complete with examples of how some of the monitor commands and front panel debugging features can be used. It’s marked NOT_WORKING in MAME for now because you need to manually set up the terminal the first time you use it, and I haven’t finished implementing the universal slots and storage cards. But you can do all the things described on that page.

Does anyone care? Probably not. Will anyone actually even try this system out in MAME? Probably not (apart from Robbbbbbbert). But this is another example of something that you can only do in MAME, and how completely unrelated systems can both benefit from emulating the same chip properly. It also gets rid of one previously unavoidable hack, and gets us one step closer to feature parity with EmuAllSystems.

https://rants.vastheman.com/2017/07/08/oldschool/feed/ 1
Attacking the Weak https://rants.vastheman.com/2017/02/13/attacking/ https://rants.vastheman.com/2017/02/13/attacking/#comments Sun, 12 Feb 2017 23:37:19 +0000 https://rants.vastheman.com/?p=285 ShouTime dumped the incredibly rare game Omega (Nihon System). It’s a ball-and-paddle game running on similar hardware to Sega’s Gigas. These games use an NEC MC-8123 CPU module containing a Z80 core, decryption circuitry, and an 8 KiB encryption key in battery-backed RAM. When fetching a byte from ROM or RAM, the CPU chooses a byte from the encryption key based on twelve of the address bits and whether it’s an M1 (opcode fetch) cycle or not. This byte from the encryption key controls what permutation (if any) is applied to the byte the CPU fetches. This encryption scheme could have been brutal, requiring extensive analysis of a working CPU module to crack, if it weren’t for a fatal flaw: Sega used a simple linear congruential generator algorithm to create 8 KiB keys from 24-bit seeds. That means there are less than seventeen million encryption keys to test. Seventeen million might sound like a lot, but it’s far less than the total possible number of keys, and definitely small enough to apply a known plaintext attack in a reasonable amount of time.

So how do we go about attacking it? First we have to make an assumption about what the game program is going to be doing. Given that the hardware looks pretty similar to Gigas and Free Kick, I guessed that one of the first things the program would do is write a zero somewhere to disable the non-maskable interrupt generator disable maskable interrupts. So I wrote a program to find candidate seeds (no, I won’t show you the source code for this program – it’s embarrassingly ugly and hacky, not something I could ever be proud of):

  • Start with first possible 24-bit seed value
  • Generate 8 KiB key using algorithm known to be used by Sega
  • Decrypt first few bytes of program ROM using this key
  • If it looks like Z80 code to store zero somewhere and disable interrupts, log the seed
  • Repeat for next possible seed value until we run out of values to try

This ran in just a few minutes on an i7 notebook, and narrowed down the millions of possible seed values to just five candidates: 36DF3D, 6F45E0, 7909D0, 861226, and BE78C9 (in hexadecimal notation). Now I could have tried these in order, but it looked like Sega had made another misstep: besides using a predictable algorithm to generate the key, they also used a predictable seed value to feed this algorithm. The candidate seeds value 861226 looks like a date in year-month-day format. It turns out this seed generates the correct key to decrypt the game program, so I guess we know what someone at Sega was doing the day after Christmas in 1986.

Brian Troha hooked up the peripheral emulation, and the game will be playable in MAME 0.183 (due for release on 22 February). Colours aren’t quite right as we don’t have dumps of the palette PROMs yet, but we expect to resolve this in a future release. Thanks to ShouTime and everyone else involved in preserving this very rare piece of arcade history.

https://rants.vastheman.com/2017/02/13/attacking/feed/ 3
My PAL with the LASERs https://rants.vastheman.com/2015/12/15/lasers/ https://rants.vastheman.com/2015/12/15/lasers/#respond Tue, 15 Dec 2015 12:54:05 +0000 https://rants.vastheman.com/?p=250 Back in the distant past, MAME started cataloguing programmable logic devices (PLDs) in addition to ROMs. This was met with considerable hostility from certain segments of the community, as it was seen as forcing them to obtain files they saw as unnecessary for emulation in order to run their precious games. However PLDs are programmable devices, and it’s important to preserve them. So far though, the PLD dumps have mainly been used by PCB owners looking to repair their games. The haven’t been used by MAME for emulation. However, PLDs are key to the operation of many arcade games, performing functions like address decoding and video mixing.

One such arcade board is Zaccaria’s Laser Battle, also released under license by Midway as Lazarian. This board uses complex video circuitry that was poorly understood. It includes:

  • TTL logic for generating two symmetrical area effects, or one area effect and one point effect
  • TTL logic for for generating an 8-colour background tilemap
  • Three Signetics S2636 Programmable Video Interfaces (PVIs), drawing four 4×4 monochrome sprites each
  • TTL logic for generating a single 32×32 4-colour sprite
  • A Signetics 82S101 16×48×8 Programmable Logic Array (PLA) for mixing the video layers and mapping colours

On top of this, they decided it was a good idea to use some clever logic to divide the master clock by four when feeding the Signetics S2621 Universal Sync Generator (USG) that generates video timings, but to divide it by three to generate the pixel clock feeding the rest of the video hardware. This lets them get one third more horizontal resolution than the Signetics chips are designed to work with. They need additional logic to line up the pixel clock with the end of horizontal blanking, because the number of pixels in a line isn’t divisible by three, and some more logic for delaying the start of the visible portion of each frame and cutting it off early because they wanted less vertical resolution than the Signetics chips are designed for. It uses an GRBGRBGR colour scheme where the most significant bits are are in the middle of the byte and the missing least significant blue bit effectively always, so it can’t produce black, only a dark blue Was this design effort worth it? I guess they must’ve made some money off the Midway license at least.

Anyway, this game has never worked properly in MAME. It’s always been missing the area and point effects, the colours have always been completely wrong, and the mixing between layers hasn’t properly either. And that’s done inside the PLA. The PLA has 48 internal logic variables, each of which can be programmed to recognise an arbitrary combination of levels on the 16 input line. Each of the internal variables can drive any combination of the eight output lines. The outputs can be configured to be inverting or non-inverting.

In theory this sounds like a job for a ROM, so why use a PLA instead? Well a ROM with 16 input bits and eight output bits would need 64kB of space. Such a ROM would likely have been prohibitively expensive when this game was produced. I mean, its program ROMs are only 2kB each, so there’s no way they’d be sourcing a ROM 32 times that size just for video mixing. The PLA maps the same number of inputs to the same number of outputs with just 1,928 bit of storage, or a little less than one of the program ROMs. It can’t produce absolutely any arbitrary input to output mapping, but it’s more than enough for this application. In fact, it turns out they didn’t even need to use all the space in the PLA.

Read the rest of the post if you want to know more about the process of decoding the PLA bitstream and examining its contents.

The hookup

By examining the schematics, we can see that the PLA’s inputs are hooked up like this:

Bit Name Description
0 NAV0 Sprite bit 0
1 NAV1 Sprite bit 1
2 CLR0 Sprite colour bit 0
3 CLR1 Sprite colour bit 0
4 LUM Sprite luminance (brightness)
5 C1* Combined PVI colour bit 1 (red) gated with blanking (active low)
6 C2* Combined PVI colour bit 2 (green) gated with blanking (active low)
7 C3* Combined PVI colour bit 3 (blue) gated with blanking (active low)
8 BKR Background tilemap red
9 BKG Background tilemap green
10 BKB Background tilemap blue
11 SHELL Shell point
12 EFF1 Effect 1 area
13 EFF2 Effect 2 area
14 COLEFF0 Area effect colour bit 0
15 COLEFF1 Area effect colour bit 1

CLR0, CLR1, LUM, COLEFF1 and COLEFF2 are relatively static bits that the game program sets by writing to I/O ports. The rest of the bits are generated dynamically based on video register and RAM contents.

Streams of bits

The PLA bitstream consists of 48 sets of 40 bits for each of the internal logic variables, followed by a final eight bits specifying which of the outputs should be active low. Each internal variable has two bits controlling how it’s affected by each of the 16 inputs (32 bits total), followed by eight bits specifying which outputs it shouldn’t activate (32+8 makes for a total of 40). If a pair of input bits are both zero (00), it’s impossible for that logic variable to be activated. This is an easy way to spot unused variables, and it’s the default state in an unprogrammed chip. If only the first bit in a pair is set (10), the corresponding input line must be high in order for the variable to be activated. If only the second of the bits is set (01), the corresponding input line must be low in order for the variable to be activated. If both bits in a pair are set (11), the input may be activated irrespective of the state of the corresponding input line (often called a “don’t care” condition).

Finally, MAME expects the bitstream in a file containing a 32-bit integer specifying the total number bits, followed by the bits themselves, packed into bytes least-significant bit first. Armed with this knowledge, we can write a some code that transforms converts the bitstream to an intermediate representation and displays it as C code:

UINT8 const *bitstream = memregion("plds")->base() + 4;
UINT32 products[48];
UINT8 sums[48];
for (unsigned term = 0; 48 > term; term++)
    products[term] = 0;
    for (unsigned byte = 0; 4 > byte; byte++)
        UINT8 bits = *bitstream++;
        for (unsigned bit = 0; 4 > bit; bit++, bits >>= 2)
            products[term] >>= 1;
            if (bits & 0x01) products[term] |= 0x80000000;
            if (bits & 0x02) products[term] |= 0x00008000;
    sums[term] = ~*bitstream++;
    if (PLA_DEBUG)
        UINT32 const sensitive = ((products[term] >> 16) ^ products[term]) & 0x0000ffff;
        UINT32 const required = ~products[term] & sensitive & 0x0000ffff;
        UINT32 const inactive = ~((products[term] >> 16) | products[term]) & 0x0000ffff;
        printf("if (!0x%04x && ((x & 0x%04x) == 0x%04x)) y |= %02x; /* %u */\n", inactive, sensitive, required, sums[term]);
UINT8 const mask = *bitstream;
if (PLA_DEBUG) printf("y ^= %02x;\n", mask);


When we feed this the PLA bitstream dumped from a Lazarian board, we get the following output (blank lines added for readability:

if (!0x0000 && ((x & 0x001f) == 0x0001)) y |= 01; /* 0 */
if (!0x0000 && ((x & 0x001f) == 0x0002)) y |= 03; /* 1 */
if (!0x0000 && ((x & 0x001f) == 0x0003)) y |= 04; /* 2 */
if (!0x0000 && ((x & 0x001f) == 0x0011)) y |= 08; /* 3 */
if (!0x0000 && ((x & 0x001f) == 0x0012)) y |= 18; /* 4 */
if (!0x0000 && ((x & 0x001f) == 0x0013)) y |= 20; /* 5 */
if (!0x0000 && ((x & 0x001f) == 0x0005)) y |= 07; /* 6 */
if (!0x0000 && ((x & 0x001f) == 0x0006)) y |= 03; /* 7 */
if (!0x0000 && ((x & 0x001f) == 0x0007)) y |= 04; /* 8 */
if (!0x0000 && ((x & 0x001f) == 0x0015)) y |= 38; /* 9 */
if (!0x0000 && ((x & 0x001f) == 0x0016)) y |= 18; /* 10 */
if (!0x0000 && ((x & 0x001f) == 0x0017)) y |= 20; /* 11 */
if (!0x0000 && ((x & 0x001f) == 0x0009)) y |= 05; /* 12 */
if (!0x0000 && ((x & 0x001f) == 0x000a)) y |= 04; /* 13 */
if (!0x0000 && ((x & 0x001f) == 0x000b)) y |= 06; /* 14 */
if (!0x0000 && ((x & 0x001f) == 0x0019)) y |= 28; /* 15 */
if (!0x0000 && ((x & 0x001f) == 0x001a)) y |= 20; /* 16 */
if (!0x0000 && ((x & 0x001f) == 0x001b)) y |= 30; /* 17 */
if (!0x0000 && ((x & 0x001f) == 0x000d)) y |= 07; /* 18 */
if (!0x0000 && ((x & 0x001f) == 0x000e)) y |= 04; /* 19 */
if (!0x0000 && ((x & 0x001f) == 0x000f)) y |= 04; /* 20 */
if (!0x0000 && ((x & 0x001f) == 0x001d)) y |= 38; /* 21 */
if (!0x0000 && ((x & 0x001f) == 0x001e)) y |= 20; /* 22 */
if (!0x0000 && ((x & 0x001f) == 0x001f)) y |= 20; /* 23 */

if (!0x0000 && ((x & 0x0023) == 0x0000)) y |= 01; /* 24 */
if (!0x0000 && ((x & 0x0043) == 0x0000)) y |= 02; /* 25 */
if (!0x0000 && ((x & 0x0083) == 0x0000)) y |= 04; /* 26 */
if (!0x0000 && ((x & 0x29e3) == 0x01e0)) y |= 01; /* 27 */
if (!0x0000 && ((x & 0x2ae3) == 0x02e0)) y |= 02; /* 28 */
if (!0x0000 && ((x & 0x2ce3) == 0x04e0)) y |= 04; /* 29 */

if (!0x0000 && ((x & 0x08e3) == 0x08e0)) y |= 38; /* 30 */
if (!0x0000 && ((x & 0xffe3) == 0x10e0)) y |= 84; /* 31 */
if (!0x0000 && ((x & 0xffe3) == 0x50e0)) y |= 84; /* 32 */

if (!0x0000 && ((x & 0x0000) == 0x0000)) y |= 00; /* 33 */

if (!0x0000 && ((x & 0xffe3) == 0xd0e0)) y |= 04; /* 34 */
if (!0x0000 && ((x & 0xe0e3) == 0x20e0)) y |= 80; /* 35 */
if (!0x0000 && ((x & 0xe0e3) == 0x60e0)) y |= 40; /* 36 */
if (!0x0000 && ((x & 0xe0e3) == 0xa0e0)) y |= c0; /* 37 */
if (!0x0000 && ((x & 0xe0e3) == 0xe0e0)) y |= c0; /* 38 */
if (!0x0000 && ((x & 0xffe3) == 0x90e0)) y |= 40; /* 39 */

if (!0xffff && ((x & 0x0000) == 0x0000)) y |= ff; /* 40 */
if (!0xffff && ((x & 0x0000) == 0x0000)) y |= ff; /* 41 */
if (!0xffff && ((x & 0x0000) == 0x0000)) y |= ff; /* 42 */
if (!0xffff && ((x & 0x0000) == 0x0000)) y |= ff; /* 43 */
if (!0xffff && ((x & 0x0000) == 0x0000)) y |= ff; /* 44 */
if (!0xffff && ((x & 0x0000) == 0x0000)) y |= ff; /* 45 */
if (!0xffff && ((x & 0x0000) == 0x0000)) y |= ff; /* 46 */
if (!0xffff && ((x & 0x0000) == 0x0000)) y |= ff; /* 47 */

y ^= 00;

Fortunately this PLA seems to have been programmed manually and not using an automatic logic minimiser. Can you spot the patterns yet? The last eight terms (40–47) have been left in their virgin, unprogrammed states and hence can’t affect the output. Term 33 has been programmed to have no effect on the output, so they’ve used 81.25% of the chip. They could’ve gotten clever and added more logic if they really wanted to, but I guess with everything else they did on the board they were out of tricks by this point. But anyway, on to the equations.

Sprite mapping

The first 24 terms (0–23) only depend on the sprite-related bits, so it’s a good bet they control sprite colours. Let’s make a table of the mappings these terms produce. For convenience we’ll treat NAV0/NAV1 and CLR0/CLR1 as two-bit numbers:

NAV 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
CLR 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3
LUM 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1
01 03 04 08 18 20 07 03 04 38 18 20 05 04 06 28 20 30 07 04 04 38 20 20

Now the pattern should be really clear. Sprite pixel value 0 produce no output (making it dark or transparent), while the other three values are each mapped to colour depending on the value of CLR. Setting LUM shifts the colour left by 3 bits into the most significant bits of the colour output. This can be summarised in a table with NAV in rows and CLR in columns:

0 1 2 3
0 00/00 00/00 00/00 00/00
1 01/08 07/38 05/28 07/38
2 03/18 03/18 04/20 04/20
3 04/20 04/20 06/30 04/20

Or we could even use human-readable colour names since we know the output format is GRBGRBGR (there’s a distinct lack of green in this palette):

0 1 2 3
0 dark dark dark dark
1 red white magenta white
2 yellow yellow blue blue
3 blue blue cyan blue

So they used half the PLA to handle sprite colour mapping.

Backgrounds and PVIs

The next set of six terms look straightforward enough, let’s make a table and see what they produce (once again we’re treating NAV0/NAV1 as a two-bit number):

NAV 0 0 0 0 0 0
C1* 0 1 1 1
C2* 0 1 1 1
C3* 0 1 1 1
SHELL 0 0 0
EFF2 0 0 0
01 02 04 01 02 04

This shows that the PVIs’ outputs are mapped directly onto the low red, green and blue bits of the output (not actually the LSBs, they’re at the top of the output byte). The TTL-generated sprite has priority over both the PVI outputs and the background tilemap; additionally, the PVIs, the shot point, and area effect 2 also have priority over the background tilemap (since the OBJ/SCR lines from the PVIs are not considered, the PVIs don’t take priority with black object pixels, only with coloured pixels).


The rest of the terms relate to effects. We can look at them all at once (NAV and COLEFF are two-bit numbers):

NAV 0 0 0 0 0 0 0 0 0
C1* 1 1 1 1 1 1 1 1 1
C2* 1 1 1 1 1 1 1 1 1
C3* 1 1 1 1 1 1 1 1 1
BKR 0 0 0 0
BKG 0 0 0 0
BKB 0 0 0 0
SHELL 1 0 0 0 0
EFF1 1 1 1 1
EFF2 0 0 0 1 1 1 1 0
COLEFF 0 1 3 0 1 2 3 2
38 84 84 04 80 40 c0 c0 40

So what does this tell us? Lots of things! You might notice that the second and third columns can easily be reduced to a single term, and so could the seventh and eighth columns, clearly an oversight but not important since there’s space to spare in the PLA. More seriously, we can work out priorities from the rows:

  • Sprite and PVI output always have priority over these effects
  • Background, shell and effect 2 have priority over effect 1
  • Remember that shell and effect 2 are mutually exclusive, so there’s no priority between them

Now we can look at the output each effect actually produces:

  • The first column says the shell sets the MSBs of all three colours, making it light grey or “dark white”.
  • Effect 1 sets the background colour (depending on COLEFF) to medium blue (3), dark magenta (2), or just on the cyan side of medium blue (1 or 0).
  • Effect 2 sets the background colour (depending on COLEFF) to dark cyan (0), dark magenta (1), or dark grey (2 or 3).


So how do we get this information into MAME? Well we could take what we’ve learned and write C++ code to draw the graphics in the appropriate sequence, but that would have several disadvantages. Firstly it’s not how the real machine works — the real machine works by composoing a 16-bit value and feeding it through the PLA to get the output colour. Secondly, implementing it in C++ wouldn’t allow someone to try a different PLA dump to see what effects is has on gameplay. Thirdly, someone couldn’t develop their own PLA program to drop into MAME to play with for homebrew purposes. Instead, we use some more code to turn our intermediate representation of the PLA terms into a 64kB mapping table:

for (UINT32 inp = 0x0000; 0xffff >= inp; inp++)
    m_mixing_table[inp] = 0;
    for (unsigned term = 0; 48 > term; term++)
        if (!~(inp | (~inp << 16) | products[term]))
            m_mixing_table[inp] |= sums[term];
    m_mixing_table[inp] ^= mask;

Then we render scanlines into a 16-bit bitmap and pass it through this table to convert it to colours for MAME’s video output. (Yes, it’s possible to run the PLA equations on the bitmap data directly from the compact intermediate representation. However it’s slower as it involves several logical operations, and 64kB is a small amount of memory these days for a cached lookup table. However, CPUs are getting pretty fast, and cache miss latency keeps getting worse, so perhaps sticking with the intermediate form wouldn’t be such a bad idea.)

https://rants.vastheman.com/2015/12/15/lasers/feed/ 0
Yet another reason to hate Google’s tentacles https://rants.vastheman.com/2015/09/05/tentacles/ https://rants.vastheman.com/2015/09/05/tentacles/#comments Fri, 04 Sep 2015 15:59:45 +0000 https://rants.vastheman.com/?p=248 It’s not secret I don’t like the way the web is succumbing to JavaScript bloat and sucking in scripts from third-party sites. But I now have another reason to hate it. A few sites are blocked from China, including most Google properties such as Google search, Google APIs and YouTube (and also Tagged, incidentally). If a site that isn’t blocked from China tries to load scripts from Google APIs, for example the minified jQuery script, I have to wait for the blocked request to time out before the page will display at all, and functionality may be broken if the page actually depends on jQuery for content display or navigation. Is it really that hard to host your own scripts? Do you really need to give Google even more data on our browsing habits? One good thing about China’s policies it they make it harder for fucking Google to track us over here.

https://rants.vastheman.com/2015/09/05/tentacles/feed/ 1
Make a real argument https://rants.vastheman.com/2014/09/22/argument/ https://rants.vastheman.com/2014/09/22/argument/#comments Mon, 22 Sep 2014 01:28:02 +0000 http://rants.vastheman.com/?p=246 The newspapers just love publishing stories about prostitution, because they know it sells. Amanda Goff aka Samantha X has been giving them plenty of fuel. Of course these stories all have comments left open, and it’s only a matter of time before a certain argument comes up in one form or another. Here’s an example of it, as found in a comment on a Fairfax newspaper site:

My argument against prostitution isn’t based on religion, conservative values or prudishness, but is more to do with the fact that, in essence, prostitutes are being bribed to have sex with someone they don’t actually want to have sex with. One wants sex and the other doesn’t. Some may protest that they do want the sex, but what if no money was involved? That’s right. The sex wouldn’t happen.

This “argument” is absolutely absurd. Do the people making it really not see the glaring flaw? How about we do a simple substitution:

My argument against garbage collection isn’t based on religion, conservative values or prudishness, but is more to do with the fact that, in essence, garbage collectors are being bribed to collect garbage they don’t actually want to collect. One wants garbage collected and the other doesn’t. Some may protest that they do want to collect garbage, but what if no money was involved? That’s right. The garbage wouldn’t be collected.

You can apply it to most occupations. If no money was involved, the roads wouldn’t be maintained, the supermarket shelves wouldn’t be stacked, the garbage wouldn’t be collected, nothing would be manufactured, and society as we know it wouldn’t exist. I’m not trying to make a case for or against prostitution, I’m just completely sick of seeing this absolutely stupid argument smugly parroted over and over again.

https://rants.vastheman.com/2014/09/22/argument/feed/ 1
Faking it https://rants.vastheman.com/2014/01/11/faking/ https://rants.vastheman.com/2014/01/11/faking/#respond Sat, 11 Jan 2014 11:57:53 +0000 http://rants.vastheman.com/?p=239 Melbourne on new year’s day is a weird place. All sorts of shops, restaurants and bars are were closed. The entire Royal Arcade was closed for some reason. It’s like Melbourne still wants to believe it’s a quiet country town. Despite the crappy weather, there was plenty of foot traffic in the CBD, so a lot of the places that had the sense to stay open seemed to be doing pretty well. Fortunately the prices are high enough at Passionflower that it wasn’t overcrowded, and we could easily get a table to enjoy some very overpriced, sugar-laden dessert. The Melbourne one (Bourke St) has friendlier staff, better service and gets the nicer presentation of the food than the one at Capitol Square in Sydney — the staff there act like customers are an unwanted nuisance.

Anyway, with my parents in town, my wife and I decided to take advantage of the possibility of free babysitting and go out for dinner. There were limited options, but most of the restaurants in the Crown complex at Southbank were open, so we ended up at Nobu. It’s immediately obvious that the floor staff don’t really speak Japanese. It makes no sense to (poorly) attempt to say “irasshaimase” as you show someone to their table; you should have said that as they approached the door, or the moment they walked in. (Something like “kochira e” works when showing a person to their table.) All the staff were doing this with everyone, which kept my wife giggling. I guess they could claim to provide free entertainment. You might get even more entertainment if you get a seat in the upper bar/lounge area with a view of the riverbank. For example we saw some really weird cougar thing going on. There was this woman of east Asian appearance with a far younger guy who looked like he was part European, part Asian. She had the bag, camera and everything, and was acting like she knew she was in charge. The also seemed to have a bit of trouble walking straight. All in all, they gave off a pretty weird vibe. I really hope it was a cougar thing, because if he was a family member, they were acting downright creepy.

Anyway, the main attraction of Nobu is supposed to be food and drink. Nobu exclusively serves Hokusetsu sake, and it was pretty clear that the waiters don’t know much about sake besides the scripted lines they’ve been given to describe each choice. We got a carafe of the Onigoroshi served cold. It was fairly dry, with a bit of a harsh, unrefined flavour. You could clearly taste the rice that went into it. Probably not for everyone, but we enjoyed it. We then proceeded to order some cocktails and eat our way through the interesting-looking parts of the tapas menu. The Godzilla is a great, refreshing cocktail that you could probably keep ordering all night. The champagne mojito lacked balance: the rum hit you, but didn’t really meld well with the lime and mint, and it was like the Veuve Clicquot didn’t know what it was doing in the mix.

The disappointment of the night was definitely the jalapeño fritters with dry miso. Seriously, don’t bother with this: the batter was oily, and there wasn’t anything interesting about it. On the other hand the baked scallops with creamy wasabi shiso were absolutely superb! The bold flavours and perfect texture left both of us wanting more. The biggest surprise came with the salmon anti-cucho and teriyaki skewers. We expected teriyaki flavour, but the sauce was almost an Indian curry. It wasn’t bad, just very surprising. The black cod with miso was definitely good, as was the wagyu tartar crispy rice butter lettuce (well apart from the live aphid on the flower garnish). The Blackmore wagyu intercostal was a bit of a let-down. It didn’t taste bad, but the texture wasn’t great. I don’t think the chef got this right.

The total damage was a bit over $200, which is pretty reasonable for this kind of restaurant. Not everything on the menu is excellent, and the staff are clearly faking it, but it still makes for a good night out. Interestingly, we noticed that despite even bars like E55 being closed KT Mart (a Korean supermarket/homewares/alcohol shop) was still open as we passed it on the tram home. I guess Koreans realise the importance of being able to get stuff like bokbunja or maehwasu on any day of the year (if only I could get it as easily in Bondi Junction).

https://rants.vastheman.com/2014/01/11/faking/feed/ 0