-
Notifications
You must be signed in to change notification settings - Fork 275
/
README.binfmt
153 lines (114 loc) · 4.38 KB
/
README.binfmt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
32bit
Uses binfmt_flat with tiny tweaks to avoid loading Linux binaries for now.
8bit
16 byte header for current style binary. We try to reflect the general
pattern of naming in classic Unixlike systems
The 16 byte header is replaced by stubs. The syscall interface for most
8bit processors is to jump to the start of the stubs. Relocations are
done by the application itself if required, except the 6502 where because
of the ZP relocations this is not practicable.
struct exec {
uint16_t a_magic;
#define EXEC_MAGIC 0x80A8 /* Just need something to id with */
uint8_t a_cpu;
#define A_8080 1 /* 8080 series processors (and Z80) */
#define A_6800 2 /* 6800 series */
#define A_6502 3 /* 6502 */
#define A_6809 4 /* 6809 */
#define A_RABBIT 5 /* Rabbit is unZ80 enough to be its own */
#define A_MSP340 6 /* MSP340 series */
#define A_PDP11 7 /* PDP-11 */
#define A_8086 8 /* x86 16bit */
#define A_68000 9 /* 68000 32bit */
#define A_NS32K 10 /* NS32K 32bit */
uint8_t a_cpufeat;
#define AF_8080_8085 1 /* Uses 8085 instructions */
#define AF_8080_Z80 2 /* Uses legal Z80 instructions */
#define AF_8080_Z180 4 /* Uses Z180 instructions */
#define AF_8080_Z280 8 /* Uses Z280 instructions */
#define AF_8080_EZ80 16 /* Uses EZ80 extensions */
#define AF_6800_6803 1 /* PSHX etc */
#define AF_6800_6303 2 /* XGDX and similar */
#define AF_6800_68HC11 4 /* Y register and other extensions */
#define AF_6C502 1 /* CMOS 6502 extra instructions */
#define AF_65C816 2 /* Uses 65C816 instructions */
#define AF_65C816_B0 4 /* 65C816 assuming bank 0 (so can use
stack relative addressing) */
#define AF_65C02_BITOP 8 /* SMB/RMB/TSB/TRB/BBR */
#define AF_6809_6309 1 /* 6309 extensions */
#define AF_RABBIT_R3K 1 /* Uses Rabbit 3000 additions */
uint8_t a_base; /* Load address page */
uint8_t a_hints;
#define HINT_GRAPHICS 1 /* Hint that this binary uses graphics */
#define HINT_DEBUG 2 /* Debug data follows binary image */
uint16_t a_text;
uint16_t a_data;
uint16_t a_bss;
uint8_t a_entry; /* Entry point - 0-255 bytes in only */
/* These are kept in pages */
uint8_t a_size; /* Binary memory request 0 = all */
uint8_t a_stack; /* Stack size hint */
uint8_t a_zp; /* Zero/Direct page space required */
/* This isn't really part of the header but a location fixed after
it */
/* uint16_t a_sigvec; */
};
Entry Conditions & System Calls
6502/65C816:
C stack pointer configured in zero page (ZP:0/1 before relocations)
C stack will be placed at the top of memory as normal (C and
CPU stack are separate)
6502 stack set to end of 6502 stack space (may not be $1FF)
X holds high byte of load address
A holds first zero page value allocated
Y undefined
Signal vector helper code must be present at offset 16
System calls via
Arguments on C stack (ZP:0 + base)
X holds the syscall number
Y holds the number of arguments
Behaves like a cc65 non fast call, so the syscall unstacks the
passed arguments
Returns in YX with error code in A and Z clear if no error
68000:
A7 is set to the C stack
Code is always relocated
Other registers are undefined
System calls:
32bit pointer / 32bit int unlike smaller ports
trap 15 causes a SIGTRAP
trap14 (currently - may relocate this)
d0 = syscall
d1 = arg1
a0 = arg2
a1 = arg3
a2 = arg4
The only register we guarantee to save is A5, thus anything using
base relative addressing needs to use A5 as the base because signal
handling at the wrong moment may mean all other registers are
undefined. This might seem a pain but it saves us a load of clocks!
return value is in d0.l and a0.l (for convenience)
error code is in d1.w
6809:
S is set to the C stack
X holds the load address
other registers undefined
Execution begins at first byte of loaded binary
No signal vector helper required
System calls are via swi
Arguments on the caller stack, call number in D when swi
Caller unstacks
Returns error code in D, return in X
8080/8085/Z80:
SP is set to the C stack
DE holds the load address
System calls:
On Z80 IX, IY and alternate registers are saved except AF' which
may be destroyed
On entry userspace stack holds the syscall arguments
On return HL holds the return value and carry is clear
On error return HL holds the error and carry is set
Signal vector helper will be present at offset 16. This is needed
for ACK 8080 binaries but for current SDCC Z80 binaries it's just
ex de,hl
jp (hl)