--- orig/lisp/text-modes/hexl.el
+++ mod/lisp/text-modes/hexl.el
@@ -354,18 +354,36 @@
 	       (/ (- current-column  (/ current-column 5)) 2))))
     hexl-address))
 
+(defun hexl-hex-position (address)
+  "Return the ascii-position."
+  (+ (* (/ address 16) 68)
+     11
+     (* 2 (% address 16))
+     (/ (% address 16) 2)))
+
+(defun hexl-ascii-position (address)
+  "Return the ascii-position."
+  (+ (* (/ address 16) 68) 52 (% address 16)))
+
+(defun hexl-at-ascii-position (address)
+  "Return t if point is at ascii position."
+  (= (point) (hexl-ascii-position address)))
+
 (defun hexl-address-to-marker (address)
   "Return buffer position for ADDRESS."
   (interactive "nAddress: ")
   (+ (* (/ address 16) 68) 11 (/ (* (% address 16) 5) 2)))
 
-(defun hexl-goto-address (address)
+(defun hexl-goto-address (address &optional nipple)
   "Go to hexl-mode (decimal) address ADDRESS.
 Signal error if ADDRESS out of range."
   (interactive "nAddress: ")
   (if (or (< address 0) (> address hexl-max-address))
-	  (error "Out of hexl region"))
-  (goto-char (hexl-address-to-marker address)))
+      (error "Out of hexl region."))
+  (goto-char
+   (if (hexl-at-ascii-position (hexl-current-address))
+       (hexl-ascii-position address)
+     (+ (hexl-address-to-marker address) (or nipple 0)))))
 
 (defun hexl-goto-hex-address (hex-address)
   "Go to hexl-mode address (hex string) HEX-ADDRESS.
@@ -399,12 +417,22 @@
 (defun hexl-backward-char (arg)
   "Move to left ARG bytes (right if ARG negative) in hexl-mode."
   (interactive "p")
-  (hexl-goto-address (- (hexl-current-address) arg)))
+  (let ((col (current-column)))
+    (if (< col 50)
+        (if (member (% col 5) '(0 2))
+            (hexl-goto-address (- (hexl-current-address) arg) 1)
+          (hexl-goto-address (hexl-current-address) 0))
+      (hexl-goto-address (- (hexl-current-address) arg) col))))
 
 (defun hexl-forward-char (arg)
   "Move right ARG bytes (left if ARG negative) in hexl-mode."
   (interactive "p")
-  (hexl-goto-address (+ (hexl-current-address) arg)))
+  (let ((col (current-column)))
+    (if (< col 50)
+        (if (member (% col 5) '(0 2))
+            (hexl-goto-address (hexl-current-address) 1)
+          (hexl-goto-address (+ (hexl-current-address) arg) 0))
+      (hexl-goto-address (+ (hexl-current-address) arg) col))))
 
 (defun hexl-backward-short (arg)
   "Move to left ARG shorts (right if ARG negative) in hexl-mode."
@@ -527,7 +555,8 @@
 (defun hexl-beginning-of-line ()
   "Goto beginning of line in hexl mode."
   (interactive)
-  (goto-char (+ (* (/ (point) 68) 68) 11)))
+  (let ((address (hexl-current-address)))
+    (hexl-goto-address (- address (% address 16)))))
 
 (defun hexl-end-of-line ()
   "Goto end of line in hexl mode."
@@ -537,6 +566,15 @@
 			   (setq address hexl-max-address))
 		       address)))
 
+(defun hexl-switch-position ()
+  "Switch cursor from ASCII to HEX position or vice versa."
+  (interactive)
+  (goto-char
+   (let ((address (hexl-current-address)))
+     (if (hexl-at-ascii-position address)
+	 (hexl-address-to-marker address)
+       (hexl-ascii-position address)))))
+
 (defun hexl-scroll-down (arg)
   "Scroll hexl buffer window upward ARG lines; or near full window if no ARG."
   (interactive "P")
@@ -680,36 +718,43 @@
 (defun hexl-self-insert-command (arg)
   "Insert this character."
   (interactive "p")
-  (hexl-insert-char last-command-char arg))
+  (let ((col (current-column)))
+    (if (and (>= col 10) ( <= col 48))
+        (let ((point (point))
+              (pos (% col 5)))
+          (if (member pos '(1 3))
+              (hexl-insert-char
+               (hexl-hex-string-to-integer
+                (concat (buffer-substring (- point 1) point)
+                        (char-to-string last-command-char)))
+               arg)
+            (hexl-insert-char
+             (hexl-hex-string-to-integer
+              (concat (char-to-string last-command-char)
+                      (buffer-substring (+ point 1) (+ point 2))))
+             arg)
+            (goto-char (1+ point))))
+      (if (not last-command-char)
+	  (setq last-command-char
+		(event-to-character last-input-event t t t)))
+      (hexl-insert-char last-command-char arg))))
 
 (defun hexl-insert-char (ch num)
   "Insert a character in a hexl buffer."
   (let ((address (hexl-current-address t)))
     (while (> num 0)
-      (let ((hex-position
-	     (+ (* (/ address 16) 68)
-		11
-		(* 2 (% address 16))
-		(/ (% address 16) 2)))
-	    (ascii-position
-	     (+ (* (/ address 16) 68) 52 (% address 16)))
-	    at-ascii-position)
-	(if (= (point) ascii-position)
-	    (setq at-ascii-position t))
-	(goto-char hex-position)
-	(delete-char 2)
-	(insert (format "%02x" ch))
-	(goto-char ascii-position)
-	(delete-char 1)
-	(insert (hexl-printable-character ch))
-	(or (eq address hexl-max-address)
-	    (setq address (1+ address)))
-	(hexl-goto-address address)
-	(if at-ascii-position
-	    (progn
-	      (beginning-of-line)
-	      (forward-char 51)
-	      (forward-char (% address 16)))))
+      (let* ((hex-position (hexl-hex-position address))
+	     (ascii-position (hexl-ascii-position address)))
+	(save-excursion
+	  (goto-char hex-position)
+	  (delete-char 2)
+	  (insert (format "%02x" ch))
+	  (goto-char ascii-position)
+	  (delete-char 1)
+	  (insert (hexl-printable-character ch))
+	  (or (eq address hexl-max-address)
+	      (setq address (1+ address))))
+	(hexl-goto-address address))
       (setq num (1- num)))))
 
 ;; hex conversion
@@ -891,7 +936,9 @@
   (define-key hexl-mode-map "\C-x]" 'hexl-end-of-1k-page)
   (define-key hexl-mode-map "\C-x\C-p" 'undefined)
   (define-key hexl-mode-map "\C-x\C-s" 'hexl-save-buffer)
-  (define-key hexl-mode-map "\C-x\C-t" 'undefined))
+  (define-key hexl-mode-map "\C-x\C-t" 'undefined)
+
+  (define-key hexl-mode-map [tab] 'hexl-switch-position))
 
 (provide 'hexl)
 
