1- Why doesn't my first example work?
The parameter is a reference to a pointer to const. &a - which is the argument - is a pointer to non-const. Pointer to const and pointer to non-const are different types. The argument could be implicitly converted to a pointer to const type. However, the result of that conversion is an rvalue - it is a temporary object. The parameter of the function is an lvalue reference to non-const, and such references cannot be bound to rvalues1.
if a regular constant can be passed like this:
In that example, you have an lvalue reference to const. Lvalue references to const can be bound to rvalues. In the case of test(a), the type of the referred object even matches with the type of the reference, so there isn't even a conversion and parameter refers directly to the passed argument.
Why isn't it doing the same in the case of passing a pointer by reference?
See 1 above
Why do I have to specify const above before int *b for it to compile?
Because the parameter is an lvalue reference to non-const pointer to const. If you don't specify const there, then you have a pointer to non-const, and thus you would need a conversion such as in the case of &a and thus the result would be an rvalue and thus the lvalue reference to non-const cannot be bound.
You could make the pointer function analogous to the integer example by using a reference to const that matches with the type of the argument:
int* a;
// analogous to your int example:
void test1(int* const& in);
test1(&a); // OK, no conversion
// now, we have a reference to non-const,
// but that's fine since there is no conversion:
void test2(int* const& in);
test2(&a); // OK, no conversion
// now there is conversion, but that's fine since
// it is an lvalue reference to const:
void test3(const int* const& in); 
test3(&a); // OK, conversion
// there's a conversion here and the reference isn't
// const but that's fine since it's an rvalue reference:
void test4(const int*&& in); 
test4(&a); // OK, conversion
Or, you could make the integer example fail by making it analogous to the pointer example by introducing a conversion and by using a reference to non-const:
long b;
// analogous to your pointer example:
void test5(int& in);
test5(b); // NOT OK
Note that whether the referred type is a pointer to const or pointer to non-const is entirely separate from the reference being a reference to const or non-const.