Author Topic: About SWOS - programming knowledge!  (Read 7634 times)

0 Members and 1 Guest are viewing this topic.

Offline Playaveli

  • 'Sherlock'
  • Administrator
  • SWOS Legend
  • *****
  • Posts: 8503
  • Gender: Male
  • "SWOS - A way of life" (J.R.)
    • Visit me on Facebook
About SWOS - programming knowledge!
« on: 23 September 2007, 12:55:28 »
(C)(P): Zlatko Karakas

Sensible World of Soccer - Programming

Basic info about executable:
filename: sw(o)s.exe
filesize: 2135087 bytes
file format: Linear Executable
offset to LE header: 0x2c90
fixup section size: 657660
offset to fixup page table: 0x694 (in file 0x3324)
offset to fixup record table: 0xc30 (in file 0x38c0)
number of pages: 358

There are two objects (in LE terms) in file: code and data.

Virtual size of code segment: 658297
Relocation address: 0x10000 <- important
Attributes: readable, executable, has preload pages, nonpermament
Page map index: 1
Page map entries: 0xa1

Virtual size of data segment: 810944
Relocation address: 0xc0000 <- important
Attributes: readable, writeable, has preload pages, nonpermament
Page map index: 0xa2
Page map entries: 0xc5
In file, offset for start of code is 0xa3e00, and offset for data is 0x144e00. From now on, each offset I write will be relative either to code or data start, depending on context.

PC version of SWOS was written as a conversion from Amiga. It can be deduced by analyzing the code, and there are even some left over strings such as "INSERT BLANK DISK IN DF0:". There are 15 memory locations (dwords) that are used as registers. Their start is at 0x3146d. These dwords correspond to Amiga's MC68000 processor registers: data registers D0-D7 and address registers A0-A7. This is not a mistake (15 locations for 16 registers) because register A7 (stack pointer) is mapped directly to Intel's esp register. This means that PC version of SWOS is using so called static emulation, where whole program is translated into host machine language and then executed. Other type of emulation is dynamic emulation, where an interpreter is used that interprets original code run-time (this is the way most emulators operate). Since SWOS is a commercial game, it was more feasibile to use the first approach. I think they did the following: first Amiga's source code (which I believe was mostly written in assembler, or some optimizing C compiler - somebody correct me if I'm wrong) was converted into C code, probably using some third party utility. Than they rewrited some heavily used routines completely in x86 assembler for speed, and rewrited non-portable routines (file handling, input handling, video) to get fully running x86 executable. Compiler used to put all this together was Watcom C - sw(o)s.exe contains whole Watcom run-time library, both 16 and 32-bit versions.

Consequences of this are that the executable is relatively large. It is also missing bss sections commonly found in other executables, and every static array is put in data section filled with zeroes. Heavy use of memory locations instead of processor's registers brings to code size explosion. For example instruction:
mov dword [tmp10], aDataEurocup_tm
is coded in 10 bytes: c7 05 91 14 0f 00 2a 73 0C 00 + fixup record while instruction:
mov eax, aDataEurocup_tm
is coded in only 5 bytes: b8 2a 73 00 00 + fixup record.
Some MC68000 registers could be mapped directly to x86 registers to shrink size a little.
For sound AIL (Audio Interface Library) version 3.03 was used. Unfortunately it is commercial software, publicly unavailable, so I didn't have access to informations about it.

I will enlist some of the most interesting locations in the game, and short descriptions, if available. 0001 means offset is relative to start of code section, and 0002 means relative to data section.
(Note: MC68000 registers are marked as tmp01 - tmp15)

