Hacker Question

Hello hackers,
as some of you might know, I am supervising the work on converting games from TR-Dos or TAP to the +D or Opus disk format for our SCENE+ disk magazine. However, for the new issue I came across 6 programs that have a strange new loader. Maybe somebody can explain here.

First game I got here is RESCUE LANDER ( http://www.worldofspectrum.org/forums/discussion/50247/ )
The Basic loader looks very simple:

5 BORDER 1
6 PAPER 1
7 INK 7
8 CLS
10 CLEAR .: LOAD "" SCREEN$: POKE .,. : LOAD ""CODE: RANDOMIZE USR .

What annoys me are the dots (.) . There should be numbers, but somehow the numbers are invisible and therefore a dot is set. So now I cannot change the Basic Loader and insert disk commands, as the Basic Interpreter will not accept the command.

First question of course is WHY? And second question is how it is done (and how to convert it back).

Who can help?

Regards

Thomas
Post edited by rich_chandler on

Comments

  • http://www.worldofspectrum.org/ZXBasicManual/zxmanchap24.html - numbers in basic are stored as readable form followed by five bytes (not shown) for the actual value. By only including one dot with an actual value, a few bytes are saved per number.
  • It's similar to 'RANDOMIZE USR 0'. The numbers you see in a listing of a Basic program can be anything, because the real values come from hidden 5-byte representations that follow each such numeric value in memory. In this case, they must have additionally changed the 0's to .'s - I guess this kinda thing is a non-issue for Basic lol

    'Solving' these isn't hard, open a debugger at around #5D00 and EXAMINE DOTS. You will see a value of #0E after each one, followed by the hidden 5-byte representation. This is mostly zeros but in the middle of it there's a 2-byte 'real value' ('FirstByte + 256 * SecondByte'). Here, we have

    CLEAR 30311
    POKE 23739,111
    RANDOMIZE USR 48010

    P.S. The same kind of 'WHY' can be found in 'why bother with a computer from 30+ years ago overall', I think
  • The line should be:
    10 CLEAR 30311: LOAD "" SCREEN$: POKE 23739,111: LOAD "" CODE: RANDOMIZE USR 48010

    I quite like the idea of adding this as well. :)
    POKE 42785,75:POKE 42786,69:POKE 42787,77:POKE 42788,80:POKE 42789,83:POKE 42790,84

    Sinclair BASIC holds numbers twice in two different formats: text and the number itself. If you look through the bytes, you see:
    23806 253 046 014 000 000 103 118 000 058

    253 = CLEAR
    046 = dot
    014 = number
    ...then five bytes, of which 103,118 is interesting, because that is 30311...
    058 = colon

    It is not unusual to find hidden numbers in BASIC loaders, as a form of protection. Usually it would be a false address that caused a crash, but one of the Magic Knight games actually included a false address that jumped to a "hello hacker!" screen.

    I have never seen it with dots instead of a false number though. There is no point in protecting such a new game, maybe it is a way of saving bytes in the BASIC loader?

    There are various special listing programs, but this is the only one I could find quickly on WoS:
    http://www.worldofspectrum.org/infoseekid.cgi?id=0007948
  • In Mackarel I use that trick to save a few bytes from the loader;
    Spoiler:
    The putdataintlit_min function generates bytes for minimal integer literal;
    Spoiler:
    I suppose the '0' could be replaced by any basic-printable character, but I didn't try it. If it accepts a symbol, that might result in some fun listings =)
    http://iki.fi/sol | http://iki.fi/sol/speccy/ | https://github.com/jarikomppa/speccy
    http://goo.gl/q2j0NZ - make ZX Spectrum choose your own adventure games, no programming needed (release 3)
  • I've seen some BASIC lister utilities that shows both the fake (dot) number and the real (stored) number, so you can see what's hidden.

    I'm spaniard, so I use the "Listador BASIC para +3" published in Microhobby 192, but I have another english counterpart (but I don't remember the name).
    I was there, too
    An' you know what they said?
    Well, some of it was true!
  • Thanks for the answers. HIKARU, your answer was a very good explanation because I didn´t want just a solution for only this game, but generally. I understand now how it works, but can you tell me what the value #0E (Decimal 14) is for? I mean, a dot have the value 46 , or not?
  • Speccyman wrote: »
    Thanks for the answers. HIKARU, your answer was a very good explanation because I didn´t want just a solution for only this game, but generally. I understand now how it works, but can you tell me what the value #0E (Decimal 14) is for? I mean, a dot have the value 46 , or not?

    I've mentioned 'the dots' because that is what they've swapped the actual numbers with in this particular loader. In other loaders these might be 0's, or even entirely fake numbers (let's say a RANDOMIZE USR 31336 that actually calls the address 25000). Generally, when you use a debugger you should look around these numbers/symbols that come after RANDOMIZE USR, CLEAR and so on.
    #0E / 14 I think is the marker byte used by BASIC in this context to indicate a 5-byte format value following. It's not actually part of the value itself

    I think Jmk above explained it better than me, and he also posted a pretty useful routine that lists the BASIC program with all the real values it uses automatically, you should check it out. I'm not sure if it has any limitations etc but it seems to work with this loader :)
  • Yes, Jmk´s answer is also brilliant, just yours was first. However, he started to write a list of values for Basic commands.
    253 = CLEAR
    What is RANDOMIZE USR? POKE? I can of course use the software tht Jmk suggestest, but I want find out how it works, not just rewrite it.

    I´ve already tried some other programms as now it seems very common to use this protecton. But I didn´t suceed. One demo (Down) had more pokes and RAND USR commands than a simple loader, because it uses RAM switching. So it get´s a bit harder, but that´s the point about when hacking, isn´t it?
  • USR xxxx is a function which makes the Z80 run the Machine Code at address xxxx. When a RET is encountered then control is returned to BASIC.
    Because USR is a function (and not a command) you need to add some command to fullfill the rules of Sinclair BASIC syntax. The most harmless command is RANDOMIZE, that is why it became a kind of standard.
  • Speccyman wrote: »
    Yes, Jmk´s answer is also brilliant, just yours was first. However, he started to write a list of values for Basic commands.
    253 = CLEAR
    What is RANDOMIZE USR? POKE? I can of course use the software tht Jmk suggestest, but I want find out how it works, not just rewrite it.

    There are several BASIC/code tables online like this one, you can look up the codes for each command there. But you don't actually have to remember all the codes in order to do it (E.g. I don't :) ).

    28sn18z.png

    As an example, this is the loader of Manic Miner. If your debugger has a memory view window like this (see the big blue window at the lower right), you can easily identify where the numbers are located, visually. Then just eventually compare that with the LISTing you get in the BASIC and you will see the way they correspond and what the actual commands are.

    There are other cues that you can use, such as let's say you can typically identify the LOAD commands by sequences of "" in the memory, and #0D's indicating ends of BASIC lines, but that's more or less it
Sign In or Register to comment.