I believe I have solved my own problem.

(I am CC'ing [EMAIL PROTECTED] for complete archives, but please
direct additional followups to freedos-devel since this is definitely
not a SYSLINUX problem.)

I have been experimenting with my own himem sources.  I applied the
following patch to himem64.asm:

======================================================================
--- himem64.asm 2004/01/27 20:42:43     1.1
+++ himem64.asm 2004/01/27 21:25:00     1.2
@@ -276,6 +276,8 @@
                             ; has to be requested
 a20_locks   dw  0           ; internal A20 lock count
 
+a20state    db  ?           ;  keeps A20 state across INT15h call
+
 xms_handle_start dw normal_driver_end
 
 
@@ -361,14 +363,27 @@
 proc enable_a20
        push ax
        mov  ah,2
-       jmp short disable_enable_a20
+       call disable_enable_a20
+        pop ax
+        ret
 
 disable_a20:
        push ax
        mov  ah,0
+       call disable_enable_a20
+        push cx
+        mov cx,32
+@@delayloop:
+        call test_a20
+        jz @@disabled
+        loop @@delayloop
+@@disabled:
+        pop cx
+        pop ax
+        ret
 
 disable_enable_a20:
-
+     push ax
      mov al,0d1h
      out 64h,al
      call delay
@@ -491,10 +506,35 @@
 ;
 
 proc    int15_handler
+    cmp ah,87h
+    je do_move
     cmp ah,88h              ; is it a ext. mem size req.?
     je  ext_mem_size
     jmp [cs:old_int15]          ; jump to old handler
 
+do_move:
+       call    test_a20                        ; check if A20 is on or off
+       jz      @@a20disabled
+       mov     [cs:a20state],1                 ; preserve state
+       jmp     @@call_old_mover
+@@a20disabled:
+       mov     [cs:a20state],0
+@@call_old_mover:
+       pushf                                   ; simulate INT call
+       call    [cs:old_int15]
+       pushf                                   ; save flags for return
+       push    ax
+       cmp     [cs:a20state],0                 ; see if A20 has to be switched
+       jz      @@disable_it
+       call    enable_a20
+       jmp     @@move_done
+@@disable_it:
+       call    disable_a20
+@@move_done:
+       pop     ax
+       popf
+       iret
+        
 ext_mem_size:
     xor ax,ax               ; no memory available
     clc                 ; no error

======================================================================

This patch does two things.

First, I stole the "save/restore A20 on INT15/AH=87" logic from FDXMS.
Judging by the comments at the top of himem64.asm, this logic used to
exist in himem64.exe as well; it is not clear why it was removed.
With this change, my "instant" crashes on the Thinkpad T20 went away!
But it still crashed somewhat later while running commands from
autoexec.bat.

Second, I stole the "delay on A20 disable" logic from memdisk.  This
made all of the crashes stop!  That is, it resulted in a himem64.exe
which works the same when invoked from PXELINUX+memdisk (with
DOS=HIGH) as it does from a floppy (or without DOS=HIGH).

Unfortunately, on my Thinkpad T20, the keyboard still locks up pretty
quickly in all of these scenarios.

The following additional patch fixes everything on my T20:

======================================================================
--- himem64.asm 2004/01/27 21:25:00     1.2
+++ himem64.asm 2004/01/27 21:37:33
@@ -362,15 +362,24 @@
 
 proc enable_a20
        push ax
-       mov  ah,2
-       call disable_enable_a20
+        mov ax,2401h
+        pushf
+        int 15h
+        popf
+        
+;      mov  ah,2
+;      call disable_enable_a20
         pop ax
         ret
 
 disable_a20:
        push ax
-       mov  ah,0
-       call disable_enable_a20
+        mov ax,2400h
+        pushf
+        int 15h
+        popf        
+;      mov  ah,0
+;      call disable_enable_a20
         push cx
         mov cx,32
 @@delayloop:
======================================================================

This patch uses the BIOS (INT15/AX=2400 and 2401) interface to
enable/disable A20.  With this additional patch, everything works
flawlessly on my T20.

...but it breaks on my Optiplex GX200, presumably because its BIOS
does not support INT15/AX=2400.

The ultimate solution, in my opinion, is to steal all of the logic
from memdisk (init32.asm) for doing A20 switching.  The logic goes:

  1) See if there is no A20 gate; if so, use NOOP to disable/enable
     A20

  2) See if the BIOS interface works (INT15/AX=2401); if so, use that.

  3) See if the keyboard controller mechanism works (this is the
     mechanism himem64.exe currently uses always); if so, use that.

  4) See if the "fast A20 gate" mechanism works; if so, use that.

  5) Retry steps 1-4 255 times...

  6) ...if that does not work, bomb out.

I believe himem64.exe would support the widest variety of systems if
it incorporated all of this logic.  But steps (2) and (3) are
mandatory for me.  I believe the BIOS interface is superior to using
PS/2 switching, since according to Ralf Brown's Interrupt List later
PS/2s support the BIOS interface anyway.

I am willing to write the code to support all this if the himem
maintainer(s) are amenable to accepting patches.  Although you will
probably want to clean up my assembly first :-).

Comments?

 - Pat

_______________________________________________
SYSLINUX mailing list
Submissions to [EMAIL PROTECTED]
Unsubscribe or set options at:
http://www.zytor.com/mailman/listinfo/syslinux
Please do not send private replies to mailing list traffic.



-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
Freedos-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/freedos-devel

Reply via email to