diff --git a/ChangeLog b/ChangeLog
index e132e78f8644eeb7ee91941f9600eb3d57be420e..799b5d4e3bb96d1379bc3e3757ff15d7981a28e8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -55,6 +55,9 @@ CVS code -
 	- Set keypad() to TRUE regardless of whether PDCurses is being
 	  used, as Meta-X apparently turns it off even under ncurses.
 	  (DLR)
+  do_backspace()
+	- Vastly simplify, and remove dependency on page_up(). (David
+	  Benbennick)
   help_init()
 	- Document the support for Esc Esc [character]'s being
 	  interpreted as Ctrl-[character], and the support for Pico's
@@ -66,6 +69,17 @@ CVS code -
 	  KEY_RESIZE, and pressing Ctrl-Z to suspend nano at the Linux
 	  console with keypad(TRUE) generates Ctrl-Z instead of
 	  KEY_SUSPEND, both unlike ncurses. (DLR)
+- move.c:
+	- Remove unneeded inclusion of stdio.h, make various cleanups,
+	  and preserve the cursor's coordinates when paging up and down.
+	  (David Benbennick)  DLR: Readd the ability to behave the old
+	  way while paging, make it so the new behavior is only used in
+	  smooth-scrolling mode, and modify page_down() to always go
+	  down a full page (even when there's less than one page of text
+	  left) for consistency.
+  page_up()
+	- Removed due to rewrite of movement functions. (David
+	  Benbennick)
 - rcfile.c:
   parse_colors()
 	- Generate an error if we try to use a bright background color
@@ -73,9 +87,15 @@ CVS code -
 	- Make sure all rcfile error messages are capitalized, for
 	  consistency. (DLR)
 - winio.c:
+  do_first_line()
+	- Call edit_update() with TOP instead of CENTER; both do the
+	  same thing, but it works faster with TOP. (DLR)
   titlebar()
 	- Fix problem with the available space for a filename on the
 	  titlebar's being short by one. (DLR)
+  edit_update()
+	- Tweak for efficiency and remove the fix_editbot() call. (David
+	  Benbennick)
   do_credits()
 	- Update the copyright years to "1999-2003", to match those
 	  given in the rest of the code. (DLR)
diff --git a/src/move.c b/src/move.c
index 994d9cb7bf341e554d49f29038b95995e79846c3..52fd5070b0a55cd43363792590624e31f6f9a89a 100644
--- a/src/move.c
+++ b/src/move.c
@@ -23,7 +23,6 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <stdio.h>
 #include <assert.h>
 #include "proto.h"
 #include "nano.h"
@@ -32,6 +31,7 @@ int do_home(void)
 {
     current_x = 0;
     placewewant = 0;
+    check_statblank();
     update_line(current, current_x);
     return 1;
 }
@@ -40,52 +40,48 @@ int do_end(void)
 {
     current_x = strlen(current->data);
     placewewant = xplustabs();
+    check_statblank();
     update_line(current, current_x);
     return 1;
 }
 
