wok annotate linld/stuff/src/A20.ASM @ rev 21984

linld: x86 support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Mon Oct 14 11:20:06 2019 +0200 (2019-10-14)
parents d8f824013cf6
children a0dccc5d133d
rev   line source
pascal@19515 1 ;***************************************************************
pascal@19515 2 ;****** This file is distributed under GPL
pascal@19515 3 ;***************************************************************
pascal@19515 4 ideal
pascal@21984 5 %PAGESIZE 1000
pascal@19515 6 %crefref
pascal@19515 7 %noincl
pascal@19515 8 %nomacs
pascal@19636 9 p8086
pascal@19515 10
pascal@19515 11 group DGROUP _TEXT,_DATA
pascal@19515 12 assume cs:DGROUP,ds:DGROUP
pascal@19515 13
pascal@19515 14 segment _DATA byte public use16 'DATA'
pascal@19515 15
pascal@19515 16 global die:near
pascal@19515 17 enable_a20_methods:
pascal@19515 18 dw _enable_a20_fast, _enable_a20_kbd, _enable_a20_xmm, die
pascal@19580 19 msg_a20 db "Can't use A20",0
pascal@21757 20 overflow db "Loaded too close to 9000:0",0
pascal@21758 21 global sssp:dword
pascal@21758 22 global _initrd_desc:dword
pascal@21758 23 _initrd_desc dd 90000218h
pascal@21758 24 org $-4
pascal@21758 25 sssp dd ?
pascal@19515 26
pascal@19515 27 ends _DATA
pascal@19515 28
pascal@19515 29 segment _TEXT byte public use16 'CODE'
pascal@19515 30
pascal@19515 31 global xmm_driver:near
pascal@19515 32 global _enable_a20_xmm:near
pascal@19515 33
pascal@19515 34 ;***************************************************************
pascal@19515 35 ;void enable_a20_kbd();
pascal@19515 36 ;***************************************************************
pascal@19515 37 proc _enable_a20_kbd near
pascal@19515 38
pascal@19515 39 call @@empty_8042
pascal@19515 40 mov al,0D1h ; command write
pascal@19515 41 out 64h,al
pascal@19515 42 call @@empty_8042
pascal@19515 43 mov al,0DFh ; A20 on
pascal@19515 44 out 60h,al
pascal@19515 45
pascal@19515 46 ; This routine checks that the keyboard command queue is empty
pascal@19515 47 ; (after emptying the output buffers)
pascal@19515 48 ; Some machines have delusions that the keyboard buffer is always full
pascal@19515 49 ; with no keyboard attached...
pascal@19515 50 ; If there is no keyboard controller, we will usually get 0xff
pascal@19515 51 ; to all the reads. With each IO taking a microsecond and
pascal@19515 52 ; a timeout of 100,000 iterations, this can take about half a
pascal@19515 53 ; second ("delay" == out to port 0x80). That should be ok,
pascal@19515 54 ; and should also be plenty of time for a real keyboard controller
pascal@19515 55 ; to empty.
pascal@19515 56
pascal@19515 57 @@empty_8042:
pascal@19515 58 xor cx,cx ; 64K iterations
pascal@19515 59 @@loop:
pascal@19515 60 call @@delay ; 8042 status port
pascal@19580 61 in al,64h
pascal@19580 62 test al,3 ; is output or input full?
pascal@19580 63 jz @@break ; no - break loop
pascal@19515 64 test al,1 ;
pascal@19515 65 jz @@no_output
pascal@19515 66 call @@delay ; yes: read it
pascal@19515 67 in al,60h ;
pascal@19515 68 @@no_output:
pascal@19515 69 loop @@loop
pascal@19515 70 @@break:
pascal@19515 71 ret
pascal@19515 72
pascal@19515 73 @@delay: out 80h,al
pascal@19515 74 ret
pascal@19515 75
pascal@19515 76 endp _enable_a20_kbd
pascal@19515 77
pascal@19515 78 ;***************************************************************
pascal@19515 79 ;void enable_a20_fast();
pascal@19515 80 ;***************************************************************
pascal@19515 81 proc _enable_a20_fast near
pascal@19515 82
pascal@19515 83 ; You must preserve the other bits here. Otherwise embarrasing things
pascal@19515 84 ; like laptops powering off on boot happen. Corrected version by Kira
pascal@19515 85 ; Brown from Linux 2.2
pascal@19515 86 in al,92h ;
pascal@19515 87 or al,02h ; "fast A20" version
pascal@19515 88 out 92h,al ; some chips have only this
pascal@19515 89 ret
pascal@19515 90
pascal@19515 91 endp _enable_a20_fast
pascal@19515 92
pascal@19515 93 ;***************************************************************
pascal@21757 94 ;_fastcall void moverm(bx:struct himem *m);
pascal@21757 95 ;***************************************************************
pascal@21757 96
pascal@21757 97 global @moverm$qp11image_himem:near
pascal@21757 98 @moverm$qp11image_himem:
pascal@21757 99 push si di
pascal@21757 100 extrn _heap_top:word
pascal@21757 101 ifdef NO386
pascal@21757 102 extrn _topseg:near
pascal@21757 103 call near _topseg
pascal@21757 104 mov cl,4
pascal@21757 105 mov [word sssp+2],ax
pascal@21757 106 xchg ax,dx
pascal@21757 107 mov ax,[_heap_top]
pascal@21757 108 shr ax,cl
pascal@21757 109 else
pascal@21757 110 p386
pascal@21757 111 mov ax,[_heap_top]
pascal@21757 112 shr ax,4
pascal@21757 113 mov dx,9000h
pascal@21757 114 endif
pascal@21757 115 mov es,dx
pascal@21757 116 mov cx,cs
pascal@21757 117 add ax,cx
pascal@21757 118 cmp ax,dx
pascal@21757 119 jb @@nooverflow
pascal@21757 120 ; Oops! We can stomp on our toes... better stop now
pascal@21757 121 mov bx,offset overflow
pascal@21757 122 call near die
pascal@21757 123 @@nooverflow:
pascal@21757 124 mov cx,[bx-5] ; size
pascal@21757 125 mov si,[bx-2] ; data
pascal@21757 126 xor di,di
pascal@21757 127 rep
pascal@21757 128 movsb
pascal@21757 129 ;push ds
pascal@21757 130 ;pop es
pascal@21757 131 ;pop di si
pascal@21757 132 pop di
pascal@21757 133
pascal@21757 134 ;***************************************************************
pascal@19580 135 ;void enable_a20_or_die();
pascal@19580 136 ;***************************************************************
pascal@19580 137 proc _enable_a20_or_die near
pascal@19580 138
pascal@21757 139 ;push si
pascal@19580 140 mov si,offset enable_a20_methods
pascal@19580 141 jmp @@check
pascal@19580 142 @@loop:
pascal@19580 143 lodsw
pascal@19580 144 mov bx,offset msg_a20
pascal@19580 145 call ax
pascal@19580 146 @@check:
pascal@19580 147 ;call _check_a20
pascal@19580 148 ;***************************************************************
pascal@19515 149 ;int check_a20();
pascal@19515 150 ;***************************************************************
pascal@19580 151 ;proc _check_a20 near
pascal@19515 152
pascal@19515 153 ; From linux kernel setup.S:
pascal@19515 154 ; wait until a20 really *is* enabled; it can take a fair amount of
pascal@19515 155 ; time on certain systems; Toshiba Tecras are known to have this
pascal@19515 156 ; problem.
pascal@19515 157
pascal@21757 158 push ds
pascal@19515 159 xor bx,bx
pascal@19515 160 mov ds,bx
pascal@19515 161 mov cx,0FFFFh
pascal@19515 162 mov es,cx
pascal@19515 163 a20lp:
pascal@19515 164 cli
pascal@19515 165 mov ax,0AA55h
pascal@19515 166 xchg al,[bx]
pascal@19515 167 xchg ah,[es:bx+10h]
pascal@19515 168 xchg al,[bx]
pascal@19515 169 xchg ah,[es:bx+10h]
pascal@19515 170 cmp al,55h
pascal@19515 171 sti
pascal@19515 172 a20ko:
pascal@19515 173 loopne a20lp
pascal@21757 174 ;xchg ax,cx
pascal@21757 175 pop ds
pascal@19580 176 ;ret
pascal@19515 177
pascal@19580 178 ;endp _check_a20
pascal@19515 179
pascal@19515 180 jne @@loop
pascal@21757 181 ;push ds
pascal@21757 182 ;pop es
pascal@19515 183 pop si
pascal@19515 184 ret
pascal@19515 185
pascal@19515 186 endp _enable_a20_or_die
pascal@19515 187
pascal@19515 188 ends _TEXT
pascal@19515 189
pascal@19515 190 end
pascal@19515 191
pascal@19515 192 ;###### END OF FILE ############################################