Initial commit.
[rmac] / sect.h
1 ////////////////////////////////////////////////////////////////////////////////////////////////////
2 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
3 // SECT.H - Code Generation, Fixups and Section Management
4 // Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
5 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
6 // Source Utilised with the Kind Permission of Landon Dyer
7
8 #ifndef __SECT_H__
9 #define __SECT_H__
10
11 #include "rmac.h"
12
13 // Macros to deposit code in the current section
14 // D_rword deposits a "6502" format (low, high) word (01).
15 // D_rlong deposits a MWC "canonical byte order" longword (2301).
16 #define D_byte(b)    {*chptr++=(char)b; ++sloc; ++ch_size; if(orgactive) ++orgaddr;}
17 #define D_word(w)          {chcheck(2);*chptr++=(char)(w>>8); *chptr++=(char)w; \
18                       sloc+=2; ch_size+=2; if(orgactive) orgaddr += 2;}
19 #define D_long(lw)   {*chptr++=(char)(lw>>24); *chptr++=(char)(lw>>16);\
20                            *chptr++=(char)(lw>>8); *chptr++=(char)lw; \
21                       sloc+=4; ch_size += 4; if(orgactive) orgaddr += 4;}
22 #define D_rword(w)   {*chptr++=(char)w; *chptr++=(char)(w>>8); \
23                       sloc+=2; ch_size+=2;if(orgactive) orgaddr += 2;}
24 #define D_rlong(lw)  {*chptr++=(char)(lw>>16);*chptr++=(char)(lw>>24);\
25                       *chptr++=(char)lw;*chptr++=(char)(lw>>8); \
26                       sloc+=4; ch_size += 4;if(orgactive) orgaddr += 4;}
27
28 #define NSECTS       16                                     // Max. number of sections
29
30 // Tunable (storage) definitions
31 #define CH_THRESHOLD    64                                  // Minimum amount of space in code chunk
32 #define CH_CODE_SIZE    2048                                // Code chunk normal allocation
33 #define CH_FIXUP_SIZE   1024                                // Fixup chunk normal allocation
34
35 // Section attributes (.scattr)
36 #define SUSED        0x8000                                 // Section is used (really, valid)
37 #define SBSS         0x4000                                 // Section can contain no data
38 #define SABS         0x2000                                 // Section is absolute
39 #define SPIC         0x1000                                 // Section is position-independent code
40
41 // Fixup record a WORD of these bits, followed by a loc and then a pointer
42 // to a symbol or an ENDEXPR-terminated postfix expression.
43 //
44 // SYMBOL               EXPRESSION
45 // ------               ----------
46 // ~FU_EXPR    FU_EXPR     fixup type
47 // loc.L       loc.L       location in section
48 // fileno.W    fileno.W    file number fixup occurred in
49 // lineno.W    lineno.W    line number fixup occurred in
50 // symbol.L    size.W      &symbol  /  size of expression
51 // token.L     expression list
52 // (etc)
53 // ENDEXPR.L    (end of expression)
54 #define FUMASK       007                                    // Mask for fixup cases:
55 #define FU_QUICK     000                                    // Fixup 3-bit quick instr field
56 #define FU_BYTE      001                                    // Fixup byte
57 #define FU_WORD      002                                    // Fixup word
58 #define FU_WBYTE     003                                    // Fixup byte (at loc+1)
59 #define FU_LONG      004                                    // Fixup long
60 #define FU_BBRA      005                                    // Fixup byte branch
61 #define FU_6BRA      007                                    // Fixup 6502-format branch offset
62 #define FU_SEXT      010                                    // Ok to sign extend
63 #define FU_PCREL     020                                    // Subtract PC first
64 #define FU_EXPR      040                                    // Expression (not symbol) follows
65
66 #define FU_MOVEI     0x0100
67 #define FU_JR        0x0200
68 #define FU_MJR       0x0300
69 #define FU_REGONE    0x0400
70 #define FU_NUM15     0x0500
71 #define FU_NUM31     0x0600
72 #define FU_NUM32     0x0700
73 #define FU_REGTWO    0x0800
74 #define FU_SUB32     0x1000
75 #define FU_ISBRA     0x2000                                 // Word forward fixup is a BRA or DBRA
76 #define FU_LBRA      0x4000                                 // Long branch, for short branch detect
77 #define FU_DONE      0x8000                                 // Fixup has been done
78
79 // Chunks are used to hold generated code and fixup records
80 #define CHUNK  struct _chunk
81 CHUNK {
82    CHUNK *chnext;                                           // Next, previous chunks in section
83    CHUNK *chprev;
84    LONG chloc;                                              // Base addr of this chunk
85    LONG challoc;                                            // #bytes allocated for chunk
86    LONG ch_size;                                            // #bytes chunk actually uses
87    char *chptr;                                             // Data for this chunk
88 };
89
90 // Section descriptor
91 #define SECT   struct _sect
92 SECT {
93    WORD scattr;                                             // Section attributes
94    LONG sloc;                                               // Current loc-in / size-of section 
95    CHUNK *sfcode;                                           // First chunk in section
96    CHUNK *scode;                                            // Last chunk in section
97    CHUNK *sffix;                                            // First fixup chunk
98    CHUNK *sfix;                                             // Last fixup chunk
99 };
100
101 // A mark is of the form:
102 // .W    <to+flags>     section mark is relative to, and flags in upper byte
103 // .L    <loc>          location of mark in "from" section
104 // .W    [from]         new from section
105 // .L    [symbol]       symbol involved in external reference
106 #define MCHUNK struct _mchunk
107 MCHUNK {
108    MCHUNK *mcnext;                                          // Next mark chunk
109    PTR mcptr;                                               // Vector of marks
110    LONG mcalloc;                                            // #marks allocted to mark block
111    LONG mcused;                                             // #marks used in block
112 };
113
114 #define MWORD        0x0000                                 // Marked word
115 #define MLONG        0x0100                                 // Marked long 
116 #define MMOVEI       0x0200
117 #define MCHFROM      0x8000                                 // Mark includes change-to-from
118 #define MSYMBOL      0x4000                                 // Mark includes symbol number
119 #define MCHEND       0x2000                                 // Indicates end of mark chunk
120 #define MPCREL       0x1000                                 // Mark is PC-relative
121
122 #define MAXFWDJUMPS  1024                                   // Maximum forward jumps to check
123 extern unsigned fwdjump[MAXFWDJUMPS];
124 extern unsigned fwindex;
125
126 // Globals, external etc
127 extern LONG sloc;
128 extern WORD scattr;
129 extern char *chptr;
130 extern LONG ch_size;
131 extern int cursect;
132 extern SECT sect[];
133 extern LONG challoc;
134 extern CHUNK *scode;
135
136 // Prototypes
137 void init_sect(void);
138 void switchsect(int);
139 void savsect(void);
140 int fixtest(int, LONG);
141 int chcheck(LONG);
142 int fixup(WORD, LONG, TOKEN *);
143 int fixups(void);
144 int resfix(int);
145
146 #endif // __SECT_H__