There's a few points that my be letting you down, I'll try and cover them all below.
The first is that in your first while loop when checking vertical position, you'll want to change:
while(place_meeting(x, y-sign(vsp), o_wall))
to
while(place_meeting(x, y+sign(vsp), o_wall))
Bye checking y-sign(vsp)
you're actually checking the position behind the ball in the y axis.
The second thing that will certainly be causing some weird behaviour are the two lines of code inside of your while loops, both for the X and Y axis. You'll want to change them to:
y += sign(vsp);
and x += sign(hsp);
The code you've written at the moment will be flipping the balls position between its actual value and the same value but negative - depending upon the value of vsp and hsp. Swapping your code out for the code above will cause the ball to move closer to the surface it was going to collide with until it can be no closer which, I'm assuming, is the intended behaviour.
Those are the only things I can see that may be hindering the Ball's behaviour.
Just to note though, you can replace y = y + vsp;
and x = x + hsp;
with their shorthand versions y += vsp;
and x += hsp;
.
Hope this helps!