#include <16f84>
#include <16f84>

area D0`1,	MyByte := 47;		// or D0.0`8 or just D0

/*
   This is equivalent to:
   area D0`1, MyByte;
   init MyByte = 47;
   /* nested /* foo */ comment */
   the first line could also be:
   enum MyByte = D0`1;
*/

area D1.1`3,	My3bits := 2;
area D1.3`1,	My1bit;
area D2`5,	My5bytes := "foo";		// the rest is undefined
area My3bits[2],foo,bar,foo2;

area D8.0`4,	blah := "12345";
//area D1.0`4,	nibble;

// setup config (could also have been done in the area defs)
init WDTE := 1, FOSC := FOSC_RC;
init CP  := -1;

init My1bit := 1;		// again, like doing it in the area def

// define a temp area
area R0x0c`0x20, temp;		// 32 bytes

alloc temp, { bytesomewhere=byte };	// get 1 byte from temp

// some 1-bit areas
area PORTA.0, led1;
area PORTA.1, led2;

code boot(base = P0)		// fixed address
{
  movwl	0xff;
  movwf	PORTA;			// turn off all outputs
  bsf	RP[0];			// select bank 1
  movwl	~(*led1 | *led2);	// LEDs are outputs
  movwf	TRISA;
  bcf	RP[0];			// bank 0
  {
    movlw *led1;
    xorwf PORTA,f;		// toggle led1
    clrw;
    call delay;			// delay 256
    clrw;
    call delay;			// delay 256
    movlw *led1 | *led2;
    xorwf PORTA,f;		// toggle both leds
    clrw;
    call delay;			// delay 256
    goto begin;
  }
  goto swamp;
}

code delay			// movable
{
  alloc temp, { i=byte, j=byte };

  movwf i;
  clrf j;
  goto begin;
  {
    freow:
    goto end;
    nop;
    nop;
    blah:
    incfsz j,f;
    goto begin;
    decfsz i,f;
    goto begin;
    def Z=1;
    foreach (bar = "foo*") {
      nop;
      def baz;
      foreach (baz = "foo*") {
        print "bar=", bar, " baz=", baz;
      }
      movwl $@bar;
      nop;
//      print Z;
      Z=Z+1;
    }
    print "Z=", Z;
    if (def("freow")) {
      nop;
      foo:
      nop;
    } else {
      foo:
      nop;
    }
  }
  add(R3,R4);
  every "add*", (R3,R4);
  return;
//  warning "this is annoying: ", begin;
  every "scr*", ();
}

option\warning\as = false;

code moof			// movable
{
  switch (bits(led2)) {
    case 1 {
      nop;
      nop;
    }
    case 2 {
      nop;
    }
    default {
      nop;
      nop;
      nop;
    }
  }
  nop;

  def X;
  for (X=1; X<10; X+=2) {
//    print X;
    movlw D3;
    bah:
    movlw X;
    goto bah;
  }
  movlw --X;
  add(R3,R4);
  nop;
}

code swamp(optional)		// movable, removable
{
  nop;
  movlw 0x88;
}

code bleh(nowrap=256)		// movable
{
  nop; nop; nop; nop;
}

code scringe(base = P30)	// fixed
{
  nop;
  nop;
  swish:
  nop;
}


macro add(a,b) {
  movf a,w;
  foo:
  addwf b,f;
  goto foo;
  print "add";
}

macro add2(a,b) {
  movwl bytes(a);
  print "add2";
}


// a.b`c;
//
// Operation		Integer result
// $foo			a
// &foo			b
// sizeof(foo)		c
// *foo			(((1<<c)-1)<<b) (area bit mask)

warning "2+2=", 2+2;