-void page_up(void)
-{
-    if (edittop != fileage) {
-#ifndef NANO_SMALL
-	if (ISSET(SMOOTHSCROLL))
-	    edit_update(edittop->prev, TOP);
-	else
-#endif
-	{
-	    edit_update(edittop, CENTER);
-	    /* Now that we've updated the edit window, edittop might be
-	       at the top of the file; if so, just move the cursor up one
-	       line and don't center it. */
-	    if (edittop != fileage)
-		center_cursor();
-	    else
-		reset_cursor();
-	}
-    } else
-	current_y = 0;
-
-    update_cursor();
-}
-
 int do_page_up(void)
 {
     int i;
 
     wrap_reset();
-    current_x = 0;
-    placewewant = 0;
 
-    if (current == fileage)
-	return 0;
-
-    current_y = 0;
-    current = edittop;
-    for (i = 0; i <= editwinrows - 3 && current->prev != NULL; i++)
-	current = current->prev;
+    /* If edittop is the first line of the file, move current up there
+     * and put the cursor at the beginning of the line. */
+    if (edittop == fileage) {
+	current = fileage;
+	placewewant = 0;
+    } else {
+	/* Move the top line of the edit window up a page. */
+	for (i = 0; i < editwinrows - 2 && edittop->prev != NULL; i++)
+	    edittop = edittop->prev;
+#ifndef NANO_SMALL
+	/* If we're in smooth scrolling mode and there was at least one
+	 * page of text left, move the current line of the edit window
+	 * up a page. */
+	if (ISSET(SMOOTHSCROLL) && current->lineno > editwinrows - 2)
+	    for (i = 0; i < editwinrows - 2; i++)
+		current = current->prev;
+	/* If we're not in smooth scrolling mode and there was at least
+	 * one page of text left, put the cursor at the beginning of the
+	 * top line of the edit window, as Pico does. */
+	else {
+#endif
+	    current = edittop;
+	    placewewant = 0;
+#ifndef NANO_SMALL
+	}
+#endif
+    }
+    /* Get the equivalent x-coordinate of the new line. */
+    current_x = actual_x(current, placewewant);
 
-    edit_update(current, TOP);
-    update_cursor();
+    edit_refresh();
 
     check_statblank();
     return 1;
@@ -93,42 +89,42 @@ int do_page_up(void)
 
 int do_page_down(void)
 {
-    wrap_reset();
-    current_x = 0;
-    placewewant = 0;
+    int i;
 
-    if (current == filebot)
-	return 0;
+    wrap_reset();
 
-    /* AHEM, if we only have a screen or less of text, DON'T do an
-       edit_update(), just move the cursor to editbot! */
-    if (edittop == fileage && editbot == filebot && totlines < editwinrows) {
-	current = editbot;
-	reset_cursor();
+    /* If the last line of the file is onscreen, move current down
+     * there and put the cursor at the beginning of the line. */
+    if (edittop->lineno + editwinrows > filebot->lineno) {
+	current = filebot;
+	placewewant = 0;
+    } else {
+	/* Move the top line of the edit window down a page. */
+	for (i = 0; i < editwinrows - 2; i++)
+	    edittop = edittop->next;
 #ifndef NANO_SMALL
-	/* ...unless marking is on, in which case we need it to update
-	   the highlight. */
-	if (ISSET(MARK_ISSET))
-	    edit_update(current, NONE);
+	/* If we're in smooth scrolling mode and there was at least one
+	 * page of text left, move the current line of the edit window
+	 * down a page. */
+	if (ISSET(SMOOTHSCROLL) && current->lineno + editwinrows - 2 <= filebot->lineno)
+	    for (i = 0; i < editwinrows - 2; i++)
+		current = current->next;
+	/* If we're not in smooth scrolling mode and there was at least
+	 * one page of text left, put the cursor at the beginning of the
+	 * top line of the edit window, as Pico does. */
+	else {
 #endif
-    } else if (editbot != filebot || edittop == fileage) {
-	current_y = 0;
-	current = editbot;
-
-	if (current->prev != NULL)
-	    current = current->prev;
-	if (current->prev != NULL)
-	    current = current->prev;
-	edit_update(current, TOP);
-    } else {
-	while (current != filebot) {
-	    current = current->next;
-	    current_y++;
+	    current = edittop;
+	    placewewant = 0;
+#ifndef NANO_SMALL
 	}
-	edit_update(edittop, TOP);
+#endif
     }
+    /* Get the equivalent x-coordinate of the new line. */
+    current_x = actual_x(current, placewewant);
+
+    edit_refresh();
 
-    update_cursor();
     check_statblank();
     return 1;
 }
@@ -136,19 +132,26 @@ int do_page_down(void)
 int do_up(void)
 {
     wrap_reset();
-    if (current->prev != NULL) {
-	current_x = actual_x(current->prev, placewewant);
-	current = current->prev;
-	if (current_y > 0) {
-	    update_line(current->next, 0);
-		/* It is necessary to change current first, so the mark
-		   display will change! */
-	    current_y--;
-	    update_line(current, current_x);
-	} else
-	    page_up();
-	check_statblank();
-    }
+    check_statblank();
+
+    if (current->prev == NULL)
+	return 0;
+
+    assert(current_y == current->lineno - edittop->lineno);
+    current = current->prev;
+    current_x = actual_x(current, placewewant);
+    if (current_y > 0) {
+	update_line(current->next, 0);
+	    /* It was necessary to change current first, so the mark
+	     * display will change! */
+	update_line(current, current_x);
+    } else
+#ifndef NANO_SMALL
+    if (ISSET(SMOOTHSCROLL))
+	edit_update(current, TOP);
+    else
+#endif
+	edit_update(current, CENTER);
     return 1;
 }
 
@@ -162,32 +165,24 @@ int do_down(void)
     if (current->next == NULL)
 	return 0;
 
+    assert(current_y == current->lineno - edittop->lineno);
     current = current->next;
     current_x = actual_x(current, placewewant);
 
-    /* Note current_y is zero-based.  This test checks for the cursor's
-     * being on the last row of the edit window. */
-    if (current_y == editwinrows - 1) {
-#ifndef NANO_SMALL
-	if (ISSET(SMOOTHSCROLL)) {
-	    /* In this case current_y does not change.  The cursor
-	     * remains at the bottom of the edit window. */
-	    edittop = edittop->next;
-	    editbot = editbot->next;
-	    edit_refresh();
-	} else
-#endif
-	{
-	    /* Set edittop so editbot->next (or else editbot) is
-	     * centered, and set current_y = editwinrows / 2. */
-	    edit_update(editbot->next != NULL ? editbot->next : editbot, CENTER);
-	    center_cursor();
-	}
-    } else {
+    /* Note that current_y is zero-based.  This test checks for the
+     * cursor's being not on the last row of the edit window. */
+    if (current_y != editwinrows - 1) {
 	update_line(current->prev, 0);
 	update_line(current, current_x);
-	current_y++;
-    }
+    } else
+#ifndef NANO_SMALL
+    if (ISSET(SMOOTHSCROLL))
+	/* In this case current_y does not change.  The cursor remains
+	 * at the bottom of the edit window. */
+	edit_update(edittop->next, TOP);
+    else
+#endif
+	edit_update(current, CENTER);
     return 1;
 }
 
@@ -200,8 +195,8 @@ int do_left(void)
 	current_x = strlen(current->data);
     }
     placewewant = xplustabs();
-    update_line(current, current_x);
     check_statblank();
+    update_line(current, current_x);
     return 1;
 }
 
