X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=as%2Flink%2Fz80%2Flkrloc.c;h=5e97dae336120fdceefcba2a0bd5b60a014b1c85;hb=e05b6df8fb31fa9db84b15f720fd6a4488dec130;hp=e5bdd05a54728235ec9974d9a7f55f3ec9a8ba1b;hpb=bd8e04b4968899d967d0190997dd602e20a94505;p=fw%2Fsdcc diff --git a/as/link/z80/lkrloc.c b/as/link/z80/lkrloc.c index e5bdd05a..5e97dae3 100644 --- a/as/link/z80/lkrloc.c +++ b/as/link/z80/lkrloc.c @@ -16,1156 +16,1120 @@ #include #include #include -//#include #include #include "aslink.h" -/*)Module lkrloc.c - * - * The module lkrloc.c contains the functions which - * perform the relocation calculations. - * - * lkrloc.c contains the following functions: - * Addr_T adb_b() - * Addr_T adb_lo() - * Addr_T adb_hi() - * Addr_T adw_w() - * Addr_T adw_lo() - * Addr_T adw_hi() - * VOID erpdmp() - * VOID errdmp() - * Addr_T evword() - * VOID prntval() - * VOID rele() - * VOID relerr() - * VOID relerp() - * VOID reloc() - * VOID relp() - * VOID relr() - * VOID relt() - * - * lkrloc.c the local variable errmsg[]. +/*)Module lkrloc.c + * + * The module lkrloc.c contains the functions which + * perform the relocation calculations. + * + * lkrloc.c contains the following functions: + * Addr_T adb_b() + * Addr_T adb_lo() + * Addr_T adb_hi() + * Addr_T adw_w() + * Addr_T adw_lo() + * Addr_T adw_hi() + * VOID erpdmp() + * VOID errdmp() + * Addr_T evword() + * VOID prntval() + * VOID rele() + * VOID relerr() + * VOID relerp() + * VOID reloc() + * VOID relp() + * VOID relr() + * VOID relt() + * + * lkrloc.c the local variable errmsg[]. * */ -/*)Function VOID reloc(c) +/*)Function VOID reloc(c) * - * char c process code + * char c process code * - * The function reloc() calls a particular relocation - * function determined by the process code. + * The function reloc() calls a particular relocation + * function determined by the process code. * - * local variable: - * none + * local variable: + * none * - * global variables: - * int lkerr error flag + * global variables: + * int lkerr error flag * - * called functions: - * int fprintf() c_library - * VOID rele() lkrloc.c - * VOID relp() lkrloc.c - * VOID relr() lkrloc.c - * VOId relt() lkrloc.c + * called functions: + * int fprintf() c_library + * VOID rele() lkrloc.c + * VOID relp() lkrloc.c + * VOID relr() lkrloc.c + * VOId relt() lkrloc.c * - * side effects: - * Refer to the called relocation functions. + * side effects: + * Refer to the called relocation functions. * */ -VOID -reloc(c) -char c; +VOID reloc(char c) { - switch(c) { + switch(c) { - case 'T': - relt(); - break; + case 'T': + relt(); + break; - case 'R': - relr(); - break; + case 'R': + relr(); + break; - case 'P': - relp(); - break; + case 'P': + relp(); + break; - case 'E': - rele(); - break; + case 'E': + rele(); + break; - default: - fprintf(stderr, "Undefined Relocation Operation\n"); - lkerr++; - break; + default: + fprintf(stderr, "Undefined Relocation Operation\n"); + lkerr++; + break; - } + } } -/*)Function VOID relt() +/*)Function VOID relt() * - * The function relt() evaluates a T line read by - * the linker. Each byte value read is saved in the - * rtval[] array, rtflg[] is set, and the number of - * evaluations is maintained in rtcnt. + * The function relt() evaluates a T line read by + * the linker. Each byte value read is saved in the + * rtval[] array, rtflg[] is set, and the number of + * evaluations is maintained in rtcnt. * - * T Line + * T Line * - * T xx xx nn nn nn nn nn ... + * T xx xx nn nn nn nn nn ... * * - * In: "T n0 n1 n2 n3 ... nn" + * In: "T n0 n1 n2 n3 ... nn" * - * Out: 0 1 2 .. rtcnt - * +----+----+----+----+----+ - * rtval | n0 | n1 | n2 | .. | nn | - * +----+----+----+----+----+ - * rtflag| 1 | 1 | 1 | 1 | 1 | - * +----+----+----+----+----+ + * Out: 0 1 2 .. rtcnt + * +----+----+----+----+----+ + * rtval | n0 | n1 | n2 | .. | nn | + * +----+----+----+----+----+ + * rtflag| 1 | 1 | 1 | 1 | 1 | + * +----+----+----+----+----+ * - * The T line contains the assembled code output by the assem- - * bler with xx xx being the offset address from the current area - * base address and nn being the assembled instructions and data in - * byte format. + * The T line contains the assembled code output by the assem- + * bler with xx xx being the offset address from the current area + * base address and nn being the assembled instructions and data in + * byte format. * - * local variable: - * none + * local variable: + * none * - * global variables: - * int rtcnt number of values evaluated - * int rtflg[] array of evaluation flags - * int rtval[] array of evaluation values + * global variables: + * int rtcnt number of values evaluated + * int rtflg[] array of evaluation flags + * int rtval[] array of evaluation values * - * called functions: - * int eval() lkeval.c - * int more() lklex.c + * called functions: + * int eval() lkeval.c + * int more() lklex.c * - * side effects: - * Linker input T line evaluated. + * side effects: + * Linker input T line evaluated. * */ -VOID -relt() +VOID relt(VOID) { - rtcnt = 0; - while (more()) { - if (rtcnt < NTXT) { - rtval[rtcnt] = eval(); - rtflg[rtcnt] = 1; - rtcnt++; - } - } + rtcnt = 0; + while (more()) { + if (rtcnt < NTXT) { + rtval[rtcnt] = eval(); + rtflg[rtcnt] = 1; + rtcnt++; + } + } } -/*)Function VOID relr() - * - * The function relr() evaluates a R line read by - * the linker. The R line data is combined with the - * previous T line data to perform the relocation of - * code and data bytes. The S19 / IHX output and - * translation of the LST files to RST files may be - * performed. - * - * R Line - * - * R 0 0 nn nn n1 n2 xx xx ... - * - * The R line provides the relocation information to the linker. - * The nn nn value is the current area index, i.e. which area the - * current values were assembled. Relocation information is en- - * coded in groups of 4 bytes: - * - * 1. n1 is the relocation mode and object format - * 1. bit 0 word(0x00)/byte(0x01) - * 2. bit 1 relocatable area(0x00)/symbol(0x02) - * 3. bit 2 normal(0x00)/PC relative(0x04) relocation - * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for - * byte data - * 5. bit 4 signed(0x00)/unsigned(0x10) byte data - * 6. bit 5 normal(0x00)/page '0'(0x20) reference - * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference - * - * 2. n2 is a byte index into the corresponding (i.e. pre- - * ceeding) T line data (i.e. a pointer to the data to be - * updated by the relocation). The T line data may be - * 1-byte or 2-byte byte data format or 2-byte word - * format. - * - * 3. xx xx is the area/symbol index for the area/symbol be- - * ing referenced. the corresponding area/symbol is found - * in the header area/symbol lists. - * - * The groups of 4 bytes are repeated for each item requiring relo- - * cation in the preceeding T line. - * - * local variable: - * areax **a pointer to array of area pointers - * int aindex area index - * char *errmsg[] array of pointers to error strings - * int error error code - * int lkerr error flag - * int mode relocation mode - * adrr_t paga paging base area address - * Addr_T pags paging symbol address - * Addr_T pc relocated base address - * Addr_T r PCR relocation value - * Addr_T reli relocation initial value - * Addr_T relv relocation final value - * int rindex symbol / area index - * Addr_T rtbase base code address - * Addr_T rtofst rtval[] index offset - * int rtp index into T data - * sym **s pointer to array of symbol pointers - * - * global variables: - * head *hp pointer to the head structure - * rerr rerr linker error structure - * FILE *stderr standard error device - * - * called functions: - * Addr_T adb_b() lkrloc.c - * Addr_T adb_lo() lkrloc.c - * Addr_T adb_hi() lkrloc.c - * Addr_T adw_w() lkrloc.c - * Addr_T evword() lkrloc.c - * int eval() lkeval.c - * int fprintf() c_library - * VOID ihx() lkihx.c - * int lkulist lklist.c - * int more() lklex.c - * VOID relerr() lkrloc.c - * VOID s19() lks19.c - * int symval() lksym.c - * - * side effects: - * The R and T lines are combined to produce - * relocated code and data. Output S19 / IHX - * and relocated listing files may be produced. +/*)Function VOID relr() + * + * The function relr() evaluates a R line read by + * the linker. The R line data is combined with the + * previous T line data to perform the relocation of + * code and data bytes. The S19 / IHX output and + * translation of the LST files to RST files may be + * performed. + * + * R Line + * + * R 0 0 nn nn n1 n2 xx xx ... + * + * The R line provides the relocation information to the linker. + * The nn nn value is the current area index, i.e. which area the + * current values were assembled. Relocation information is en- + * coded in groups of 4 bytes: + * + * 1. n1 is the relocation mode and object format + * 1. bit 0 word(0x00)/byte(0x01) + * 2. bit 1 relocatable area(0x00)/symbol(0x02) + * 3. bit 2 normal(0x00)/PC relative(0x04) relocation + * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for + * byte data + * 5. bit 4 signed(0x00)/unsigned(0x10) byte data + * 6. bit 5 normal(0x00)/page '0'(0x20) reference + * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference + * + * 2. n2 is a byte index into the corresponding (i.e. pre- + * ceeding) T line data (i.e. a pointer to the data to be + * updated by the relocation). The T line data may be + * 1-byte or 2-byte byte data format or 2-byte word + * format. + * + * 3. xx xx is the area/symbol index for the area/symbol be- + * ing referenced. the corresponding area/symbol is found + * in the header area/symbol lists. + * + * The groups of 4 bytes are repeated for each item requiring relo- + * cation in the preceeding T line. + * + * local variable: + * areax **a pointer to array of area pointers + * int aindex area index + * char *errmsg[] array of pointers to error strings + * int error error code + * int lkerr error flag + * int mode relocation mode + * adrr_t paga paging base area address + * Addr_T pags paging symbol address + * Addr_T pc relocated base address + * Addr_T r PCR relocation value + * Addr_T reli relocation initial value + * Addr_T relv relocation final value + * int rindex symbol / area index + * Addr_T rtbase base code address + * Addr_T rtofst rtval[] index offset + * int rtp index into T data + * sym **s pointer to array of symbol pointers + * + * global variables: + * head *hp pointer to the head structure + * rerr rerr linker error structure + * FILE *stderr standard error device + * + * called functions: + * Addr_T adb_b() lkrloc.c + * Addr_T adb_lo() lkrloc.c + * Addr_T adb_hi() lkrloc.c + * Addr_T adw_w() lkrloc.c + * Addr_T evword() lkrloc.c + * int eval() lkeval.c + * int fprintf() c_library + * VOID ihx() lkihx.c + * int lkulist lklist.c + * int more() lklex.c + * VOID relerr() lkrloc.c + * VOID s19() lks19.c + * int symval() lksym.c + * + * side effects: + * The R and T lines are combined to produce + * relocated code and data. Output S19 / IHX + * and relocated listing files may be produced. * */ -VOID -relr() +VOID relr(VOID) { - register int mode; - register Addr_T reli, relv; - int aindex, rindex, rtp, error; - Addr_T r, rtbase, rtofst, paga = 0, pags = 0, pc; - struct areax **a; - struct sym **s; - - /* - * Get area and symbol lists - */ - a = hp->a_list; - s = hp->s_list; - - /* - * Verify Area Mode - */ - if (eval() != (R_WORD | R_AREA) || eval()) { - fprintf(stderr, "R input error\n"); - lkerr++; - } - - /* - * Get area pointer - */ - aindex = evword(); - if (aindex >= hp->h_narea) { - fprintf(stderr, "R area error\n"); - lkerr++; - return; - } - - /* - * Base values - */ - rtbase = adw_w(0, 0); - rtofst = 2; - - /* - * Relocate address - */ - pc = adw_w(a[aindex]->a_addr, 0); + register int mode; + register Addr_T reli, relv; + int aindex, rindex, rtp, error; + Addr_T r, rtbase, rtofst, paga = 0, pags = 0, pc; + struct areax **a; + struct sym **s; + + /* + * Get area and symbol lists + */ + a = hp->a_list; + s = hp->s_list; + + /* + * Verify Area Mode + */ + if (eval() != (R_WORD | R_AREA) || eval()) { + fprintf(stderr, "R input error\n"); + lkerr++; + } + + /* + * Get area pointer + */ + aindex = evword(); + if (aindex >= hp->h_narea) { + fprintf(stderr, "R area error\n"); + lkerr++; + return; + } + + /* + * Base values + */ + rtbase = adw_w(0, 0); + rtofst = 2; + + /* + * Relocate address + */ + pc = adw_w(a[aindex]->a_addr, 0); #ifdef GAMEBOY - { - char *s = strrchr(a[aindex]->a_bap->a_id, '_'); - if(s != NULL && isdigit((unsigned char)s[1])) - current_rom_bank = atoi(s+1); - else - current_rom_bank = 0; - } + { + char *s = strrchr(a[aindex]->a_bap->a_id, '_'); + if(s != NULL && isdigit((unsigned char)s[1])) + current_rom_bank = atoi(s+1); + else + current_rom_bank = 0; + } #endif /* GAMEBOY */ - /* - * Do remaining relocations - */ - while (more()) { - error = 0; - mode = eval(); - rtp = eval(); - rindex = evword(); - - /* - * R_SYM or R_AREA references - */ - if (mode & R_SYM) { - if (rindex >= hp->h_nglob) { - fprintf(stderr, "R symbol error\n"); - lkerr++; - return; - } - reli = symval(s[rindex]); - } else { - if (rindex >= hp->h_narea) { - fprintf(stderr, "R area error\n"); - lkerr++; - return; - } - reli = a[rindex]->a_addr; - } - - /* - * R_PCR addressing - */ - if (mode & R_PCR) { - if (mode & R_BYTE) { - reli -= (pc + (rtp-rtofst) + 1); - } else { - reli -= (pc + (rtp-rtofst) + 2); - } - } - - /* - * R_PAG0 or R_PAG addressing - */ - if (mode & (R_PAG0|R_PAG)) { - paga = sdp.s_area->a_addr; - pags = sdp.s_addr; - reli -= paga + pags; - } - - /* - * R_BYTE or R_WORD operation - */ - if (mode & R_BYTE) { - if (mode & R_BYT2) { - if (mode & R_MSB) { - relv = adb_hi(reli, rtp); - } else { - relv = adb_lo(reli, rtp); - } - } else { - relv = adb_b(reli, rtp); - } - } else { - /* - * R_WORD with the R_BYT2 mode is flagged - * as an 'r' error by the assembler, - * but it is processed here anyway. - */ - if (mode & R_BYT2) { - if (mode & R_MSB) { - relv = adw_hi(reli, rtp); - } else { - relv = adw_lo(reli, rtp); - } - } else { - relv = adw_w(reli, rtp); - } - } - - /* - * R_BYTE with R_BYT2 offset adjust - */ - if (mode & R_BYTE) { - if (mode & R_BYT2) { - rtofst += 1; - } - } - - /* - * Unsigned Byte Checking - */ - if (mode & R_USGN && mode & R_BYTE && relv & ~0xFF) - error = 1; - - /* - * PCR Relocation Error Checking - */ - if (mode & R_PCR && mode & R_BYTE) { - r = relv & ~0x7F; - if (r != (Addr_T) ~0x7F && r != 0) - error = 2; - } - - /* - * Page Relocation Error Checking - */ - if (mode & R_PAG0 && (relv & ~0xFF || paga || pags)) - error = 3; - if (mode & R_PAG && (relv & ~0xFF)) - error = 4; - - /* - * Error Processing - */ - if (error) { - rerr.aindex = aindex; - rerr.mode = mode; - rerr.rtbase = rtbase + rtp - rtofst - 1; - rerr.rindex = rindex; - rerr.rval = relv - reli; - relerr(errmsg[error-1]); - } - } - if (uflag != 0) { - lkulist(1); - } - if (oflag == 1) { - ihx(1); - } else - if (oflag == 2) { - s19(1); + /* + * Do remaining relocations + */ + while (more()) { + error = 0; + mode = eval(); + rtp = eval(); + rindex = evword(); + + /* + * R_SYM or R_AREA references + */ + if (mode & R_SYM) { + if (rindex >= hp->h_nglob) { + fprintf(stderr, "R symbol error\n"); + lkerr++; + return; + } + reli = symval(s[rindex]); + } else { + if (rindex >= hp->h_narea) { + fprintf(stderr, "R area error\n"); + lkerr++; + return; + } + reli = a[rindex]->a_addr; + } + + /* + * R_PCR addressing + */ + if (mode & R_PCR) { + if (mode & R_BYTE) { + reli -= (pc + (rtp-rtofst) + 1); + } else { + reli -= (pc + (rtp-rtofst) + 2); + } + } + + /* + * R_PAG0 or R_PAG addressing + */ + if (mode & (R_PAG0 | R_PAG)) { + paga = sdp.s_area->a_addr; + pags = sdp.s_addr; + reli -= paga + pags; + } + + /* + * R_BYTE or R_WORD operation + */ + if (mode & R_BYTE) { + if (mode & R_BYT2) { + /* This is a two byte address, of + * which we will select one byte. + */ + if (mode & R_MSB) { + relv = adb_hi(reli, rtp); + } else { + relv = adb_lo(reli, rtp); + } + } else { + relv = adb_b(reli, rtp); + } + } else { + /* + * R_WORD with the R_BYT2 mode is flagged + * as an 'r' error by the assembler, + * but it is processed here anyway. + */ + if (mode & R_BYT2) { + if (mode & R_MSB) { + relv = adw_hi(reli, rtp); + } else { + relv = adw_lo(reli, rtp); + } + } else { + relv = adw_w(reli, rtp); + } + } + + /* + * R_BYTE with R_BYT2 offset adjust + */ + if (mode & R_BYTE) { + if (mode & R_BYT2) { + rtofst += 1; + } + } + + /* + * Unsigned Byte Checking + */ + if (mode & R_USGN && mode & R_BYTE && relv & ~0xFF) + error = 1; + + /* + * PCR Relocation Error Checking + */ + if (mode & R_PCR && mode & R_BYTE) { + r = relv & ~0x7F; + if (r != (Addr_T) ~0x7F && r != 0) + error = 2; + } + + /* + * Page Relocation Error Checking + */ + if (mode & R_PAG0 && (relv & ~0xFF || paga || pags)) + error = 3; + if (mode & R_PAG && (relv & ~0xFF)) + error = 4; + + /* + * Error Processing + */ + if (error) { + rerr.aindex = aindex; + rerr.mode = mode; + rerr.rtbase = rtbase + rtp - rtofst - 1; + rerr.rindex = rindex; + rerr.rval = relv - reli; + relerr(errmsg[error-1]); + } + } + if (uflag != 0) { + lkulist(1); + } + if (oflag == 1) { + ihx(1); + } else + if (oflag == 2) { + s19(1); #ifdef SDK - } else - if (oflag == 3) { + } else + if (oflag == 3) { #ifdef GAMEGEAR - gg(1); + gg(1); #endif /* GAMEGEAR */ #ifdef GAMEBOY - gb(1); + gb(1); #endif /* GAMEBOY */ #endif /* SDK */ - } + } } char *errmsg[] = { - "Unsigned Byte error", - "Byte PCR relocation error", - "Page0 relocation error", - "Page Mode relocation error" + "Unsigned Byte error", + "Byte PCR relocation error", + "Page0 relocation error", + "Page Mode relocation error" }; -/*)Function VOID relp() - * - * The function relp() evaluates a P line read by - * the linker. The P line data is combined with the - * previous T line data to set the base page address - * and test the paging boundary and length. - * - * P Line - * - * P 0 0 nn nn n1 n2 xx xx - * - * The P line provides the paging information to the linker as - * specified by a .setdp directive. The format of the relocation - * information is identical to that of the R line. The correspond- - * ing T line has the following information: - * T xx xx aa aa bb bb - * - * Where aa aa is the area reference number which specifies the - * selected page area and bb bb is the base address of the page. - * bb bb will require relocation processing if the 'n1 n2 xx xx' is - * specified in the P line. The linker will verify that the base - * address is on a 256 byte boundary and that the page length of an - * area defined with the PAG type is not larger than 256 bytes. - * - * local variable: - * areax **a pointer to array of area pointers - * int aindex area index - * int mode relocation mode - * Addr_T relv relocation value - * int rindex symbol / area index - * int rtp index into T data - * sym **s pointer to array of symbol pointers - * - * global variables: - * head *hp pointer to the head structure - * int lkerr error flag - * sdp sdp base page structure - * FILE *stderr standard error device - * - * called functions: - * Addr_T adw_w() lkrloc.c - * Addr_T evword() lkrloc.c - * int eval() lkeval.c - * int fprintf() c_library - * int more() lklex.c - * int symval() lksym.c - * - * side effects: - * The P and T lines are combined to set - * the base page address and report any - * paging errors. +/*)Function VOID relp() + * + * The function relp() evaluates a P line read by + * the linker. The P line data is combined with the + * previous T line data to set the base page address + * and test the paging boundary and length. + * + * P Line + * + * P 0 0 nn nn n1 n2 xx xx + * + * The P line provides the paging information to the linker as + * specified by a .setdp directive. The format of the relocation + * information is identical to that of the R line. The correspond- + * ing T line has the following information: + * T xx xx aa aa bb bb + * + * Where aa aa is the area reference number which specifies the + * selected page area and bb bb is the base address of the page. + * bb bb will require relocation processing if the 'n1 n2 xx xx' is + * specified in the P line. The linker will verify that the base + * address is on a 256 byte boundary and that the page length of an + * area defined with the PAG type is not larger than 256 bytes. + * + * local variable: + * areax **a pointer to array of area pointers + * int aindex area index + * int mode relocation mode + * Addr_T relv relocation value + * int rindex symbol / area index + * int rtp index into T data + * sym **s pointer to array of symbol pointers + * + * global variables: + * head *hp pointer to the head structure + * int lkerr error flag + * sdp sdp base page structure + * FILE *stderr standard error device + * + * called functions: + * Addr_T adw_w() lkrloc.c + * Addr_T evword() lkrloc.c + * int eval() lkeval.c + * int fprintf() c_library + * int more() lklex.c + * int symval() lksym.c + * + * side effects: + * The P and T lines are combined to set + * the base page address and report any + * paging errors. * */ -VOID -relp() +VOID relp(VOID) { - register int aindex, rindex; - int mode, rtp; - Addr_T relv; - struct areax **a; - struct sym **s; - - /* - * Get area and symbol lists - */ - a = hp->a_list; - s = hp->s_list; - - /* - * Verify Area Mode - */ - if (eval() != (R_WORD | R_AREA) || eval()) { - fprintf(stderr, "P input error\n"); - lkerr++; - } - - /* - * Get area pointer - */ - aindex = evword(); - if (aindex >= hp->h_narea) { - fprintf(stderr, "P area error\n"); - lkerr++; - return; - } - - /* - * Do remaining relocations - */ - while (more()) { - mode = eval(); - rtp = eval(); - rindex = evword(); - - /* - * R_SYM or R_AREA references - */ - if (mode & R_SYM) { - if (rindex >= hp->h_nglob) { - fprintf(stderr, "P symbol error\n"); - lkerr++; - return; - } - relv = symval(s[rindex]); - } else { - if (rindex >= hp->h_narea) { - fprintf(stderr, "P area error\n"); - lkerr++; - return; - } - relv = a[rindex]->a_addr; - } - adw_w(relv, rtp); - } - - /* - * Paged values - */ - aindex = adw_w(0,2); - if (aindex >= hp->h_narea) { - fprintf(stderr, "P area error\n"); - lkerr++; - return; - } - sdp.s_areax = a[aindex]; - sdp.s_area = sdp.s_areax->a_bap; - sdp.s_addr = adw_w(0,4); - if (sdp.s_area->a_addr & 0xFF || sdp.s_addr & 0xFF) - relerp("Page Definition Boundary Error"); + register int aindex, rindex; + int mode, rtp; + Addr_T relv; + struct areax **a; + struct sym **s; + + /* + * Get area and symbol lists + */ + a = hp->a_list; + s = hp->s_list; + + /* + * Verify Area Mode + */ + if (eval() != (R_WORD | R_AREA) || eval()) { + fprintf(stderr, "P input error\n"); + lkerr++; + } + + /* + * Get area pointer + */ + aindex = evword(); + if (aindex >= hp->h_narea) { + fprintf(stderr, "P area error\n"); + lkerr++; + return; + } + + /* + * Do remaining relocations + */ + while (more()) { + mode = eval(); + rtp = eval(); + rindex = evword(); + + /* + * R_SYM or R_AREA references + */ + if (mode & R_SYM) { + if (rindex >= hp->h_nglob) { + fprintf(stderr, "P symbol error\n"); + lkerr++; + return; + } + relv = symval(s[rindex]); + } else { + if (rindex >= hp->h_narea) { + fprintf(stderr, "P area error\n"); + lkerr++; + return; + } + relv = a[rindex]->a_addr; + } + adw_w(relv, rtp); + } + + /* + * Paged values + */ + aindex = adw_w(0,2); + if (aindex >= hp->h_narea) { + fprintf(stderr, "P area error\n"); + lkerr++; + return; + } + sdp.s_areax = a[aindex]; + sdp.s_area = sdp.s_areax->a_bap; + sdp.s_addr = adw_w(0,4); + if (sdp.s_area->a_addr & 0xFF || sdp.s_addr & 0xFF) + relerp("Page Definition Boundary Error"); } -/*)Function VOID rele() +/*)Function VOID rele() * - * The function rele() closes all open output files - * at the end of the linking process. + * The function rele() closes all open output files + * at the end of the linking process. * - * local variable: - * none + * local variable: + * none * - * global variables: - * int oflag output type flag - * int uflag relocation listing flag + * global variables: + * int oflag output type flag + * int uflag relocation listing flag * - * called functions: - * VOID ihx() lkihx.c - * VOID lkulist() lklist.c - * VOID s19() lks19.c + * called functions: + * VOID ihx() lkihx.c + * VOID lkulist() lklist.c + * VOID s19() lks19.c * - * side effects: - * All open output files are closed. + * side effects: + * All open output files are closed. * */ -VOID -rele() +VOID rele(VOID) { - if (uflag != 0) { - lkulist(0); - } - if (oflag == 1) { - ihx(0); - } else - if (oflag == 2) { - s19(0); + if (uflag != 0) { + lkulist(0); + } + if (oflag == 1) { + ihx(0); + } else + if (oflag == 2) { + s19(0); #ifdef SDK - } else - if (oflag == 3) { + } else + if (oflag == 3) { #ifdef GAMEGEAR - gg(0); + gg(0); #endif /* GAMEGEAR */ #ifdef GAMEBOY - gb(0); + gb(0); #endif /* GAMEBOY */ #endif /* SDK */ - } + } } -/*)Function Addr_T evword() +/*)Function Addr_T evword() * - * The function evword() combines two byte values - * into a single word value. + * The function evword() combines two byte values + * into a single word value. * - * local variable: - * Addr_T v temporary evaluation variable + * local variable: + * Addr_T v temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * int eval() lkeval.c + * called functions: + * int eval() lkeval.c * - * side effects: - * Relocation text line is scanned to combine - * two byte values into a single word value. + * side effects: + * Relocation text line is scanned to combine + * two byte values into a single word value. * */ -Addr_T -evword() +Addr_T evword(VOID) { - register Addr_T v; - - if (hilo) { - v = (eval() << 8); - v += eval(); - } else { - v = eval(); - v += (eval() << 8); - } - return(v); + register Addr_T v; + + if (hilo) { + v = (eval() << 8); + v += eval(); + } else { + v = eval(); + v += (eval() << 8); + } + return(v); } -/*)Function Addr_T adb_b(v, i) +/*)Function Addr_T adb_b(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adb_b() adds the value of v to - * the single byte value contained in rtval[i]. - * The new value of rtval[i] is returned. + * The function adb_b() adds the value of v to + * the single byte value contained in rtval[i]. + * The new value of rtval[i] is returned. * - * local variable: - * none + * local variable: + * none * - * global variables: - * none + * global variables: + * none * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. + * side effects: + * The value of rtval[] is changed. * */ -Addr_T -adb_b(v, i) -register Addr_T v; -register int i; +Addr_T adb_b(register Addr_T v, register int i) { - return(rtval[i] += v); + return(rtval[i] += v); } -/*)Function Addr_T adb_lo(v, i) +/*)Function Addr_T adb_lo(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adb_lo() adds the value of v to the - * double byte value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The MSB rtflg[] is cleared. + * The function adb_lo() adds the value of v to the + * double byte value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The MSB rtflg[] is cleared. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The rtflg[] value corresponding to the - * MSB of the word value is cleared to reflect - * the fact that the LSB is the selected byte. + * side effects: + * The value of rtval[] is changed. + * The rtflg[] value corresponding to the + * MSB of the word value is cleared to reflect + * the fact that the LSB is the selected byte. * */ -Addr_T -adb_lo(v, i) -Addr_T v; -int i; +Addr_T adb_lo(Addr_T v, int i) { - register Addr_T j; - - j = adw_w(v, i); - /* - * Remove Hi byte - */ - if (hilo) { - rtflg[i] = 0; - } else { - rtflg[i+1] = 0; - } - return (j); + register Addr_T j; + + j = adw_w(v, i); + /* + * Remove Hi byte + */ + if (hilo) { + rtflg[i] = 0; + } else { + rtflg[i+1] = 0; + } + return (j); } -/*)Function Addr_T adb_hi(v, i) +/*)Function Addr_T adb_hi(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adb_hi() adds the value of v to the - * double byte value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The LSB rtflg[] is cleared. + * The function adb_hi() adds the value of v to the + * double byte value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The LSB rtflg[] is cleared. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The rtflg[] value corresponding to the - * LSB of the word value is cleared to reflect - * the fact that the MSB is the selected byte. + * side effects: + * The value of rtval[] is changed. + * The rtflg[] value corresponding to the + * LSB of the word value is cleared to reflect + * the fact that the MSB is the selected byte. * */ -Addr_T -adb_hi(v, i) -Addr_T v; -int i; +Addr_T adb_hi(Addr_T v, int i) { - register Addr_T j; - - j = adw_w(v, i); - /* - * Remove Lo byte - */ - if (hilo) { - rtflg[i+1] = 0; - } else { - rtflg[i] = 0; - } - return (j); + register Addr_T j; + + j = adw_w(v, i); + /* + * Remove Lo byte + */ + if (hilo) { + rtflg[i+1] = 0; + } else { + rtflg[i] = 0; + } + return (j); } -/*)Function Addr_T adw_w(v, i) +/*)Function Addr_T adw_w(v, i) * - * int v value to add to word - * int i rtval[] index + * int v value to add to word + * int i rtval[] index * - * The function adw_w() adds the value of v to the - * word value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. + * The function adw_w() adds the value of v to the + * word value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The word value of rtval[] is changed. + * side effects: + * The word value of rtval[] is changed. * */ -Addr_T -adw_w(v, i) -register Addr_T v; -register int i; +Addr_T adw_w(register Addr_T v, register int i) { - register Addr_T j; - - if (hilo) { - j = v + (rtval[i] << 8) + (rtval[i+1] & 0xff); - rtval[i] = (j >> 8) & 0xff; - rtval[i+1] = j & 0xff; - } else { - j = v + (rtval[i] & 0xff) + (rtval[i+1] << 8); - rtval[i] = j & 0xff; - rtval[i+1] = (j >> 8) & 0xff; - } - return(j); + register Addr_T j; + + if (hilo) { + j = v + (rtval[i] << 8) + (rtval[i+1] & 0xff); + rtval[i] = (j >> 8) & 0xff; + rtval[i+1] = j & 0xff; + } else { + j = v + (rtval[i] & 0xff) + (rtval[i+1] << 8); + rtval[i] = j & 0xff; + rtval[i+1] = (j >> 8) & 0xff; + } + return(j); } -/*)Function Addr_T adw_lo(v, i) +/*)Function Addr_T adw_lo(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adw_lo() adds the value of v to the - * double byte value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The MSB rtval[] is zeroed. + * The function adw_lo() adds the value of v to the + * double byte value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The MSB rtval[] is zeroed. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The MSB of the word value is cleared to reflect - * the fact that the LSB is the selected byte. + * side effects: + * The value of rtval[] is changed. + * The MSB of the word value is cleared to reflect + * the fact that the LSB is the selected byte. * */ -Addr_T -adw_lo(v, i) -Addr_T v; -int i; +Addr_T adw_lo(Addr_T v, int i) { - register Addr_T j; - - j = adw_w(v, i); - /* - * Clear Hi byte - */ - if (hilo) { - rtval[i] = 0; - } else { - rtval[i+1] = 0; - } - return (j); + register Addr_T j; + + j = adw_w(v, i); + /* + * Clear Hi byte + */ + if (hilo) { + rtval[i] = 0; + } else { + rtval[i+1] = 0; + } + return (j); } -/*)Function Addr_T adw_hi(v, i) +/*)Function Addr_T adw_hi(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adw_hi() adds the value of v to the - * double byte value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The MSB and LSB values are interchanged. - * The MSB rtval[] is zeroed. + * The function adw_hi() adds the value of v to the + * double byte value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The MSB and LSB values are interchanged. + * The MSB rtval[] is zeroed. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The MSB and LSB values are interchanged and - * then the MSB cleared. + * side effects: + * The value of rtval[] is changed. + * The MSB and LSB values are interchanged and + * then the MSB cleared. * */ -Addr_T -adw_hi(v, i) -Addr_T v; -int i; +Addr_T adw_hi(Addr_T v, int i) { - register Addr_T j; - - j = adw_w(v, i); - /* - * LSB = MSB, Clear MSB - */ - if (hilo) { - rtval[i+1] = rtval[i]; - rtval[i] = 0; - } else { - rtval[i] = rtval[i+1]; - rtval[i+1] = 0; - } - return (j); + register Addr_T j; + + j = adw_w(v, i); + /* + * LSB = MSB, Clear MSB + */ + if (hilo) { + rtval[i+1] = rtval[i]; + rtval[i] = 0; + } else { + rtval[i] = rtval[i+1]; + rtval[i+1] = 0; + } + return (j); } -/*)Function VOID relerr(str) +/*)Function VOID relerr(str) * - * char *str error string + * char *str error string * - * The function relerr() outputs the error string to - * stderr and to the map file (if it is open). + * The function relerr() outputs the error string to + * stderr and to the map file (if it is open). * - * local variable: - * none + * local variable: + * none * - * global variables: - * FILE *mfp handle for the map file + * global variables: + * FILE *mfp handle for the map file * - * called functions: - * VOID errdmp() lkrloc.c + * called functions: + * VOID errdmp() lkrloc.c * - * side effects: - * Error message inserted into map file. + * side effects: + * Error message inserted into map file. * */ -VOID -relerr(str) -char *str; +VOID relerr(char *str) { - errdmp(stderr, str); - if (mfp) - errdmp(mfp, str); + errdmp(stderr, str); + if (mfp) + errdmp(mfp, str); } -/*)Function VOID errdmp(fptr, str) +/*)Function VOID errdmp(fptr, str) * - * FILE *fptr output file handle - * char *str error string + * FILE *fptr output file handle + * char *str error string * - * The function errdmp() outputs the error string str - * to the device specified by fptr. Additional information - * is output about the definition and referencing of - * the symbol / area error. + * The function errdmp() outputs the error string str + * to the device specified by fptr. Additional information + * is output about the definition and referencing of + * the symbol / area error. * - * local variable: - * int mode error mode - * int aindex area index - * int lkerr error flag - * int rindex error index - * sym **s pointer to array of symbol pointers - * areax **a pointer to array of area pointers - * areax *raxp error area extension pointer + * local variable: + * int mode error mode + * int aindex area index + * int lkerr error flag + * int rindex error index + * sym **s pointer to array of symbol pointers + * areax **a pointer to array of area pointers + * areax *raxp error area extension pointer * - * global variables: - * sdp sdp base page structure + * global variables: + * sdp sdp base page structure * - * called functions: - * int fprintf() c_library - * VOID prntval() lkrloc.c + * called functions: + * int fprintf() c_library + * VOID prntval() lkrloc.c * - * side effects: - * Error reported. + * side effects: + * Error reported. * */ -VOID -errdmp(fptr, str) -FILE *fptr; -char *str; +VOID errdmp(FILE *fptr, char *str) { - int mode, aindex, rindex; - struct sym **s; - struct areax **a; - struct areax *raxp; - - a = hp->a_list; - s = hp->s_list; - - mode = rerr.mode; - aindex = rerr.aindex; - rindex = rerr.rindex; - - /* - * Print Error - */ - fprintf(fptr, "\n?ASlink-Warning-%s", str); - lkerr++; - - /* - * Print symbol if symbol based - */ - if (mode & R_SYM) { - fprintf(fptr, " for symbol %.*s\n", - NCPS, &s[rindex]->s_id[0]); - } else { - fprintf(fptr, "\n"); - } - - /* - * Print Ref Info - */ - fprintf(fptr, - " file module area offset\n"); - fprintf(fptr, - " Refby %-8.8s %-8.8s %-8.8s ", - hp->h_lfile->f_idp, - &hp->m_id[0], - &a[aindex]->a_bap->a_id[0]); - prntval(fptr, rerr.rtbase); - - /* - * Print Def Info - */ - if (mode & R_SYM) { - raxp = s[rindex]->s_axp; - } else { - raxp = a[rindex]; - } - fprintf(fptr, - " Defin %-8.8s %-8.8s %-8.8s ", - raxp->a_bhp->h_lfile->f_idp, - &raxp->a_bhp->m_id[0], - &raxp->a_bap->a_id[0]); - if (mode & R_SYM) { - prntval(fptr, s[rindex]->s_addr); - } else { - prntval(fptr, rerr.rval); - } + int mode, aindex, rindex; + struct sym **s; + struct areax **a; + struct areax *raxp; + + a = hp->a_list; + s = hp->s_list; + + mode = rerr.mode; + aindex = rerr.aindex; + rindex = rerr.rindex; + + /* + * Print Error + */ + fprintf(fptr, "\n?ASlink-Warning-%s", str); + lkerr++; + + /* + * Print symbol if symbol based + */ + if (mode & R_SYM) { + fprintf(fptr, " for symbol %.*s\n", + NCPS, &s[rindex]->s_id[0]); + } else { + fprintf(fptr, "\n"); + } + + /* + * Print Ref Info + */ + fprintf(fptr, + " file module area offset\n"); + fprintf(fptr, + " Refby %-8.8s %-8.8s %-8.8s ", + hp->h_lfile->f_idp, + &hp->m_id[0], + &a[aindex]->a_bap->a_id[0]); + prntval(fptr, rerr.rtbase); + + /* + * Print Def Info + */ + if (mode & R_SYM) { + raxp = s[rindex]->s_axp; + } else { + raxp = a[rindex]; + } + fprintf(fptr, + " Defin %-8.8s %-8.8s %-8.8s ", + raxp->a_bhp->h_lfile->f_idp, + &raxp->a_bhp->m_id[0], + &raxp->a_bap->a_id[0]); + if (mode & R_SYM) { + prntval(fptr, s[rindex]->s_addr); + } else { + prntval(fptr, rerr.rval); + } } -/*)Function VOID prntval(fptr, v) +/*)Function VOID prntval(fptr, v) * - * FILE *fptr output file handle - * Addr_T v value to output + * FILE *fptr output file handle + * Addr_T v value to output * - * The function prntval() outputs the value v, in the - * currently selected radix, to the device specified - * by fptr. + * The function prntval() outputs the value v, in the + * currently selected radix, to the device specified + * by fptr. * - * local variable: - * none + * local variable: + * none * - * global variables: - * int xflag current radix + * global variables: + * int xflag current radix * - * called functions: - * int fprintf() c_library + * called functions: + * int fprintf() c_library * - * side effects: - * none + * side effects: + * none * */ -VOID -prntval(fptr, v) -FILE *fptr; -Addr_T v; +VOID prntval(FILE *fptr, Addr_T v) { - if (xflag == 0) { - fprintf(fptr, "%04X\n", v); - } else - if (xflag == 1) { - fprintf(fptr, "%06o\n", v); - } else - if (xflag == 2) { - fprintf(fptr, "%05u\n", v); - } + if (xflag == 0) { + fprintf(fptr, "%04X\n", v); + } else + if (xflag == 1) { + fprintf(fptr, "%06o\n", v); + } else + if (xflag == 2) { + fprintf(fptr, "%05u\n", v); + } } -/*)Function VOID relerp(str) +/*)Function VOID relerp(str) * - * char *str error string + * char *str error string * - * The function relerp() outputs the paging error string to - * stderr and to the map file (if it is open). + * The function relerp() outputs the paging error string to + * stderr and to the map file (if it is open). * - * local variable: - * none + * local variable: + * none * - * global variables: - * FILE *mfp handle for the map file + * global variables: + * FILE *mfp handle for the map file * - * called functions: - * VOID erpdmp() lkrloc.c + * called functions: + * VOID erpdmp() lkrloc.c * - * side effects: - * Error message inserted into map file. + * side effects: + * Error message inserted into map file. * */ -VOID -relerp(str) -char *str; +VOID relerp(char *str) { - erpdmp(stderr, str); - if (mfp) - erpdmp(mfp, str); + erpdmp(stderr, str); + if (mfp) + erpdmp(mfp, str); } -/*)Function VOID erpdmp(fptr, str) +/*)Function VOID erpdmp(fptr, str) * - * FILE *fptr output file handle - * char *str error string + * FILE *fptr output file handle + * char *str error string * - * The function erpdmp() outputs the error string str - * to the device specified by fptr. + * The function erpdmp() outputs the error string str + * to the device specified by fptr. * - * local variable: - * head *thp pointer to head structure + * local variable: + * head *thp pointer to head structure * - * global variables: - * int lkerr error flag - * sdp sdp base page structure + * global variables: + * int lkerr error flag + * sdp sdp base page structure * - * called functions: - * int fprintf() c_library - * VOID prntval() lkrloc.c + * called functions: + * int fprintf() c_library + * VOID prntval() lkrloc.c * - * side effects: - * Error reported. + * side effects: + * Error reported. * */ -VOID -erpdmp(fptr, str) -FILE *fptr; -char *str; +VOID erpdmp(FILE *fptr, char *str) { - register struct head *thp; - - thp = sdp.s_areax->a_bhp; - - /* - * Print Error - */ - fprintf(fptr, "\n?ASlink-Warning-%s\n", str); - lkerr++; - - /* - * Print PgDef Info - */ - fprintf(fptr, - " file module pgarea pgoffset\n"); - fprintf(fptr, - " PgDef %-8.8s %-8.8s %-8.8s ", - thp->h_lfile->f_idp, - &thp->m_id[0], - &sdp.s_area->a_id[0]); - prntval(fptr, sdp.s_area->a_addr + sdp.s_addr); + register struct head *thp; + + thp = sdp.s_areax->a_bhp; + + /* + * Print Error + */ + fprintf(fptr, "\n?ASlink-Warning-%s\n", str); + lkerr++; + + /* + * Print PgDef Info + */ + fprintf(fptr, + " file module pgarea pgoffset\n"); + fprintf(fptr, + " PgDef %-8.8s %-8.8s %-8.8s ", + thp->h_lfile->f_idp, + &thp->m_id[0], + &sdp.s_area->a_id[0]); + prntval(fptr, sdp.s_area->a_addr + sdp.s_addr); }