Skip to content

Hacking

Tavis Ormandy edited this page Mar 26, 2023 · 7 revisions

Tips for developers who want to hack on 123, fixing bugs or making improvements.

Rewriting Routines

You've found that a function doesn't work and want to rewrite it.

  • Add the symbol name to undefine.lst
  • Use a disassembler to make sure you understand the prototype.
  • Write your own implementation, that's it!

Are you trying to change an @FUNCTION? I usually add these to atfuncs.a, to keep them all together. There are some existing examples you can see.

Hooking/Wrapping Routines

You want to add your own code to examine or change parameters.

  • Rename the symbol in redefine.lst, call it something like __unix_originalname.
  • Add the new name to globalize.lst, so that you can call it from your code.
  • Now implement originalname, and call __unix_originalname

Keymap format

The output each key generates differs for every terminal, but luckily most modern terminals are xterm compatible. If you're reading this, you're probably not using an xterm-compatible terminal and want to get it to work.

The keymap files map the output of each key to a lotus function, and are stored as a binary tree.

For example, PgUp might generate \e[6~ and might generate \e[C

It could be stored like this:

                \e
                /\
               [  Escape
              /\
             6  C
            /\   \
           ~  ?  Right
           |
          PgUp

This way you navigate the tree to figure out what the user just pressed. There is a basic working implementation in the keymap directory that queries terminfo what each sequence is. You can try running it to generate a keymap for your $TERM, but you might find there are missing keys.

This is relatively easy to fix, but is not currently automated.

See also, Keybindings#keymaps.

Testing

There is a script in the test subdirectory that tries to use macros to verify various features are working correctly.

$ ./runtests.sh 
usage: runtests.sh [gold|test|help|calc|menu|file]
    test    - verify that outputs still match golden outputs
    calc    - verify the result of some calculations
    menu    - verify various menu options are working
    file    - check that file management works
    gold    - generate golden outputs
    help    - print this message

Your terminal may flicker as the test macros play.
$ ./runtests.sh file
Testing /File Save...ok
Testing /File Retrieve...ok
Testing /File Combine...ok
Testing /File Xtract...ok
Testing /File Open...ok
Testing /File Admin...ok
Testing /File Erase...ok
Testing /File List...ok
Testing /File Import...ok
Testing /File Dir...ok
Testing /File New...ok
Testing wildcards...ok
Testing /File Import w/Long Name...ok

VMRs

If you look at 1-2-3 internals you will probably notice the VMR logic.

1-2-3 supported DOS, where programs needed to use Expanded Memory to access more than 640k of memory. This wasn't necessary on SysV/386, but the details were abstracted away so that the same code can be used with or without EMS.

VMR (I don't know what it stands for, maybe Virtual Memory Range?) is that abstraction.

On UNIX this code looks confusing and redundant, just passing around pointers in a weird way, but on DOS this would bank swap in a different memory range.

You don't have to use VMRs in any new code, but you might need to setup the pointers to make sure existing code works.

Resources

All the strings and help files are stored in resource (.ri) files.

There are some tools to modify them in the res directory.

The help files are compressed (see huffman_decode in 123.o), but the binary format is easy to modify.

Clone this wiki locally