@@ -216,7 +211,7 @@ int do_right(void)
 	current_x = 0;
     }
     placewewant = xplustabs();
-    update_line(current, current_x);
     check_statblank();
+    update_line(current, current_x);
     return 1;
 }
diff --git a/src/nano.c b/src/nano.c
index 0a5e60780a307c0606752d9267e546a76c46e338..3d3682905aae462235eeab9e47cdedabf4c1990c 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -1018,82 +1018,10 @@ void do_char(char ch)
 
 int do_backspace(void)
 {
-    int refresh = 0;
-    if (current_x > 0) {
-	assert(current_x <= strlen(current->data));
-	/* Let's get dangerous */
-	memmove(&current->data[current_x - 1], &current->data[current_x],
-		strlen(current->data) - current_x + 1);
-#ifdef DEBUG
-	fprintf(stderr, "current->data now = \"%s\"\n", current->data);
-#endif
-	align(&current->data);
-#ifndef NANO_SMALL
-	if (current_x <= mark_beginx && mark_beginbuf == current)
-	    mark_beginx--;
-#endif
+    if (current != fileage || current_x > 0) {
 	do_left();
-#ifdef ENABLE_COLOR
-	refresh = 1;
-#endif
-    } else {
-	filestruct *previous;
-	const filestruct *tmp;
-
-	if (current == fileage)
-	    return 0;		/* Can't delete past top of file */
-
-	previous = current->prev;
-	current_x = strlen(previous->data);
-	placewewant = strlenpt(previous->data);
-#ifndef NANO_SMALL
-	if (current == mark_beginbuf) {
-	    mark_beginx += current_x;
-	    mark_beginbuf = previous;
-	}
-#endif
-	previous->data = charealloc(previous->data,
-				  current_x + strlen(current->data) + 1);
-	strcpy(previous->data + current_x, current->data);
-
-	unlink_node(current);
-	delete_node(current);
-	tmp = current;
-	current = (previous->next ? previous->next : previous);
-	renumber(current);
-	    /* We had to renumber before doing update_line. */
-	if (tmp == edittop)
-	    page_up();
-
-	/* Ooops, sanity check */
-	if (tmp == filebot) {
-	    filebot = current;
-	    editbot = current;
-
-	    /* Recreate the magic line if we're deleting it AND if the
-	       line we're on now is NOT blank.  if it is blank we
-	       can just use IT for the magic line.   This is how Pico
-	       appears to do it, in any case. */
-	    if (current->data[0] != '\0') {
-		new_magicline();
-		fix_editbot();
-	    }
-	}
-
-	current = previous;
-	if (current_y > 0)
-	    current_y--;
-	totlines--;
-#ifdef DEBUG
-	fprintf(stderr, "After, data = \"%s\"\n", current->data);
-#endif
-	refresh = 1;
+	do_delete();
     }
-
-    totsize--;
-    set_modified();
-    if (refresh)
-	edit_refresh();
     return 1;
 }
 
diff --git a/src/nano.h b/src/nano.h
index 43dc466ba205c52a07d7dba86ad2af8a7556f8c9..be6c0e9327ea47fa0235d382363c753c638b5674 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -29,7 +29,7 @@
 /* Macros for the flags int... */
 #define SET(bit) flags |= bit
 #define UNSET(bit) flags &= ~bit
-#define ISSET(bit) (flags & bit)
+#define ISSET(bit) ((flags & bit) != 0)
 #define TOGGLE(bit) flags ^= bit
 
 /* Define charalloc as a macro rather than duplicating code */
diff --git a/src/proto.h b/src/proto.h
index a341abbdec009a290422b831e83b6d41294fb321..7ba235c7a61bb710d90a125bdd805ecc0bf8666b 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -221,7 +221,6 @@ void thanks_for_all_the_fish(void);
 /* Public functions in move.c */
 int do_home(void);
 int do_end(void);
-void page_up(void);
 int do_page_up(void);
 int do_page_down(void);
 int do_up(void);
diff --git a/src/winio.c b/src/winio.c
index e88d1c13f51524e9a230a71bb891dd7d25b51e35..44583401437772229a0010b43351db4ae9e77440 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -322,7 +322,7 @@ int do_first_line(void)
     current = fileage;
     placewewant = 0;
     current_x = 0;
-    edit_update(current, CENTER);
+    edit_update(current, TOP);
     return 1;
 }
 
@@ -1387,14 +1387,12 @@ void edit_update(filestruct *fileptr, topmidbotnone location)
 	return;
 
     if (location != TOP) {
-	int goal = location == NONE ? current_y - 1 : editwinrows / 2;
+	int goal = location == NONE ? current_y : editwinrows / 2;
 
-	for (; goal >= 0 && fileptr->prev != NULL; goal--)
+	for (; goal > 0 && fileptr->prev != NULL; goal--)
 	    fileptr = fileptr->prev;
     }
     edittop = fileptr;
-    fix_editbot();
-
     edit_refresh();
 }