For Intel 80x86 assembly language proabably the best reference is book "Art of Assembly language", available at For Amiga assembly language, I used "AMIGA MACHINE LANGUAGE - FROM ABACUS BOOKS", available somewhere on the Net (archive name: amigamachine.lha).
Sprites Map
Sprite 1286 contains an error: width is erroneously set to 5 pixels. It should be 16 pixels.
0-162 characters
0-56 small set:
0 - x in a box
1 - '
2 - (
3 - )
4 - ,
5 - -
6 - .
7 - /
8-17 - numbers
18-43 - letters
44 - box (cursor)
45 - *
46 - pound
47 - longer dash
48 - ?
49 - :
50 - +
51 - %
52 - ;
53 - A with two accents above
54 - U         -||-
55 - O         -||-
56 - vertical bar
big set follows, for big character add 57 to small character index (except for number 56, it is unique)
113-122 stars, for player skills
123 - picture of a ball, probably for edit tactics menu
small players with corresponding color and shirt stripes; used for editing tactics (corresponding pictures are copied into them)
124 - white guy
125 - red guy
126 - black guy
small goalkeepers, used for editing tactics
127 - white guy
128 - red guy
129 - black guy
small players with plain shirts
130 - white guy
131 - red guy
132 - black guy
small player with colored sleeves shirts
133 - white guy
134 - red guy
135 - black guy
small players with vertical stripes shirts
136 - white guy
137 - red guy
138 - black guy
small players with horizontal stripes shirts
139 - white guy
140 - red guy
141 - black guy
small goalkeepers
142 - white guy
143 - red guy
144 - black guy
149 - cursor while editing tactics, frame 1
150 -                -||-                 2
151 -                -||-                 3
181, 182 - two empty sprites, they are located in edit teams menu, in invisible entries near the end
183 - up arrow (for scrolling)
184 - down arrow
player faces, during edit tactics (maybe used someplace else too)
186 - white guy
187 - red guy
188 - black guy
189 - empty sprite, also used in edit teams menu as a last, invisible entry
215 - national league champion
216 - invitation tournament winner
217 - national cup winner
218 - unknown trophy
219 - european champions cup
220 - european cup-winners cup
221 - UEFA cup
222 - world championship
223 - european championship
227-234 first scrolling advertisement
235-242 second         -||-
243-250 third          -||-
225-270 numbers + player names, written in upper left corner during the game, marking player with ball, team 1
271-286 numbers + player names for team 2
These sprites are filled before the game, they're intially empty.
307 - First team name
308 These two sprites have special properties, and special drawing function is used
330 - current game time (118. mins at the beginning, for maximum width)
This is still incomplete and under construction. If you find errors or wish to contribute to list, let me know.


About SWOS++

SWOS++ consists of three parts contained in files:, loader.bin and swospp.bin. This partitioning was done because of the nature of SWOS executable itself - it is in Linear Executable format. This means that the program is loaded by DOS extender to some, before loading unknown address. Address varies, and is different almost every execution time. Due to this fact, loader must do a process called "fix up". It consists of adding load address to every reference to data or code, which is invalid - therefore fixing it. To be able to do so, executable besides code and data also contains "fixup records" that are pointing to places that need to be fixed up. Fixup records point to various places scattered around the file, making direct patching by hand extremly labourous - besides patching, fixup records also need to be updated.
First part is program which will patch SWOS executable to allow loading of the rest of the program. After patching, SWOS executable will load loader.bin and execute it. Code itself isn't very interesting.
Second part is loader.bin. It is in some way similar to boot loader. It will load the main part - swospp.bin, fix it up and do patches to SWOS. swospp.bin has a strict structure, which enables loader to do all this and check file correctness.
Third part is swospp.bin, the main part. This file contains acutal code and data, relocation offsets and patch instructions. It is in custom made binary format.
Whole this process is somewhat similar to functioning of dynamic load libraries in Windows, or generaly dynamic libraries in operating systems.
Most of the code was written in Intel x86 assembler using NASM (Net-wide assembler) and some small parts were written using excellent Watcom C compiler (which was by the way used for compiling original PC SWOS). Because of very flexibile nature of build system even C++, Pascal and perhaps some other comilers could be used too.
SWOS++ binary format makes making patches much easier than before - there is absolutely no need for hex editing. All patching is done after the program is loaded into memory and fixed up by loader, so there is no need to worry about fixup records overwritting code.


(C)(P): Zlatko Karakas
« Last Edit: 15 May 2018, 19:02:02 by Playaveli »

For those about to SWOS - We salute you

Offline Tomplus

  • Mine names is Tom.... Tom+
  • Superstar
  • ****
  • Posts: 513
  • Gender: Male
    • Polish Sensible Center
Re: About SWOS - programming knowledge!
« Reply #1 on: 23 September 2007, 14:36:23 »
I did't know  few  things.

Polish SWOS Center
Sensible Manager
"One life, one love, one SWOS"

Offline swoozh

  • Superstar
  • ****
  • Posts: 515
  • Gender: Male
  • I'ma Dapper Dan man!
Re: About SWOS - programming knowledge!
« Reply #2 on: 16 June 2011, 14:00:19 »
Nice topic :)

Wish we could have the entire swos source code