#!/usr/bin/perl
##
## legOS - the independent LEGO Mindstorms OS
## genlds - generate a dynamic linker command file
## (c) 1999 by Markus L. Noga <markus@noga.de>
##
## usage: defsym kernelname < kernel.map
##

# parse global text, data and bss symbols (TDB)
#
$numsyms=0;
while(<STDIN>) {
  if(/0000([0-9a-fA-F]+) [TDB] (.+)/) {
    $sym [$numsyms]=$2;
    $addr[$numsyms]="0x$1";
    
    # find start of program area
    if($sym[$numsyms] eq "_mm_start") {
      $ram=sprintf "0x%04x",(hex $addr[$numsyms])+2;
    }
    $numsyms++;
  }
}

$name=shift;
$ramval =hex $ram;
$kernlen=sprintf "0x%04x",$ramval - 0x8000;
$ramlen =sprintf "0x%04x",0xfefc  - $ramval;

$now    =localtime;


print <<"////////////////////";
/*
 * 
 *  dynamic linker command file
 *  generated: $now
 *  kernel   : $name
 *  app start: $ram
 * 
 *  legOS - the independent LEGO Mindstorms OS
 *  (c) 1999 by Markus L. Noga <markus\@noga.de>    
 * 
 */

OUTPUT_FORMAT(\"symbolsrec\")
OUTPUT_ARCH(h8300)
ENTRY(\"_main\")

MEMORY {
  rom   : o = 0x0000, l = 0x8000
  kern  : o = 0x8000, l = $kernlen
  ram   : o = $ram, l = $ramlen
  stack : o = 0xfefc, l = 0x0004
  eight : o = 0xff00, l = 0x0100
}

SECTIONS {

  .rom : {
    /* used rom functions */
    
    _rom_reset_vector = 0x0000;
        
    _reset        = 0x03ae ;
    lcd_show      = 0x1b62 ;
    lcd_hide      = 0x1e4a ;
    lcd_number    = 0x1ff2 ;
    lcd_clear     = 0x27ac ;
    lcd_refresh   = 0x27c8 ;
    power_init    = 0x2964 ;
    sound_system  = 0x299a ;
    power_off     = 0x2a62 ;
    sound_playing = 0x3ccc ;

    _rom_dummy_handler   = 0x046a ;
    _rom_ocia_handler    = 0x04cc ;
    _rom_ocia_return     = 0x04d4 ;
    
  } > rom

  .kernel :	{
    /* kernel symbols (relative to 0x8000) */
    
////////////////////

# convert global text, data and bss symbols (TDB)
#
for($cur=0; $cur<$numsyms; $cur++) {
  if($sym[$cur] ne "_main" && !($sym[$cur]=~/^___(text|data|bss)/)) {
    $off=sprintf "0x%04x",hex($addr[$cur])-0x8000;
    print "    $sym[$cur] = $off ;\n";
  }
}

# footer
#
print <<'////////////////////';

    /* end of kernel symbols */
  }  > kern
      
  .text :	{
    ___text = . ;
    *(.text) 	      /* must start with text for clean entry */			
    *(.rodata)
    *(.strings)
    *(.vectors)       /* vectors region (dummy) */

    ___text_end = . ;
  }  > ram

  .tors : {
    ___ctors = . ;
    *(.ctors)
    ___ctors_end = . ;
    ___dtors = . ;
    *(.dtors)
    ___dtors_end = . ;
  }  > ram

  .data : {
    ___data = . ;
    *(.data)
    *(.tiny)
    ___data_end = . ;
  }  > ram

  .bss : {
    ___bss = . ;
    *(.bss)
    *(COMMON)
    ___bss_end = ALIGN(2) ;
  }  >ram

  .stack : {
    _stack = . ; 
    *(.stack)
  }  > topram

  .eight 0xff00: {
    *(.eight)

    /* on-chip module registers (relative to 0xff00) */

    _T_IER = 0x90 ;
    _T_CSR = 0x91 ;
    _T_CNT = 0x92 ;
    _T_OCRA = 0x94 ;
    _T_OCRB = 0x94 ;
    _T_CR = 0x96 ;
    _T_OCR = 0x97 ;
    _T_ICRA = 0x98 ;
    _T_ICRB = 0x9a ;
    _T_ICRC = 0x9c ;
    _T_ICRD = 0x9e ;
    _PORT1_PCR = 0xac ;
    _PORT2_PCR = 0xad ;
    _PORT3_PCR = 0xae ;
    _PORT1_DDR = 0xb0 ;
    _PORT2_DDR = 0xb1 ;
    _PORT1 = 0xb2 ;
    _PORT2 = 0xb3 ;
    _PORT3_DDR = 0xb4 ;
    _PORT4_DDR = 0xb5 ;
    _PORT3 = 0xb6 ;
    _PORT4 = 0xb7 ;
    _PORT5_DDR = 0xb8 ;
    _PORT6_DDR = 0xb9 ;
    _PORT5 = 0xba ;
    _PORT6 = 0xbb ;
    _PORT7 = 0xbe ;
    _STCR = 0xc3 ;
    _SYSCR = 0xc4 ;
    _T0_CR = 0xc8 ;
    _T0_CSR = 0xc9 ;
    _T0_CORA = 0xca ;
    _T0_CORB = 0xcb ;
    _T0_CNT = 0xcc ;
    _T1_CR = 0xd0 ;
    _T1_CSR = 0xd1 ;
    _T1_CORA = 0xd2 ;
    _T1_CORB = 0xd3 ;
    _T1_CNT = 0xd4 ;
    _S_MR = 0xd8 ;
    _S_BRR = 0xd9 ;
    _S_CR = 0xda ;
    _S_TDR = 0xdb ;
    _S_SR = 0xdc ;
    _S_RDR = 0xdd ;
    _AD_A = 0xe0 ;
    _AD_A_H = 0xe0 ;
    _AD_A_L = 0xe1 ;
    _AD_B = 0xe2 ;
    _AD_B_H = 0xe2 ;
    _AD_B_L = 0xe3 ;
    _AD_C = 0xe4 ;
    _AD_C_H = 0xe4 ;
    _AD_C_L = 0xe5 ;
    _AD_D = 0xe6 ;
    _AD_D_H = 0xe6 ;
    _AD_D_L = 0xe7 ;
    _AD_CSR = 0xe8 ;
    _AD_CR = 0xe9 ;
    
    /* end of on-chip module registers */
    
  }  > eight

  .stab 0 (NOLOAD) : {
    [ .stab ]
  }

  .stabstr 0 (NOLOAD) : {
    [ .stabstr ]
  }

} /* SECTIONS */
////////////////////
