File: ldlinux.lst

package info (click to toggle)
syslinux 1.66-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 1,192 kB
  • ctags: 2,528
  • sloc: asm: 11,376; ansic: 1,505; perl: 487; makefile: 248; pascal: 126; sh: 6
file content (4556 lines) | stat: -rw-r--r-- 295,462 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
     1                                  ; -*- fundamental -*- (asm-mode sucks)
     2                                  ; $Id: ldlinux.asm,v 1.100 2001/12/10 09:03:27 hpa Exp $
     3                                  ; ****************************************************************************
     4                                  ;
     5                                  ;  ldlinux.asm
     6                                  ;
     7                                  ;  A program to boot Linux kernels off an MS-DOS formatted floppy disk.	 This
     8                                  ;  functionality is good to have for installation floppies, where it may
     9                                  ;  be hard to find a functional Linux system to run LILO off.
    10                                  ;
    11                                  ;  This program allows manipulation of the disk to take place entirely
    12                                  ;  from MS-LOSS, and can be especially useful in conjunction with the
    13                                  ;  umsdos filesystem.
    14                                  ;
    15                                  ;  This file is loaded in stages; first the boot sector at offset 7C00h,
    16                                  ;  then the first sector (cluster, really, but we can only assume 1 sector)
    17                                  ;  of LDLINUX.SYS at 7E00h and finally the remainder of LDLINUX.SYS at 8000h.
    18                                  ;
    19                                  ;   Copyright (C) 1994-2002  H. Peter Anvin
    20                                  ;
    21                                  ;  This program is free software; you can redistribute it and/or modify
    22                                  ;  it under the terms of the GNU General Public License as published by
    23                                  ;  the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
    24                                  ;  USA; either version 2 of the License, or (at your option) any later
    25                                  ;  version; incorporated herein by reference.
    26                                  ; 
    27                                  ; ****************************************************************************
    28                                  
    29                                  ;
    30                                  ; Some semi-configurable constants... change on your own risk.  Most are imposed
    31                                  ; by the kernel.
    32                                  ;
    33                                  max_cmd_len	equ 255			; Must be odd; 255 is the kernel limit
    34                                  retry_count	equ 6			; How patient are we with the disk?
    35                                  HIGHMEM_MAX	equ 037FFFFFFh		; DEFAULT highest address for an initrd
    36                                  DEFAULT_BAUD	equ 9600		; Default baud rate for serial port
    37                                  BAUD_DIVISOR	equ 115200		; Serial port parameter
    38                                  ;
    39                                  ; Should be updated with every release to avoid bootsector/SYS file mismatch
    40                                  ;
    41                                  %define	version_str	VERSION		; Must be 4 characters long!
    42                                  %define date		DATE_STR	; Defined from the Makefile
    43                                  %define	year		'2002'
    44                                  ;
    45                                  ; Debgging stuff
    46                                  ;
    47                                  ; %define debug 1			; Uncomment to enable debugging
    48                                  ;
    49                                  ; ID for SYSLINUX (reported to kernel)
    50                                  ;
    51                                  syslinux_id	equ 031h		; SYSLINUX (3) version 1.x (1)
    52                                  ;
    53                                  ; Segments used by Linux
    54                                  ;
    55                                  ; Note: the real_mode_seg is supposed to be 9000h, but some device drivers
    56                                  ; hog some of high memory.  Therefore, we load it at 7000:0000h and copy
    57                                  ; it before starting the Linux kernel.
    58                                  ;
    59                                  real_mode_seg	equ 7000h
    60                                  fake_setup_seg	equ real_mode_seg+020h
    61                                  
    62                                  		struc real_mode_seg_t
    63 00000000 <res 00000020>          		resb 20h-($-$$)		; org 20h
    64 00000020 <res 00000002>          kern_cmd_magic	resw 1			; 0020 Magic # for command line
    65 00000022 <res 00000002>          kern_cmd_offset resw 1			; 0022 Offset for kernel command line
    66 00000024 <res 000001CD>          		resb 497-($-$$)		; org 497d
    67 000001F1 <res 00000001>          bs_setupsecs	resb 1			; 01F1 Sectors for setup code (0 -> 4)
    68 000001F2 <res 00000002>          bs_rootflags	resw 1			; 01F2 Root readonly flag
    69 000001F4 <res 00000002>          bs_syssize	resw 1			; 01F4
    70 000001F6 <res 00000002>          bs_swapdev	resw 1			; 01F6 Swap device (obsolete)
    71 000001F8 <res 00000002>          bs_ramsize	resw 1			; 01F8 Ramdisk flags, formerly ramdisk size
    72 000001FA <res 00000002>          bs_vidmode	resw 1			; 01FA Video mode
    73 000001FC <res 00000002>          bs_rootdev	resw 1			; 01FC Root device
    74 000001FE <res 00000002>          bs_bootsign	resw 1			; 01FE Boot sector signature (0AA55h)
    75 00000200 <res 00000001>          su_jump		resb 1			; 0200 0EBh
    76 00000201 <res 00000001>          su_jump2	resb 1			; 0201 Size of following header
    77 00000202 <res 00000004>          su_header	resd 1			; 0202 New setup code: header
    78 00000206 <res 00000002>          su_version	resw 1			; 0206 See linux/arch/i386/boot/setup.S
    79 00000208 <res 00000002>          su_switch	resw 1			; 0208
    80 0000020A <res 00000002>          su_setupseg	resw 1			; 020A
    81 0000020C <res 00000002>          su_startsys	resw 1			; 020C
    82 0000020E <res 00000002>          su_kver		resw 1			; 020E Kernel version pointer
    83 00000210 <res 00000001>          su_loader	resb 1			; 0210 Loader ID
    84 00000211 <res 00000001>          su_loadflags	resb 1			; 0211 Load high flag
    85 00000212 <res 00000002>          su_movesize	resw 1			; 0212
    86 00000214 <res 00000004>          su_code32start	resd 1			; 0214 Start of code loaded high
    87 00000218 <res 00000004>          su_ramdiskat	resd 1			; 0218 Start of initial ramdisk
    88                                  su_ramdisklen	equ $			; Length of initial ramdisk
    89 0000021C <res 00000002>          su_ramdisklen1	resw 1			; 021C
    90 0000021E <res 00000002>          su_ramdisklen2	resw 1			; 021E
    91 00000220 <res 00000002>          su_bsklugeoffs	resw 1			; 0220
    92 00000222 <res 00000002>          su_bsklugeseg	resw 1			; 0222
    93 00000224 <res 00000002>          su_heapend	resw 1			; 0224
    94 00000226 <res 00000002>          su_pad1		resw 1			; 0226
    95 00000228 <res 00000004>          su_cmd_line_ptr	resd 1			; 0228
    96 0000022C <res 00000004>          su_ramdisk_max	resd 1			; 022C
    97 00000230 <res 00008DC4>          		resb (9000h-12)-($-$$)	; The setup is up to 32K long
    98                                  linux_stack	equ $			; 8FF4
    99                                  linux_fdctab	equ $
   100 00008FF4 <res 0000000C>          		resb 9000h-($-$$)
   101                                  cmd_line_here	equ $			; 9000 Should be out of the way
   102                                  		endstruc
   103                                  
   104                                  ;
   105                                  ; Kernel command line signature
   106                                  ;
   107                                  CMD_MAGIC	equ 0A33Fh		; Command line magic
   108                                  
   109                                  ;
   110                                  ; Magic number of su_header field
   111                                  ;
   112                                  HEADER_ID       equ 'HdrS'		; HdrS (in littleendian hex)
   113                                  
   114                                  ;
   115                                  ; Flags for the su_loadflags field
   116                                  ;
   117                                  LOAD_HIGH	equ 01h			; Large kernel, load high
   118                                  CAN_USE_HEAP    equ 80h                 ; Boot loader reports heap size
   119                                  
   120                                  ;
   121                                  ; The following structure is used for "virtual kernels"; i.e. LILO-style
   122                                  ; option labels.  The options we permit here are `kernel' and `append
   123                                  ; Since there is no room in the bottom 64K for all of these, we
   124                                  ; stick them at vk_seg:0000 and copy them down before we need them.
   125                                  ;
   126                                  ; Note: this structure can be added to, but it must 
   127                                  ;
   128                                  %define vk_power	7		; log2(max number of vkernels)
   129                                  %define	max_vk		(1 << vk_power)	; Maximum number of vkernels
   130                                  %define vk_shift	(16-vk_power)	; Number of bits to shift
   131                                  %define vk_size		(1 << vk_shift)	; Size of a vkernel buffer
   132                                  
   133                                  		struc vkernel
   134 00000000 <res 0000000B>          vk_vname:	resb 11			; Virtual name **MUST BE FIRST!**
   135 0000000B <res 0000000B>          vk_rname:	resb 11			; Real name
   136 00000016 <res 00000002>          vk_appendlen:	resw 1
   137                                  		alignb 4
   138 00000018 <res 00000100>          vk_append:	resb max_cmd_len+1	; Command line
   139                                  		alignb 4
   140                                  vk_end:		equ $			; Should be <= vk_size
   141                                  		endstruc
   142                                  
   143                                  %if (vk_end > vk_size) || (vk_size*max_vk > 65536)
   144                                  %error "Too many vkernels defined, reduce vk_power"
   145                                  %endif
   146                                  
   147                                  ;
   148                                  ; Segment assignments in the bottom 640K
   149                                  ; Stick to the low 512K in case we're using something like M-systems flash
   150                                  ; which load a driver into low RAM (evil!!)
   151                                  ;
   152                                  ; 0000h - main code/data segment (and BIOS segment)
   153                                  ; 7000h - real_mode_seg
   154                                  ;
   155                                  fat_seg		equ 5000h		; 128K area for FAT (2x64K)
   156                                  vk_seg          equ 4000h		; Virtual kernels
   157                                  xfer_buf_seg	equ 3000h		; Bounce buffer for I/O to high mem
   158                                  comboot_seg	equ 2000h		; COMBOOT image loading zone
   159                                  
   160                                  ;
   161                                  ; For our convenience: define macros for jump-over-unconditinal jumps
   162                                  ;
   163                                  %macro	jmpz	1
   164                                  	jnz %%skip
   165                                  	jmp %1
   166                                  %%skip:
   167                                  %endmacro
   168                                  
   169                                  %macro	jmpnz	1
   170                                  	jz %%skip
   171                                  	jmp %1
   172                                  %%skip:
   173                                  %endmacro
   174                                  
   175                                  %macro	jmpe	1
   176                                  	jne %%skip
   177                                  	jmp %1
   178                                  %%skip:
   179                                  %endmacro
   180                                  
   181                                  %macro	jmpne	1
   182                                  	je %%skip
   183                                  	jmp %1
   184                                  %%skip:
   185                                  %endmacro
   186                                  
   187                                  %macro	jmpc	1
   188                                  	jnc %%skip
   189                                  	jmp %1
   190                                  %%skip:
   191                                  %endmacro
   192                                  
   193                                  %macro	jmpnc	1
   194                                  	jc %%skip
   195                                  	jmp %1
   196                                  %%skip:
   197                                  %endmacro
   198                                  
   199                                  %macro	jmpb	1
   200                                  	jnb %%skip
   201                                  	jmp %1
   202                                  %%skip:
   203                                  %endmacro
   204                                  
   205                                  %macro	jmpnb	1
   206                                  	jb %%skip
   207                                  	jmp %1
   208                                  %%skip:
   209                                  %endmacro
   210                                  
   211                                  ;
   212                                  ; Macros similar to res[bwd], but which works in the code segment (after
   213                                  ; section .text)
   214                                  ;
   215                                  %macro	zb	1
   216                                  	times %1 db 0
   217                                  %endmacro
   218                                  
   219                                  %macro	zw	1
   220                                  	times %1 dw 0
   221                                  %endmacro
   222                                  
   223                                  %macro	zd	1
   224                                  	times %1 dd 0
   225                                  %endmacro
   226                                  
   227                                  ; ---------------------------------------------------------------------------
   228                                  ;   BEGIN THE BIOS/CODE/DATA SEGMENT
   229                                  ; ---------------------------------------------------------------------------
   230                                  		absolute 4*1Eh		; In the interrupt table
   231                                  fdctab		equ $
   232 00000078 <res 00000002>          fdctab1		resw 1
   233 0000007A <res 00000002>          fdctab2		resw 1
   234                                  
   235                                  		absolute 0400h
   236 00000400 <res 00000008>          serial_base	resw 4			; Base addresses for 4 serial ports
   237                                  
   238                                                  absolute 0484h
   239 00000484 <res 00000001>          BIOS_vidrows    resb 1			; Number of screen rows
   240                                  
   241                                  ;
   242                                  ; Memory below this point is reserved for the BIOS and the MBR
   243                                  ;
   244                                   		absolute 1000h
   245                                  trackbuf	equ $			; Track buffer goes here
   246                                  trackbufsize	equ 16384		; Safe size of track buffer
   247                                  ;		trackbuf ends at 5000h
   248                                  
   249                                  
   250                                  ;
   251                                  ; Constants for the xfer_buf_seg
   252                                  ;
   253                                  ; The xfer_buf_seg is also used to store message file buffers.  We
   254                                  ; need two trackbuffers (text and graphics), plus a work buffer
   255                                  ; for the graphics decompressor.
   256                                  ;
   257                                  xbs_textbuf	equ 0			; Also hard-coded, do not change
   258                                  xbs_vgabuf	equ trackbufsize
   259                                  xbs_vgatmpbuf	equ 2*trackbufsize
   260                                  
   261                                  
   262                                                  absolute 5000h          ; Here we keep our BSS stuff
   263 00005000 <res 00000200>          VKernelBuf:	resb vk_size		; "Current" vkernel
   264                                  		alignb 4
   265 00005200 <res 00000100>          AppendBuf       resb max_cmd_len+1	; append=
   266 00005300 <res 00000100>          KbdMap		resb 256		; Keyboard map
   267 00005400 <res 000000A0>          FKeyName	resb 10*16		; File names for F-key help
   268 000054A0 <res 0000000F>          NumBuf		resb 15			; Buffer to load number
   269 000054AF <res 00000001>          NumBufEnd	resb 1			; Last byte in NumBuf
   270                                  		alignb 4
   271 000054B0 <res 00000010>          PartInfo	resb 16			; Partition table entry
   272 000054C0 <res 00000014>          E820Buf		resd 5			; INT 15:E820 data buffer
   273 000054D4 <res 00000004>          InitRDat	resd 1			; Load address (linear) for initrd
   274 000054D8 <res 00000004>          HiLoadAddr      resd 1			; Address pointer for high load loop
   275 000054DC <res 00000004>          HighMemSize	resd 1			; End of memory pointer (bytes)
   276 000054E0 <res 00000004>          RamdiskMax	resd 1			; Highest address for a ramdisk
   277 000054E4 <res 00000004>          KernelSize	resd 1			; Size of kernel (bytes)
   278 000054E8 <res 0000000C>          KernelName      resb 12		        ; Mangled name for kernel
   279                                  					; (note the spare byte after!)
   280                                  RootDir		equ $			; Location of root directory
   281 000054F4 <res 00000002>          RootDir1	resw 1
   282 000054F6 <res 00000002>          RootDir2	resw 1
   283                                  DataArea	equ $			; Location of data area
   284 000054F8 <res 00000002>          DataArea1	resw 1
   285 000054FA <res 00000002>          DataArea2	resw 1
   286                                  FBytes		equ $			; Used by open/getc
   287 000054FC <res 00000002>          FBytes1		resw 1
   288 000054FE <res 00000002>          FBytes2		resw 1
   289 00005500 <res 00000002>          RootDirSize	resw 1			; Root dir size in sectors
   290 00005502 <res 00000002>          DirScanCtr	resw 1			; Used while searching directory
   291 00005504 <res 00000002>          DirBlocksLeft	resw 1			; Ditto
   292 00005506 <res 00000002>          EndofDirSec	resw 1			; = trackbuf+bsBytesPerSec-31
   293 00005508 <res 00000002>          RunLinClust	resw 1			; Cluster # for LDLINUX.SYS
   294 0000550A <res 00000002>          ClustSize	resw 1			; Bytes/cluster
   295 0000550C <res 00000002>          SecPerClust	resw 1			; Same as bsSecPerClust, but a word
   296 0000550E <res 00000002>          NextCluster	resw 1			; Pointer to "nextcluster" routine
   297 00005510 <res 00000002>          BufSafe		resw 1			; Clusters we can load into trackbuf
   298 00005512 <res 00000002>          BufSafeSec	resw 1			; = how many sectors?
   299 00005514 <res 00000002>          BufSafeBytes	resw 1			; = how many bytes?
   300 00005516 <res 00000002>          EndOfGetCBuf	resw 1			; = getcbuf+BufSafeBytes
   301 00005518 <res 00000002>          KernelClust	resw 1			; Kernel size in clusters
   302 0000551A <res 00000002>          InitRDClust	resw 1			; Ramdisk size in clusters
   303 0000551C <res 00000002>          ClustPerMoby	resw 1			; Clusters per 64K
   304 0000551E <res 00000002>          FClust		resw 1			; Number of clusters in open/getc file
   305 00005520 <res 00000002>          FNextClust	resw 1			; Pointer to next cluster in d:o
   306 00005522 <res 00000002>          FPtr		resw 1			; Pointer to next char in buffer
   307 00005524 <res 00000002>          CmdOptPtr       resw 1			; Pointer to first option on cmd line
   308 00005526 <res 00000002>          KernelCNameLen  resw 1			; Length of unmangled kernel name
   309 00005528 <res 00000002>          InitRDCNameLen  resw 1			; Length of unmangled initrd name
   310 0000552A <res 00000002>          NextCharJump    resw 1			; Routine to interpret next print char
   311 0000552C <res 00000002>          SetupSecs	resw 1			; Number of setup sectors
   312 0000552E <res 00000002>          SavedSP		resw 1			; Our SP while running a COMBOOT image
   313 00005530 <res 00000002>          A20Test		resw 1			; Counter for testing status of A20
   314 00005532 <res 00000002>          CmdLineLen	resw 1			; Length of command line including null
   315 00005534 <res 00000002>          GraphXSize	resw 1			; Width of splash screen file
   316 00005536 <res 00000002>          VGAPos		resw 1			; Pointer into VGA memory
   317 00005538 <res 00000002>          VGACluster	resw 1			; Cluster pointer for VGA image file
   318 0000553A <res 00000002>          VGAFilePtr	resw 1			; Pointer into VGAFileBuf
   319                                  TextAttrBX      equ $
   320 0000553C <res 00000001>          TextAttribute   resb 1			; Text attribute for message file
   321 0000553D <res 00000001>          TextPage        resb 1			; Active display page
   322                                  CursorDX        equ $
   323 0000553E <res 00000001>          CursorCol       resb 1			; Cursor column for message file
   324 0000553F <res 00000001>          CursorRow       resb 1			; Cursor row for message file
   325                                  ScreenSize      equ $
   326 00005540 <res 00000001>          VidCols         resb 1			; Columns on screen-1
   327 00005541 <res 00000001>          VidRows         resb 1			; Rows on screen-1
   328                                  FlowControl	equ $
   329 00005542 <res 00000001>          FlowOutput	resb 1			; Outputs to assert for serial flow
   330 00005543 <res 00000001>          FlowInput	resb 1			; Input bits for serial flow
   331 00005544 <res 00000001>          FlowIgnore	resb 1			; Ignore input unless these bits set
   332 00005545 <res 00000001>          RetryCount      resb 1			; Used for disk access retries
   333 00005546 <res 00000001>          KbdFlags	resb 1			; Check for keyboard escapes
   334 00005547 <res 00000001>          LoadFlags	resb 1			; Loadflags from kernel
   335 00005548 <res 00000001>          A20Tries	resb 1			; Times until giving up on A20
   336 00005549 <res 00000001>          FuncFlag	resb 1			; Escape sequences received from keyboard
   337 0000554A <res 00000001>          DisplayMask	resb 1			; Display modes mask
   338 0000554B <res 0000000B>          MNameBuf        resb 11            	; Generic mangled file name buffer
   339 00005556 <res 0000000B>          InitRD          resb 11                 ; initrd= mangled name
   340 00005561 <res 0000000D>          KernelCName     resb 13                 ; Unmangled kernel name
   341 0000556E <res 0000000D>          InitRDCName     resb 13            	; Unmangled initrd name
   342 0000557B <res 00000011>          TextColorReg	resb 17			; VGA color registers for text mode
   343 0000558C <res 0000000D>          VGAFileBuf	resb 13			; Unmangled VGA image name
   344                                  VGAFileBufEnd	equ $
   345 00005599 <res 0000000B>          VGAFileMBuf	resb 11			; Mangled VGA image name
   346                                  
   347                                  		section .text
   348                                                  org 7C00h
   349                                  StackBuf	equ $			; Start the stack here (grow down - 4K)
   350                                  
   351                                  ;
   352                                  ; Primary entry point.  Tempting as though it may be, we can't put the
   353                                  ; initial "cli" here; the jmp opcode in the first byte is part of the
   354                                  ; "magic number" (using the term very loosely) for the DOS superblock.
   355                                  ;
   356                                  bootsec		equ $
   357 00000000 EB3C                    		jmp short start		; 2 bytes
   358 00000002 90                      		nop			; 1 byte
   359                                  ;
   360                                  ; "Superblock" follows -- it's in the boot sector, so it's already
   361                                  ; loaded and ready for us
   362                                  ;
   363 00000003 5359534C494E5558        bsOemName	db 'SYSLINUX'		; The SYS command sets this, so...
   364                                  superblock	equ $
   365                                  bsBytesPerSec	zw 1
   366                              <1> bsBytesPerSec	:
   367 0000000B 0000                <1> 	times %1 dw 0
   368                                  bsSecPerClust	zb 1
   369                              <1> bsSecPerClust	:
   370 0000000D 00                  <1> 	times %1 db 0
   371                                  bsResSectors	zw 1
   372                              <1> bsResSectors	:
   373 0000000E 0000                <1> 	times %1 dw 0
   374                                  bsFATs		zb 1
   375                              <1> bsFATs		:
   376 00000010 00                  <1> 	times %1 db 0
   377                                  bsRootDirEnts	zw 1
   378                              <1> bsRootDirEnts	:
   379 00000011 0000                <1> 	times %1 dw 0
   380                                  bsSectors	zw 1
   381                              <1> bsSectors	:
   382 00000013 0000                <1> 	times %1 dw 0
   383                                  bsMedia		zb 1
   384                              <1> bsMedia		:
   385 00000015 00                  <1> 	times %1 db 0
   386                                  bsFATsecs	zw 1
   387                              <1> bsFATsecs	:
   388 00000016 0000                <1> 	times %1 dw 0
   389                                  bsSecPerTrack	zw 1
   390                              <1> bsSecPerTrack	:
   391 00000018 0000                <1> 	times %1 dw 0
   392                                  bsHeads		zw 1
   393                              <1> bsHeads		:
   394 0000001A 0000                <1> 	times %1 dw 0
   395                                  bsHiddenSecs	equ $
   396                                  bsHidden1	zw 1
   397                              <1> bsHidden1	:
   398 0000001C 0000                <1> 	times %1 dw 0
   399                                  bsHidden2	zw 1
   400                              <1> bsHidden2	:
   401 0000001E 0000                <1> 	times %1 dw 0
   402                                  bsHugeSectors	equ $
   403                                  bsHugeSec1	zw 1
   404                              <1> bsHugeSec1	:
   405 00000020 0000                <1> 	times %1 dw 0
   406                                  bsHugeSec2	zw 1
   407                              <1> bsHugeSec2	:
   408 00000022 0000                <1> 	times %1 dw 0
   409                                  bsDriveNumber	zb 1
   410                              <1> bsDriveNumber	:
   411 00000024 00                  <1> 	times %1 db 0
   412                                  bsReserved1	zb 1
   413                              <1> bsReserved1	:
   414 00000025 00                  <1> 	times %1 db 0
   415                                  bsBootSignature zb 1			; 29h if the following fields exist
   416                              <1> bsBootSignature :
   417 00000026 00                  <1> 	times %1 db 0
   418                                  bsVolumeID	zd 1
   419                              <1> bsVolumeID	:
   420 00000027 00000000            <1> 	times %1 dd 0
   421                                  bsVolumeLabel	zb 11
   422                              <1> bsVolumeLabel	:
   423 0000002B 00<rept>            <1> 	times %1 db 0
   424                                  bsFileSysType	zb 8			; Must be FAT12 for this version
   425                              <1> bsFileSysType	:
   426 00000036 00<rept>            <1> 	times %1 db 0
   427                                  superblock_len	equ $-superblock
   428                                  ;
   429                                  ; Note we don't check the constraints above now; we did that at install
   430                                  ; time (we hope!)
   431                                  ;
   432                                  
   433                                  ;floppy_table	equ $			; No sense in wasting memory, overwrite start
   434                                  
   435                                  start:
   436 0000003E FA                      		cli			; No interrupts yet, please
   437 0000003F FC                      		cld			; Copy upwards
   438                                  ;
   439                                  ; Set up the stack
   440                                  ;
   441 00000040 31C9                    		xor cx,cx
   442 00000042 8ED1                    		mov ss,cx
   443 00000044 BC[0000]                		mov sp,StackBuf		; Just below BSS
   444 00000047 8EC1                    		mov es,cx
   445                                  ;
   446                                  ; DS:SI may contain a partition table entry.  Preserve it for us.
   447                                  ;
   448 00000049 B108                    		mov cl,8		; Save partition info (CH == 0)
   449 0000004B BFB054                  		mov di,PartInfo
   450 0000004E F3A5                    		rep movsw
   451                                  ;
   452                                  ; Now sautee the BIOS floppy info block to that it will support decent-
   453                                  ; size transfers; the floppy block is 11 bytes and is stored in the
   454                                  ; INT 1Eh vector (brilliant waste of resources, eh?)
   455                                  ;
   456                                  ; Of course, if BIOSes had been properly programmed, we wouldn't have
   457                                  ; had to waste precious boot sector space with this code.
   458                                  ;
   459                                  ; This code no longer fits.  Hope that noone really needs it anymore.
   460                                  ; (If so, it needs serious updating.)  In fact, some indications is that
   461                                  ; this code does more harm than good with all the new kinds of drives and
   462                                  ; media.
   463                                  ;
   464                                  %ifdef SUPPORT_REALLY_BROKEN_BIOSES
   465                                  		lds si,[ss:fdctab]	; DS:SI -> original
   466                                  		push ds			; Save on stack in case
   467                                  		push si			; we have to bail
   468                                  		push bx
   469                                  		mov cx,6		; 12 bytes
   470                                  		mov di,floppy_table
   471                                  		push di
   472                                  		cld
   473                                  		rep movsw		; Faster to move words
   474                                  		pop di
   475                                  		mov ds,ax		; Now we can point DS to here, too
   476                                  		mov cl,[bsSecPerTrack]  ; Patch the sector count
   477                                  		mov [di+4],cl
   478                                  		mov [fdctab+2],ax	; Segment 0
   479                                  		mov [fdctab],di		; offset floppy_block
   480                                  %else
   481 00000050 8ED9                    		mov ds,cx		; CX == 0
   482                                  %endif
   483                                  ;
   484                                  ; Ready to enable interrupts, captain
   485                                  ;
   486 00000052 FB                      		sti
   487                                  ;
   488                                  ; The drive number and possibly partition information was passed to us
   489                                  ; by the BIOS or previous boot loader (MBR).  Current "best practice" is to
   490                                  ; trust that rather than what the superblock contains.
   491                                  ;
   492                                  ; Would it be better to zero out bsHidden if we don't have a partition table?
   493                                  ;
   494                                  ; Note: di points to beyond the end of PartInfo
   495                                  ;
   496 00000053 8816[2400]              		mov [bsDriveNumber],dl
   497 00000057 F6C280                  		test dl,80h		; If floppy disk (00-7F), assume no
   498 0000005A 7428                    		jz not_harddisk		; partition table
   499 0000005C F645F07F                		test byte [di-16],7Fh	; Sanity check: "active flag" should
   500 00000060 750A                    		jnz no_partition	; be 00 or 80
   501 00000062 8D75F8                  		lea si,[di-8]		; Partition offset (dword)
   502 00000065 BF[1C00]                		mov di,bsHidden1
   503 00000068 B102                    		mov cl,2		; CH == 0
   504 0000006A F3A5                    		rep movsw
   505                                  no_partition:
   506                                  ;
   507                                  ; Get disk drive parameters (don't trust the superblock.)  Don't do this for
   508                                  ; floppy drives -- INT 13:08 on floppy drives will (may?) return info about
   509                                  ; what the *drive* supports, not about the *media*.  Fortunately floppy disks
   510                                  ; tend to have a fixed, well-defined geometry which is stored in the superblock.
   511                                  ;
   512                                  		; DL == drive # still
   513 0000006C B408                    		mov ah,08h
   514 0000006E CD13                    		int 13h
   515 00000070 7212                    		jc no_driveparm
   516 00000072 20E4                    		and ah,ah
   517 00000074 750E                    		jnz no_driveparm
   518 00000076 FEC6                    		inc dh			; Contains # of heads - 1
   519 00000078 8836[1A00]              		mov [bsHeads],dh
   520 0000007C 81E13F00                		and cx,3fh
   521 00000080 890E[1800]              		mov [bsSecPerTrack],cx
   522                                  no_driveparm:
   523                                  not_harddisk:
   524                                  ;
   525                                  ; Now we have to do some arithmetric to figure out where things are located.
   526                                  ; If Micro$oft had had brains they would already have done this for us,
   527                                  ; and stored it in the superblock at format time, but here we go,
   528                                  ; wasting precious boot sector space again...
   529                                  ;
   530                                  debugentrypt:
   531 00000084 31C0                    		xor ax,ax		; INT 13:08 destroys ES
   532 00000086 8EC0                    		mov es,ax
   533 00000088 A0[1000]                		mov al,[bsFATs]		; Number of FATs (AH == 0)
   534 0000008B F726[1600]              		mul word [bsFATsecs]	; Get the size of the FAT area
   535 0000008F 0306[1C00]              		add ax,[bsHidden1]	; Add hidden sectors
   536 00000093 1316[1E00]              		adc dx,[bsHidden2]
   537 00000097 0306[0E00]              		add ax,[bsResSectors]	; And reserved sectors
   538 0000009B 83D200                  		adc dx,byte 0
   539                                  
   540 0000009E A3F454                  		mov [RootDir1],ax	; Location of root directory
   541 000000A1 8916F654                		mov [RootDir2],dx
   542 000000A5 A3F854                  		mov [DataArea1],ax
   543 000000A8 8916FA54                		mov [DataArea2],dx
   544 000000AC 50                      		push ax
   545 000000AD 52                      		push dx
   546                                  
   547 000000AE B82000                  		mov ax,32		; Size of a directory entry
   548 000000B1 F726[1100]              		mul word [bsRootDirEnts]
   549 000000B5 8B1E[0B00]              		mov bx,[bsBytesPerSec]
   550 000000B9 01D8                    		add ax,bx		; Round up, not down
   551 000000BB 48                      		dec ax
   552 000000BC F7F3                    		div bx			; Now we have the size of the root dir
   553 000000BE A30055                  		mov [RootDirSize],ax
   554 000000C1 A30255                  		mov [DirScanCtr],ax
   555 000000C4 81C3E10F                		add bx,trackbuf-31
   556 000000C8 891E0655                		mov [EndofDirSec],bx	; End of a single directory sector
   557                                  
   558 000000CC 0106F854                		add [DataArea1],ax
   559 000000D0 8316FA5400              		adc word [DataArea2],byte 0
   560                                  
   561 000000D5 5A                      		pop dx			; Reload root directory starting point
   562 000000D6 58                      		pop ax
   563                                  ;
   564                                  ; Now the fun begins.  We have to search the root directory for
   565                                  ; LDLINUX.SYS and load the first sector, so we have a little more
   566                                  ; space to have fun with.  Then we can go chasing through the FAT.
   567                                  ; Joy!!
   568                                  ;
   569 000000D7 50                      sd_nextsec:	push ax
   570 000000D8 52                      		push dx
   571 000000D9 BB0010                  		mov bx,trackbuf
   572 000000DC 53                      		push bx
   573 000000DD E89100                  		call getonesec
   574 000000E0 5E                      		pop si
   575 000000E1 803C00                  sd_nextentry:	cmp byte [si],0		; Directory high water mark
   576 000000E4 7429                    		je kaboom
   577 000000E6 F6440B18                		test byte [si+11],18h	; Must be a file
   578 000000EA 750C                    		jnz sd_not_file
   579 000000EC BF[EF01]                		mov di,ldlinux_name
   580 000000EF B90B00                  		mov cx,11
   581 000000F2 56                      		push si
   582 000000F3 F3A6                    		repe cmpsb
   583 000000F5 5E                      		pop si
   584 000000F6 742D                    		je found_it
   585 000000F8 83C620                  sd_not_file:	add si,byte 32		; Distance to next
   586 000000FB 3B360655                		cmp si,[EndofDirSec]
   587 000000FF 72E0                    		jb sd_nextentry
   588 00000101 5A                      		pop dx
   589 00000102 58                      		pop ax
   590 00000103 83C001                  		add ax,byte 1
   591 00000106 83D200                  		adc dx,byte 0
   592 00000109 FF0E0255                		dec word [DirScanCtr]
   593 0000010D 75C8                    		jnz sd_nextsec
   594                                  ;
   595                                  ; kaboom: write a message and bail out.
   596                                  ;
   597                                  kaboom:
   598 0000010F 31F6                    		xor si,si
   599 00000111 8ED6                    		mov ss,si		
   600 00000113 BC[0000]                		mov sp,StackBuf 	; Reset stack
   601 00000116 8EDE                    		mov ds,si		; Reset data segment
   602 00000118 BE[DE01]                .patch:		mov si,bailmsg
   603 0000011B E83900                  		call writestr		; Returns with AL = 0
   604 0000011E 98                      		cbw			; AH <- 0
   605 0000011F CD16                    		int 16h			; Wait for keypress
   606 00000121 CD19                    		int 19h			; And try once more to boot...
   607 00000123 EBFE                    .norge:		jmp short .norge	; If int 19h returned; this is the end
   608                                  
   609                                  ;
   610                                  ; found_it: now we compute the location of the first sector, then
   611                                  ;	    load it and JUMP (since we're almost out of space)
   612                                  ;
   613                                  found_it:	; Note: we actually leave two words on the stack here
   614                                  		; (who cares?)
   615 00000125 31C0                    		xor ax,ax
   616 00000127 A0[0D00]                		mov al,[bsSecPerClust]
   617 0000012A 89C5                    		mov bp,ax		; Load an entire cluster
   618 0000012C 8B5C1A                  		mov bx,[si+26]		; First cluster
   619 0000012F 891E0855                		mov [RunLinClust],bx	; Save for later use
   620 00000133 4B                      		dec bx			; First cluster is "cluster 2"
   621 00000134 4B                      		dec bx
   622 00000135 F7E3                    		mul bx
   623 00000137 0306F854                		add ax,[DataArea1]
   624 0000013B 1316FA54                		adc dx,[DataArea2]
   625 0000013F BB[0002]                		mov bx,ldlinux_sys
   626 00000142 E82F00                  		call getlinsec
   627 00000145 BE[EF01]                		mov si,bs_magic
   628 00000148 BF[1F02]                		mov di,ldlinux_magic
   629 0000014B B91100                  		mov cx,magic_len
   630 0000014E F3A6                    		repe cmpsb		; Make sure that the bootsector
   631 00000150 75BD                    		jne kaboom		; matches LDLINUX.SYS
   632                                  ;
   633                                  ; Done! Jump to the entry point!
   634                                  ; 
   635                                  ; Note that some BIOSes are buggy and run the boot sector at 07C0:0000
   636                                  ; instead of 0000:7C00 and the like.  We don't want to add anything
   637                                  ; more to the boot sector, so it is written to not assume a fixed
   638                                  ; value in CS, but we don't want to deal with that anymore from now
   639                                  ; on.
   640                                  ;
   641 00000152 EA[3002]0000            		jmp 0:ldlinux_ent
   642                                  
   643                                  ;
   644                                  ;
   645                                  ; writestr: write a null-terminated string to the console
   646                                  ;
   647                                  writestr:
   648 00000157 AC                      wstr_1:         lodsb
   649 00000158 20C0                    		and al,al
   650 0000015A 7414                                    jz return
   651 0000015C B40E                    		mov ah,0Eh		; Write to screen as TTY
   652 0000015E BB0700                  		mov bx,0007h		; White on black, current page
   653 00000161 CD10                    		int 10h
   654 00000163 EBF2                    		jmp short wstr_1
   655                                  ;
   656                                  ; disk_error: decrement the retry count and bail if zero
   657                                  ;
   658 00000165 4E                      disk_error:	dec si			; SI holds the disk retry counter
   659 00000166 74A7                    		jz kaboom
   660 00000168 5B                      		pop bx			; <I>
   661 00000169 59                      		pop cx			; <H>
   662 0000016A 5A                      		pop dx			; <G>
   663 0000016B 58                      		pop ax			; <F> (AH = 0)
   664 0000016C B001                    		mov al,1		; Once we fail, only transfer 1 sector
   665 0000016E EB39                    		jmp short disk_try_again
   666                                  
   667 00000170 C3                      return:		ret
   668                                  
   669                                  ;
   670                                  ; getonesec: like getlinsec, but pre-sets the count to 1
   671                                  ;
   672                                  getonesec:
   673 00000171 BD0100                  		mov bp,1
   674                                  		; Fall through to getlinsec
   675                                  
   676                                  ;
   677                                  ; getlinsec: load a sequence of BP floppy sector given by the linear sector
   678                                  ;	     number in DX:AX into the buffer at ES:BX.	We try to optimize
   679                                  ;	     by loading up to a whole track at a time, but the user
   680                                  ;	     is responsible for not crossing a 64K boundary.
   681                                  ;	     (Yes, BP is weird for a count, but it was available...)
   682                                  ;
   683                                  ;	     On return, BX points to the first byte after the transferred
   684                                  ;	     block.
   685                                  ;
   686                                  ;	     The "stupid patch area" gets replaced by the code
   687                                  ;	     mov bp,1 ; nop ... (BD 01 00 90 90...) when installing with
   688                                  ;	     the -s option.
   689                                  ;
   690                                  ; Stylistic note: use "xchg" instead of "mov" when the source is a register
   691                                  ; that is dead from that point; this saves space.  However, please keep
   692                                  ; the order to dst,src to keep things sane.
   693                                  ;
   694                                  getlinsec:
   695 00000174 8B36[1800]              		mov si,[bsSecPerTrack]
   696                                  		;
   697                                  		; Dividing by sectors to get (track,sector): we may have
   698                                  		; up to 2^18 tracks, so we need to do this in two steps
   699                                  		; to produce a 32-bit quotient.
   700                                  		;
   701 00000178 91                      		xchg cx,ax		; CX <- LSW of LBA
   702 00000179 92                      		xchg ax,dx
   703 0000017A 31D2                    		xor dx,dx		; DX:AX now == MSW of LBA
   704 0000017C F7F6                    		div si			; Obtain MSW of track #
   705 0000017E 91                      		xchg ax,cx		; Remainder -> MSW of new dividend
   706                                  					; LSW of LBA -> LSW of new dividend
   707                                  					; Quotient -> MSW of track # 
   708 0000017F F7F6                    		div si			; Obtain LSW of track #, remainder
   709 00000181 87CA                    		xchg cx,dx		; CX <- Sector index (0-based)
   710                                  					; DX <- MSW of track #
   711 00000183 F736[1A00]              		div word [bsHeads]	; Convert track to head/cyl
   712                                  		;
   713                                  		; Now we have AX = cyl, DX = head, CX = sector (0-based),
   714                                  		; BP = sectors to transfer, SI = bsSecPerTrack,
   715                                  		; ES:BX = data target
   716                                  		;
   717 00000187 56                      gls_nextchunk:	push si			; <A> bsSecPerTrack
   718 00000188 55                      		push bp			; <B> Sectors to transfer
   719                                  
   720                                  __BEGIN_STUPID_PATCH_AREA:
   721 00000189 29CE                    		sub si,cx		; Sectors left on track
   722 0000018B 39F5                    		cmp bp,si
   723 0000018D 7602                    		jna gls_lastchunk
   724 0000018F 89F5                    		mov bp,si		; No more than a trackful, please!
   725                                  __END_STUPID_PATCH_AREA:
   726                                  gls_lastchunk:	
   727 00000191 50                      		push ax			; <C> Cylinder #
   728 00000192 52                      		push dx			; <D> Head #
   729                                  
   730 00000193 51                      		push cx			; <E> Sector #
   731 00000194 B106                    		mov cl,6		; Because IBM was STOOPID
   732 00000196 D2E4                    		shl ah,cl		; and thought 8 bits were enough
   733                                  					; then thought 10 bits were enough...
   734 00000198 59                      		pop cx			; <E> Sector #
   735 00000199 51                      		push cx			; <E> Sector #
   736 0000019A 41                      		inc cx			; Sector numbers are 1-based
   737 0000019B 08E1                    		or cl,ah
   738 0000019D 88C5                    		mov ch,al
   739 0000019F 88D6                    		mov dh,dl
   740 000001A1 8A16[2400]              		mov dl,[bsDriveNumber]
   741 000001A5 95                      		xchg ax,bp		; Sector to transfer count
   742                                  					; (xchg shorter than mov)
   743 000001A6 BE0600                  		mov si,retry_count	; # of times to retry a disk access
   744                                  ;
   745                                  ; Do the disk transfer... save the registers in case we fail :(
   746                                  ;
   747                                  disk_try_again: 
   748 000001A9 50                      		push ax			; <F> Number of sectors we're transferring
   749 000001AA B402                    		mov ah,02h		; READ DISK
   750 000001AC 52                      		push dx			; <G>
   751 000001AD 51                      		push cx			; <H>
   752 000001AE 53                      		push bx			; <I>
   753 000001AF 56                      		push si			; <J>
   754 000001B0 CD13                    		int 13h
   755 000001B2 5E                      		pop si			; <J>
   756 000001B3 72B0                    		jc disk_error
   757                                  ;
   758                                  ; Disk access successful
   759                                  ;
   760 000001B5 5B                      		pop bx			; <I> Buffer location
   761 000001B6 58                      		pop ax			; <H> No longer needed
   762 000001B7 58                      		pop ax			; <G> No longer needed
   763 000001B8 5F                      		pop di			; <F> Sector transferred count
   764 000001B9 59                      		pop cx			; <E> Sector #
   765 000001BA 89F8                    		mov ax,di		; Reduce sector left count
   766 000001BC F726[0B00]              		mul word [bsBytesPerSec] ; Figure out how much to advance ptr
   767 000001C0 01C3                    		add bx,ax		; Update buffer location
   768 000001C2 5A                      		pop dx			; <D> Head #
   769 000001C3 58                      		pop ax			; <C> Cyl #
   770 000001C4 5D                      		pop bp			; <B> Sectors left to transfer
   771 000001C5 5E                      		pop si			; <A> Number of sectors/track
   772 000001C6 29FD                    		sub bp,di		; Reduce with # of sectors just read
   773 000001C8 74A6                    		jz return		; Done!
   774 000001CA 01F9                    		add cx,di
   775 000001CC 39F1                    		cmp cx,si
   776 000001CE 72B7                    		jb gls_nextchunk
   777 000001D0 42                      		inc dx			; Next track on cyl
   778 000001D1 3B16[1A00]              		cmp dx,[bsHeads]	; Was this the last one?
   779 000001D5 7203                    		jb gls_nonewcyl
   780 000001D7 40                      		inc ax			; If so, new cylinder
   781 000001D8 31D2                    		xor dx,dx		; First head on new cylinder
   782 000001DA 29F1                    gls_nonewcyl:	sub cx,si		; First sector on new track
   783 000001DC EBA9                    		jmp short gls_nextchunk
   784                                  
   785 000001DE 426F6F74206661696C-     bailmsg:	db 'Boot failed', 0Dh, 0Ah, 0
   786 000001E7 65640D0A00         
   787                                  
   788                                  bs_checkpt	equ $			; Must be <= 7DEFh
   789                                  
   790                                  bs_checkpt_off	equ ($-$$)
   791                                  %if bs_checkpt_off > 1EFh
   792                                  %error "Boot sector overflow"
   793                                  %endif
   794                                  
   795                                  		zb 1EFh-($-$$)
   796 000001EC 00<rept>            <1> 	times %1 db 0
   797                                  bs_magic	equ $			; From here to the magic_len equ
   798                                  					; must match ldlinux_magic
   799 000001EF 4C444C494E55582053-     ldlinux_name:	db 'LDLINUX SYS'	; Looks like this in the root dir
   800 000001F8 5953               
   801 000001FA 73AE323C                		dd HEXDATE		; Hopefully unique between compiles
   802                                  
   803 000001FE 55AA                    bootsignature	dw 0AA55h
   804                                  magic_len	equ $-bs_magic
   805                                  
   806                                  ;
   807                                  ; ===========================================================================
   808                                  ;  End of boot sector
   809                                  ; ===========================================================================
   810                                  ;  Start of LDLINUX.SYS
   811                                  ; ===========================================================================
   812                                  
   813                                  ldlinux_sys:
   814                                  
   815 00000200 0D0A5359534C494E55-     syslinux_banner	db 0Dh, 0Ah, 'SYSLINUX ', version_str, ' ', date, ' ', 0
   816 00000209 5820312E3636203230-
   817 00000212 30322D30312D303120-
   818 0000021B 00                 
   819 0000021C 0D0A1A                  		db 0Dh, 0Ah, 1Ah	; EOF if we "type" this in DOS
   820                                  
   821 0000021F 4C444C494E55582053-     ldlinux_magic	db 'LDLINUX SYS'
   822 00000228 5953               
   823 0000022A 73AE323C                		dd HEXDATE
   824 0000022E 55AA                    		dw 0AA55h
   825                                  
   826                                  		align 4
   827                                  
   828                                  ldlinux_ent:
   829                                  ;
   830                                  ; Tell the user we got this far
   831                                  ;
   832 00000230 BE[0002]                		mov si,syslinux_banner
   833 00000233 E821FF                  		call writestr
   834                                  ;
   835                                  ; Remember, the boot sector loaded only the first cluster of LDLINUX.SYS.
   836                                  ; We can really only rely on a single sector having been loaded.  Hence
   837                                  ; we should load the FAT into RAM and start chasing pointers...
   838                                  ;
   839 00000236 BA0100                  		mov dx,1			; 64K
   840 00000239 31C0                    		xor ax,ax
   841 0000023B F736[0B00]              		div word [bsBytesPerSec]	; sectors/64K
   842 0000023F 89C6                    		mov si,ax
   843                                  
   844 00000241 06                      		push es
   845 00000242 BB0050                  		mov bx,fat_seg			; Load into fat_seg:0000
   846 00000245 8EC3                    		mov es,bx
   847                                  		
   848 00000247 A1[1C00]                		mov ax,[bsHidden1]		; Hidden sectors
   849 0000024A 8B16[1E00]              		mov dx,[bsHidden2]
   850 0000024E 0306[0E00]              		add ax,[bsResSectors]		; plus reserved sectors = FAT
   851 00000252 83D200                  		adc dx,byte 0
   852 00000255 8B0E[1600]              		mov cx,[bsFATsecs]		; Sectors/FAT
   853                                  fat_load_loop:	
   854 00000259 89CD                    		mov bp,cx
   855 0000025B 39F5                    		cmp bp,si
   856 0000025D 7602                    		jna fat_load
   857 0000025F 89F5                    		mov bp,si			; A full 64K moby
   858                                  fat_load:	
   859 00000261 31DB                    		xor bx,bx			; Offset 0 in the current ES
   860 00000263 E82201                  		call getlinsecsr
   861 00000266 29E9                    		sub cx,bp
   862 00000268 740F                    		jz fat_load_done		; Last moby?
   863 0000026A 01E8                    		add ax,bp			; Advance sector count
   864 0000026C 83D200                  		adc dx,byte 0
   865 0000026F 8CC3                    		mov bx,es			; Next 64K moby
   866 00000271 81C30010                		add bx,1000h
   867 00000275 8EC3                    		mov es,bx
   868 00000277 EBE0                    		jmp short fat_load_loop
   869                                  fat_load_done:
   870 00000279 07                      		pop es
   871                                  ;
   872                                  ; Fine, now we have the FAT in memory.	How big is a cluster, really?
   873                                  ; Also figure out how many clusters will fit in an 8K buffer, and how
   874                                  ; many sectors and bytes that is
   875                                  ;
   876 0000027A 8B3E[0B00]              		mov di,[bsBytesPerSec]		; Used a lot below
   877                                  
   878 0000027E A0[0D00]                		mov al,[bsSecPerClust]		; We do this in the boot
   879 00000281 30E4                    		xor ah,ah			; sector, too, but there
   880 00000283 A30C55                  		mov [SecPerClust],ax		; wasn't space to save it
   881 00000286 89C6                    		mov si,ax			; Also used a lot...
   882 00000288 F7E7                    		mul di
   883 0000028A A30A55                  		mov [ClustSize],ax		; Bytes/cluster
   884 0000028D 89C3                    		mov bx,ax
   885 0000028F B80040                  		mov ax,trackbufsize
   886 00000292 31D2                    		xor dx,dx
   887 00000294 F7F3                    		div bx
   888 00000296 A31055                  		mov [BufSafe],ax		; # of cluster in trackbuf
   889 00000299 F7260C55                		mul word [SecPerClust]
   890 0000029D A31255                  		mov [BufSafeSec],ax
   891 000002A0 F7E7                    		mul di
   892 000002A2 A31455                  		mov [BufSafeBytes],ax
   893 000002A5 05009C                  		add ax,getcbuf			; Size of getcbuf is the same
   894 000002A8 A31655                  		mov [EndOfGetCBuf],ax		; as for trackbuf
   895                                  ;
   896                                  ; FAT12 or FAT16?  This computation is fscking ridiculous...
   897                                  ;
   898 000002AB 31D2                    		xor dx,dx
   899 000002AD 31C9                    		xor cx,cx
   900 000002AF A1[1300]                		mov ax,[bsSectors]
   901 000002B2 21C0                    		and ax,ax
   902 000002B4 7507                    		jnz have_secs
   903 000002B6 A1[2000]                		mov ax,[bsHugeSectors]
   904 000002B9 8B16[2200]              		mov dx,[bsHugeSectors+2]
   905 000002BD 2B06[0E00]              have_secs:	sub ax,[bsResSectors]
   906 000002C1 83DA00                  		sbb dx,byte 0
   907 000002C4 8A0E[1000]              		mov cl,[bsFATs]
   908 000002C8 2B06[1600]              sec_fat_loop:	sub ax,[bsFATsecs]
   909 000002CC 83DA00                  		sbb dx,byte 0
   910 000002CF E2F7                    		loop sec_fat_loop
   911 000002D1 50                      		push ax
   912 000002D2 52                      		push dx
   913 000002D3 A1[1100]                		mov ax,[bsRootDirEnts]
   914 000002D6 BB2000                  		mov bx,32			; Smaller than shift since we
   915 000002D9 F7E3                    		mul bx				; need the doubleword product
   916 000002DB 01F8                    		add ax,di
   917 000002DD 83D200                  		adc dx,byte 0
   918 000002E0 83E801                  		sub ax,byte 1
   919 000002E3 83DA00                  		sbb dx,byte 0
   920 000002E6 F7F7                    		div di
   921 000002E8 89C3                    		mov bx,ax
   922 000002EA 5A                      		pop dx
   923 000002EB 58                      		pop ax
   924 000002EC 29D8                    		sub ax,bx
   925 000002EE 83DA00                  		sbb dx,byte 0
   926 000002F1 F7F6                    		div si
   927 000002F3 3DF60F                  		cmp ax,4086			; Right value?
   928 000002F6 B8[BF03]                		mov ax,nextcluster_fat16
   929 000002F9 7703                    		ja have_fat_type
   930 000002FB B8[9803]                have_fat12:	mov ax,nextcluster_fat12
   931 000002FE A30E55                  have_fat_type:	mov word [NextCluster],ax
   932                                  
   933                                  ;
   934                                  ; Now we read the rest of LDLINUX.SYS.	Don't bother loading the first
   935                                  ; cluster again, though.
   936                                  ;
   937                                  load_rest:
   938 00000301 8B0E0A55                		mov cx,[ClustSize]
   939 00000305 BB[0002]                		mov bx,ldlinux_sys
   940 00000308 01CB                    		add bx,cx
   941 0000030A 8B360855                		mov si,[RunLinClust]
   942 0000030E FF160E55                		call [NextCluster]
   943 00000312 31D2                    		xor dx,dx
   944 00000314 B8751D                  		mov ax,ldlinux_len-1		; To be on the safe side
   945 00000317 01C8                    		add ax,cx
   946 00000319 F7F1                    		div cx				; the number of clusters
   947 0000031B 48                      		dec ax				; We've already read one
   948 0000031C 7405                    		jz all_read_jmp
   949 0000031E 89C1                    		mov cx,ax
   950 00000320 E80300                  		call getfssec
   951                                  ;
   952                                  ; All loaded up
   953                                  ;
   954                                  all_read_jmp:
   955 00000323 E9B100                  		jmp all_read
   956                                  ;
   957                                  ; -----------------------------------------------------------------------------
   958                                  ; Subroutines that have to be in the first sector
   959                                  ; -----------------------------------------------------------------------------
   960                                  ;
   961                                  ; getfssec: Get multiple clusters from a file, given the starting cluster.
   962                                  ;
   963                                  ;	This routine makes sure the subtransfers do not cross a 64K boundary,
   964                                  ;	and will correct the situation if it does, UNLESS *sectors* cross
   965                                  ;	64K boundaries.
   966                                  ;
   967                                  ;	ES:BX	-> Buffer
   968                                  ;	SI	-> Starting cluster number (2-based)
   969                                  ;	CX	-> Cluster count (0FFFFh = until end of file)
   970                                  ;
   971                                  						; 386 check
   972                                  getfssec:
   973 00000326 31ED                    getfragment:	xor bp,bp			; Fragment sector count
   974 00000328 89F0                    		mov ax,si			; Get sector address
   975 0000032A 48                      		dec ax				; Convert to 0-based
   976 0000032B 48                      		dec ax
   977 0000032C F7260C55                		mul word [SecPerClust]
   978 00000330 0306F854                		add ax,[DataArea1]
   979 00000334 1316FA54                		adc dx,[DataArea2]
   980                                  getseccnt:					; See if we can read > 1 clust
   981 00000338 032E0C55                		add bp,[SecPerClust]
   982 0000033C 49                      		dec cx				; Reduce clusters left to find
   983 0000033D 89F7                    		mov di,si			; Predict next cluster
   984 0000033F 47                      		inc di
   985 00000340 FF160E55                		call [NextCluster]
   986 00000344 7207                    		jc gfs_eof			; At EOF?
   987 00000346 E304                    		jcxz endfragment		; Or was it the last we wanted?
   988 00000348 39FE                    		cmp si,di			; Is file continuous?
   989 0000034A 74EC                    		jz getseccnt			; Yes, we can get
   990 0000034C F8                      endfragment:	clc				; Not at EOF
   991 0000034D 9C                      gfs_eof:	pushf				; Remember EOF or not
   992 0000034E 56                      		push si
   993 0000034F 51                      		push cx
   994                                  gfs_getchunk:
   995 00000350 50                      		push ax
   996 00000351 52                      		push dx
   997 00000352 8CC0                    		mov ax,es			; Check for 64K boundaries.
   998 00000354 B104                    		mov cl,4
   999 00000356 D3E0                    		shl ax,cl
  1000 00000358 01D8                    		add ax,bx
  1001 0000035A 31D2                    		xor dx,dx
  1002 0000035C F7D8                    		neg ax
  1003 0000035E 7501                    		jnz gfs_partseg
  1004 00000360 42                      		inc dx				; Full 64K segment
  1005                                  gfs_partseg:
  1006 00000361 F736[0B00]              		div word [bsBytesPerSec]	; How many sectors fit?
  1007 00000365 89EE                    		mov si,bp
  1008 00000367 29C6                    		sub si,ax			; Compute remaining sectors
  1009 00000369 7610                    		jbe gfs_lastchunk
  1010 0000036B 89C5                    		mov bp,ax
  1011 0000036D 5A                      		pop dx
  1012 0000036E 58                      		pop ax
  1013 0000036F E81600                  		call getlinsecsr
  1014 00000372 01E8                    		add ax,bp
  1015 00000374 83D200                  		adc dx,byte 0
  1016 00000377 89F5                    		mov bp,si			; Remaining sector count
  1017 00000379 EBD5                    		jmp short gfs_getchunk
  1018 0000037B 5A                      gfs_lastchunk:	pop dx
  1019 0000037C 58                      		pop ax		
  1020 0000037D E8F4FD                  		call getlinsec
  1021 00000380 59                      		pop cx
  1022 00000381 5E                      		pop si
  1023 00000382 9D                      		popf
  1024 00000383 E302                    		jcxz gfs_return			; If we hit the count limit
  1025 00000385 739F                    		jnc getfragment			; If we didn't hit EOF
  1026 00000387 C3                      gfs_return:	ret
  1027                                  
  1028                                  ;
  1029                                  ; getlinsecsr: save registers, call getlinsec, restore registers
  1030                                  ;
  1031 00000388 50                      getlinsecsr:	push ax
  1032 00000389 52                      		push dx
  1033 0000038A 51                      		push cx
  1034 0000038B 55                      		push bp
  1035 0000038C 56                      		push si
  1036 0000038D 57                      		push di
  1037 0000038E E8E3FD                  		call getlinsec
  1038 00000391 5F                      		pop di
  1039 00000392 5E                      		pop si
  1040 00000393 5D                      		pop bp
  1041 00000394 59                      		pop cx
  1042 00000395 5A                      		pop dx
  1043 00000396 58                      		pop ax
  1044 00000397 C3                      		ret
  1045                                  
  1046                                  ;
  1047                                  ; nextcluster: Advance a cluster pointer in SI to the next cluster
  1048                                  ;	       pointed at in the FAT tables (note: FAT12 assumed)
  1049                                  ;	       Sets CF on return if end of file.
  1050                                  ;
  1051                                  ;	       The variable NextCluster gets set to the appropriate
  1052                                  ;	       value here.
  1053                                  ;
  1054                                  nextcluster_fat12:
  1055 00000398 50                      		push ax
  1056 00000399 1E                      		push ds
  1057 0000039A B80050                  		mov ax,fat_seg
  1058 0000039D 8ED8                    		mov ds,ax
  1059 0000039F 89F0                    		mov ax,si			; Multiply by 3/2
  1060 000003A1 D1E8                    		shr ax,1
  1061 000003A3 9C                      		pushf				; CF now set if odd
  1062 000003A4 01C6                    		add si,ax
  1063 000003A6 8B34                    		mov si,[si]
  1064 000003A8 9D                      		popf
  1065 000003A9 7308                    		jnc nc_even
  1066 000003AB D1EE                    		shr si,1			; Needed for odd only
  1067 000003AD D1EE                    		shr si,1
  1068 000003AF D1EE                    		shr si,1
  1069 000003B1 D1EE                    		shr si,1
  1070                                  nc_even:
  1071 000003B3 81E6FF0F                		and si,0FFFh
  1072 000003B7 81FEF00F                		cmp si,0FF0h			; Clears CF if at end of file
  1073 000003BB F5                      		cmc				; But we want it SET...
  1074 000003BC 1F                      		pop ds
  1075 000003BD 58                      		pop ax
  1076 000003BE C3                      nc_return:	ret
  1077                                  
  1078                                  ;
  1079                                  ; FAT16 decoding routine.  Note that a 16-bit FAT can be up to 128K,
  1080                                  ; so we have to decide if we're in the "low" or the "high" 64K-segment...
  1081                                  ;
  1082                                  nextcluster_fat16:
  1083 000003BF 50                      		push ax
  1084 000003C0 1E                      		push ds
  1085 000003C1 B80050                  		mov ax,fat_seg
  1086 000003C4 D1E6                    		shl si,1
  1087 000003C6 7303                    		jnc .seg0
  1088 000003C8 B80060                  		mov ax,fat_seg+1000h
  1089 000003CB 8ED8                    .seg0:		mov ds,ax
  1090 000003CD 8B34                    		mov si,[si]
  1091 000003CF 81FEF0FF                		cmp si,0FFF0h
  1092 000003D3 F5                      		cmc
  1093 000003D4 1F                      		pop ds
  1094 000003D5 58                      		pop ax
  1095 000003D6 C3                      		ret
  1096                                  ;
  1097                                  ; Debug routine
  1098                                  ;
  1099                                  %ifdef debug
  1100                                  safedumpregs:
  1101                                  		cmp word [Debug_Magic],0D00Dh
  1102                                  		jnz nc_return
  1103                                  		jmp dumpregs
  1104                                  %endif
  1105                                  
  1106                                  rl_checkpt	equ $				; Must be <= 8000h
  1107                                  
  1108                                  rl_checkpt_off	equ ($-$$)
  1109                                  %if rl_checkpt_off > 400h
  1110                                  %error "Sector 1 overflow"
  1111                                  %endif
  1112                                  
  1113                                  ; ----------------------------------------------------------------------------
  1114                                  ;  End of code and data that have to be in the first sector
  1115                                  ; ----------------------------------------------------------------------------
  1116                                  
  1117                                  all_read:
  1118                                  ;
  1119                                  ; Let the user (and programmer!) know we got this far.  This used to be
  1120                                  ; in Sector 1, but makes a lot more sense here.
  1121                                  ;
  1122 000003D7 BE[F318]                		mov si,copyright_str
  1123 000003DA E87AFD                  		call writestr
  1124                                  ;
  1125                                  ; Check that no moron is trying to boot Linux on a 286 or so.  According
  1126                                  ; to Intel, the way to check is to see if the high 4 bits of the FLAGS
  1127                                  ; register are either all stuck at 1 (8086/8088) or all stuck at 0
  1128                                  ; (286 in real mode), if not it is a 386 or higher.  They didn't
  1129                                  ; say how to check for a 186/188, so I *hope* it falls out as a 8086
  1130                                  ; or 286 in this test.
  1131                                  ;
  1132                                  ; Also, provide an escape route in case it doesn't work.
  1133                                  ;
  1134                                  check_escapes:
  1135 000003DD B402                    		mov ah,02h			; Check keyboard flags
  1136 000003DF CD16                    		int 16h
  1137 000003E1 A24655                  		mov [KbdFlags],al		; Save for boot prompt check
  1138 000003E4 A804                    		test al,04h			; Ctrl->skip 386 check
  1139 000003E6 7538                    		jnz skip_checks
  1140                                  test_8086:
  1141 000003E8 9C                      		pushf				; Get flags
  1142 000003E9 58                      		pop ax
  1143 000003EA 25FF0F                  		and ax,0FFFh			; Clear top 4 bits
  1144 000003ED 50                      		push ax				; Load into FLAGS
  1145 000003EE 9D                      		popf
  1146 000003EF 9C                      		pushf				; And load back
  1147 000003F0 58                      		pop ax
  1148 000003F1 2500F0                  		and ax,0F000h			; Get top 4 bits
  1149 000003F4 3D00F0                  		cmp ax,0F000h			; If set -> 8086/8088
  1150 000003F7 740E                    		je not_386
  1151                                  test_286:
  1152 000003F9 9C                      		pushf				; Get flags
  1153 000003FA 58                      		pop ax
  1154 000003FB 0D00F0                  		or ax,0F000h			; Set top 4 bits
  1155 000003FE 50                      		push ax
  1156 000003FF 9D                      		popf
  1157 00000400 9C                      		pushf
  1158 00000401 58                      		pop ax
  1159 00000402 2500F0                  		and ax,0F000h			; Get top 4 bits
  1160 00000405 7509                    		jnz is_386			; If not clear -> 386
  1161                                  not_386:
  1162 00000407 BE[6B19]                		mov si,err_not386
  1163 0000040A E84AFD                  		call writestr
  1164 0000040D E9FFFC                  		jmp kaboom
  1165                                  is_386:
  1166                                  		; Now we know it's a 386 or higher
  1167                                  ;
  1168                                  ; Now check that there is at least 512K of low (DOS) memory
  1169                                  ;
  1170 00000410 CD12                    		int 12h
  1171 00000412 3D0002                  		cmp ax,512
  1172 00000415 7309                    		jae enough_ram
  1173 00000417 BE[581A]                		mov si,err_noram
  1174 0000041A E83AFD                  		call writestr
  1175 0000041D E9EFFC                  		jmp kaboom
  1176                                  enough_ram:
  1177                                  skip_checks:
  1178                                  ;
  1179                                  ; Check if we're 386 (as opposed to 486+); if so we need to blank out
  1180                                  ; the WBINVD instruction
  1181                                  ;
  1182                                  ; We check for 486 by setting EFLAGS.AC
  1183                                  ;
  1184 00000420 669C                    		pushfd				; Save the good flags
  1185 00000422 669C                    		pushfd
  1186 00000424 6658                    		pop eax
  1187 00000426 6689C3                  		mov ebx,eax
  1188 00000429 663500000400            		xor eax,(1 << 18)		; AC bit
  1189 0000042F 6650                    		push eax
  1190 00000431 669D                    		popfd
  1191 00000433 669C                    		pushfd
  1192 00000435 6658                    		pop eax
  1193 00000437 669D                    		popfd				; Restore the original flags
  1194 00000439 6631D8                  		xor eax,ebx
  1195 0000043C 7505                    		jnz is_486
  1196                                  ;
  1197                                  ; 386 - Looks like we better blot out the WBINVD instruction
  1198                                  ;
  1199 0000043E C606[0810]C3            		mov byte [try_wbinvd],0c3h		; Near RET		
  1200                                  is_486:
  1201                                  
  1202                                  ;
  1203                                  ; Initialization that does not need to go into the any of the pre-load
  1204                                  ; areas
  1205                                  ;
  1206                                  		; Now set up screen parameters
  1207 00000443 E8710D                  		call adjust_screen
  1208                                  ;
  1209                                  ; Now, everything is "up and running"... patch kaboom for more
  1210                                  ; verbosity and using the full screen system
  1211                                  ;
  1212 00000446 C606[1801]E9            		mov byte [kaboom.patch],0e9h		; JMP NEAR
  1213 0000044B C706[1901]3313          		mov word [kaboom.patch+1],kaboom2-(kaboom.patch+3)
  1214                                  
  1215                                  ;
  1216                                  ; Now we're all set to start with our *real* business.	First load the
  1217                                  ; configuration file (if any) and parse it.
  1218                                  ;
  1219                                  ; In previous versions I avoided using 32-bit registers because of a
  1220                                  ; rumour some BIOSes clobbered the upper half of 32-bit registers at
  1221                                  ; random.  I figure, though, that if there are any of those still left
  1222                                  ; they probably won't be trying to install Linux on them...
  1223                                  ;
  1224                                  ; The code is still ripe with 16-bitisms, though.  Not worth the hassle
  1225                                  ; to take'm out.  In fact, we may want to put them back if we're going
  1226                                  ; to boot ELKS at some point.
  1227                                  ;
  1228 00000451 BE[7C1D]                		mov si,linuxauto_cmd		; Default command: "linux auto"
  1229 00000454 BF[951E]                		mov di,default_cmd
  1230 00000457 B90B00                                  mov cx,linuxauto_len
  1231 0000045A F3A4                    		rep movsb
  1232                                  
  1233 0000045C BF0053                  		mov di,KbdMap			; Default keymap 1:1
  1234 0000045F 30C0                    		xor al,al
  1235 00000461 B90001                  		mov cx,256
  1236 00000464 AA                      mkkeymap:	stosb
  1237 00000465 FEC0                    		inc al
  1238 00000467 E2FB                    		loop mkkeymap
  1239                                  
  1240                                  ;
  1241                                  ; Load configuration file
  1242                                  ;
  1243 00000469 BF[FE1C]                		mov di,syslinux_cfg
  1244 0000046C E8EF0F                  		call open
  1245 0000046F 0F844D02                		jz near no_config_file
  1246                                  parse_config:
  1247 00000473 E88410                  		call getkeyword
  1248 00000476 0F824302                                jc near end_config_file		; Config file loaded
  1249 0000047A 3D6465                  		cmp ax,'de'			; DEfault
  1250 0000047D 7449                    		je pc_default
  1251 0000047F 3D6170                  		cmp ax,'ap'			; APpend
  1252 00000482 744F                    		je pc_append
  1253 00000484 3D7469                  		cmp ax,'ti'			; TImeout
  1254 00000487 0F849700                		je near pc_timeout
  1255 0000048B 3D7072                  		cmp ax,'pr'			; PRompt
  1256 0000048E 0F84AD00                		je near pc_prompt
  1257 00000492 3D666F                  		cmp ax,'fo'			; FOnt
  1258 00000495 0F84CE01                		je near pc_font
  1259 00000499 3D6B62                  		cmp ax,'kb'			; KBd
  1260 0000049C 0F84D101                		je near pc_kbd
  1261 000004A0 3D6469                  		cmp ax,'di'			; DIsplay
  1262 000004A3 0F848D00                		je near pc_display
  1263 000004A7 3D6C61                  		cmp ax,'la'			; LAbel
  1264 000004AA 0F848601                		je near pc_label
  1265 000004AE 3D6B65                  		cmp ax,'ke'			; KErnel
  1266 000004B1 7456                    		je pc_kernel
  1267 000004B3 3D696D                                  cmp ax,'im'                     ; IMplicit
  1268 000004B6 0F849000                                je near pc_implicit
  1269 000004BA 3D7365                  		cmp ax,'se'			; SErial
  1270 000004BD 0F849400                		je near pc_serial
  1271 000004C1 3C66                    		cmp al,'f'			; F-key
  1272 000004C3 75AE                    		jne parse_config
  1273 000004C5 E94201                  		jmp pc_fkey
  1274                                  
  1275 000004C8 BF[951E]                pc_default:	mov di,default_cmd		; "default" command
  1276 000004CB E83D11                  		call getline
  1277 000004CE 30C0                    		xor al,al
  1278 000004D0 AA                      		stosb				; null-terminate
  1279 000004D1 EBA0                    		jmp short parse_config
  1280                                  
  1281 000004D3 833E[5A1D]00            pc_append:      cmp word [VKernelCtr],byte 0	; "append" command
  1282 000004D8 7710                    		ja pc_append_vk
  1283 000004DA BF0052                                  mov di,AppendBuf
  1284 000004DD E82B11                  		call getline
  1285 000004E0 81EF0052                                sub di,AppendBuf
  1286 000004E4 893E[501D]              pc_app1:        mov [AppendLen],di
  1287 000004E8 EB89                                    jmp short parse_config
  1288 000004EA BF1850                  pc_append_vk:	mov di,VKernelBuf+vk_append	; "append" command (vkernel)
  1289 000004ED E81B11                  		call getline
  1290 000004F0 81EF1850                		sub di,VKernelBuf+vk_append
  1291 000004F4 83FF02                                  cmp di,byte 2
  1292 000004F7 750A                                    jne pc_app2
  1293 000004F9 803E18502D                              cmp byte [VKernelBuf+vk_append],'-'
  1294 000004FE 7503                                    jne pc_app2
  1295 00000500 BF0000                                  mov di,0                        ; If "append -" -> null string
  1296 00000503 893E1650                pc_app2:        mov [VKernelBuf+vk_appendlen],di
  1297 00000507 EB33                    		jmp short parse_config_2	
  1298                                  
  1299 00000509 833E[5A1D]00            pc_kernel:	cmp word [VKernelCtr],byte 0	; "kernel" command
  1300 0000050E 0F8461FF                		je near parse_config		; ("label" section only)
  1301 00000512 BF0010                  		mov di,trackbuf
  1302 00000515 57                      		push di
  1303 00000516 E8F210                  		call getline
  1304 00000519 5E                      		pop si
  1305 0000051A BF0B50                  		mov di,VKernelBuf+vk_rname
  1306 0000051D E82811                  		call mangle_name
  1307 00000520 EB1A                    		jmp short parse_config_2
  1308                                  
  1309 00000522 E83110                  pc_timeout:	call getint			; "timeout" command
  1310 00000525 7215                    		jc parse_config_2
  1311 00000527 B815D2                  		mov ax,0D215h			; There are approx 1.D215h
  1312 0000052A F7E3                    		mul bx				; clock ticks per 1/10 s
  1313 0000052C 01D3                    		add bx,dx
  1314 0000052E 891E[521D]              		mov [KbdTimeOut],bx
  1315 00000532 EB08                    		jmp short parse_config_2
  1316                                  
  1317 00000534 E84501                  pc_display:	call pc_getfile			; "display" command
  1318 00000537 7403                    		jz parse_config_2		; File not found?
  1319 00000539 E8B50C                  		call get_msg_file		; Load and display file
  1320 0000053C E934FF                  parse_config_2: jmp parse_config
  1321                                  
  1322 0000053F E81410                  pc_prompt:	call getint			; "prompt" command
  1323 00000542 72F8                    		jc parse_config_2
  1324 00000544 891E[5C1D]              		mov [ForcePrompt],bx
  1325 00000548 EBF2                    		jmp short parse_config_2
  1326                                  
  1327 0000054A E80910                  pc_implicit:    call getint                     ; "implicit" command
  1328 0000054D 72ED                                    jc parse_config_2
  1329 0000054F 891E[5E1D]                              mov [AllowImplicit],bx
  1330 00000553 EBE7                                    jmp short parse_config_2
  1331                                  
  1332 00000555 E8FE0F                  pc_serial:	call getint			; "serial" command
  1333 00000558 72E2                    		jc parse_config_2
  1334 0000055A 53                      		push bx				; Serial port #
  1335 0000055B E8830F                  		call skipspace
  1336 0000055E 72DC                    		jc parse_config_2
  1337 00000560 E86D0F                  		call ungetc
  1338 00000563 E8F00F                  		call getint
  1339 00000566 C70642550000            		mov [FlowControl], word 0	; Default to no flow control
  1340 0000056C 7229                    		jc .nobaud
  1341                                  .valid_baud:	
  1342 0000056E 6653                    		push ebx
  1343 00000570 E86E0F                  		call skipspace
  1344 00000573 7208                    		jc .no_flow
  1345 00000575 E8580F                  		call ungetc
  1346 00000578 E8DB0F                  		call getint			; Hardware flow control?
  1347 0000057B 7302                    		jnc .valid_flow
  1348                                  .no_flow:
  1349 0000057D 31DB                    		xor bx,bx			; Default -> no flow control
  1350                                  .valid_flow:
  1351 0000057F 80E70F                  		and bh,0Fh			; FlowIgnore
  1352 00000582 C0E704                  		shl bh,4
  1353 00000585 883E4455                		mov [FlowIgnore],bh
  1354 00000589 88DF                    		mov bh,bl
  1355 0000058B 81E303F0                		and bx,0F003h			; Valid bits
  1356 0000058F 891E4255                		mov [FlowControl],bx
  1357 00000593 665B                    		pop ebx				; Baud rate
  1358 00000595 EB06                    		jmp short .parse_baud
  1359                                  .nobaud:
  1360 00000597 66BB80250000            		mov ebx,DEFAULT_BAUD		; No baud rate given
  1361                                  .parse_baud:
  1362 0000059D 5F                      		pop di				; Serial port #
  1363 0000059E 6683FB4B                		cmp ebx,byte 75
  1364 000005A2 7298                    		jb parse_config_2		; < 75 baud == bogus
  1365 000005A4 66B800C20100            		mov eax,BAUD_DIVISOR
  1366 000005AA 6699                    		cdq
  1367 000005AC 66F7F3                  		div ebx
  1368 000005AF 50                      		push ax				; Baud rate divisor
  1369 000005B0 81FF0300                		cmp di,3
  1370 000005B4 7706                    		ja .port_is_io			; If port > 3 then port is I/O addr
  1371 000005B6 D1E7                    		shl di,1
  1372 000005B8 8BBD0004                		mov di,[di+serial_base]		; Get the I/O port from the BIOS
  1373                                  .port_is_io:
  1374 000005BC 893E[601D]              		mov [SerialPort],di
  1375 000005C0 8D5503                  		lea dx,[di+3]			; DX -> LCR
  1376 000005C3 B083                    		mov al,83h			; Enable DLAB
  1377 000005C5 E83509                  		call slow_out
  1378 000005C8 58                      		pop ax				; Divisor
  1379 000005C9 89FA                    		mov dx,di			; DX -> LS
  1380 000005CB E82F09                  		call slow_out
  1381 000005CE 42                      		inc dx				; DX -> MS
  1382 000005CF 88E0                    		mov al,ah
  1383 000005D1 E82909                  		call slow_out
  1384 000005D4 B003                    		mov al,03h			; Disable DLAB
  1385 000005D6 83C202                  		add dx,byte 2			; DX -> LCR
  1386 000005D9 E82109                  		call slow_out
  1387 000005DC EC                      		in al,dx			; Read back LCR (detect missing hw)
  1388 000005DD 3C03                    		cmp al,03h			; If nothing here we'll read 00 or FF
  1389 000005DF 7521                    		jne .serial_port_bad		; Assume serial port busted
  1390 000005E1 83EA02                  		sub dx,byte 2			; DX -> IER
  1391 000005E4 30C0                    		xor al,al			; IRQ disable
  1392 000005E6 E81409                  		call slow_out
  1393                                  
  1394 000005E9 83C203                  		add dx,byte 3			; DX -> MCR
  1395 000005EC EC                      		in al,dx
  1396 000005ED 0A064255                		or al,[FlowOutput]		; Assert bits
  1397 000005F1 E80909                  		call slow_out
  1398                                  
  1399                                  		; Show some life
  1400 000005F4 BE[0002]                		mov si,syslinux_banner
  1401 000005F7 E8C10D                  		call write_serial_str
  1402 000005FA BE[F318]                		mov si,copyright_str
  1403 000005FD E8BB0D                  		call write_serial_str
  1404                                  
  1405 00000600 EB77                    		jmp short parse_config_3
  1406                                  
  1407                                  .serial_port_bad:
  1408 00000602 C706[601D]0000          		mov [SerialPort], word 0
  1409 00000608 EB6F                    		jmp short parse_config_3
  1410                                  
  1411 0000060A 80EC31                  pc_fkey:	sub ah,'1'
  1412 0000060D 7302                    		jnb pc_fkey1
  1413 0000060F B409                    		mov ah,9			; F10
  1414 00000611 31C9                    pc_fkey1:	xor cx,cx
  1415 00000613 88E1                    		mov cl,ah
  1416 00000615 51                      		push cx
  1417 00000616 B80100                  		mov ax,1
  1418 00000619 D3E0                    		shl ax,cl
  1419 0000061B 0906[541D]              		or [FKeyMap], ax		; Mark that we have this loaded
  1420 0000061F BF0010                  		mov di,trackbuf
  1421 00000622 57                      		push di
  1422 00000623 E8E50F                  		call getline			; Get filename to display
  1423 00000626 5E                      		pop si
  1424 00000627 5F                      		pop di
  1425 00000628 C1E704                  		shl di,4			; Multiply number by 16
  1426 0000062B 81C70054                		add di,FKeyName
  1427 0000062F E81610                  		call mangle_name		; Mangle file name
  1428 00000632 EB45                    		jmp short parse_config_3
  1429                                  
  1430 00000634 E85800                  pc_label:	call commit_vk			; Commit any current vkernel
  1431 00000637 BF0010                  		mov di,trackbuf			; Get virtual filename
  1432 0000063A 57                      		push di
  1433 0000063B E8CD0F                  		call getline
  1434 0000063E 5E                      		pop si
  1435 0000063F BF0050                  		mov di,VKernelBuf+vk_vname
  1436 00000642 E80310                  		call mangle_name		; Mangle virtual name
  1437 00000645 FF06[5A1D]              		inc word [VKernelCtr]		; One more vkernel
  1438 00000649 BE0050                  		mov si,VKernelBuf+vk_vname 	; By default, rname == vname
  1439 0000064C BF0B50                  		mov di,VKernelBuf+vk_rname
  1440 0000064F B90B00                  		mov cx,11
  1441 00000652 F3A4                    		rep movsb
  1442 00000654 BE0052                                  mov si,AppendBuf         	; Default append==global append
  1443 00000657 BF1850                                  mov di,VKernelBuf+vk_append
  1444 0000065A 8B0E[501D]                              mov cx,[AppendLen]
  1445 0000065E 890E1650                                mov [VKernelBuf+vk_appendlen],cx
  1446 00000662 F3A4                                    rep movsb
  1447 00000664 E91200                  		jmp near parse_config_3
  1448                                  
  1449 00000667 E81200                  pc_font:	call pc_getfile			; "font" command
  1450 0000066A 740D                    		jz parse_config_3		; File not found?
  1451 0000066C E8C40A                  		call loadfont			; Load and install font
  1452 0000066F EB08                    		jmp short parse_config_3
  1453                                  
  1454 00000671 E80800                  pc_kbd:		call pc_getfile			; "kbd" command
  1455 00000674 7403                    		jz parse_config_3
  1456 00000676 E8590B                  		call loadkeys
  1457 00000679 E9F7FD                  parse_config_3:	jmp parse_config
  1458                                  
  1459                                  ;
  1460                                  ; pc_getfile:	For command line options that take file argument, this
  1461                                  ; 		routine decodes the file argument and runs it through searchdir
  1462                                  ;
  1463 0000067C BF0010                  pc_getfile:	mov di,trackbuf
  1464 0000067F 57                      		push di
  1465 00000680 E8880F                  		call getline
  1466 00000683 5E                      		pop si
  1467 00000684 BF4B55                  		mov di,MNameBuf
  1468 00000687 57                      		push di
  1469 00000688 E8BD0F                  		call mangle_name
  1470 0000068B 5F                      		pop di
  1471 0000068C E9210A                  		jmp searchdir			; Tailcall
  1472                                  
  1473                                  ;
  1474                                  ; commit_vk: Store the current VKernelBuf into buffer segment
  1475                                  ;
  1476                                  commit_vk:
  1477 0000068F 833E[5A1D]00            		cmp word [VKernelCtr],byte 0
  1478 00000694 741F                    		je cvk_ret			; No VKernel = return
  1479 00000696 813E[5A1D]8000          		cmp word [VKernelCtr],max_vk	; Above limit?
  1480 0000069C 7718                    		ja cvk_overflow
  1481 0000069E 8B3E[5A1D]              		mov di,[VKernelCtr]
  1482 000006A2 4F                      		dec di
  1483 000006A3 C1E709                  		shl di,vk_shift
  1484 000006A6 BE0050                  		mov si,VKernelBuf
  1485 000006A9 B98000                  		mov cx,(vk_size >> 2)
  1486 000006AC 06                      		push es
  1487 000006AD 680040                  		push word vk_seg
  1488 000006B0 07                      		pop es
  1489 000006B1 F366A5                  		rep movsd			; Copy to buffer segment
  1490 000006B4 07                      		pop es
  1491 000006B5 C3                      cvk_ret:	ret
  1492 000006B6 C706[5A1D]8000          cvk_overflow:	mov word [VKernelCtr],max_vk	; No more than max_vk, please
  1493 000006BC C3                      		ret
  1494                                  
  1495                                  ;
  1496                                  ; End of configuration file
  1497                                  ;
  1498                                  end_config_file:
  1499 000006BD E8CFFF                  		call commit_vk			; Commit any current vkernel
  1500                                  no_config_file:
  1501                                  ;
  1502                                  ; Check whether or not we are supposed to display the boot prompt.
  1503                                  ;
  1504                                  check_for_key:
  1505 000006C0 833E[5C1D]00            		cmp word [ForcePrompt],byte 0	; Force prompt?
  1506 000006C5 7509                    		jnz enter_command
  1507 000006C7 F60646555B              		test byte [KbdFlags],5Bh	; Caps, Scroll, Shift, Alt
  1508 000006CC 0F84FA00                		jz near auto_boot		; If neither, default boot
  1509                                  
  1510                                  enter_command:
  1511 000006D0 BE[1D19]                		mov si,boot_prompt
  1512 000006D3 E8060D                  		call cwritestr
  1513                                  
  1514 000006D6 C606495500              		mov byte [FuncFlag],0		; <Ctrl-F> not pressed
  1515 000006DB BF[941D]                		mov di,command_line
  1516                                  ;
  1517                                  ; get the very first character -- we can either time
  1518                                  ; out, or receive a character press at this time.  Some dorky BIOSes stuff
  1519                                  ; a return in the buffer on bootup, so wipe the keyboard buffer first.
  1520                                  ;
  1521 000006DE B401                    clear_buffer:	mov ah,1			; Check for pending char
  1522 000006E0 CD16                    		int 16h
  1523 000006E2 7406                    		jz get_char_time
  1524 000006E4 31C0                    		xor ax,ax			; Get char
  1525 000006E6 CD16                    		int 16h
  1526 000006E8 EBF4                    		jmp short clear_buffer
  1527                                  get_char_time:	
  1528 000006EA E8B011                  		call vgashowcursor
  1529 000006ED 8B0E[521D]              		mov cx,[KbdTimeOut]
  1530 000006F1 21C9                    		and cx,cx
  1531 000006F3 741C                    		jz get_char			; Timeout == 0 -> no timeout
  1532 000006F5 41                      		inc cx				; The first loop will happen
  1533                                  						; immediately as we don't
  1534                                  						; know the appropriate DX value
  1535 000006F6 51                      time_loop:	push cx
  1536 000006F7 52                      tick_loop:	push dx
  1537 000006F8 E8F40C                  		call pollchar
  1538 000006FB 7512                    		jnz get_char_pop
  1539 000006FD 31C0                    		xor ax,ax
  1540 000006FF CD1A                    		int 1Ah				; Get time "of day"
  1541 00000701 58                      		pop ax
  1542 00000702 39C2                    		cmp dx,ax			; Has the timer advanced?
  1543 00000704 74F1                    		je tick_loop
  1544 00000706 59                      		pop cx
  1545 00000707 E2ED                    		loop time_loop			; If so, decrement counter
  1546 00000709 E89711                  		call vgahidecursor
  1547 0000070C E9C900                  		jmp command_done		; Timeout!
  1548                                  
  1549 0000070F 6658                    get_char_pop:	pop eax				; Clear stack
  1550                                  get_char:
  1551 00000711 E88911                  		call vgashowcursor
  1552 00000714 E8020D                  		call getchar
  1553 00000717 E88911                  		call vgahidecursor
  1554 0000071A 20C0                    		and al,al
  1555 0000071C 7462                    		jz func_key
  1556                                  
  1557 0000071E 3C7F                    got_ascii:	cmp al,7Fh			; <DEL> == <BS>
  1558 00000720 743F                    		je backspace
  1559 00000722 3C20                    		cmp al,' '			; ASCII?
  1560 00000724 722A                    		jb not_ascii
  1561 00000726 7706                    		ja enter_char
  1562 00000728 81FF[941D]              		cmp di,command_line		; Space must not be first
  1563 0000072C 74E3                    		je get_char
  1564 0000072E F606495501              enter_char:	test byte [FuncFlag],1
  1565 00000733 740F                    		jz .not_ctrl_f
  1566 00000735 C606495500              		mov byte [FuncFlag],0
  1567 0000073A 3C30                    		cmp al,'0'
  1568 0000073C 7206                    		jb .not_ctrl_f
  1569 0000073E 7437                    		je ctrl_f_0
  1570 00000740 3C39                    		cmp al,'9'
  1571 00000742 7635                    		jbe ctrl_f
  1572 00000744 81FF[931E]              .not_ctrl_f:	cmp di,max_cmd_len+command_line ; Check there's space
  1573 00000748 73C7                    		jnb get_char
  1574 0000074A AA                      		stosb				; Save it
  1575 0000074B E8780C                  		call writechr			; Echo to screen
  1576 0000074E EBC1                    get_char_2:	jmp short get_char
  1577 00000750 C606495500              not_ascii:	mov byte [FuncFlag],0
  1578 00000755 3C0D                    		cmp al,0Dh			; Enter
  1579 00000757 747F                    		je command_done
  1580 00000759 3C06                    		cmp al,06h			; <Ctrl-F>
  1581 0000075B 7413                    		je set_func_flag
  1582 0000075D 3C08                    		cmp al,08h			; Backspace
  1583 0000075F 75B0                    		jne get_char
  1584 00000761 81FF[941D]              backspace:	cmp di,command_line		; Make sure there is anything
  1585 00000765 74AA                    		je get_char			; to erase
  1586 00000767 4F                      		dec di				; Unstore one character
  1587 00000768 BE[2419]                		mov si,wipe_char		; and erase it from the screen
  1588 0000076B E86E0C                  		call cwritestr
  1589 0000076E EBDE                    		jmp short get_char_2
  1590                                  
  1591                                  set_func_flag:
  1592 00000770 C606495501              		mov byte [FuncFlag],1
  1593 00000775 EBD7                    		jmp short get_char_2
  1594                                  
  1595 00000777 040A                    ctrl_f_0:	add al,10			; <Ctrl-F>0 == F10
  1596 00000779 57                      ctrl_f:		push di
  1597 0000077A 2C31                    		sub al,'1'
  1598 0000077C 30E4                    		xor ah,ah
  1599 0000077E EB0E                    		jmp short show_help
  1600                                  
  1601                                  func_key:
  1602 00000780 57                      		push di
  1603 00000781 80FC44                  		cmp ah,68			; F10
  1604 00000784 77C8                    		ja get_char_2
  1605 00000786 80EC3B                  		sub ah,59			; F1
  1606 00000789 72C3                    		jb get_char_2
  1607 0000078B C1E808                  		shr ax,8
  1608                                  show_help:	; AX = func key # (0 = F1, 9 = F10)
  1609 0000078E 88C1                    		mov cl,al
  1610 00000790 C1E004                  		shl ax,4			; Convert to x16
  1611 00000793 BB0100                  		mov bx,1
  1612 00000796 D3E3                    		shl bx,cl
  1613 00000798 231E[541D]              		and bx,[FKeyMap]
  1614 0000079C 74B0                    		jz get_char_2			; Undefined F-key
  1615 0000079E 89C7                    		mov di,ax
  1616 000007A0 81C70054                		add di,FKeyName
  1617 000007A4 E80909                  		call searchdir
  1618 000007A7 740A                    		jz fk_nofile
  1619 000007A9 56                      		push si
  1620 000007AA E82C0C                  		call crlf
  1621 000007AD 5E                      		pop si
  1622 000007AE E8400A                  		call get_msg_file
  1623 000007B1 EB03                    		jmp short fk_wrcmd
  1624                                  fk_nofile:
  1625 000007B3 E8230C                  		call crlf
  1626                                  fk_wrcmd:
  1627 000007B6 BE[1D19]                		mov si,boot_prompt
  1628 000007B9 E8200C                  		call cwritestr
  1629 000007BC 5F                      		pop di				; Command line write pointer
  1630 000007BD 57                      		push di
  1631 000007BE C60500                  		mov byte [di],0			; Null-terminate command line
  1632 000007C1 BE[941D]                		mov si,command_line
  1633 000007C4 E8150C                  		call cwritestr			; Write command line so far
  1634 000007C7 5F                      		pop di
  1635 000007C8 EB84                    		jmp short get_char_2
  1636                                  auto_boot:
  1637 000007CA BE[951E]                		mov si,default_cmd
  1638 000007CD BF[941D]                		mov di,command_line
  1639 000007D0 B94000                  		mov cx,(max_cmd_len+4) >> 2
  1640 000007D3 F366A5                  		rep movsd
  1641 000007D6 EB0C                    		jmp short load_kernel
  1642                                  command_done:
  1643 000007D8 E8FE0B                  		call crlf
  1644 000007DB 81FF[941D]              		cmp di,command_line		; Did we just hit return?
  1645 000007DF 74E9                    		je auto_boot
  1646 000007E1 30C0                    		xor al,al			; Store a final null
  1647 000007E3 AA                      		stosb
  1648                                  
  1649                                  load_kernel:					; Load the kernel now
  1650                                  ;
  1651                                  ; First we need to mangle the kernel name the way DOS would...
  1652                                  ;
  1653 000007E4 BE[941D]                		mov si,command_line
  1654 000007E7 BFE854                                  mov di,KernelName
  1655 000007EA 56                                      push si
  1656 000007EB 57                                      push di
  1657 000007EC E8590E                  		call mangle_name
  1658 000007EF 5F                      		pop di
  1659 000007F0 5E                                      pop si
  1660                                  ;
  1661                                  ; Fast-forward to first option (we start over from the beginning, since
  1662                                  ; mangle_name doesn't necessarily return a consistent ending state.)
  1663                                  ;
  1664 000007F1 AC                      clin_non_wsp:   lodsb
  1665 000007F2 3C20                                    cmp al,' '
  1666 000007F4 77FB                                    ja clin_non_wsp
  1667 000007F6 20C0                    clin_is_wsp:    and al,al
  1668 000007F8 7405                                    jz clin_opt_ptr
  1669 000007FA AC                                      lodsb
  1670 000007FB 3C20                                    cmp al,' '
  1671 000007FD 76F7                                    jbe clin_is_wsp
  1672 000007FF 4E                      clin_opt_ptr:   dec si                          ; Point to first nonblank
  1673 00000800 89362455                                mov [CmdOptPtr],si		; Save ptr to first option
  1674                                  ;
  1675                                  ; Now check if it is a "virtual kernel"
  1676                                  ;
  1677 00000804 8B0E[5A1D]              		mov cx,[VKernelCtr]
  1678 00000808 1E                      		push ds
  1679 00000809 680040                  		push word vk_seg
  1680 0000080C 1F                      		pop ds
  1681 0000080D 83F900                  		cmp cx,byte 0
  1682 00000810 7413                    		je not_vk
  1683 00000812 31F6                    		xor si,si			; Point to first vkernel
  1684 00000814 60                      vk_check:	pusha
  1685 00000815 B90B00                  		mov cx,11
  1686 00000818 F3A6                    		repe cmpsb			; Is this it?
  1687 0000081A 0F847700                		je near vk_found
  1688 0000081E 61                      		popa
  1689 0000081F 81C60002                		add si,vk_size
  1690 00000823 E2EF                    		loop vk_check
  1691 00000825 1F                      not_vk:		pop ds
  1692                                  ;
  1693                                  ; Not a "virtual kernel" - check that's OK and construct the command line
  1694                                  ;
  1695 00000826 833E[5E1D]00                            cmp word [AllowImplicit],byte 0
  1696 0000082B 745D                                    je bad_implicit
  1697 0000082D 06                                      push es
  1698 0000082E 56                                      push si
  1699 0000082F 57                                      push di
  1700 00000830 BF0070                                  mov di,real_mode_seg
  1701 00000833 8EC7                                    mov es,di
  1702 00000835 BE0052                                  mov si,AppendBuf
  1703 00000838 BF0090                                  mov di,cmd_line_here
  1704 0000083B 8B0E[501D]                              mov cx,[AppendLen]
  1705 0000083F F3A4                                    rep movsb
  1706 00000841 893E[561D]                              mov [CmdLinePtr],di
  1707 00000845 5F                                      pop di
  1708 00000846 5E                                      pop si
  1709 00000847 07                                      pop es
  1710 00000848 BB1000                  		mov bx,exten_count << 2		; Alternates to try
  1711                                  ;
  1712                                  ; Find the kernel on disk
  1713                                  ;
  1714 0000084B C606F35400              get_kernel:     mov byte [KernelName+11],0	; Zero-terminate filename/extension
  1715 00000850 66A1F054                		mov eax,[KernelName+8]		; Save initial extension
  1716 00000854 66A3[3C1D]              		mov [OrigKernelExt],eax
  1717 00000858 53                      .search_loop:	push bx
  1718 00000859 BFE854                                  mov di,KernelName	      	; Search on disk
  1719 0000085C E85108                                  call searchdir
  1720 0000085F 5B                      		pop bx
  1721 00000860 756C                                    jnz kernel_good
  1722 00000862 668B87[3C1D]            		mov eax,[exten_table+bx]	; Try a different extension
  1723 00000867 66A3F054                		mov [KernelName+8],eax
  1724 0000086B 83EB04                  		sub bx,byte 4
  1725 0000086E 73E8                    		jnb .search_loop
  1726                                  bad_kernel:     
  1727 00000870 BEE854                  		mov si,KernelName
  1728 00000873 BF6155                                  mov di,KernelCName
  1729 00000876 57                      		push di
  1730 00000877 E82A0E                                  call unmangle_name              ; Get human form
  1731 0000087A BE[2819]                		mov si,err_notfound		; Complain about missing kernel
  1732 0000087D E85C0B                  		call cwritestr
  1733 00000880 5E                      		pop si				; KernelCName
  1734 00000881 E8580B                                  call cwritestr
  1735 00000884 BE[F81C]                                mov si,crlf_msg
  1736 00000887 E91108                                  jmp abort_load                  ; Ask user for clue
  1737                                  ;
  1738                                  ; bad_implicit: The user entered a nonvirtual kernel name, with "implicit 0"
  1739                                  ;
  1740 0000088A BEE854                  bad_implicit:   mov si,KernelName		; For the error message
  1741 0000088D BF6155                                  mov di,KernelCName
  1742 00000890 E8110E                                  call unmangle_name
  1743 00000893 EBDB                                    jmp short bad_kernel
  1744                                  ;
  1745                                  ; vk_found: We *are* using a "virtual kernel"
  1746                                  ;
  1747 00000895 61                      vk_found:	popa
  1748 00000896 57                      		push di
  1749 00000897 BF0050                  		mov di,VKernelBuf
  1750 0000089A B98000                  		mov cx,vk_size >> 2
  1751 0000089D F366A5                  		rep movsd
  1752 000008A0 06                      		push es				; Restore old DS
  1753 000008A1 1F                      		pop ds
  1754 000008A2 06                      		push es
  1755 000008A3 680070                  		push word real_mode_seg
  1756 000008A6 07                      		pop es
  1757 000008A7 BF0090                  		mov di,cmd_line_here
  1758 000008AA BE1850                  		mov si,VKernelBuf+vk_append
  1759 000008AD 8B0E1650                		mov cx,[VKernelBuf+vk_appendlen]
  1760 000008B1 F3A4                    		rep movsb
  1761 000008B3 893E[561D]              		mov [CmdLinePtr],di		; Where to add rest of cmd
  1762 000008B7 07                      		pop es
  1763 000008B8 5F                                      pop di                          ; DI -> KernelName
  1764 000008B9 57                      		push di	
  1765 000008BA BE0B50                  		mov si,VKernelBuf+vk_rname
  1766 000008BD B90B00                  		mov cx,11			; We need ECX == CX later
  1767 000008C0 F3A4                    		rep movsb
  1768 000008C2 5F                      		pop di
  1769 000008C3 31DB                    		xor bx,bx			; Try only one version
  1770 000008C5 E983FF                  		jmp get_kernel
  1771                                  ;
  1772                                  ; kernel_corrupt: Called if the kernel file does not seem healthy
  1773                                  ;
  1774 000008C8 BE[4619]                kernel_corrupt: mov si,err_notkernel
  1775 000008CB E9CD07                                  jmp abort_load
  1776                                  ;
  1777                                  ; This is it!  We have a name (and location on the disk)... let's load
  1778                                  ; that sucker!!  First we have to decide what kind of file this is; base
  1779                                  ; that decision on the file extension.  The following extensions are
  1780                                  ; recognized:
  1781                                  ;
  1782                                  ; .COM 	- COMBOOT image
  1783                                  ; .CBT	- COMBOOT image
  1784                                  ; .BS	- Boot sector
  1785                                  ; .BSS	- Boot sector, but transfer over DOS superblock
  1786                                  ;
  1787                                  ; Anything else is assumed to be a Linux kernel.
  1788                                  ;
  1789                                  kernel_good:
  1790 000008CE 60                      		pusha
  1791 000008CF BEE854                  		mov si,KernelName
  1792 000008D2 BF6155                                  mov di,KernelCName
  1793 000008D5 E8CC0D                                  call unmangle_name              ; Get human form
  1794 000008D8 81EF6155                                sub di,KernelCName
  1795 000008DC 893E2655                                mov [KernelCNameLen],di
  1796 000008E0 61                      		popa
  1797                                  
  1798 000008E1 668B0EF054              		mov ecx,[KernelName+8]		; Get (mangled) extension
  1799 000008E6 6681F9434F4D00          		cmp ecx,'COM'
  1800 000008ED 0F847C04                		je near is_comboot_image
  1801 000008F1 6681F943425400          		cmp ecx,'CBT'
  1802 000008F8 0F847104                		je near is_comboot_image
  1803 000008FC 6681F942532000          		cmp ecx,'BS '
  1804 00000903 0F841B05                		je near is_bootsector
  1805 00000907 6681F942535300          		cmp ecx,'BSS'
  1806 0000090E 0F841505                		je near is_bss_sector
  1807                                  		; Otherwise Linux kernel
  1808                                  ;
  1809                                  ; A Linux kernel consists of three parts: boot sector, setup code, and
  1810                                  ; kernel code.	The boot sector is never executed when using an external
  1811                                  ; booting utility, but it contains some status bytes that are necessary.
  1812                                  ; The boot sector and setup code together form exactly 5 sectors that
  1813                                  ; should be loaded at 9000:0.  The subsequent code should be loaded
  1814                                  ; at 1000:0.  For simplicity, we load the whole thing at 0F60:0, and
  1815                                  ; copy the latter stuff afterwards.
  1816                                  ;
  1817                                  ; NOTE: In the previous code I have avoided making any assumptions regarding
  1818                                  ; the size of a sector, in case this concept ever gets extended to other
  1819                                  ; media like CD-ROM (not that a CD-ROM would be bloody likely to use a FAT
  1820                                  ; filesystem, of course).  However, a "sector" when it comes to Linux booting
  1821                                  ; stuff means 512 bytes *no matter what*, so here I am using that piece
  1822                                  ; of knowledge.
  1823                                  ;
  1824                                  ; First check that our kernel is at least 1K and less than 8M (if it is
  1825                                  ; more than 8M, we need to change the logic for loading it anyway...)
  1826                                  ;
  1827                                  ; We used to require the kernel to be 64K or larger, but it has gotten
  1828                                  ; popular to use the Linux kernel format for other things, which may
  1829                                  ; not be so large.
  1830                                  ;
  1831                                  is_linux_kernel:
  1832 00000912 81FA8000                                cmp dx,80h			; 8 megs
  1833 00000916 77B0                    		ja kernel_corrupt
  1834 00000918 21D2                    		and dx,dx
  1835 0000091A 7505                    		jnz kernel_sane
  1836 0000091C 3D0004                  		cmp ax,1024			; Bootsect + 1 setup sect
  1837 0000091F 72A7                    		jb kernel_corrupt
  1838 00000921 50                      kernel_sane:	push ax
  1839 00000922 52                      		push dx
  1840 00000923 56                      		push si
  1841 00000924 BE[E31C]                		mov si,loading_msg
  1842 00000927 E8B20A                                  call cwritestr
  1843                                  ;
  1844                                  ; Now start transferring the kernel
  1845                                  ;
  1846 0000092A 680070                  		push word real_mode_seg
  1847 0000092D 07                      		pop es
  1848                                  
  1849 0000092E 50                      		push ax
  1850 0000092F 52                      		push dx
  1851 00000930 F7360A55                		div word [ClustSize]		; # of clusters total
  1852 00000934 21D2                    		and dx,dx			; Round up
  1853 00000936 0F95C2                  		setnz dl
  1854 00000939 0FB6D2                  		movzx dx,dl
  1855 0000093C 01D0                    		add ax,dx
  1856 0000093E A31855                                  mov [KernelClust],ax
  1857 00000941 5A                      		pop dx
  1858 00000942 58                      		pop ax
  1859 00000943 A3E454                  		mov [KernelSize],ax
  1860 00000946 8916E654                		mov [KernelSize+2],dx
  1861                                  ;
  1862                                  ; Now, if we transfer these straight, we'll hit 64K boundaries.	 Hence we
  1863                                  ; have to see if we're loading more than 64K, and if so, load it step by
  1864                                  ; step.
  1865                                  ;
  1866 0000094A BA0100                  		mov dx,1			; 10000h
  1867 0000094D 31C0                    		xor ax,ax
  1868 0000094F F7360A55                		div word [ClustSize]
  1869 00000953 A31C55                  		mov [ClustPerMoby],ax		; Clusters/64K
  1870                                  ;
  1871                                  ; Start by loading the bootsector/setup code, to see if we need to
  1872                                  ; do something funky.  It should fit in the first 32K (loading 64K won't
  1873                                  ; work since we might have funny stuff up near the end of memory).
  1874                                  ; If we have larger than 32K clusters, yes, we're hosed.
  1875                                  ;
  1876 00000956 E82E07                  		call abort_check		; Check for abort key
  1877 00000959 8B0E1C55                		mov cx,[ClustPerMoby]
  1878 0000095D D1E9                    		shr cx,1			; Half a moby
  1879 0000095F 3B0E1855                		cmp cx,[KernelClust]
  1880 00000963 7604                    		jna .normalkernel
  1881 00000965 8B0E1855                		mov cx,[KernelClust]
  1882                                  .normalkernel:
  1883 00000969 290E1855                		sub [KernelClust],cx
  1884 0000096D 31DB                    		xor bx,bx
  1885 0000096F 5E                                      pop si                          ; Cluster pointer on stack
  1886 00000970 E8B3F9                  		call getfssec
  1887 00000973 26813EFE0155AA                          cmp word [es:bs_bootsign],0AA55h
  1888 0000097A 0F854AFF                		jne near kernel_corrupt		; Boot sec signature missing
  1889                                  ;
  1890                                  ; Get the BIOS' idea of what the size of high memory is.
  1891                                  ;
  1892 0000097E 56                      		push si				; Save our cluster pointer!
  1893                                  ;
  1894                                  ; First, try INT 15:E820 (get BIOS memory map)
  1895                                  ;
  1896                                  get_e820:
  1897 0000097F 06                      		push es
  1898 00000980 6631DB                  		xor ebx,ebx			; Start with first record
  1899 00000983 8EC3                    		mov es,bx			; Need ES = DS = 0 for now
  1900 00000985 EB05                    		jmp short .do_e820		; Skip "at end" check first time!
  1901 00000987 6621DB                  .int_loop:	and ebx,ebx			; If we're back at beginning...
  1902 0000098A 745A                    		jz no_e820			; ... bail; nothing found
  1903 0000098C 66B820E80000            .do_e820:	mov eax,0000E820h
  1904 00000992 66BA50414D53            		mov edx,534D4150h		; "SMAP" backwards
  1905 00000998 66B914000000            		mov ecx,20
  1906 0000099E BFC054                  		mov di,E820Buf
  1907 000009A1 CD15                    		int 15h
  1908 000009A3 7241                    		jc no_e820
  1909 000009A5 663D50414D53            		cmp eax,534D4150h
  1910 000009AB 7539                    		jne no_e820
  1911                                  ;
  1912                                  ; Look for a memory block starting at <= 1 MB and continuing upward
  1913                                  ;
  1914 000009AD 66833EC45400            		cmp dword [E820Buf+4], byte 0
  1915 000009B3 77D2                    		ja .int_loop			; Start >= 4 GB?
  1916 000009B5 66BA00001000            		mov edx, (1 << 20)
  1917 000009BB 662B16C054              		sub edx, [E820Buf]
  1918 000009C0 72C5                    		jb .int_loop			; Start >= 1 MB?
  1919 000009C2 66B8FFFFFFFF            		mov eax, 0FFFFFFFFh
  1920 000009C8 66833ECC5400            		cmp dword [E820Buf+12], byte 0
  1921 000009CE 7704                    		ja .huge			; Size >= 4 GB
  1922 000009D0 66A1C854                		mov eax, [E820Buf+8]
  1923 000009D4 6629D0                  .huge:		sub eax, edx			; Adjust size to start at 1 MB
  1924 000009D7 76AE                    		jbe .int_loop			; Completely below 1 MB?
  1925                                  
  1926                                  		; Now EAX contains the size of memory 1 MB...up
  1927 000009D9 66833ED05401            		cmp dword [E820Buf+16], byte 1
  1928 000009DF 0F85B911                		jne near err_nohighmem		; High memory isn't usable memory!!!!
  1929                                  
  1930                                  		; We're good!
  1931 000009E3 07                      		pop es
  1932 000009E4 EB33                    		jmp short got_highmem_add1mb	; Still need to add low 1 MB
  1933                                  
  1934                                  ;
  1935                                  ; INT 15:E820 failed.  Try INT 15:E801.
  1936                                  ;
  1937 000009E6 07                      no_e820:	pop es
  1938                                  
  1939 000009E7 B801E8                  		mov ax,0e801h			; Query high memory (semi-recent)
  1940 000009EA CD15                    		int 15h
  1941 000009EC 7215                    		jc no_e801
  1942 000009EE 3D003C                  		cmp ax,3c00h
  1943 000009F1 7710                    		ja no_e801			; > 3C00h something's wrong with this call
  1944 000009F3 721A                    		jb e801_hole			; If memory hole we can only use low part
  1945                                  
  1946 000009F5 89D8                    		mov ax,bx
  1947 000009F7 66C1E010                		shl eax,16			; 64K chunks
  1948 000009FB 660500000001            		add eax,(16 << 20)		; Add first 16M
  1949 00000A01 EB1C                    		jmp short got_highmem				
  1950                                  
  1951                                  ;
  1952                                  ; INT 15:E801 failed.  Try INT 15:88.
  1953                                  ;
  1954                                  no_e801:
  1955 00000A03 B488                    		mov ah,88h			; Query high memory (oldest)
  1956 00000A05 CD15                    		int 15h
  1957 00000A07 3D0038                  		cmp ax,14*1024			; Don't trust memory >15M
  1958 00000A0A 7603                    		jna e801_hole
  1959 00000A0C B80038                  		mov ax,14*1024
  1960                                  e801_hole:
  1961 00000A0F 6625FFFF0000            		and eax,0ffffh
  1962 00000A15 66C1E00A                		shl eax,10			; Convert from kilobytes
  1963                                  got_highmem_add1mb:
  1964 00000A19 660500001000            		add eax,(1 << 20)		; First megabyte
  1965                                  got_highmem:
  1966 00000A1F 66A3DC54                		mov [HighMemSize],eax
  1967                                  
  1968                                  ;
  1969                                  ; Construct the command line (append options have already been copied)
  1970                                  ;
  1971 00000A23 8B3E[561D]              		mov di,[CmdLinePtr]
  1972 00000A27 BE[871D]                                mov si,boot_image        	; BOOT_IMAGE=
  1973 00000A2A B90B00                                  mov cx,boot_image_len
  1974 00000A2D F3A4                                    rep movsb
  1975 00000A2F BE6155                                  mov si,KernelCName       	; Unmangled kernel name
  1976 00000A32 8B0E2655                                mov cx,[KernelCNameLen]
  1977 00000A36 F3A4                                    rep movsb
  1978 00000A38 B020                                    mov al,' '                      ; Space
  1979 00000A3A AA                                      stosb
  1980 00000A3B 8B362455                                mov si,[CmdOptPtr]              ; Options from user input
  1981 00000A3F B98100                  		mov cx,(kern_cmd_len+3) >> 2
  1982 00000A42 F366A5                  		rep movsd
  1983                                  ;
  1984                                  %ifdef debug
  1985                                                  push ds                         ; DEBUG DEBUG DEBUG
  1986                                                  push es
  1987                                                  pop ds
  1988                                                  mov si,cmd_line_here
  1989                                                  call cwritestr
  1990                                                  pop ds
  1991                                  		call crlf
  1992                                  %endif
  1993                                  ;
  1994                                  ; Scan through the command line for anything that looks like we might be
  1995                                  ; interested in.  The original version of this code automatically assumed
  1996                                  ; the first option was BOOT_IMAGE=, but that is no longer certain.
  1997                                  ;
  1998 00000A45 BE0090                  		mov si,cmd_line_here
  1999 00000A48 C606[581D]00                            mov byte [initrd_flag],0
  2000 00000A4D 06                                      push es				; Set DS <- real_mode_seg
  2001 00000A4E 1F                                      pop ds
  2002 00000A4F AC                      get_next_opt:   lodsb
  2003 00000A50 20C0                    		and al,al
  2004 00000A52 0F848A00                		jz near cmdline_end
  2005 00000A56 3C20                    		cmp al,' '
  2006 00000A58 76F5                    		jbe get_next_opt
  2007 00000A5A 4E                      		dec si
  2008 00000A5B 668B04                                  mov eax,[si]
  2009 00000A5E 663D7667613D                            cmp eax,'vga='
  2010 00000A64 7432                    		je is_vga_cmd
  2011 00000A66 663D6D656D3D                            cmp eax,'mem='
  2012 00000A6C 7462                    		je is_mem_cmd
  2013 00000A6E 06                                      push es                         ; Save ES -> real_mode_seg
  2014 00000A6F 16                                      push ss
  2015 00000A70 07                                      pop es                          ; Set ES <- normal DS
  2016 00000A71 BF[091D]                                mov di,initrd_cmd
  2017 00000A74 B90700                  		mov cx,initrd_cmd_len
  2018 00000A77 F3A6                    		repe cmpsb
  2019 00000A79 7514                                    jne not_initrd
  2020 00000A7B BF5655                  		mov di,InitRD
  2021 00000A7E 56                                      push si                         ; mangle_dir mangles si
  2022 00000A7F E8C60B                                  call mangle_name                ; Mangle ramdisk name
  2023 00000A82 5E                                      pop si
  2024 00000A83 26803E565520            		cmp byte [es:InitRD],' '	; Null filename?
  2025 00000A89 260F9706[581D]                          seta byte [es:initrd_flag]	; Set flag if not
  2026 00000A8F 07                      not_initrd:	pop es                          ; Restore ES -> real_mode_seg
  2027 00000A90 AC                      skip_this_opt:  lodsb                           ; Load from command line
  2028 00000A91 3C20                                    cmp al,' '
  2029 00000A93 77FB                                    ja skip_this_opt
  2030 00000A95 4E                                      dec si
  2031 00000A96 EBB7                                    jmp short get_next_opt
  2032                                  is_vga_cmd:
  2033 00000A98 83C604                                  add si,byte 4
  2034 00000A9B 668B04                                  mov eax,[si]
  2035 00000A9E BBFFFF                                  mov bx,-1
  2036 00000AA1 663D6E6F726D                            cmp eax, 'norm'                 ; vga=normal
  2037 00000AA7 7421                                    je vc0
  2038 00000AA9 6625FFFFFF00                            and eax,0ffffffh		; 3 bytes
  2039 00000AAF BBFEFF                                  mov bx,-2
  2040 00000AB2 663D65787400                            cmp eax, 'ext'                  ; vga=ext
  2041 00000AB8 7410                                    je vc0
  2042 00000ABA BBFDFF                                  mov bx,-3
  2043 00000ABD 663D61736B00                            cmp eax, 'ask'                  ; vga=ask
  2044 00000AC3 7405                                    je vc0
  2045 00000AC5 E8AC0A                                  call parseint                   ; vga=<number>
  2046 00000AC8 72C6                    		jc skip_this_opt		; Not an integer
  2047 00000ACA 891EFA01                vc0:		mov [bs_vidmode],bx		; Set video mode
  2048 00000ACE EBC0                    		jmp short skip_this_opt
  2049                                  is_mem_cmd:
  2050 00000AD0 83C604                                  add si,byte 4
  2051 00000AD3 E89E0A                                  call parseint
  2052 00000AD6 72B8                    		jc skip_this_opt		; Not an integer
  2053 00000AD8 2E66891EDC54            		mov [cs:HighMemSize],ebx
  2054 00000ADE EBB0                    		jmp short skip_this_opt
  2055                                  cmdline_end:
  2056 00000AE0 0E                                      push cs                         ; Restore standard DS
  2057 00000AE1 1F                                      pop ds
  2058 00000AE2 81EE0090                		sub si,cmd_line_here
  2059 00000AE6 89363255                		mov [CmdLineLen],si		; Length including final null
  2060                                  ;
  2061                                  ; Now check if we have a large kernel, which needs to be loaded high
  2062                                  ;
  2063 00000AEA 66C706E054FFFFFF37      		mov dword [RamdiskMax], HIGHMEM_MAX	; Default initrd limit
  2064 00000AF3 2666813E0202486472-     		cmp dword [es:su_header],HEADER_ID	; New setup code ID
  2065 00000AFC 53                 
  2066 00000AFD 0F855102                		jne near old_kernel		; Old kernel, load low
  2067 00000B01 26813E06020002          		cmp word [es:su_version],0200h	; Setup code version 2.0
  2068 00000B08 0F824602                		jb near old_kernel		; Old kernel, load low
  2069 00000B0C 26813E06020102                          cmp word [es:su_version],0201h	; Version 2.01+?
  2070 00000B13 721F                                    jb new_kernel                   ; If 2.00, skip this step
  2071 00000B15 26C7062402F48F                          mov word [es:su_heapend],linux_stack	; Set up the heap
  2072 00000B1C 26800E110280                            or byte [es:su_loadflags],80h	; Let the kernel know we care
  2073 00000B22 26813E06020302          		cmp word [es:su_version],0203h	; Version 2.03+?
  2074 00000B29 7209                    		jb new_kernel			; Not 2.03+
  2075 00000B2B 2666A12C02              		mov eax,[es:su_ramdisk_max]
  2076 00000B30 66A3E054                		mov [RamdiskMax],eax		; Set the ramdisk limit
  2077                                  
  2078                                  ;
  2079                                  ; We definitely have a new-style kernel.  Let the kernel know who we are,
  2080                                  ; and that we are clueful
  2081                                  ;
  2082                                  new_kernel:
  2083 00000B34 26C606100231            		mov byte [es:su_loader],syslinux_id	; Show some ID
  2084 00000B3A 260FB606F101            		movzx ax,byte [es:bs_setupsecs]	; Variable # of setup sectors
  2085 00000B40 A32C55                  		mov [SetupSecs],ax
  2086                                  ;
  2087                                  ; Now see if we have an initial RAMdisk; if so, do requisite computation
  2088                                  ;
  2089 00000B43 F606[581D]01                            test byte [initrd_flag],1
  2090 00000B48 747A                                    jz nk_noinitrd
  2091 00000B4A 06                                      push es                         ; ES->real_mode_seg
  2092 00000B4B 1E                                      push ds
  2093 00000B4C 07                                      pop es                          ; We need ES==DS
  2094 00000B4D BE5655                                  mov si,InitRD
  2095 00000B50 BF6E55                                  mov di,InitRDCName
  2096 00000B53 E84E0B                                  call unmangle_name              ; Create human-readable name
  2097 00000B56 81EF6E55                                sub di,InitRDCName
  2098 00000B5A 893E2855                                mov [InitRDCNameLen],di
  2099 00000B5E BF5655                                  mov di,InitRD
  2100 00000B61 E84C05                                  call searchdir                  ; Look for it in directory
  2101 00000B64 07                                      pop es
  2102 00000B65 7445                    		jz initrd_notthere
  2103 00000B67 8936[581D]              		mov [initrd_ptr],si		; Save cluster pointer
  2104 00000B6B 26A31C02                		mov [es:su_ramdisklen1],ax	; Ram disk length
  2105 00000B6F 2689161E02              		mov [es:su_ramdisklen2],dx
  2106 00000B74 F7360A55                		div word [ClustSize]
  2107 00000B78 21D2                    		and dx,dx			; Round up
  2108 00000B7A 0F95C2                  		setnz dl
  2109 00000B7D 0FB6D2                  		movzx dx,dl
  2110 00000B80 01D0                    		add ax,dx
  2111 00000B82 A31A55                  		mov [InitRDClust],ax		; Ramdisk clusters
  2112 00000B85 668B16DC54              		mov edx,[HighMemSize]		; End of memory
  2113 00000B8A 664A                    		dec edx
  2114 00000B8C 66A1E054                		mov eax,[RamdiskMax]		; Highest address allowed by kernel
  2115 00000B90 6639C2                  		cmp edx,eax
  2116 00000B93 7603                    		jna memsize_ok
  2117 00000B95 6689C2                  		mov edx,eax			; Adjust to fit inside limit
  2118                                  memsize_ok:
  2119 00000B98 6642                    		inc edx
  2120 00000B9A 26662B161C02            		sub edx,[es:su_ramdisklen]	; Subtract size of ramdisk
  2121 00000BA0 31D2                                    xor dx,dx			; Round down to 64K boundary
  2122 00000BA2 668916D454                              mov [InitRDat],edx		; Load address
  2123 00000BA7 E86104                  		call loadinitrd			; Load initial ramdisk
  2124 00000BAA EB18                    		jmp short initrd_end
  2125                                  
  2126                                  initrd_notthere:
  2127 00000BAC BE[7B1B]                                mov si,err_noinitrd
  2128 00000BAF E82A08                                  call cwritestr
  2129 00000BB2 BE6E55                                  mov si,InitRDCName
  2130 00000BB5 E82408                                  call cwritestr
  2131 00000BB8 BE[F81C]                                mov si,crlf_msg
  2132 00000BBB E9DD04                                  jmp abort_load
  2133                                  
  2134 00000BBE BE[9C1B]                no_high_mem:    mov si,err_nohighmem		; Error routine
  2135 00000BC1 E9D704                                  jmp abort_load
  2136                                  ;
  2137                                  ; About to load the kernel.  This is a modern kernel, so use the boot flags
  2138                                  ; we were provided.
  2139                                  ;
  2140                                  nk_noinitrd:
  2141                                  initrd_end:
  2142 00000BC4 26A01102                                mov al,[es:su_loadflags]
  2143 00000BC8 A24755                  		mov [LoadFlags],al
  2144                                  ;
  2145                                  ; Load the kernel.  We always load it at 100000h even if we're supposed to
  2146                                  ; load it "low"; for a "low" load we copy it down to low memory right before
  2147                                  ; jumping to it.
  2148                                  ;
  2149                                  read_kernel:
  2150 00000BCB BE6155                                  mov si,KernelCName		; Print kernel name part of
  2151 00000BCE E80B08                                  call cwritestr                  ; "Loading" message
  2152 00000BD1 BE[EC1C]                                mov si,dotdot_msg		; Print dots
  2153 00000BD4 E80508                                  call cwritestr
  2154                                  
  2155 00000BD7 66A1DC54                                mov eax,[HighMemSize]
  2156 00000BDB 662D00001000            		sub eax,100000h			; Load address
  2157 00000BE1 663B06E454              		cmp eax,[KernelSize]
  2158 00000BE6 72D6                    		jb no_high_mem			; Not enough high memory
  2159                                  ;
  2160                                  ; Move the stuff beyond the setup code to high memory at 100000h
  2161                                  ;
  2162 00000BE8 660FB7362C55            		movzx esi,word [SetupSecs]	; Setup sectors
  2163 00000BEE 6646                    		inc esi				; plus 1 boot sector
  2164 00000BF0 66C1E609                                shl esi,9			; Convert to bytes
  2165 00000BF4 66B900801000                            mov ecx,108000h			; 108000h = 1M + 32K
  2166 00000BFA 6629F1                                  sub ecx,esi			; Adjust pointer to 2nd block
  2167 00000BFD 66890ED854                              mov [HiLoadAddr],ecx
  2168 00000C02 6681E900001000          		sub ecx,100000h			; Turn into a counter
  2169 00000C09 66C1E902                		shr ecx,2			; Convert to dwords
  2170 00000C0D 6681C600000700          		add esi,(real_mode_seg << 4)	; Pointer to source
  2171 00000C14 66BF00001000                            mov edi,100000h                 ; Copy to address 100000h
  2172 00000C1A E88B02                                  call bcopy			; Transfer to high memory
  2173                                  
  2174 00000C1D 680030                                  push word xfer_buf_seg		; Transfer buffer segment
  2175 00000C20 07                                      pop es
  2176                                  high_load_loop: 
  2177 00000C21 BE[ED1C]                                mov si,dot_msg			; Progress report
  2178 00000C24 E8B507                                  call cwritestr
  2179 00000C27 E85D04                                  call abort_check
  2180 00000C2A 8B0E1855                                mov cx,[KernelClust]
  2181 00000C2E 21C9                    		and cx,cx
  2182 00000C30 743B                    		jz high_load_done		; Zero left (tiny kernel?)
  2183 00000C32 3B0E1C55                		cmp cx,[ClustPerMoby]
  2184 00000C36 7604                    		jna high_last_moby
  2185 00000C38 8B0E1C55                		mov cx,[ClustPerMoby]
  2186                                  high_last_moby:
  2187 00000C3C 290E1855                		sub [KernelClust],cx
  2188 00000C40 31DB                    		xor bx,bx			; Load at offset 0
  2189 00000C42 5E                                      pop si                          ; Restore cluster pointer
  2190 00000C43 E8E0F6                                  call getfssec
  2191 00000C46 56                                      push si                         ; Save cluster pointer
  2192 00000C47 9C                                      pushf                           ; Save EOF
  2193 00000C48 31DB                                    xor bx,bx
  2194 00000C4A 66BE00000300            		mov esi,(xfer_buf_seg << 4)
  2195 00000C50 668B3ED854                              mov edi,[HiLoadAddr]		; Destination address
  2196 00000C55 66B900400000                            mov ecx,4000h			; Cheating - transfer 64K
  2197 00000C5B E84A02                                  call bcopy			; Transfer to high memory
  2198 00000C5E 66893ED854              		mov [HiLoadAddr],edi		; Point to next target area
  2199 00000C63 9D                                      popf                            ; Restore EOF
  2200 00000C64 7207                                    jc high_load_done               ; If EOF we are done
  2201 00000C66 833E185500                              cmp word [KernelClust],byte 0	; Are we done?
  2202 00000C6B 75B4                    		jne high_load_loop		; Apparently not
  2203                                  high_load_done:
  2204 00000C6D 5E                      		pop si				; No longer needed
  2205 00000C6E B80070                                  mov ax,real_mode_seg		; Set to real mode seg
  2206 00000C71 8EC0                                    mov es,ax
  2207                                  
  2208 00000C73 BE[ED1C]                                mov si,dot_msg
  2209 00000C76 E86307                                  call cwritestr
  2210                                  ;
  2211                                  ; Abandon hope, ye that enter here!  We do no longer permit aborts.
  2212                                  ;
  2213 00000C79 E80B04                                  call abort_check        	; Last chance!!
  2214                                  
  2215 00000C7C BE[D91C]                		mov si,ready_msg
  2216 00000C7F E85A07                  		call cwritestr
  2217                                  
  2218 00000C82 E8F00B                  		call vgaclearmode		; We can't trust ourselves after this
  2219                                  ;
  2220                                  ; Now, if we were supposed to load "low", copy the kernel down to 10000h
  2221                                  ; and the real mode stuff to 90000h.  We assume that all bzImage kernels are
  2222                                  ; capable of starting their setup from a different address.
  2223                                  ;
  2224 00000C85 BB0070                  		mov bx,real_mode_seg		; Real mode segment
  2225 00000C88 8EE3                    		mov fs,bx			; FS -> real_mode_seg
  2226                                  ;
  2227                                  ; Copy command line.  Unfortunately, the kernel boot protocol requires
  2228                                  ; the command line to exist in the 9xxxxh range even if the rest of the
  2229                                  ; setup doesn't.
  2230                                  ;
  2231 00000C8A FA                      		cli				; In case of hooked interrupts
  2232 00000C8B F606475501              		test byte [LoadFlags],LOAD_HIGH
  2233 00000C90 7415                    		jz need_high_cmdline
  2234 00000C92 64813E06020202          		cmp word [fs:su_version],0202h	; Support new cmdline protocol?
  2235 00000C99 720C                    		jb need_high_cmdline
  2236                                  		; New cmdline protocol
  2237                                  		; Store 32-bit (flat) pointer to command line
  2238 00000C9B 6466C7062802009007-     		mov dword [fs:su_cmd_line_ptr],(real_mode_seg << 4) + cmd_line_here
  2239 00000CA4 00                 
  2240 00000CA5 EB7D                    		jmp short in_proper_place
  2241                                  
  2242                                  need_high_cmdline:
  2243                                  ;
  2244                                  ; Copy command line up to 90000h
  2245                                  ;
  2246 00000CA7 B80090                  		mov ax,9000h
  2247 00000CAA 8EC0                    		mov es,ax
  2248 00000CAC BE0090                  		mov si,cmd_line_here
  2249 00000CAF 89F7                    		mov di,si
  2250 00000CB1 64C70620003FA3          		mov [fs:kern_cmd_magic],word CMD_MAGIC ; Store magic
  2251 00000CB8 64893E2200              		mov [fs:kern_cmd_offset],di	; Store pointer
  2252                                  
  2253 00000CBD 8B0E3255                		mov cx,[CmdLineLen]
  2254 00000CC1 83C103                  		add cx,byte 3
  2255 00000CC4 C1E902                  		shr cx,2			; Convert to dwords
  2256 00000CC7 64F366A5                		fs rep movsd
  2257                                  
  2258 00000CCB F606475501              		test byte [LoadFlags],LOAD_HIGH
  2259                                  		; Note bx -> real_mode_seg still
  2260 00000CD0 7552                    		jnz in_proper_place		; If high load, we're done
  2261                                  
  2262                                  ;
  2263                                  ; Loading low; we can't assume it's safe to run in place.
  2264                                  ;
  2265                                  ; Copy real_mode stuff up to 90000h
  2266                                  ;
  2267 00000CD2 B80070                  		mov ax,real_mode_seg
  2268 00000CD5 8EE0                    		mov fs,ax
  2269 00000CD7 B80090                  		mov ax,9000h
  2270 00000CDA 8EC0                    		mov es,ax
  2271 00000CDC 8B0E2C55                		mov cx,[SetupSecs]
  2272 00000CE0 41                      		inc cx				; Setup + boot sector
  2273 00000CE1 C1E107                  		shl cx,7			; Sectors -> dwords
  2274 00000CE4 31F6                    		xor si,si
  2275 00000CE6 31FF                    		xor di,di
  2276 00000CE8 64F366A5                		fs rep movsd			; Copy setup + boot sector
  2277                                  ;
  2278                                  ; Some kernels in the 1.2 ballpark but pre-bzImage have more than 4
  2279                                  ; setup sectors, but the boot protocol had not yet been defined.  They
  2280                                  ; rely on a signature to figure out if they need to copy stuff from
  2281                                  ; the "protected mode" kernel area.  Unfortunately, we used that area
  2282                                  ; as a transfer buffer, so it's going to find the signature there.
  2283                                  ; Hence, zero the low 32K beyond the setup area.
  2284                                  ;
  2285 00000CEC 8B3E2C55                		mov di,[SetupSecs]
  2286 00000CF0 47                      		inc di				; Setup + boot sector
  2287 00000CF1 B94000                  		mov cx,32768/512		; Sectors/32K
  2288 00000CF4 29F9                    		sub cx,di			; Remaining sectors
  2289 00000CF6 C1E709                  		shl di,9			; Sectors -> bytes
  2290 00000CF9 C1E107                  		shl cx,7			; Sectors -> dwords
  2291 00000CFC 6631C0                  		xor eax,eax
  2292 00000CFF F366AB                  		rep stosd			; Clear region
  2293                                  ;
  2294 00000D02 668B0EE454              		mov ecx,[KernelSize]
  2295 00000D07 6681C103000000          		add ecx,3			; Round upwards
  2296 00000D0E 66C1E902                		shr ecx,2			; Bytes -> dwords
  2297 00000D12 66BE00001000            		mov esi,100000h
  2298 00000D18 66BF00000100            		mov edi,10000h
  2299 00000D1E E88701                  		call bcopy
  2300                                  
  2301 00000D21 BB0090                  		mov bx,9000h			; Real mode segment
  2302                                  
  2303                                  ;
  2304                                  ; Now everything is where it needs to be...
  2305                                  ;
  2306                                  in_proper_place:
  2307 00000D24 8EC3                    		mov es,bx			; Real mode segment
  2308                                  ;
  2309                                  ; If the default root device is set to FLOPPY (0000h), change to
  2310                                  ; /dev/fd0 (0200h)
  2311                                  ;
  2312 00000D26 26833EFC0100            		cmp word [es:bs_rootdev],byte 0
  2313 00000D2C 7507                    		jne root_not_floppy
  2314 00000D2E 26C706FC010002          		mov word [es:bs_rootdev],0200h
  2315                                  root_not_floppy:
  2316                                  ;
  2317                                  ; Copy the disk table to high memory, then re-initialize the floppy
  2318                                  ; controller
  2319                                  ;
  2320                                  ; This needs to be moved before the copy
  2321                                  ;
  2322                                  %if 0
  2323                                  		push ds
  2324                                  		push bx
  2325                                  		lds si,[fdctab]
  2326                                  		mov di,linux_fdctab
  2327                                  		mov cx,3			; 12 bytes
  2328                                  		push di
  2329                                  		rep movsd
  2330                                  		pop di
  2331                                  		mov [fdctab1],di		; Save new floppy tab pos
  2332                                  		mov [fdctab2],es
  2333                                  		xor ax,ax
  2334                                  		xor dx,dx
  2335                                  		int 13h
  2336                                  		pop bx
  2337                                  		pop ds
  2338                                  %endif
  2339                                  ;
  2340                                  ; Linux wants the floppy motor shut off before starting the kernel,
  2341                                  ; at least bootsect.S seems to imply so
  2342                                  ;
  2343                                  kill_motor:
  2344 00000D35 BAF203                  		mov dx,03F2h
  2345 00000D38 30C0                    		xor al,al
  2346 00000D3A E8C001                  		call slow_out
  2347                                  ;
  2348                                  ; If we're debugging, wait for a keypress so we can read any debug messages
  2349                                  ;
  2350                                  %ifdef debug
  2351                                                  xor ax,ax
  2352                                                  int 16h
  2353                                  %endif
  2354                                  ;
  2355                                  ; Set up segment registers and the Linux real-mode stack
  2356                                  ; Note: bx == the real mode segment
  2357                                  ;
  2358 00000D3D FA                      		cli
  2359                                  		; es is already == real mode segment
  2360 00000D3E 8EDB                    		mov ds,bx
  2361 00000D40 8EE3                    		mov fs,bx
  2362 00000D42 8EEB                    		mov gs,bx
  2363 00000D44 8ED3                    		mov ss,bx
  2364 00000D46 BCF48F                  		mov sp,linux_stack
  2365                                  ;
  2366                                  ; We're done... now RUN THAT KERNEL!!!!
  2367                                  ; Setup segment == real mode segment + 020h; we need to jump to offset
  2368                                  ; zero in the real mode segment.
  2369                                  ;
  2370 00000D49 81C32000                		add bx,020h
  2371 00000D4D 53                      		push bx
  2372 00000D4E 680000                  		push word 0h
  2373 00000D51 CB                      		retf
  2374                                  
  2375                                  ;
  2376                                  ; Load an older kernel.  Older kernels always have 4 setup sectors, can't have
  2377                                  ; initrd, and are always loaded low.
  2378                                  ;
  2379                                  old_kernel:
  2380 00000D52 F606[581D]01                            test byte [initrd_flag],1	; Old kernel can't have initrd
  2381 00000D57 7406                                    jz load_old_kernel
  2382 00000D59 BE[E71B]                                mov si,err_oldkernel
  2383 00000D5C E93C03                                  jmp abort_load
  2384                                  load_old_kernel:
  2385 00000D5F C7062C550400            		mov word [SetupSecs],4		; Always 4 setup sectors
  2386 00000D65 C606475500              		mov byte [LoadFlags],0		; Always low
  2387 00000D6A E95EFE                  		jmp read_kernel
  2388                                  
  2389                                  ;
  2390                                  ; Load a COMBOOT image.  A COMBOOT image is basically a DOS .COM file,
  2391                                  ; except that it may, of course, not contain any DOS system calls.  We
  2392                                  ; do, however, allow the execution of INT 20h to return to SYSLINUX.
  2393                                  ;
  2394                                  is_comboot_image:
  2395 00000D6D 21D2                    		and dx,dx
  2396 00000D6F 7578                    		jnz comboot_too_large
  2397 00000D71 3D00FF                  		cmp ax,0ff00h		; Max size in bytes
  2398 00000D74 7373                    		jae comboot_too_large
  2399                                  
  2400                                  		;
  2401                                  		; Set up the DOS vectors in the IVT (INT 20h-3fh)
  2402                                  		;
  2403 00000D76 66C7068000-             		mov dword [4*0x20],comboot_return	; INT 20h vector
  2404 00000D7B [F20D0000]         
  2405 00000D7F 66B8[040E0000]          		mov eax,comboot_bogus
  2406 00000D85 BF8400                  		mov di,4*0x21
  2407 00000D88 B91F00                  		mov cx,31		; All remaining DOS vectors
  2408 00000D8B F366AB                  		rep stosd
  2409                                  	
  2410 00000D8E B90020                  		mov cx,comboot_seg
  2411 00000D91 8EC1                    		mov es,cx
  2412                                  
  2413 00000D93 BB0001                  		mov bx,100h		; Load at <seg>:0100h
  2414                                  
  2415 00000D96 8B0E1C55                		mov cx,[ClustPerMoby]	; Absolute maximum # of clusters
  2416 00000D9A E889F5                  		call getfssec
  2417                                  
  2418 00000D9D 31FF                    		xor di,di
  2419 00000D9F B94000                  		mov cx,64		; 256 bytes (size of PSP)
  2420 00000DA2 6631C0                  		xor eax,eax		; Clear PSP
  2421 00000DA5 F366AB                  		rep stosd
  2422                                  
  2423 00000DA8 26C7060000CD20          		mov word [es:0], 020CDh	; INT 20h instruction
  2424                                  		; First non-free paragraph
  2425 00000DAF 26C70602000030          		mov word [es:02h], comboot_seg+1000h
  2426                                  
  2427                                  		; Copy the command line from high memory
  2428 00000DB6 B97D00                  		mov cx,125		; Max cmdline len (minus space and CR)
  2429 00000DB9 8B362455                		mov si,[CmdOptPtr]
  2430 00000DBD BF8100                  		mov di,081h		; Offset in PSP for command line
  2431 00000DC0 B020                    		mov al,' '		; DOS command lines begin with a space
  2432 00000DC2 AA                      		stosb
  2433                                  
  2434 00000DC3 AC                      comboot_cmd_cp:	lodsb
  2435 00000DC4 20C0                    		and al,al
  2436 00000DC6 7403                    		jz comboot_end_cmd
  2437 00000DC8 AA                      		stosb
  2438 00000DC9 E2F8                    		loop comboot_cmd_cp
  2439 00000DCB B00D                    comboot_end_cmd: mov al,0Dh		; CR after last character
  2440 00000DCD AA                      		stosb
  2441 00000DCE B07E                    		mov al,126		; Include space but not CR
  2442 00000DD0 28C8                    		sub al,cl
  2443 00000DD2 26A28000                		mov [es:80h], al	; Store command line length
  2444                                  
  2445 00000DD6 E89C0A                  		call vgaclearmode	; Reset video
  2446                                  
  2447 00000DD9 8CC0                    		mov ax,es
  2448 00000DDB 8ED8                    		mov ds,ax
  2449 00000DDD 8ED0                    		mov ss,ax
  2450 00000DDF 31E4                    		xor sp,sp
  2451 00000DE1 680000                  		push word 0		; Return to address 0 -> exit
  2452                                  
  2453 00000DE4 EA00010020              		jmp comboot_seg:100h	; Run it
  2454                                  
  2455                                  ; Looks like a COMBOOT image but too large
  2456                                  comboot_too_large:
  2457 00000DE9 BE[371C]                		mov si,err_comlarge
  2458 00000DEC E8ED05                  		call cwritestr
  2459 00000DEF E9DEF8                  cb_enter:	jmp enter_command
  2460                                  
  2461                                  ; Proper return vector
  2462 00000DF2 FA                      comboot_return:	cli			; Don't trust anyone
  2463 00000DF3 31C0                    		xor ax,ax
  2464 00000DF5 8ED0                    		mov ss,ax
  2465 00000DF7 368B262E55              		mov sp,[ss:SavedSP]
  2466 00000DFC 8ED8                    		mov ds,ax
  2467 00000DFE 8EC0                    		mov es,ax
  2468 00000E00 FB                      		sti
  2469 00000E01 FC                      		cld
  2470 00000E02 EBEB                    		jmp short cb_enter
  2471                                  
  2472                                  ; Attempted to execute DOS system call
  2473 00000E04 FA                      comboot_bogus:	cli			; Don't trust anyone
  2474 00000E05 31C0                    		xor ax,ax
  2475 00000E07 8ED0                    		mov ss,ax
  2476 00000E09 368B262E55              		mov sp,[ss:SavedSP]
  2477 00000E0E 8ED8                    		mov ds,ax
  2478 00000E10 8EC0                    		mov es,ax
  2479 00000E12 FB                      		sti
  2480 00000E13 FC                      		cld
  2481 00000E14 BE6155                  		mov si,KernelCName
  2482 00000E17 E8C205                  		call cwritestr
  2483 00000E1A BE[191C]                		mov si,err_notdos
  2484 00000E1D E8BC05                  		call cwritestr
  2485 00000E20 EBCD                    		jmp short cb_enter
  2486                                  
  2487                                  ;
  2488                                  ; Load a boot sector
  2489                                  ;
  2490                                  is_bootsector:
  2491                                  		; Transfer zero bytes
  2492 00000E22 680000                  		push word 0
  2493 00000E25 EB03                    		jmp short load_bootsec
  2494                                  is_bss_sector:
  2495                                  		; Transfer the superblock
  2496 00000E27 683300                  		push word superblock_len
  2497                                  load_bootsec:
  2498 00000E2A 21D2                    		and dx,dx
  2499 00000E2C 754F                    		jnz bad_bootsec
  2500 00000E2E 8B1E[0B00]              		mov bx,[bsBytesPerSec]
  2501 00000E32 39D8                    		cmp ax,bx
  2502 00000E34 7547                    		jne bad_bootsec
  2503                                  
  2504                                  		; Make sure we don't test this uninitialized
  2505 00000E36 8997FE0F                		mov [bx+trackbuf-2],dx	; Note DX == 0
  2506                                  
  2507 00000E3A BB0010                  		mov bx,trackbuf
  2508 00000E3D B90100                  		mov cx,1		; 1 cluster >= 1 sector
  2509 00000E40 E8E3F4                  		call getfssec
  2510                                  
  2511 00000E43 8B1E[0B00]              		mov bx,[bsBytesPerSec]
  2512 00000E47 8B87FE0F                		mov ax,[bx+trackbuf-2]
  2513 00000E4B 3D55AA                  		cmp ax,0AA55h		; Boot sector signature
  2514 00000E4E 752D                    		jne bad_bootsec
  2515                                  
  2516 00000E50 BE[0B00]                		mov si,superblock
  2517 00000E53 BF0B10                  		mov di,trackbuf+(superblock-bootsec)
  2518 00000E56 59                      		pop cx			; Transfer count
  2519 00000E57 F3A4                    		rep movsb
  2520                                  ;
  2521                                  ; Okay, here we go... copy over our own boot sector and run the new one
  2522                                  ;
  2523 00000E59 E8190A                  		call vgaclearmode	; Reset video
  2524                                  
  2525 00000E5C FA                      		cli			; Point of no return
  2526                                  	
  2527 00000E5D 8A16[2400]              		mov dl,[bsDriveNumber]	; May not be in new bootsector!
  2528                                  
  2529 00000E61 BE0010                  		mov si,trackbuf
  2530 00000E64 BF[0000]                		mov di,bootsec
  2531 00000E67 8B0E[0B00]              		mov cx,[bsBytesPerSec]
  2532 00000E6B F3A4                    		rep movsb		; Copy the boot sector!
  2533                                  		
  2534 00000E6D BEB054                  		mov si,PartInfo
  2535 00000E70 BFEE07                  		mov di,800h-18		; Put partition info here
  2536 00000E73 57                      		push di
  2537 00000E74 B90800                  		mov cx,8		; 16 bytes
  2538 00000E77 F3A5                    		rep movsw
  2539 00000E79 5E                      		pop si			; DS:SI points to partition info
  2540                                  
  2541 00000E7A E983F1                  		jmp bootsec
  2542                                  
  2543                                  bad_bootsec:
  2544 00000E7D BE[521C]                		mov si,err_bootsec
  2545 00000E80 E85905                  		call cwritestr
  2546 00000E83 E94AF8                  		jmp enter_command
  2547                                  
  2548                                  ;
  2549                                  ; 32-bit bcopy routine for real mode
  2550                                  ;
  2551                                  ; We enter protected mode, set up a flat 32-bit environment, run rep movsd
  2552                                  ; and then exit.  IMPORTANT: This code assumes cs == ss == 0.
  2553                                  ;
  2554                                  ; This code is probably excessively anal-retentive in its handling of
  2555                                  ; segments, but this stuff is painful enough as it is without having to rely
  2556                                  ; on everything happening "as it ought to."
  2557                                  ;
  2558 00000E86 90<rept>                		align 4
  2559 00000E88 1F00                    bcopy_gdt:	dw bcopy_gdt_size-1	; Null descriptor - contains GDT
  2560 00000E8A [880E0000]              		dd bcopy_gdt		; pointer for LGDT instruction
  2561 00000E8E 0000                    		dw 0
  2562 00000E90 FFFF0000                		dd 0000ffffh		; Code segment, use16, readable,
  2563 00000E94 009B0000                		dd 00009b00h		; present, dpl 0, cover 64K
  2564 00000E98 FFFF0000                		dd 0000ffffh		; Data segment, use16, read/write,
  2565 00000E9C 00938F00                		dd 008f9300h		; present, dpl 0, cover all 4G
  2566 00000EA0 FFFF0000                		dd 0000ffffh		; Data segment, use16, read/write,
  2567 00000EA4 00930000                		dd 00009300h		; present, dpl 0, cover 64K
  2568                                  bcopy_gdt_size:	equ $-bcopy_gdt
  2569                                  
  2570 00000EA8 6650                    bcopy:		push eax
  2571 00000EAA 9C                      		pushf			; Saves, among others, the IF flag
  2572 00000EAB 0FA8                    		push gs
  2573 00000EAD 0FA0                    		push fs
  2574 00000EAF 1E                      		push ds
  2575 00000EB0 06                      		push es
  2576                                  
  2577 00000EB1 FA                      		cli
  2578 00000EB2 E84E00                  		call enable_a20
  2579                                  
  2580 00000EB5 660F0116[880E]          		o32 lgdt [bcopy_gdt]
  2581 00000EBB 0F20C0                  		mov eax,cr0
  2582 00000EBE 0C01                    		or al,1
  2583 00000EC0 0F22C0                  		mov cr0,eax		; Enter protected mode
  2584 00000EC3 EA[C80E]0800            		jmp 08h:.in_pm
  2585                                  
  2586 00000EC8 B81000                  .in_pm:		mov ax,10h		; Data segment selector
  2587 00000ECB 8EC0                    		mov es,ax
  2588 00000ECD 8ED8                    		mov ds,ax
  2589                                  
  2590 00000ECF B018                    		mov al,18h		; "Real-mode-like" data segment
  2591 00000ED1 8ED0                    		mov ss,ax
  2592 00000ED3 8EE0                    		mov fs,ax
  2593 00000ED5 8EE8                    		mov gs,ax	
  2594                                  	
  2595 00000ED7 67F366A5                		a32 rep movsd		; Do our business
  2596                                  		
  2597 00000EDB 8EC0                    		mov es,ax		; Set to "real-mode-like"
  2598 00000EDD 8ED8                    		mov ds,ax
  2599                                  	
  2600 00000EDF 0F20C0                  		mov eax,cr0
  2601 00000EE2 24FE                    		and al,~1
  2602 00000EE4 0F22C0                  		mov cr0,eax		; Disable protected mode
  2603 00000EE7 EA[EC0E]0000            		jmp 0:.in_rm
  2604                                  
  2605 00000EEC 31C0                    .in_rm:		xor ax,ax		; Back in real mode
  2606 00000EEE 8ED0                    		mov ss,ax
  2607 00000EF0 07                      		pop es
  2608 00000EF1 1F                      		pop ds
  2609 00000EF2 0FA1                    		pop fs
  2610 00000EF4 0FA9                    		pop gs
  2611 00000EF6 E8AD00                  		call disable_a20
  2612                                  
  2613 00000EF9 9D                      		popf			; Re-enables interrupts
  2614 00000EFA 6658                    		pop eax
  2615 00000EFC C3                      		ret
  2616                                  
  2617                                  ;
  2618                                  ; Routines to enable and disable (yuck) A20.  These routines are gathered
  2619                                  ; from tips from a couple of sources, including the Linux kernel and
  2620                                  ; http://www.x86.org/.  The need for the delay to be as large as given here
  2621                                  ; is indicated by Donnie Barnes of RedHat, the problematic system being an
  2622                                  ; IBM ThinkPad 760EL.
  2623                                  ;
  2624                                  ; We typically toggle A20 twice for every 64K transferred.
  2625                                  ; 
  2626                                  %define	io_delay	call _io_delay
  2627                                  %define IO_DELAY_PORT	80h		; Invalid port (we hope!)
  2628                                  %define disable_wait 	32		; How long to wait for a disable
  2629                                  
  2630                                  %define A20_DUNNO	0		; A20 type unknown
  2631                                  %define A20_NONE	1		; A20 always on?
  2632                                  %define A20_BIOS	2		; A20 BIOS enable
  2633                                  %define A20_KBC		3		; A20 through KBC
  2634                                  %define A20_FAST	4		; A20 through port 92h
  2635                                  
  2636 00000EFD EE                      slow_out:	out dx, al		; Fall through
  2637                                  
  2638 00000EFE E680                    _io_delay:	out IO_DELAY_PORT,al
  2639 00000F00 E680                    		out IO_DELAY_PORT,al
  2640 00000F02 C3                      		ret
  2641                                  
  2642                                  enable_a20:
  2643 00000F03 6660                    		pushad
  2644 00000F05 2EC6064855FF            		mov byte [cs:A20Tries],255 ; Times to try to make this work
  2645                                  
  2646                                  try_enable_a20:
  2647                                  ;
  2648                                  ; Flush the caches
  2649                                  ;
  2650                                  ;		call try_wbinvd
  2651                                  
  2652                                  ;
  2653                                  ; If the A20 type is known, jump straight to type
  2654                                  ;
  2655 00000F0B 2E8B2E[761D]            		mov bp,[cs:A20Type]
  2656 00000F10 01ED                    		add bp,bp			; Convert to word offset
  2657 00000F12 2EFFA6[621D]            		jmp word [cs:bp+A20List]
  2658                                  
  2659                                  ;
  2660                                  ; First, see if we are on a system with no A20 gate
  2661                                  ;
  2662                                  a20_dunno:
  2663                                  a20_none:
  2664 00000F17 2EC606[761D]01          		mov byte [cs:A20Type], A20_NONE
  2665 00000F1D E86400                  		call a20_test
  2666 00000F20 755F                    		jnz a20_done
  2667                                  
  2668                                  ;
  2669                                  ; Next, try the BIOS (INT 15h AX=2401h)
  2670                                  ;
  2671                                  a20_bios:
  2672 00000F22 2EC606[761D]02          		mov byte [cs:A20Type], A20_BIOS
  2673 00000F28 B80124                  		mov ax,2401h
  2674 00000F2B 9C                      		pushf				; Some BIOSes muck with IF
  2675 00000F2C CD15                    		int 15h
  2676 00000F2E 9D                      		popf
  2677                                  
  2678 00000F2F E85200                  		call a20_test
  2679 00000F32 754D                    		jnz a20_done
  2680                                  
  2681                                  ;
  2682                                  ; Enable the keyboard controller A20 gate
  2683                                  ;
  2684                                  a20_kbc:
  2685 00000F34 B201                    		mov dl, 1			; Allow early exit
  2686 00000F36 E8AE00                  		call empty_8042
  2687 00000F39 7546                    		jnz a20_done			; A20 live, no need to use KBC
  2688                                  
  2689 00000F3B 2EC606[761D]03          		mov byte [cs:A20Type], A20_KBC	; Starting KBC command sequence
  2690                                  
  2691 00000F41 B0D1                    		mov al,0D1h			; Command write
  2692 00000F43 E664                    		out 064h, al
  2693 00000F45 E89D00                  		call empty_8042_uncond
  2694                                  
  2695 00000F48 B0DF                    		mov al,0DFh			; A20 on
  2696 00000F4A E660                    		out 060h, al
  2697 00000F4C E89600                  		call empty_8042_uncond
  2698                                  
  2699                                  		; Verify that A20 actually is enabled.  Do that by
  2700                                  		; observing a word in low memory and the same word in
  2701                                  		; the HMA until they are no longer coherent.  Note that
  2702                                  		; we don't do the same check in the disable case, because
  2703                                  		; we don't want to *require* A20 masking (SYSLINUX should
  2704                                  		; work fine without it, if the BIOS does.)
  2705 00000F4F 51                      .kbc_wait:	push cx
  2706 00000F50 31C9                    		xor cx,cx
  2707                                  .kbc_wait_loop:
  2708 00000F52 E82F00                  		call a20_test
  2709 00000F55 7529                    		jnz a20_done_pop
  2710 00000F57 E2F9                    		loop .kbc_wait_loop
  2711                                  
  2712 00000F59 59                      		pop cx
  2713                                  ;
  2714                                  ; Running out of options here.  Final attempt: enable the "fast A20 gate"
  2715                                  ;
  2716                                  a20_fast:
  2717 00000F5A 2EC606[761D]04          		mov byte [cs:A20Type], A20_FAST	; Haven't used the KBC yet
  2718 00000F60 E492                    		in al, 092h
  2719 00000F62 0C02                    		or al,02h
  2720 00000F64 24FE                    		and al,~01h			; Don't accidentally reset the machine!
  2721 00000F66 E692                    		out 092h, al
  2722                                  
  2723 00000F68 51                      .fast_wait:	push cx
  2724 00000F69 31C9                    		xor cx,cx
  2725                                  .fast_wait_loop:
  2726 00000F6B E81600                  		call a20_test
  2727 00000F6E 7510                    		jnz a20_done_pop
  2728 00000F70 E2F9                    		loop .fast_wait_loop
  2729                                  
  2730 00000F72 59                      		pop cx
  2731                                  
  2732                                  ;
  2733                                  ; Oh bugger.  A20 is not responding.  Try frobbing it again; eventually give up
  2734                                  ; and report failure to the user.
  2735                                  ;
  2736                                  
  2737                                  
  2738 00000F73 2EFE0E4855              		dec byte [cs:A20Tries]
  2739 00000F78 7591                    		jnz try_enable_a20
  2740                                  
  2741 00000F7A BE[7A1C]                		mov si, err_a20
  2742 00000F7D E91B01                  		jmp abort_load
  2743                                  ;
  2744                                  ; A20 unmasked, proceed...
  2745                                  ;
  2746 00000F80 59                      a20_done_pop:	pop cx
  2747 00000F81 6661                    a20_done:	popad
  2748 00000F83 C3                      		ret
  2749                                  
  2750                                  ;
  2751                                  ; This routine tests if A20 is enabled (ZF = 0).  This routine
  2752                                  ; must not destroy any register contents.
  2753                                  ;
  2754                                  a20_test:
  2755 00000F84 06                      		push es
  2756 00000F85 51                      		push cx
  2757 00000F86 50                      		push ax
  2758 00000F87 B9FFFF                  		mov cx,0FFFFh		; HMA = segment 0FFFFh
  2759 00000F8A 8EC1                    		mov es,cx
  2760 00000F8C B92000                  		mov cx,32		; Loop count
  2761 00000F8F 2EA13055                		mov ax,[cs:A20Test]
  2762 00000F93 40                      .a20_wait:	inc ax
  2763 00000F94 2EA33055                		mov [cs:A20Test],ax
  2764 00000F98 E863FF                  		io_delay		; Serialize, and fix delay
  2765 00000F9B 263B064055              		cmp ax,[es:A20Test+10h]
  2766 00000FA0 E1F1                    		loopz .a20_wait
  2767 00000FA2 58                      .a20_done:	pop ax
  2768 00000FA3 59                      		pop cx
  2769 00000FA4 07                      		pop es
  2770 00000FA5 C3                      		ret
  2771                                  
  2772                                  disable_a20:
  2773 00000FA6 6660                    		pushad
  2774                                  ;
  2775                                  ; Flush the caches
  2776                                  ;
  2777                                  ;		call try_wbinvd
  2778                                  
  2779 00000FA8 2E8B2E[761D]            		mov bp,[cs:A20Type]
  2780 00000FAD 01ED                    		add bp,bp			; Convert to word offset
  2781 00000FAF 2EFFA6[6C1D]            		jmp word [cs:bp+A20DList]
  2782                                  
  2783                                  a20d_bios:
  2784 00000FB4 B80024                  		mov ax,2400h
  2785 00000FB7 9C                      		pushf				; Some BIOSes muck with IF
  2786 00000FB8 CD15                    		int 15h
  2787 00000FBA 9D                      		popf
  2788 00000FBB EB19                    		jmp short a20d_snooze
  2789                                  
  2790                                  ;
  2791                                  ; Disable the "fast A20 gate"
  2792                                  ;
  2793                                  a20d_fast:
  2794 00000FBD E492                    		in al, 092h
  2795 00000FBF 24FC                    		and al,~03h
  2796 00000FC1 E692                    		out 092h, al
  2797 00000FC3 EB11                    		jmp short a20d_snooze
  2798                                  
  2799                                  ;
  2800                                  ; Disable the keyboard controller A20 gate
  2801                                  ;
  2802                                  a20d_kbc:
  2803 00000FC5 E81D00                  		call empty_8042_uncond
  2804 00000FC8 B0D1                    		mov al,0D1h
  2805 00000FCA E664                    		out 064h, al		; Command write
  2806 00000FCC E81600                  		call empty_8042_uncond
  2807 00000FCF B0DD                    		mov al,0DDh		; A20 off
  2808 00000FD1 E660                    		out 060h, al
  2809 00000FD3 E80F00                  		call empty_8042_uncond
  2810                                  		; Wait a bit for it to take effect
  2811                                  a20d_snooze:
  2812 00000FD6 51                      		push cx
  2813 00000FD7 B92000                  		mov cx, disable_wait
  2814 00000FDA E8A7FF                  .delayloop:	call a20_test
  2815 00000FDD 7402                    		jz .disabled
  2816 00000FDF E2F9                    		loop .delayloop
  2817 00000FE1 59                      .disabled:	pop cx
  2818                                  a20d_dunno:
  2819                                  a20d_none:
  2820 00000FE2 6661                    		popad
  2821 00000FE4 C3                      		ret
  2822                                  
  2823                                  ;
  2824                                  ; Routine to empty the 8042 KBC controller.  If dl != 0
  2825                                  ; then we will test A20 in the loop and exit if A20 is
  2826                                  ; suddenly enabled.
  2827                                  ;
  2828                                  empty_8042_uncond:
  2829 00000FE5 30D2                    		xor dl,dl
  2830                                  empty_8042:
  2831 00000FE7 E89AFF                  		call a20_test
  2832 00000FEA 7404                    		jz .a20_on
  2833 00000FEC 20D2                    		and dl,dl
  2834 00000FEE 7517                    		jnz .done
  2835 00000FF0 E80BFF                  .a20_on:	io_delay
  2836 00000FF3 E464                    		in al, 064h		; Status port
  2837 00000FF5 A801                    		test al,1
  2838 00000FF7 7407                    		jz .no_output
  2839 00000FF9 E802FF                  		io_delay
  2840 00000FFC E460                    		in al, 060h		; Read input
  2841 00000FFE EBE7                    		jmp short empty_8042
  2842                                  .no_output:
  2843 00001000 A802                    		test al,2
  2844 00001002 75E3                    		jnz empty_8042
  2845 00001004 E8F7FE                  		io_delay
  2846 00001007 C3                      .done:		ret	
  2847                                  
  2848                                  ;
  2849                                  ; WBINVD instruction; gets auto-eliminated on 386 CPUs
  2850                                  ;
  2851                                  try_wbinvd:
  2852 00001008 0F09                    		wbinvd
  2853 0000100A C3                      		ret
  2854                                  
  2855                                  ;
  2856                                  ; Load RAM disk into high memory
  2857                                  ;
  2858                                  loadinitrd:
  2859 0000100B 06                                      push es                         ; Save ES on entry
  2860 0000100C B80070                                  mov ax,real_mode_seg
  2861 0000100F 8EC0                                    mov es,ax
  2862 00001011 8B36[581D]                              mov si,[initrd_ptr]
  2863 00001015 668B3ED454                              mov edi,[InitRDat]		; initrd load address
  2864 0000101A 2666893E1802            		mov [es:su_ramdiskat],edi	; Offset for ram disk
  2865 00001020 56                      		push si
  2866 00001021 BE6E55                                  mov si,InitRDCName		; Write ramdisk name
  2867 00001024 E8B503                                  call cwritestr
  2868 00001027 BE[EC1C]                                mov si,dotdot_msg		; Write dots
  2869 0000102A E8AF03                                  call cwritestr
  2870                                  rd_load_loop:	
  2871 0000102D BE[ED1C]                		mov si,dot_msg			; Progress report
  2872 00001030 E8A903                                  call cwritestr
  2873 00001033 5E                      		pop si				; Restore cluster pointer
  2874 00001034 E85000                                  call abort_check
  2875 00001037 8B0E1A55                                mov cx,[InitRDClust]
  2876 0000103B 3B0E1C55                		cmp cx,[ClustPerMoby]
  2877 0000103F 7604                    		jna rd_last_moby
  2878 00001041 8B0E1C55                		mov cx,[ClustPerMoby]
  2879                                  rd_last_moby:
  2880 00001045 290E1A55                		sub [InitRDClust],cx
  2881 00001049 31DB                    		xor bx,bx			; Load at offset 0
  2882 0000104B 680030                                  push word xfer_buf_seg		; Bounce buffer segment
  2883 0000104E 07                      		pop es
  2884 0000104F 51                      		push cx
  2885 00001050 E8D3F2                  		call getfssec
  2886 00001053 59                      		pop cx
  2887 00001054 56                                      push si				; Save cluster pointer
  2888 00001055 66BE00000300            		mov esi,(xfer_buf_seg << 4)
  2889 0000105B 668B3ED454              		mov edi,[InitRDat]
  2890 00001060 66B900400000            		mov ecx,4000h			; Copy 64K
  2891 00001066 E83FFE                  		call bcopy			; Does not change flags!!
  2892 00001069 7210                                    jc rd_load_done                 ; EOF?
  2893 0000106B 668106D45400000100                      add dword [InitRDat],10000h	; Point to next 64K
  2894 00001074 833E1A5500              		cmp word [InitRDClust],byte 0	; Are we done?
  2895 00001079 75B2                    		jne rd_load_loop		; Apparently not
  2896                                  rd_load_done:
  2897 0000107B 5E                                      pop si                          ; Clean up the stack
  2898 0000107C E85A03                  		call crlf
  2899 0000107F BE[E31C]                                mov si,loading_msg		; Write new "Loading " for
  2900 00001082 E85703                                  call cwritestr                  ; the benefit of the kernel
  2901 00001085 07                                      pop es                          ; Restore original ES
  2902 00001086 C3                                      ret
  2903                                  
  2904                                  ;
  2905                                  ; abort_check: let the user abort with <ESC> or <Ctrl-C>
  2906                                  ;
  2907                                  abort_check:
  2908 00001087 E86503                  		call pollchar
  2909 0000108A 7423                    		jz ac_ret1
  2910 0000108C 60                      		pusha
  2911 0000108D E88903                  		call getchar
  2912 00001090 3C1B                    		cmp al,27			; <ESC>
  2913 00001092 7404                    		je ac_kill
  2914 00001094 3C03                    		cmp al,3			; <Ctrl-C>
  2915 00001096 7516                    		jne ac_ret2
  2916 00001098 BE[EF1C]                ac_kill:	mov si,aborted_msg
  2917                                  
  2918                                  ;
  2919                                  ; abort_load: Called by various routines which wants to print a fatal
  2920                                  ;             error message and return to the command prompt.  Since this
  2921                                  ;             may happen at just about any stage of the boot process, assume
  2922                                  ;             our state is messed up, and just reset the segment registers
  2923                                  ;             and the stack forcibly.
  2924                                  ;
  2925                                  ;             SI    = offset (in _text) of error message to print
  2926                                  ;
  2927                                  abort_load:
  2928 0000109B 8CC8                                    mov ax,cs                       ; Restore CS = DS = ES
  2929 0000109D 8ED8                                    mov ds,ax
  2930 0000109F 8EC0                                    mov es,ax
  2931 000010A1 FA                                      cli
  2932 000010A2 BC[FAFF]                                mov sp,StackBuf-2*3    		; Reset stack
  2933 000010A5 8ED0                                    mov ss,ax                       ; Just in case...
  2934 000010A7 FB                                      sti
  2935 000010A8 E83103                                  call cwritestr                  ; Expects SI -> error msg
  2936 000010AB E922F6                  al_ok:          jmp enter_command               ; Return to command prompt
  2937                                  ;
  2938                                  ; End of abort_check
  2939                                  ;
  2940 000010AE 61                      ac_ret2:	popa
  2941 000010AF C3                      ac_ret1:	ret
  2942                                  
  2943                                  ;
  2944                                  ; searchdir: Search the root directory for a pre-mangled filename in
  2945                                  ;	     DS:DI.  This routine is similar to the one in the boot
  2946                                  ;	     sector, but is a little less Draconian when it comes to
  2947                                  ;	     error handling, plus it reads the root directory in
  2948                                  ;	     larger chunks than a sector at a time (which is probably
  2949                                  ;	     a waste of coding effort, but I like to do things right).
  2950                                  ;
  2951                                  ;	     FIXME: usually we can load the entire root dir in memory,
  2952                                  ;	     and files are usually at the beginning anyway.  It probably
  2953                                  ;	     would be worthwhile to remember if we have the first chunk
  2954                                  ;	     in memory and skip the load if that (it would speed up online
  2955                                  ;	     help, mainly.)
  2956                                  ;
  2957                                  ;	     NOTE: This file considers finding a zero-length file an
  2958                                  ;	     error.  This is so we don't have to deal with that special
  2959                                  ;	     case elsewhere in the program (most loops have the test
  2960                                  ;	     at the end).
  2961                                  ;
  2962                                  ;	     If successful:
  2963                                  ;		ZF clear
  2964                                  ;		SI	= cluster # for the first cluster
  2965                                  ;		DX:AX	= file length in bytes
  2966                                  ;	     If unsuccessful
  2967                                  ;		ZF set
  2968                                  ;
  2969                                  
  2970                                  searchdir:
  2971 000010B0 A1[1100]                		mov ax,[bsRootDirEnts]
  2972 000010B3 A30255                  		mov [DirScanCtr],ax
  2973 000010B6 A10055                  		mov ax,[RootDirSize]
  2974 000010B9 A30455                  		mov [DirBlocksLeft],ax
  2975 000010BC A1F454                  		mov ax,[RootDir1]
  2976 000010BF 8B16F654                		mov dx,[RootDir2]
  2977                                  scan_group:
  2978 000010C3 8B2E0455                		mov bp,[DirBlocksLeft]
  2979 000010C7 21ED                    		and bp,bp
  2980 000010C9 7467                    		jz dir_return
  2981 000010CB 3B2E1255                		cmp bp,[BufSafeSec]
  2982 000010CF 7604                    		jna load_last
  2983 000010D1 8B2E1255                		mov bp,[BufSafeSec]
  2984                                  load_last:
  2985 000010D5 292E0455                		sub [DirBlocksLeft],bp
  2986 000010D9 50                      		push ax
  2987 000010DA 52                      		push dx
  2988 000010DB A1[0B00]                		mov ax,[bsBytesPerSec]
  2989 000010DE F7E5                    		mul bp
  2990 000010E0 05E10F                  		add ax,trackbuf-31
  2991 000010E3 A30655                  		mov [EndofDirSec],ax	; End of loaded
  2992 000010E6 5A                      		pop dx
  2993 000010E7 58                      		pop ax
  2994 000010E8 55                      		push bp			; Save number of sectors
  2995 000010E9 50                      		push ax			; Save present location
  2996 000010EA 52                      		push dx
  2997 000010EB 57                      		push di			; Save name
  2998 000010EC BB0010                  		mov bx,trackbuf
  2999 000010EF E882F0                  		call getlinsec
  3000 000010F2 5F                      		pop di
  3001 000010F3 5A                      		pop dx
  3002 000010F4 58                      		pop ax
  3003 000010F5 5D                      		pop bp
  3004 000010F6 BE0010                  		mov si,trackbuf
  3005 000010F9 803C00                  dir_test_name:	cmp byte [si],0		; Directory high water mark
  3006 000010FC 7434                    		je dir_return		; Failed
  3007 000010FE F6440B18                                test byte [si+11],18h	; Check it really is a file
  3008 00001102 750B                                    jnz dir_not_this
  3009 00001104 57                      		push di
  3010 00001105 56                      		push si
  3011 00001106 B90B00                  		mov cx,11		; Filename = 11 bytes
  3012 00001109 F3A6                    		repe cmpsb
  3013 0000110B 5E                      		pop si
  3014 0000110C 5F                      		pop di
  3015 0000110D 7416                    		je dir_success
  3016 0000110F 83C620                  dir_not_this:   add si,byte 32
  3017 00001112 FF0E0255                		dec word [DirScanCtr]
  3018 00001116 741A                    		jz dir_return		; Out of it...
  3019 00001118 3B360655                		cmp si,[EndofDirSec]
  3020 0000111C 72DB                    		jb dir_test_name
  3021 0000111E 01E8                    		add ax,bp		; Increment linear sector number
  3022 00001120 83D200                  		adc dx,byte 0
  3023 00001123 EB9E                    		jmp short scan_group
  3024                                  dir_success:
  3025 00001125 8B441C                  		mov ax,[si+28]		; Length of file
  3026 00001128 8B541E                  		mov dx,[si+30]
  3027 0000112B 8B741A                  		mov si,[si+26]		; Cluster pointer
  3028 0000112E 89C3                    		mov bx,ax
  3029 00001130 09D3                    		or bx,dx		; Sets ZF iff DX:AX is zero
  3030                                  dir_return:
  3031 00001132 C3                      lf_ret:		ret
  3032                                  
  3033                                  ;
  3034                                  ; loadfont:	Load a .psf font file and install it onto the VGA console
  3035                                  ;		(if we're not on a VGA screen then ignore.)  It is called with
  3036                                  ;		SI and DX:AX set by routine searchdir
  3037                                  ;
  3038                                  loadfont:
  3039 00001133 BB0010                  		mov bx,trackbuf			; The trackbuf is >= 16K; the part
  3040 00001136 8B0E1055                		mov cx,[BufSafe]		; of a PSF file we care about is no
  3041 0000113A E8E9F1                  		call getfssec			; more than 8K+4 bytes
  3042                                  
  3043 0000113D A10010                  		mov ax,[trackbuf]		; Magic number
  3044 00001140 3D3604                  		cmp ax,0436h
  3045 00001143 75ED                    		jne lf_ret
  3046                                  
  3047 00001145 A00210                  		mov al,[trackbuf+2]		; File mode
  3048 00001148 3C05                    		cmp al,5			; Font modes 0-5 supported
  3049 0000114A 77E6                    		ja lf_ret
  3050                                  
  3051 0000114C 8A3E0310                		mov bh,byte [trackbuf+3]	; Height of font
  3052 00001150 80FF02                  		cmp bh,2			; VGA minimum
  3053 00001153 72DD                    		jb lf_ret
  3054 00001155 80FF20                  		cmp bh,32			; VGA maximum
  3055 00001158 77D8                    		ja lf_ret
  3056                                  
  3057                                  		; Copy to font buffer
  3058 0000115A BE0410                  		mov si,trackbuf+4		; Start of font data
  3059 0000115D 883E[781D]              		mov [VGAFontSize],bh
  3060 00001161 BF00E0                  		mov di,vgafontbuf
  3061 00001164 B90008                  		mov cx,(32*256) >> 2		; Maximum size
  3062 00001167 F366A5                  		rep movsd
  3063                                  
  3064 0000116A C606[7A1D]01            		mov [UserFont], byte 1		; Set font flag
  3065                                  
  3066                                  		; Fall through to use_font
  3067                                  
  3068                                  ;
  3069                                  ; use_font:
  3070                                  ; 	This routine activates whatever font happens to be in the
  3071                                  ;	vgafontbuf, and updates the adjust_screen data.
  3072                                  ;       Must be called with CS = DS = ES
  3073                                  ;
  3074                                  use_font:
  3075 0000116F F606[7A1D]01            		test [UserFont], byte 1		; Are we using a user-specified font?
  3076 00001174 7441                    		jz adjust_screen		; If not, just do the normal stuff
  3077                                  
  3078 00001176 BD00E0                  		mov bp,vgafontbuf
  3079 00001179 8A3E[781D]              		mov bh,[VGAFontSize]
  3080                                  
  3081 0000117D 30DB                    		xor bl,bl			; Needed by both INT 10h calls
  3082 0000117F 803E[CC18]01            		cmp [UsingVGA], byte 1		; Are we in graphics mode?
  3083 00001184 7520                    		jne .text
  3084                                  
  3085                                  .graphics:
  3086 00001186 31C9                    		xor cx,cx
  3087 00001188 88F9                    		mov cl,bh			; CX = bytes/character
  3088 0000118A B8E001                  		mov ax,480
  3089 0000118D F6F1                    		div cl				; Compute char rows per screen
  3090 0000118F 88C2                    		mov dl,al
  3091 00001191 FEC8                    		dec al
  3092 00001193 A24155                  		mov [VidRows],al
  3093 00001196 B82111                  		mov ax,1121h			; Set user character table
  3094 00001199 CD10                    		int 10h
  3095 0000119B C60640554F              		mov [VidCols], byte 79		; Always 80 bytes/line
  3096 000011A0 C6063D5500              		mov [TextPage], byte 0		; Always page 0
  3097 000011A5 C3                      		ret	; No need to call adjust_screen
  3098                                  
  3099                                  .text:
  3100 000011A6 B90001                  		mov cx,256
  3101 000011A9 31D2                    		xor dx,dx
  3102 000011AB B81011                  		mov ax,1110h
  3103 000011AE CD10                    		int 10h				; Load into VGA RAM
  3104                                  
  3105 000011B0 30DB                    		xor bl,bl
  3106 000011B2 B80311                  		mov ax,1103h			; Select page 0
  3107 000011B5 CD10                    		int 10h
  3108                                  
  3109                                  		; Fall through to adjust_screen
  3110                                  
  3111                                  ;
  3112                                  ; adjust_screen: Set the internal variables associated with the screen size.
  3113                                  ;		This is a subroutine in case we're loading a custom font.
  3114                                  ;
  3115                                  adjust_screen:
  3116 000011B7 A08404                                  mov al,[BIOS_vidrows]
  3117 000011BA 20C0                                    and al,al
  3118 000011BC 7502                                    jnz vidrows_is_ok
  3119 000011BE B018                                    mov al,24                       ; No vidrows in BIOS, assume 25
  3120                                  						; (Remember: vidrows == rows-1)
  3121 000011C0 A24155                  vidrows_is_ok:  mov [VidRows],al
  3122 000011C3 B40F                                    mov ah,0fh
  3123 000011C5 CD10                                    int 10h                         ; Read video state
  3124 000011C7 883E3D55                                mov [TextPage],bh
  3125 000011CB FECC                                    dec ah                          ; Store count-1 (same as rows)
  3126 000011CD 88264055                                mov [VidCols],ah
  3127 000011D1 C3                      		ret
  3128                                  
  3129                                  ;
  3130                                  ; loadkeys:	Load a LILO-style keymap; SI and DX:AX set by searchdir
  3131                                  ;
  3132                                  loadkeys:
  3133 000011D2 21D2                    		and dx,dx			; Should be 256 bytes exactly
  3134 000011D4 751A                    		jne loadkeys_ret
  3135 000011D6 3D0001                  		cmp ax,256
  3136 000011D9 7515                    		jne loadkeys_ret
  3137                                  
  3138 000011DB BB0010                  		mov bx,trackbuf
  3139 000011DE B90100                  		mov cx,1			; 1 cluster should be >= 256 bytes
  3140 000011E1 E842F1                  		call getfssec
  3141                                  
  3142 000011E4 BE0010                  		mov si,trackbuf
  3143 000011E7 BF0053                  		mov di,KbdMap
  3144 000011EA B94000                  		mov cx,256 >> 2
  3145 000011ED F366A5                  		rep movsd
  3146                                  
  3147 000011F0 C3                      loadkeys_ret:	ret
  3148                                  		
  3149                                  ;
  3150                                  ; get_msg_file: Load a text file and write its contents to the screen,
  3151                                  ;               interpreting color codes.  Is called with SI and DX:AX
  3152                                  ;               set by routine searchdir
  3153                                  ;
  3154                                  get_msg_file:
  3155 000011F1 06                      		push es
  3156 000011F2 66C1E210                		shl edx,16			; EDX <- DX:AX (length of file)
  3157 000011F6 89C2                    		mov dx,ax
  3158 000011F8 B80030                  		mov ax,xfer_buf_seg		; Use for temporary storage
  3159 000011FB 8EC0                    		mov es,ax
  3160                                  
  3161 000011FD C6063C5507                              mov byte [TextAttribute],07h	; Default grey on white
  3162 00001202 C6064A5507              		mov byte [DisplayMask],07h	; Display text in all modes
  3163 00001207 E86001                  		call msg_initvars
  3164                                  
  3165 0000120A 6652                    get_msg_chunk:  push edx			; EDX = length of file
  3166 0000120C 31DB                    		xor bx,bx			; == xbs_textbuf
  3167 0000120E 8B0E1055                		mov cx,[BufSafe]
  3168 00001212 E811F1                  		call getfssec
  3169 00001215 665A                    		pop edx
  3170 00001217 56                      		push si				; Save current cluster
  3171 00001218 31F6                    		xor si,si			; == xbs_textbuf
  3172 0000121A 8B0E1455                		mov cx,[BufSafeBytes]		; Number of bytes left in chunk
  3173                                  print_msg_file:
  3174 0000121E 51                      		push cx
  3175 0000121F 6652                    		push edx
  3176 00001221 26AC                    		es lodsb
  3177 00001223 3C1A                                    cmp al,1Ah                      ; DOS EOF?
  3178 00001225 7418                    		je msg_done_pop
  3179 00001227 56                      		push si
  3180 00001228 8A0E[CC18]              		mov cl,[UsingVGA]
  3181 0000122C FEC1                    		inc cl				; 01h = text mode, 02h = graphics
  3182 0000122E FF162A55                                call [NextCharJump]		; Do what shall be done
  3183 00001232 5E                      		pop si
  3184 00001233 665A                    		pop edx
  3185 00001235 59                                      pop cx
  3186 00001236 664A                    		dec edx
  3187 00001238 7408                    		jz msg_done
  3188 0000123A E2E2                    		loop print_msg_file
  3189 0000123C 5E                      		pop si
  3190 0000123D EBCB                    		jmp short get_msg_chunk
  3191                                  msg_done_pop:
  3192 0000123F 83C406                                  add sp,byte 6			; Drop pushed EDX, CX
  3193                                  msg_done:
  3194 00001242 5E                      		pop si
  3195 00001243 07                      		pop es
  3196 00001244 C3                      		ret
  3197                                  msg_putchar:                                    ; Normal character
  3198 00001245 3C0F                                    cmp al,0Fh                      ; ^O = color code follows
  3199 00001247 744E                                    je msg_ctrl_o
  3200 00001249 3C0D                                    cmp al,0Dh                      ; Ignore <CR>
  3201 0000124B 7449                                    je msg_ignore
  3202 0000124D 3C0A                                    cmp al,0Ah                      ; <LF> = newline
  3203 0000124F 744D                                    je msg_newline
  3204 00001251 3C0C                                    cmp al,0Ch                      ; <FF> = clear screen
  3205 00001253 747E                                    je msg_formfeed
  3206 00001255 3C19                    		cmp al,19h			; <EM> = return to text mode
  3207 00001257 0F84F300                		je near msg_novga
  3208 0000125B 3C18                    		cmp al,18h			; <CAN> = VGA filename follows
  3209 0000125D 0F84BC00                		je near msg_vga
  3210 00001261 7306                    		jnb .not_modectl
  3211 00001263 3C10                    		cmp al,10h			; 10h to 17h are mode controls
  3212 00001265 0F831101                		jae near msg_modectl
  3213                                  .not_modectl:
  3214                                  
  3215 00001269 E81501                  msg_normal:	call write_serial_displaymask	; Write to serial port
  3216 0000126C 840E4A55                		test [DisplayMask],cl
  3217 00001270 7424                    		jz msg_ignore			; Not screen
  3218 00001272 8B1E3C55                                mov bx,[TextAttrBX]
  3219 00001276 B409                                    mov ah,09h                      ; Write character/attribute
  3220 00001278 B90100                                  mov cx,1                        ; One character only
  3221 0000127B CD10                                    int 10h                         ; Write to screen
  3222 0000127D A03E55                                  mov al,[CursorCol]
  3223 00001280 40                                      inc ax
  3224 00001281 3A064055                                cmp al,[VidCols]
  3225 00001285 771D                                    ja msg_line_wrap		; Screen wraparound
  3226 00001287 A23E55                                  mov [CursorCol],al
  3227                                  
  3228 0000128A 8A3E3D55                msg_gotoxy:     mov bh,[TextPage]
  3229 0000128E 8B163E55                                mov dx,[CursorDX]
  3230 00001292 B402                                    mov ah,02h                      ; Set cursor position
  3231 00001294 CD10                                    int 10h
  3232 00001296 C3                      msg_ignore:     ret
  3233                                  msg_ctrl_o:                                     ; ^O = color code follows
  3234 00001297 C7062A55[F412]                          mov word [NextCharJump],msg_setbg
  3235 0000129D C3                                      ret
  3236                                  msg_newline:                                    ; Newline char or end of line
  3237 0000129E BE[F81C]                		mov si,crlf_msg
  3238 000012A1 E81001                  		call write_serial_str_displaymask
  3239                                  msg_line_wrap:					; Screen wraparound
  3240 000012A4 840E4A55                		test [DisplayMask],cl
  3241 000012A8 74EC                    		jz msg_ignore
  3242 000012AA C6063E5500                              mov byte [CursorCol],0
  3243 000012AF A03F55                                  mov al,[CursorRow]
  3244 000012B2 40                                      inc ax
  3245 000012B3 3A064155                                cmp al,[VidRows]
  3246 000012B7 7705                                    ja msg_scroll
  3247 000012B9 A23F55                                  mov [CursorRow],al
  3248 000012BC EBCC                                    jmp short msg_gotoxy
  3249 000012BE 31C9                    msg_scroll:     xor cx,cx                       ; Upper left hand corner
  3250 000012C0 8B164055                                mov dx,[ScreenSize]
  3251 000012C4 88363F55                                mov [CursorRow],dh		; New cursor at the bottom
  3252 000012C8 8A3E[7B1D]                              mov bh,[ScrollAttribute]
  3253 000012CC B80106                                  mov ax,0601h                    ; Scroll up one line
  3254 000012CF CD10                                    int 10h
  3255 000012D1 EBB7                                    jmp short msg_gotoxy
  3256                                  msg_formfeed:                                   ; Form feed character
  3257 000012D3 BE[FB1C]                		mov si,crff_msg
  3258 000012D6 E8DB00                  		call write_serial_str_displaymask
  3259 000012D9 840E4A55                		test [DisplayMask],cl
  3260 000012DD 74B7                    		jz msg_ignore
  3261 000012DF 31C9                                    xor cx,cx
  3262 000012E1 890E3E55                                mov [CursorDX],cx		; Upper lefthand corner
  3263 000012E5 8B164055                                mov dx,[ScreenSize]
  3264 000012E9 8A3E3C55                                mov bh,[TextAttribute]
  3265 000012ED B80006                                  mov ax,0600h                    ; Clear screen region
  3266 000012F0 CD10                                    int 10h
  3267 000012F2 EB96                                    jmp short msg_gotoxy
  3268                                  msg_setbg:                                      ; Color background character
  3269 000012F4 E8FA02                                  call unhexchar
  3270 000012F7 722F                                    jc msg_color_bad
  3271 000012F9 C0E004                                  shl al,4
  3272 000012FC 840E4A55                		test [DisplayMask],cl
  3273 00001300 7403                    		jz .dontset
  3274 00001302 A23C55                                  mov [TextAttribute],al
  3275                                  .dontset:
  3276 00001305 C7062A55[0C13]                          mov word [NextCharJump],msg_setfg
  3277 0000130B C3                                      ret
  3278                                  msg_setfg:                                      ; Color foreground character
  3279 0000130C E8E202                                  call unhexchar
  3280 0000130F 7217                                    jc msg_color_bad
  3281 00001311 840E4A55                		test [DisplayMask],cl
  3282 00001315 7404                    		jz .dontset
  3283 00001317 08063C55                                or [TextAttribute],al		; setbg set foreground to 0
  3284                                  .dontset:
  3285 0000131B EB10                    		jmp short msg_putcharnext
  3286                                  msg_vga:
  3287 0000131D C7062A55[3413]          		mov word [NextCharJump],msg_filename
  3288 00001323 BF8C55                  		mov di, VGAFileBuf
  3289 00001326 EB21                    		jmp short msg_setvgafileptr
  3290                                  
  3291                                  msg_color_bad:
  3292 00001328 C6063C5507                              mov byte [TextAttribute],07h	; Default attribute
  3293                                  msg_putcharnext:
  3294 0000132D C7062A55[4512]                          mov word [NextCharJump],msg_putchar
  3295 00001333 C3                      		ret
  3296                                  
  3297                                  msg_filename:					; Getting VGA filename
  3298 00001334 3C0A                    		cmp al,0Ah			; <LF> = end of filename
  3299 00001336 741B                    		je msg_viewimage
  3300 00001338 3C20                    		cmp al,' '
  3301 0000133A 7611                    		jbe msg_ret			; Ignore space/control char
  3302 0000133C 8B3E3A55                		mov di,[VGAFilePtr]
  3303 00001340 81FF9955                		cmp di,VGAFileBufEnd
  3304 00001344 7307                    		jnb msg_ret
  3305 00001346 8805                    		mov [di],al			; Can't use stosb (DS:)
  3306 00001348 47                      		inc di
  3307                                  msg_setvgafileptr:
  3308 00001349 893E3A55                		mov [VGAFilePtr],di
  3309 0000134D C3                      msg_ret:	ret
  3310                                  
  3311                                  msg_novga:
  3312 0000134E E82405                  		call vgaclearmode
  3313 00001351 EB17                    		jmp short msg_initvars
  3314                                  
  3315                                  msg_viewimage:
  3316 00001353 06                      		push es
  3317 00001354 1E                      		push ds
  3318 00001355 07                      		pop es				; ES <- DS
  3319 00001356 BE8C55                  		mov si,VGAFileBuf
  3320 00001359 BF9955                  		mov di,VGAFileMBuf
  3321 0000135C 57                      		push di
  3322 0000135D E8E802                  		call mangle_name
  3323 00001360 5F                      		pop di
  3324 00001361 E84CFD                  		call searchdir
  3325 00001364 07                      		pop es
  3326 00001365 74C6                    		jz msg_putcharnext		; Not there
  3327 00001367 E88503                  		call vgadisplayfile
  3328                                  		; Fall through
  3329                                  
  3330                                  		; Subroutine to initialize variables, also needed
  3331                                  		; after loading a graphics file
  3332                                  msg_initvars:
  3333 0000136A 60                                      pusha
  3334 0000136B 8A3E3D55                                mov bh,[TextPage]
  3335 0000136F B403                                    mov ah,03h                      ; Read cursor position
  3336 00001371 CD10                                    int 10h
  3337 00001373 89163E55                                mov [CursorDX],dx
  3338 00001377 61                                      popa
  3339 00001378 EBB3                    		jmp short msg_putcharnext	; Initialize state machine
  3340                                  
  3341                                  msg_modectl:
  3342 0000137A 2407                    		and al,07h
  3343 0000137C A24A55                  		mov [DisplayMask],al
  3344 0000137F EBAC                    		jmp short msg_putcharnext
  3345                                  
  3346                                  ;
  3347                                  ; write_serial:	If serial output is enabled, write character on serial port
  3348                                  ; write_serial_displaymask: d:o, but ignore if DisplayMask & 04h == 0
  3349                                  ;
  3350                                  write_serial_displaymask:
  3351 00001381 F6064A5504              		test byte [DisplayMask], 04h
  3352 00001386 742B                    		jz write_serial.end
  3353                                  write_serial:
  3354 00001388 669C                    		pushfd
  3355 0000138A 6660                    		pushad
  3356 0000138C 8B1E[601D]              		mov bx,[SerialPort]
  3357 00001390 21DB                    		and bx,bx
  3358 00001392 741B                    		je .noserial
  3359 00001394 50                      		push ax
  3360 00001395 8A264355                		mov ah,[FlowInput]
  3361                                  .waitspace:
  3362                                  		; Wait for space in transmit register
  3363 00001399 8D5705                  		lea dx,[bx+5]			; DX -> LSR
  3364 0000139C EC                      		in al,dx
  3365 0000139D A820                    		test al,20h
  3366 0000139F 74F8                    		jz .waitspace
  3367                                  
  3368                                  		; Wait for input flow control
  3369 000013A1 42                      		inc dx				; DX -> MSR
  3370 000013A2 EC                      		in al,dx
  3371 000013A3 20E0                    		and al,ah
  3372 000013A5 38E0                    		cmp al,ah
  3373 000013A7 75F0                    		jne .waitspace	
  3374                                  .no_flow:		
  3375                                  
  3376 000013A9 87D3                    		xchg dx,bx			; DX -> THR
  3377 000013AB 58                      		pop ax
  3378 000013AC E84EFB                  		call slow_out			; Send data
  3379 000013AF 6661                    .noserial:	popad
  3380 000013B1 669D                    		popfd
  3381 000013B3 C3                      .end:		ret
  3382                                  
  3383                                  ;
  3384                                  ; write_serial_str: write_serial for strings
  3385                                  ; write_serial_str_displaymask: d:o, but ignore if DisplayMask & 04h == 0
  3386                                  ;
  3387                                  write_serial_str_displaymask:
  3388 000013B4 F6064A5504              		test byte [DisplayMask], 04h
  3389 000013B9 740A                    		jz write_serial_str.end
  3390                                  
  3391                                  write_serial_str:
  3392 000013BB AC                      .loop		lodsb
  3393 000013BC 20C0                    		and al,al
  3394 000013BE 7405                    		jz .end
  3395 000013C0 E8C5FF                  		call write_serial
  3396 000013C3 EBF6                    		jmp short .loop
  3397 000013C5 C3                      .end:		ret
  3398                                  
  3399                                  ;
  3400                                  ; writechr:	Write a single character in AL to the console without
  3401                                  ;		mangling any registers
  3402                                  ;
  3403                                  writechr:
  3404 000013C6 E8BFFF                  		call write_serial	; write to serial port if needed
  3405 000013C9 669C                    		pushfd
  3406 000013CB 6660                    		pushad
  3407 000013CD B40E                    		mov ah,0Eh
  3408 000013CF BB0700                  		mov bx,0007h		; white text on this page
  3409 000013D2 CD10                    		int 10h
  3410 000013D4 6661                    		popad
  3411 000013D6 669D                    		popfd
  3412 000013D8 C3                      		ret
  3413                                  
  3414                                  ;
  3415                                  ; crlf: Print a newline
  3416                                  ;
  3417 000013D9 BE[F81C]                crlf:		mov si,crlf_msg
  3418                                  		; Fall through
  3419                                  
  3420                                  ;
  3421                                  ; cwritestr: write a null-terminated string to the console, saving
  3422                                  ;            registers on entry.
  3423                                  ;
  3424                                  cwritestr:
  3425 000013DC 669C                    		pushfd
  3426 000013DE 6660                                    pushad
  3427 000013E0 AC                      .top:		lodsb
  3428 000013E1 20C0                    		and al,al
  3429 000013E3 7405                                    jz .end
  3430 000013E5 E8DEFF                  		call writechr
  3431 000013E8 EBF6                                    jmp short .top
  3432 000013EA 6661                    .end:		popad
  3433 000013EC 669D                    		popfd
  3434 000013EE C3                                      ret
  3435                                  
  3436                                  %ifdef debug
  3437                                  
  3438                                  ;
  3439                                  ; writehex[248]: Write a hex number in (AL, AX, EAX) to the console
  3440                                  ;
  3441                                  writehex2:
  3442                                  		pushfd
  3443                                  		pushad
  3444                                  		rol eax,24
  3445                                  		mov cx,2
  3446                                  		jmp short writehex_common
  3447                                  writehex4:
  3448                                  		pushfd
  3449                                  		pushad
  3450                                  		rol eax,16
  3451                                  		mov cx,4
  3452                                  		jmp short writehex_common
  3453                                  writehex8:
  3454                                  		pushfd
  3455                                  		pushad
  3456                                  		mov cx,8
  3457                                  writehex_common:
  3458                                  .loop:		rol eax,4
  3459                                  		push eax
  3460                                  		and al,0Fh
  3461                                  		cmp al,10
  3462                                  		jae .high
  3463                                  .low:		add al,'0'
  3464                                  		jmp short .ischar
  3465                                  .high:		add al,'A'-10
  3466                                  .ischar:	call writechr
  3467                                  		pop eax
  3468                                  		loop .loop
  3469                                  		popad
  3470                                  		popfd
  3471                                  		ret
  3472                                  
  3473                                  ;
  3474                                  ; crlf: write CR LF
  3475                                  ;
  3476                                  crlf:		push ax
  3477                                  		mov al, 13
  3478                                  		call writechr
  3479                                  		mov al, 10
  3480                                  		call writechr
  3481                                  		pop ax
  3482                                  		ret
  3483                                  
  3484                                  %endif
  3485                                  
  3486                                  ;
  3487                                  ; pollchar: check if we have an input character pending (ZF = 0)
  3488                                  ;
  3489                                  pollchar:
  3490 000013EF 6660                    		pushad
  3491 000013F1 B401                    		mov ah,1		; Poll keyboard
  3492 000013F3 CD16                    		int 16h
  3493 000013F5 751F                    		jnz .done		; Keyboard response
  3494 000013F7 8B16[601D]              		mov dx,[SerialPort]
  3495 000013FB 21D2                    		and dx,dx
  3496 000013FD 7417                    		jz .done		; No serial port -> no input
  3497 000013FF 83C205                  		add dx,byte 5		; DX -> LSR
  3498 00001402 EC                      		in al,dx
  3499 00001403 A801                    		test al,1		; ZF = 0 if data pending
  3500 00001405 740F                    		jz .done
  3501 00001407 42                      		inc dx			; DX -> MSR
  3502 00001408 8A264455                		mov ah,[FlowIgnore]	; Required status bits
  3503 0000140C EC                      		in al,dx
  3504 0000140D 20E0                    		and al,ah
  3505 0000140F 38E0                    		cmp al,ah
  3506 00001411 0F95C0                  		setne al
  3507 00001414 FEC8                    		dec al			; Set ZF = 0 if equal
  3508 00001416 6661                    .done:		popad
  3509 00001418 C3                      		ret
  3510                                  
  3511                                  ;
  3512                                  ; getchar: Read a character from keyboard or serial port
  3513                                  ;
  3514                                  getchar:
  3515 00001419 B401                    .again:		mov ah,1		; Poll keyboard
  3516 0000141B CD16                    		int 16h
  3517 0000141D 7522                    		jnz .kbd		; Keyboard input?
  3518 0000141F 8B1E[601D]              		mov bx,[SerialPort]
  3519 00001423 21DB                    		and bx,bx
  3520 00001425 74F2                    		jz .again
  3521 00001427 8D5705                  		lea dx,[bx+5]		; DX -> LSR
  3522 0000142A EC                      		in al,dx
  3523 0000142B A801                    		test al,1
  3524 0000142D 74EA                    		jz .again
  3525 0000142F 42                      		inc dx			; DX -> MSR
  3526 00001430 8A264455                		mov ah,[FlowIgnore]
  3527 00001434 EC                      		in al,dx
  3528 00001435 20E0                    		and al,ah
  3529 00001437 38E0                    		cmp al,ah
  3530 00001439 75DE                    		jne .again
  3531 0000143B 30E4                    .serial:	xor ah,ah		; Avoid confusion
  3532 0000143D 87D3                    		xchg dx,bx		; Data port
  3533 0000143F EC                      		in al,dx
  3534 00001440 C3                      		ret
  3535 00001441 31C0                    .kbd:		xor ax,ax		; Get keyboard input
  3536 00001443 CD16                    		int 16h
  3537 00001445 20C0                    		and al,al
  3538 00001447 7404                    		jz .func_key
  3539 00001449 BB0053                  		mov bx,KbdMap		; Convert character sets
  3540 0000144C D7                      		xlatb
  3541 0000144D C3                      .func_key:	ret
  3542                                  
  3543                                  ;
  3544                                  ;
  3545                                  ; kaboom2: once everything is loaded, replace the part of kaboom
  3546                                  ;	   starting with "kaboom.patch" with this part
  3547                                  
  3548                                  kaboom2:
  3549 0000144E BE[971C]                		mov si,err_bootfailed
  3550 00001451 E888FF                  		call cwritestr
  3551 00001454 E8C2FF                  		call getchar
  3552 00001457 E81B04                  		call vgaclearmode
  3553 0000145A CD19                    		int 19h			; And try once more to boot...
  3554 0000145C EBFE                    .norge:		jmp short .norge	; If int 19h returned; this is the end
  3555                                  
  3556                                  ;
  3557                                  ; open,getc:	Load a file a character at a time for parsing in a manner
  3558                                  ;		similar to the C library getc routine.	Only one simultaneous
  3559                                  ;		use is supported.  Note: "open" trashes the trackbuf.
  3560                                  ;
  3561                                  ;		open:	Input:	mangled filename in DS:DI
  3562                                  ;			Output: ZF set on file not found or zero length
  3563                                  ;
  3564                                  ;		getc:	Output: CF set on end of file
  3565                                  ;				Character loaded in AL
  3566                                  ;
  3567                                  open:
  3568 0000145E E84FFC                  		call searchdir
  3569 00001461 7427                    		jz open_return
  3570 00001463 9C                      		pushf
  3571 00001464 A3FC54                  		mov [FBytes1],ax
  3572 00001467 8916FE54                		mov [FBytes2],dx
  3573 0000146B 03060A55                		add ax,[ClustSize]
  3574 0000146F 83D200                  		adc dx,byte 0
  3575 00001472 83E801                  		sub ax,byte 1
  3576 00001475 83DA00                  		sbb dx,byte 0
  3577 00001478 F7360A55                		div word [ClustSize]
  3578 0000147C A31E55                  		mov [FClust],ax		; Number of clusters
  3579 0000147F 89362055                		mov [FNextClust],si	; Cluster pointer
  3580 00001483 A11655                  		mov ax,[EndOfGetCBuf]	; Pointer at end of buffer ->
  3581 00001486 A32255                  		mov [FPtr],ax		;  nothing loaded yet
  3582 00001489 9D                      		popf			; Restore no ZF
  3583 0000148A C3                      open_return:	ret
  3584                                  
  3585                                  ;
  3586                                  getc:
  3587 0000148B F9                      		stc			; If we exit here -> EOF
  3588 0000148C 668B0EFC54              		mov ecx,[FBytes]
  3589 00001491 66E33B                  		jecxz getc_ret
  3590 00001494 8B362255                		mov si,[FPtr]
  3591 00001498 3B361655                		cmp si,[EndOfGetCBuf]
  3592 0000149C 7226                    		jb getc_loaded
  3593                                  		; Buffer empty -- load another set
  3594 0000149E 8B0E1E55                		mov cx,[FClust]
  3595 000014A2 3B0E1055                		cmp cx,[BufSafe]
  3596 000014A6 7604                    		jna getc_oksize
  3597 000014A8 8B0E1055                		mov cx,[BufSafe]
  3598 000014AC 290E1E55                getc_oksize:	sub [FClust],cx		; Reduce remaining clusters
  3599 000014B0 8B362055                		mov si,[FNextClust]
  3600 000014B4 BB009C                  		mov bx,getcbuf
  3601 000014B7 53                      		push bx
  3602 000014B8 06                      		push es			; ES may be != DS, save old ES
  3603 000014B9 1E                      		push ds			; Trackbuf is in DS, not ES
  3604 000014BA 07                      		pop es
  3605 000014BB E868EE                  		call getfssec		; Load a trackbuf full of data
  3606 000014BE 89362055                		mov [FNextClust],si	; Store new next pointer
  3607 000014C2 07                      		pop es			; Restore ES
  3608 000014C3 5E                      		pop si			; SI -> newly loaded data
  3609 000014C4 AC                      getc_loaded:	lodsb			; Load a byte
  3610 000014C5 89362255                		mov [FPtr],si		; Update next byte pointer
  3611 000014C9 66FF0EFC54              		dec dword [FBytes]	; Update bytes left counter (CF = 1)
  3612 000014CE F8                      		clc			; Not EOF
  3613 000014CF C3                      getc_ret:	ret
  3614                                  
  3615                                  ;
  3616                                  ; ungetc:	Push a character (in AL) back into the getc buffer
  3617                                  ;		Note: if more than one byte is pushed back, this may cause
  3618                                  ;		bytes to be written below the getc buffer boundary.  If there
  3619                                  ;		is a risk for this to occur, the getcbuf base address should
  3620                                  ;		be moved up.
  3621                                  ;
  3622                                  ungetc:
  3623 000014D0 8B362255                		mov si,[FPtr]
  3624 000014D4 4E                      		dec si
  3625 000014D5 8804                    		mov [si],al
  3626 000014D7 89362255                		mov [FPtr],si
  3627 000014DB 66FF06FC54              		inc dword [FBytes]
  3628 000014E0 C3                      		ret
  3629                                  
  3630                                  ;
  3631                                  ; skipspace:	Skip leading whitespace using "getc".  If we hit end-of-line
  3632                                  ;		or end-of-file, return with carry set; ZF = true of EOF
  3633                                  ;		ZF = false for EOLN; otherwise CF = ZF = 0.
  3634                                  ;
  3635                                  ;		Otherwise AL = first character after whitespace
  3636                                  ;
  3637                                  skipspace:
  3638 000014E1 E8A7FF                  skipspace_loop: call getc
  3639 000014E4 720D                    		jc skipspace_eof
  3640 000014E6 3C1A                    		cmp al,1Ah			; DOS EOF
  3641 000014E8 7409                    		je skipspace_eof
  3642 000014EA 3C0A                    		cmp al,0Ah
  3643 000014EC 7409                    		je skipspace_eoln
  3644 000014EE 3C20                    		cmp al,' '
  3645 000014F0 76EF                    		jbe skipspace_loop
  3646 000014F2 C3                      		ret				; CF = ZF = 0
  3647 000014F3 38C0                    skipspace_eof:	cmp al,al			; Set ZF
  3648 000014F5 F9                      		stc				; Set CF
  3649 000014F6 C3                      		ret
  3650 000014F7 04FF                    skipspace_eoln: add al,0FFh			; Set CF, clear ZF
  3651 000014F9 C3                      		ret
  3652                                  
  3653                                  ;
  3654                                  ; getkeyword:	Get a keyword from the current "getc" file; only the two
  3655                                  ;		first characters are considered significant.
  3656                                  ;
  3657                                  ;		Lines beginning with ASCII characters 33-47 are treated
  3658                                  ;		as comments and ignored; other lines are checked for
  3659                                  ;		validity by scanning through the keywd_table.
  3660                                  ;
  3661                                  ;		The keyword and subsequent whitespace is skipped.
  3662                                  ;
  3663                                  ;		On EOF, CF = 1; otherwise, CF = 0, AL:AH = lowercase char pair
  3664                                  ;
  3665                                  getkeyword:
  3666 000014FA E8E4FF                  gkw_find:	call skipspace
  3667 000014FD 7438                    		jz gkw_eof		; end of file
  3668 000014FF 72F9                    		jc gkw_find		; end of line: try again
  3669 00001501 3C30                    		cmp al,'0'
  3670 00001503 7246                    		jb gkw_skipline		; skip comment line
  3671 00001505 50                      		push ax
  3672 00001506 E882FF                  		call getc
  3673 00001509 5B                      		pop bx
  3674 0000150A 722B                    		jc gkw_eof
  3675 0000150C 88C7                    		mov bh,al		; Move character pair into BL:BH
  3676 0000150E 81CB2020                		or bx,2020h		; Lower-case it
  3677 00001512 BE[101D]                		mov si,keywd_table
  3678 00001515 AD                      gkw_check:	lodsw
  3679 00001516 21C0                    		and ax,ax
  3680 00001518 7429                    		jz gkw_badline		; Bad keyword, write message
  3681 0000151A 39D8                    		cmp ax,bx
  3682 0000151C 75F7                    		jne gkw_check
  3683 0000151E 50                      		push ax
  3684                                  gkw_skiprest:
  3685 0000151F E869FF                  		call getc
  3686 00001522 7212                    		jc gkw_eof_pop
  3687 00001524 3C30                    		cmp al,'0'
  3688 00001526 77F7                    		ja gkw_skiprest
  3689 00001528 E8A5FF                  		call ungetc
  3690 0000152B E8B3FF                  		call skipspace
  3691 0000152E 7406                    		jz gkw_eof_pop
  3692 00001530 7206                                    jc gkw_missingpar       ; Missing parameter after keyword
  3693 00001532 E89BFF                  		call ungetc		; Return character to buffer
  3694 00001535 F8                      		clc			; Successful return
  3695 00001536 58                      gkw_eof_pop:	pop ax
  3696 00001537 C3                      gkw_eof:	ret			; CF = 1 on all EOF conditions
  3697 00001538 58                      gkw_missingpar: pop ax
  3698 00001539 BE[561B]                                mov si,err_noparm
  3699 0000153C E89DFE                                  call cwritestr
  3700 0000153F E9B8FF                                  jmp gkw_find
  3701 00001542 58                      gkw_badline_pop: pop ax
  3702 00001543 BE[331B]                gkw_badline:	mov si,err_badcfg
  3703 00001546 E893FE                  		call cwritestr
  3704 00001549 EBAF                    		jmp short gkw_find
  3705 0000154B 3C0A                    gkw_skipline:	cmp al,10		; Scan for LF
  3706 0000154D 74AB                    		je gkw_find
  3707 0000154F E839FF                  		call getc
  3708 00001552 72E3                    		jc gkw_eof
  3709 00001554 EBF5                    		jmp short gkw_skipline
  3710                                  
  3711                                  ;
  3712                                  ; getint:	Load an integer from the getc file.
  3713                                  ;		Return CF if error; otherwise return integer in EBX
  3714                                  ;
  3715                                  getint:
  3716 00001556 BFA054                  		mov di,NumBuf
  3717 00001559 81FFAF54                gi_getnum:	cmp di,NumBufEnd	; Last byte in NumBuf
  3718 0000155D 730F                    		jae gi_loaded
  3719 0000155F 57                      		push di
  3720 00001560 E828FF                  		call getc
  3721 00001563 5F                      		pop di
  3722 00001564 7208                    		jc gi_loaded
  3723 00001566 AA                      		stosb
  3724 00001567 3C2D                    		cmp al,'-'
  3725 00001569 73EE                    		jnb gi_getnum
  3726 0000156B E862FF                  		call ungetc		; Unget non-numeric
  3727 0000156E C60500                  gi_loaded:	mov byte [di],0
  3728 00001571 BEA054                  		mov si,NumBuf
  3729                                  		; Fall through to parseint
  3730                                  
  3731                                  ;
  3732                                  ; parseint:	Convert an integer to a number in EBX
  3733                                  ;		Get characters from string in DS:SI
  3734                                  ;		Return CF on error
  3735                                  ;		DS:SI points to first character after number
  3736                                  ;
  3737                                  ;               Syntaxes accepted: [-]dec, [-]0+oct, [-]0x+hex, val+K, val+M
  3738                                  ;
  3739                                  parseint:
  3740 00001574 6650                                    push eax
  3741 00001576 6651                                    push ecx
  3742 00001578 55                      		push bp
  3743 00001579 6631C0                  		xor eax,eax		; Current digit (keep eax == al)
  3744 0000157C 6689C3                  		mov ebx,eax		; Accumulator
  3745 0000157F 6689D9                  		mov ecx,ebx		; Base
  3746 00001582 31ED                                    xor bp,bp               ; Used for negative flag
  3747 00001584 AC                      pi_begin:	lodsb
  3748 00001585 3C2D                    		cmp al,'-'
  3749 00001587 7506                    		jne pi_not_minus
  3750 00001589 81F50100                		xor bp,1		; Set unary minus flag
  3751 0000158D EBF5                    		jmp short pi_begin
  3752                                  pi_not_minus:
  3753 0000158F 3C30                    		cmp al,'0'
  3754 00001591 724F                    		jb pi_err
  3755 00001593 7408                    		je pi_octhex
  3756 00001595 3C39                    		cmp al,'9'
  3757 00001597 7749                    		ja pi_err
  3758 00001599 B10A                    		mov cl,10		; Base = decimal
  3759 0000159B EB17                    		jmp short pi_foundbase
  3760                                  pi_octhex:
  3761 0000159D AC                      		lodsb
  3762 0000159E 3C30                    		cmp al,'0'
  3763 000015A0 7225                    		jb pi_km		; Value is zero
  3764 000015A2 0C20                    		or al,20h		; Downcase
  3765 000015A4 3C78                    		cmp al,'x'
  3766 000015A6 7408                    		je pi_ishex
  3767 000015A8 3C37                    		cmp al,'7'
  3768 000015AA 7736                    		ja pi_err
  3769 000015AC B108                    		mov cl,8		; Base = octal
  3770 000015AE EB04                    		jmp short pi_foundbase
  3771                                  pi_ishex:
  3772 000015B0 B030                    		mov al,'0'		; No numeric value accrued yet
  3773 000015B2 B110                    		mov cl,16		; Base = hex
  3774                                  pi_foundbase:
  3775 000015B4 E83A00                                  call unhexchar
  3776 000015B7 720E                                    jc pi_km                ; Not a (hex) digit
  3777 000015B9 38C8                                    cmp al,cl
  3778 000015BB 730A                    		jae pi_km		; Invalid for base
  3779 000015BD 660FAFD9                		imul ebx,ecx		; Multiply accumulated by base
  3780 000015C1 6601C3                                  add ebx,eax             ; Add current digit
  3781 000015C4 AC                      		lodsb
  3782 000015C5 EBED                    		jmp short pi_foundbase
  3783                                  pi_km:
  3784 000015C7 4E                      		dec si			; Back up to last non-numeric
  3785 000015C8 AC                      		lodsb
  3786 000015C9 0C20                    		or al,20h
  3787 000015CB 3C6B                    		cmp al,'k'
  3788 000015CD 7416                    		je pi_isk
  3789 000015CF 3C6D                    		cmp al,'m'
  3790 000015D1 7418                    		je pi_ism
  3791 000015D3 4E                      		dec si			; Back up
  3792 000015D4 21ED                    pi_fini:	and bp,bp
  3793 000015D6 7404                    		jz pi_ret		; CF=0!
  3794 000015D8 66F7DB                  		neg ebx			; Value was negative
  3795 000015DB F8                      pi_done:	clc
  3796 000015DC 5D                      pi_ret:		pop bp
  3797 000015DD 6659                                    pop ecx
  3798 000015DF 6658                                    pop eax
  3799 000015E1 C3                      		ret
  3800 000015E2 F9                      pi_err:		stc
  3801 000015E3 EBF7                    		jmp short pi_ret
  3802 000015E5 66C1E30A                pi_isk:		shl ebx,10		; x 2^10
  3803 000015E9 EBF0                    		jmp short pi_done
  3804 000015EB 66C1E314                pi_ism:		shl ebx,20		; x 2^20
  3805 000015EF EBEA                    		jmp short pi_done
  3806                                  
  3807                                  ;
  3808                                  ; unhexchar:    Convert a hexadecimal digit in AL to the equivalent number;
  3809                                  ;               return CF=1 if not a hex digit
  3810                                  ;
  3811                                  unhexchar:
  3812 000015F1 3C30                                    cmp al,'0'
  3813 000015F3 7215                    		jb uxc_ret		; If failure, CF == 1 already
  3814 000015F5 3C39                                    cmp al,'9'
  3815 000015F7 7703                                    ja uxc_1
  3816 000015F9 2C30                    		sub al,'0'		; CF <- 0
  3817 000015FB C3                      		ret
  3818 000015FC 0C20                    uxc_1:          or al,20h		; upper case -> lower case
  3819 000015FE 3C61                    		cmp al,'a'
  3820 00001600 7208                                    jb uxc_ret		; If failure, CF == 1 already
  3821 00001602 3C66                                    cmp al,'f'
  3822 00001604 7703                                    ja uxc_err
  3823 00001606 2C57                                    sub al,'a'-10           ; CF <- 0
  3824 00001608 C3                                      ret
  3825 00001609 F9                      uxc_err:        stc
  3826 0000160A C3                      uxc_ret:	ret
  3827                                  
  3828                                  ;
  3829                                  ;
  3830                                  ; getline:	Get a command line, converting control characters to spaces
  3831                                  ;               and collapsing streches to one; a space is appended to the
  3832                                  ;               end of the string, unless the line is empty.
  3833                                  ;		The line is terminated by ^J, ^Z or EOF and is written
  3834                                  ;		to ES:DI.  On return, DI points to first char after string.
  3835                                  ;		CF is set if we hit EOF.
  3836                                  ;
  3837                                  getline:
  3838 0000160B E8D3FE                  		call skipspace
  3839 0000160E B201                                    mov dl,1                ; Empty line -> empty string.
  3840 00001610 742B                                    jz gl_eof               ; eof
  3841 00001612 7226                                    jc gl_eoln              ; eoln
  3842 00001614 E8B9FE                  		call ungetc
  3843 00001617 52                      gl_fillloop:	push dx
  3844 00001618 57                      		push di
  3845 00001619 E86FFE                  		call getc
  3846 0000161C 5F                      		pop di
  3847 0000161D 5A                      		pop dx
  3848 0000161E 721E                    		jc gl_ret		; CF set!
  3849 00001620 3C20                    		cmp al,' '
  3850 00001622 7605                    		jna gl_ctrl
  3851 00001624 31D2                    		xor dx,dx
  3852 00001626 AA                      gl_store:	stosb
  3853 00001627 EBEE                    		jmp short gl_fillloop
  3854 00001629 3C0A                    gl_ctrl:	cmp al,10
  3855 0000162B 7411                    		je gl_ret		; CF clear!
  3856 0000162D 3C1A                    		cmp al,26
  3857 0000162F 740C                    		je gl_eof
  3858 00001631 20D2                    		and dl,dl
  3859 00001633 75E2                    		jnz gl_fillloop		; Ignore multiple spaces
  3860 00001635 B020                    		mov al,' '		; Ctrl -> space
  3861 00001637 42                      		inc dx
  3862 00001638 EBEC                    		jmp short gl_store
  3863 0000163A F8                      gl_eoln:        clc                     ; End of line is not end of file
  3864 0000163B EB01                                    jmp short gl_ret
  3865 0000163D F9                      gl_eof:         stc
  3866 0000163E 9C                      gl_ret:		pushf			; We want the last char to be space!
  3867 0000163F 20D2                    		and dl,dl
  3868 00001641 7503                    		jnz gl_xret
  3869 00001643 B020                    		mov al,' '
  3870 00001645 AA                      		stosb
  3871 00001646 9D                      gl_xret:	popf
  3872 00001647 C3                      		ret
  3873                                  
  3874                                  
  3875                                  ;
  3876                                  ; mangle_name: Mangle a DOS filename pointed to by DS:SI into a buffer pointed
  3877                                  ;	       to by ES:DI; ends on encountering any whitespace
  3878                                  ;
  3879                                  
  3880                                  mangle_name:
  3881 00001648 B90B00                  		mov cx,11			; # of bytes to write
  3882                                  mn_loop:
  3883 0000164B AC                      		lodsb
  3884 0000164C 3C20                    		cmp al,' '			; If control or space, end
  3885 0000164E 762B                    		jna mn_end
  3886 00001650 3C2E                    		cmp al,'.'			; Period -> space-fill
  3887 00001652 740C                    		je mn_is_period
  3888 00001654 3C61                    		cmp al,'a'
  3889 00001656 7220                    		jb mn_not_lower
  3890 00001658 3C7A                    		cmp al,'z'
  3891 0000165A 770F                    		ja mn_not_uslower
  3892 0000165C 2C20                    		sub al,020h
  3893 0000165E EB18                    		jmp short mn_not_lower
  3894 00001660 B020                    mn_is_period:	mov al,' '			; We need to space-fill
  3895 00001662 81F90300                mn_period_loop: cmp cx,3			; If <= 3 characters left
  3896 00001666 76E3                    		jbe mn_loop			; Just ignore it
  3897 00001668 AA                      		stosb				; Otherwise, write a period
  3898 00001669 E2F7                    		loop mn_period_loop		; Dec CX and (always) jump
  3899 0000166B 3C81                    mn_not_uslower: cmp al,ucase_low
  3900 0000166D 7209                    		jb mn_not_lower
  3901 0000166F 3CA4                    		cmp al,ucase_high
  3902 00001671 7705                    		ja mn_not_lower
  3903 00001673 BB[FF15]                		mov bx,ucase_tab-ucase_low
  3904 00001676 2ED7                                    cs xlatb
  3905 00001678 AA                      mn_not_lower:	stosb
  3906 00001679 E2D0                    		loop mn_loop			; Don't continue if too long
  3907                                  mn_end:
  3908 0000167B B020                    		mov al,' '			; Space-fill name
  3909 0000167D F3AA                    		rep stosb			; Doesn't do anything if CX=0
  3910 0000167F C3                      		ret				; Done
  3911                                  
  3912                                  ;
  3913                                  ; Upper-case table for extended characters; this is technically code page 865,
  3914                                  ; but code page 437 users will probably not miss not being able to use the
  3915                                  ; cent sign in kernel images too much :-)
  3916                                  ;
  3917                                  ; The table only covers the range 129 to 164; the rest we can deal with.
  3918                                  ;
  3919                                  ucase_low	equ 129
  3920                                  ucase_high	equ 164
  3921 00001680 9A90418E418F804545-     ucase_tab	db 154, 144, 'A', 142, 'A', 143, 128, 'EEEIII'
  3922 00001689 45494949           
  3923 0000168D 8E8F9092924F994F55-     		db 142, 143, 144, 146, 146, 'O', 153, 'OUUY', 153, 154
  3924 00001696 5559999A           
  3925 0000169A 9D9C9D9E9F41494F55-     		db 157, 156, 157, 158, 159, 'AIOU', 165
  3926 000016A3 A5                 
  3927                                  
  3928                                  ;
  3929                                  ; unmangle_name: Does the opposite of mangle_name; converts a DOS-mangled
  3930                                  ;                filename to the conventional representation.  This is needed
  3931                                  ;                for the BOOT_IMAGE= parameter for the kernel.
  3932                                  ;                NOTE: A 13-byte buffer is mandatory, even if the string is
  3933                                  ;                known to be shorter.
  3934                                  ;
  3935                                  ;                DS:SI -> input mangled file name
  3936                                  ;                ES:DI -> output buffer
  3937                                  ;
  3938                                  ;                On return, DI points to the first byte after the output name,
  3939                                  ;                which is set to a null byte.
  3940                                  ;
  3941                                  unmangle_name:
  3942 000016A4 56                                      push si                 ; Save pointer to original name
  3943 000016A5 B90800                                  mov cx,8
  3944 000016A8 89FD                                    mov bp,di
  3945 000016AA AC                      un_copy_body:   lodsb
  3946 000016AB E82600                                  call lower_case
  3947 000016AE AA                                      stosb
  3948 000016AF 3C20                                    cmp al,' '
  3949 000016B1 7602                                    jbe un_cb_space
  3950 000016B3 89FD                                    mov bp,di               ; Position of last nonblank+1
  3951 000016B5 E2F3                    un_cb_space:    loop un_copy_body
  3952 000016B7 89EF                                    mov di,bp
  3953 000016B9 B02E                                    mov al,'.'              ; Don't save
  3954 000016BB AA                                      stosb
  3955 000016BC B90300                                  mov cx,3
  3956 000016BF AC                      un_copy_ext:    lodsb
  3957 000016C0 E81100                                  call lower_case
  3958 000016C3 AA                                      stosb
  3959 000016C4 3C20                                    cmp al,' '
  3960 000016C6 7602                                    jbe un_ce_space
  3961 000016C8 89FD                                    mov bp,di
  3962 000016CA E2F3                    un_ce_space:    loop un_copy_ext
  3963 000016CC 89EF                                    mov di,bp
  3964 000016CE 26C60500                                mov byte [es:di], 0
  3965 000016D2 5E                                      pop si
  3966 000016D3 C3                                      ret
  3967                                  
  3968                                  ;
  3969                                  ; lower_case: Lower case a character in AL
  3970                                  ;
  3971                                  lower_case:
  3972 000016D4 3C41                                    cmp al,'A'
  3973 000016D6 7216                                    jb lc_ret
  3974 000016D8 3C5A                                    cmp al,'Z'
  3975 000016DA 7703                                    ja lc_1
  3976 000016DC 0C20                                    or al,20h
  3977 000016DE C3                                      ret
  3978 000016DF 3C80                    lc_1:           cmp al,lcase_low
  3979 000016E1 720B                                    jb lc_ret
  3980 000016E3 3CA5                                    cmp al,lcase_high
  3981 000016E5 7707                                    ja lc_ret
  3982 000016E7 53                                      push bx
  3983 000016E8 BB[4D18]                                mov bx,lcase_tab-lcase_low
  3984 000016EB 2ED7                                   	cs xlatb
  3985 000016ED 5B                                      pop bx
  3986 000016EE C3                      lc_ret:         ret
  3987                                  
  3988                                  ; ----------------------------------------------------------------------------------
  3989                                  ;  VGA splash screen code
  3990                                  ; ----------------------------------------------------------------------------------
  3991                                  
  3992                                  ;
  3993                                  ; vgadisplayfile:
  3994                                  ;	Display a graphical splash screen.
  3995                                  ;
  3996                                  ; Input:
  3997                                  ;
  3998                                  ; SI	= cluster/socket pointer
  3999                                  ;
  4000                                  vgadisplayfile:
  4001 000016EF 89363855                		mov [VGACluster],si
  4002 000016F3 06                      		push es
  4003                                  
  4004                                  		; This is a cheap and easy way to make sure the screen is
  4005                                  		; cleared in case we were in graphics mode already
  4006 000016F4 E87E01                  		call vgaclearmode
  4007 000016F7 E85001                  		call vgasetmode
  4008 000016FA 7514                    		jnz .error_nz
  4009                                  
  4010                                  .graphalready:
  4011 000016FC B80030                  		mov ax,xfer_buf_seg		; Use as temporary storage
  4012 000016FF 8EC0                    		mov es,ax
  4013 00001701 8EE0                    		mov fs,ax
  4014                                  
  4015 00001703 E8F600                  		call vgagetchunk		; Get the first chunk
  4016                                  
  4017                                  		; The header WILL be in the first chunk.
  4018 00001706 2666813E00403DF313-     		cmp dword [es:xbs_vgabuf],0x1413f33d	; Magic number
  4019 0000170F 14                 
  4020 00001710 0F857D00                .error_nz:	jne near .error
  4021 00001714 26A10440                		mov ax,[es:xbs_vgabuf+4]
  4022 00001718 A33455                  		mov [GraphXSize],ax
  4023                                  
  4024 0000171B BA0840                  		mov dx,xbs_vgabuf+8		; Color map offset
  4025 0000171E B81210                  		mov ax,1012h			; Set RGB registers
  4026 00001721 31DB                    		xor bx,bx			; First register number
  4027 00001723 B91000                  		mov cx,16			; 16 registers
  4028 00001726 CD10                    		int 10h
  4029                                  	
  4030                                  .movecursor:
  4031 00001728 26A10640                		mov ax,[es:xbs_vgabuf+6]	; Number of pixel rows
  4032 0000172C 8B16[781D]              		mov dx,[VGAFontSize]
  4033 00001730 01D0                    		add ax,dx
  4034 00001732 48                      		dec ax
  4035 00001733 F6F2                    		div dl
  4036 00001735 31D2                    		xor dx,dx			; Set column to 0
  4037 00001737 3A064155                		cmp al,[VidRows]
  4038 0000173B 7205                    		jb .rowsok
  4039 0000173D A04155                  		mov al,[VidRows]
  4040 00001740 FEC8                    		dec al
  4041                                  .rowsok:
  4042 00001742 88C6                    		mov dh,al
  4043 00001744 B402                    		mov ah,2
  4044 00001746 31DB                    		xor bx,bx
  4045 00001748 CD10                    		int 10h				; Set cursor below image
  4046                                  
  4047 0000174A 268B0E0640              		mov cx,[es:xbs_vgabuf+6]	; Number of graphics rows
  4048                                  
  4049 0000174F BE3840                  		mov si,xbs_vgabuf+8+3*16	; Beginning of pixel data
  4050 00001752 C70636550000            		mov word [VGAPos],0
  4051                                  
  4052                                  .drawpixelrow:
  4053 00001758 51                      		push cx
  4054 00001759 8B0E3455                		mov cx,[GraphXSize]
  4055 0000175D BF0080                  		mov di,xbs_vgatmpbuf		; Row buffer
  4056 00001760 E83000                  		call rledecode			; Decode one row
  4057 00001763 56                      		push si
  4058 00001764 BE0080                  		mov si,xbs_vgatmpbuf
  4059 00001767 89F7                    		mov di,si
  4060 00001769 033E3455                		add di,[GraphXSize]
  4061 0000176D B9A000                  		mov cx,640/4
  4062 00001770 6631C0                  		xor eax,eax
  4063 00001773 F366AB                  		rep stosd			; Clear rest of row
  4064 00001776 BF00A0                  		mov di,0A000h			; VGA segment
  4065 00001779 8EC7                    		mov es,di
  4066 0000177B 8B3E3655                		mov di,[VGAPos]
  4067 0000177F BD8002                  		mov bp,640
  4068 00001782 E89600                  		call packedpixel2vga
  4069 00001785 8306365550              		add word [VGAPos],byte 80	; Advance to next pixel row
  4070 0000178A 0FA0                    		push fs
  4071 0000178C 07                      		pop es
  4072 0000178D 5E                      		pop si
  4073 0000178E 59                      		pop cx
  4074 0000178F E2C7                    		loop .drawpixelrow
  4075                                  
  4076                                  .error:
  4077 00001791 07                      		pop es
  4078 00001792 C3                      		ret
  4079                                  
  4080                                  ;
  4081                                  ; rledecode:
  4082                                  ;	Decode a pixel row in RLE16 format.
  4083                                  ;
  4084                                  ; FS:SI	-> input
  4085                                  ; CX -> pixel count
  4086                                  ; ES:DI -> output (packed pixel)
  4087                                  ;
  4088                                  rledecode:
  4089 00001793 66D1E6                  		shl esi,1		; Nybble pointer
  4090 00001796 30D2                    		xor dl,dl		; Last pixel
  4091                                  .loop:
  4092 00001798 E83F00                  		call .getnybble
  4093 0000179B 38D0                    		cmp al,dl
  4094 0000179D 740D                    		je .run			; Start of run sequence
  4095 0000179F AA                      		stosb
  4096 000017A0 88C2                    		mov dl,al
  4097 000017A2 49                      		dec cx
  4098 000017A3 75F3                    		jnz .loop
  4099                                  .done:
  4100 000017A5 66D1EE                  		shr esi,1
  4101 000017A8 83D600                  		adc si,byte 0
  4102 000017AB C3                      		ret
  4103                                  .run:
  4104 000017AC 31DB                    		xor bx,bx
  4105 000017AE E82900                  		call .getnybble
  4106 000017B1 20C0                    		and al,al
  4107 000017B3 7410                    		jz .longrun
  4108 000017B5 88C3                    		mov bl,al
  4109                                  .dorun:
  4110 000017B7 51                      		push cx
  4111 000017B8 89D9                    		mov cx,bx
  4112 000017BA 88D0                    		mov al,dl
  4113 000017BC F3AA                    		rep stosb
  4114 000017BE 59                      		pop cx
  4115 000017BF 29D9                    		sub cx,bx
  4116 000017C1 77D5                    		ja .loop
  4117 000017C3 EBE0                    		jmp short .done
  4118                                  .longrun:
  4119 000017C5 E81200                  		call .getnybble
  4120 000017C8 88C4                    		mov ah,al
  4121 000017CA E80D00                  		call .getnybble
  4122 000017CD C0E004                  		shl al,4
  4123 000017D0 08E0                    		or al,ah
  4124 000017D2 88C3                    		mov bl,al
  4125 000017D4 81C31000                		add bx,16
  4126 000017D8 EBDD                    		jmp short .dorun
  4127                                  .getnybble:
  4128 000017DA 66D1EE                  		shr esi,1
  4129 000017DD 64AC                    		fs lodsb
  4130 000017DF 7208                    		jc .high
  4131 000017E1 4E                      		dec si
  4132 000017E2 240F                    		and al,0Fh
  4133 000017E4 F9                      		stc
  4134 000017E5 66D1D6                  		rcl esi,1
  4135 000017E8 C3                      		ret
  4136                                  .high:
  4137 000017E9 C0E804                  		shr al,4
  4138 000017EC 81FE0080                		cmp si,xbs_vgabuf+trackbufsize	; Chunk overrun
  4139 000017F0 7206                    		jb .nonewchunk
  4140 000017F2 E80700                  		call vgagetchunk
  4141 000017F5 BE0040                  		mov si,xbs_vgabuf		; Start at beginning of buffer
  4142                                  .nonewchunk:
  4143 000017F8 66D1E6                  		shl esi,1
  4144 000017FB C3                      		ret
  4145                                  
  4146                                  ;
  4147                                  ; vgagetchunk:
  4148                                  ;	Get a new trackbufsize chunk of VGA image data
  4149                                  ;
  4150                                  ; On input, ES is assumed to point to the buffer segment.
  4151                                  ;
  4152                                  vgagetchunk:
  4153 000017FC 6660                    		pushad
  4154 000017FE 8B363855                		mov si,[VGACluster]
  4155 00001802 21F6                    		and si,si
  4156 00001804 7412                    		jz .eof				; EOF overrun, not much to do...
  4157                                  
  4158 00001806 8B0E1055                		mov cx,[BufSafe]		; One trackbuf worth of data
  4159 0000180A BB0040                  		mov bx,xbs_vgabuf
  4160 0000180D E816EB                  		call getfssec
  4161                                  
  4162 00001810 7302                    		jnc .noteof
  4163 00001812 31F6                    		xor si,si
  4164 00001814 89363855                .noteof:	mov [VGACluster],si
  4165                                  
  4166 00001818 6661                    .eof:		popad
  4167 0000181A C3                      		ret
  4168                                  
  4169                                  ;
  4170                                  ; packedpixel2vga:
  4171                                  ;	Convert packed-pixel to VGA bitplanes
  4172                                  ;
  4173                                  ; FS:SI -> packed pixel string
  4174                                  ; BP    -> pixel count (multiple of 8)
  4175                                  ; ES:DI -> output
  4176                                  ;
  4177                                  packedpixel2vga:
  4178 0000181B BAC403                  		mov dx,3C4h	; VGA Sequencer Register select port
  4179 0000181E B002                    		mov al,2	; Sequencer mask
  4180 00001820 EE                      		out dx,al	; Select the sequencer mask
  4181 00001821 42                      		inc dx		; VGA Sequencer Register data port
  4182 00001822 B001                    		mov al,1
  4183 00001824 88C3                    		mov bl,al
  4184                                  .planeloop:
  4185 00001826 60                      		pusha
  4186 00001827 EE                      		out dx,al
  4187                                  .loop1:
  4188 00001828 B90800                  		mov cx,8
  4189                                  .loop2:
  4190 0000182B 87CB                    		xchg cx,bx
  4191 0000182D 64AC                    		fs lodsb
  4192 0000182F D2E8                    		shr al,cl
  4193 00001831 D0D5                    		rcl ch,1	; VGA is bigendian.  Sigh.
  4194 00001833 87CB                    		xchg cx,bx
  4195 00001835 E2F4                    		loop .loop2
  4196 00001837 88F8                    		mov al,bh
  4197 00001839 AA                      		stosb
  4198 0000183A 83ED08                  		sub bp,byte 8
  4199 0000183D 77E9                    		ja .loop1
  4200 0000183F 61                      		popa
  4201 00001840 FEC3                    		inc bl
  4202 00001842 D0E0                    		shl al,1
  4203 00001844 80FB04                  		cmp bl,4
  4204 00001847 76DD                    		jbe .planeloop
  4205 00001849 C3                      		ret
  4206                                  
  4207                                  ;
  4208                                  ; vgasetmode:
  4209                                  ;	Enable VGA graphics, if possible; return ZF=1 on success
  4210                                  ;	DS must be set to the base segment; ES is set to DS.
  4211                                  ;
  4212                                  vgasetmode:
  4213 0000184A 1E                      		push ds
  4214 0000184B 07                      		pop es
  4215 0000184C B8001A                  		mov ax,1A00h		; Get video card and monitor
  4216 0000184F 31DB                    		xor bx,bx
  4217 00001851 CD10                    		int 10h
  4218 00001853 80FB08                  		cmp bl, 8		; If not VGA card/VGA monitor, give up
  4219 00001856 751C                    		jne .error		; ZF=0
  4220                                  ;		mov bx,TextColorReg
  4221                                  ;		mov dx,1009h		; Read color registers
  4222                                  ;		int 10h
  4223 00001858 B81200                  		mov ax,0012h		; Set mode = 640x480 VGA 16 colors
  4224 0000185B CD10                    		int 10h
  4225 0000185D BA[BB18]                		mov dx,linear_color
  4226 00001860 B80210                  		mov ax,1002h		; Write color registers
  4227 00001863 CD10                    		int 10h
  4228 00001865 C606[CC18]01            		mov [UsingVGA], byte 1
  4229                                  
  4230 0000186A E802F9                  		call use_font		; Set graphics font/data
  4231 0000186D C606[7B1D]00            		mov byte [ScrollAttribute], 00h
  4232                                  
  4233 00001872 31C0                    		xor ax,ax		; Set ZF
  4234                                  .error:
  4235 00001874 C3                      		ret
  4236                                  
  4237                                  ;
  4238                                  ; vgaclearmode:
  4239                                  ;	Disable VGA graphics.  It is not safe to assume any value
  4240                                  ;	for DS or ES.
  4241                                  ;
  4242                                  vgaclearmode:
  4243 00001875 1E                      		push ds
  4244 00001876 06                      		push es
  4245 00001877 6660                    		pushad
  4246 00001879 8CC8                    		mov ax,cs
  4247 0000187B 8ED8                    		mov ds,ax
  4248 0000187D 8EC0                    		mov es,ax
  4249 0000187F 803E[CC18]01            		cmp [UsingVGA], byte 1
  4250 00001884 7512                    		jne .done
  4251 00001886 B80300                  		mov ax,0003h		; Return to normal video mode
  4252 00001889 CD10                    		int 10h
  4253                                  ;		mov dx,TextColorReg	; Restore color registers
  4254                                  ;		mov ax,1002h
  4255                                  ;		int 10h
  4256 0000188B C606[CC18]00            		mov [UsingVGA], byte 0
  4257                                  
  4258 00001890 E8DCF8                  		call use_font		; Restore text font/data
  4259 00001893 C606[7B1D]07            		mov byte [ScrollAttribute], 07h
  4260                                  .done:
  4261 00001898 6661                    		popad
  4262 0000189A 07                      		pop es
  4263 0000189B 1F                      		pop ds
  4264 0000189C C3                      		ret
  4265                                  
  4266                                  ;
  4267                                  ; vgashowcursor/vgahidecursor:
  4268                                  ;	If VGA graphics is enabled, draw a cursor/clear a cursor
  4269                                  ;
  4270                                  vgashowcursor:
  4271 0000189D 6660                    		pushad
  4272 0000189F B05F                    		mov al,'_'
  4273 000018A1 EB04                    		jmp short vgacursorcommon
  4274                                  vgahidecursor:
  4275 000018A3 6660                    		pushad
  4276 000018A5 B020                    		mov al,' '
  4277                                  vgacursorcommon:
  4278 000018A7 803E[CC18]01            		cmp [UsingVGA], byte 1
  4279 000018AC 750A                    		jne .done
  4280 000018AE B409                    		mov ah,09h
  4281 000018B0 BB0700                  		mov bx,0007h
  4282 000018B3 B90100                  		mov cx,1
  4283 000018B6 CD10                    		int 10h
  4284                                  .done:
  4285 000018B8 6661                    		popad
  4286 000018BA C3                      		ret
  4287                                  
  4288                                  
  4289                                  		; Map colors to consecutive DAC registers
  4290 000018BB 000102030405060708-     linear_color	db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0
  4291 000018C4 090A0B0C0D0E0F00   
  4292 000018CC 00                      UsingVGA	db 0
  4293                                  
  4294                                  ; ----------------------------------------------------------------------------------
  4295                                  ;  Begin data section
  4296                                  ; ----------------------------------------------------------------------------------
  4297                                  
  4298                                  CR		equ 13		; Carriage Return
  4299                                  LF		equ 10		; Line Feed
  4300                                  FF		equ 12		; Form Feed
  4301                                  BS		equ  8		; Backspace
  4302                                  
  4303                                  ;
  4304                                  ; Lower-case table for codepage 865
  4305                                  ;
  4306                                  lcase_low       equ 128
  4307                                  lcase_high      equ 165
  4308 000018CD 878182838485868788-     lcase_tab       db 135, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138
  4309 000018D6 898A               
  4310 000018D8 8B8C8D848682919193-                     db 139, 140, 141, 132, 134, 130, 145, 145, 147, 148, 149
  4311 000018E1 9495               
  4312 000018E3 96979894819B9C9B9E-                     db 150, 151, 152, 148, 129, 155, 156, 155, 158, 159, 160
  4313 000018EC 9FA0               
  4314 000018EE A1A2A3A4A4                              db 161, 162, 163, 164, 164
  4315                                  
  4316 000018F3 20436F707972696768-     copyright_str   db ' Copyright (C) 1994-', year, ' H. Peter Anvin'
  4317 000018FC 742028432920313939-
  4318 00001905 342D3230303220482E-
  4319 0000190E 20506574657220416E-
  4320 00001917 76696E             
  4321 0000191A 0D0A00                  		db CR, LF, 0
  4322 0000191D 626F6F743A2000          boot_prompt	db 'boot: ', 0
  4323 00001924 08200800                wipe_char	db BS, ' ', BS, 0
  4324 00001928 436F756C64206E6F74-     err_notfound	db 'Could not find kernel image: ',0
  4325 00001931 2066696E64206B6572-
  4326 0000193A 6E656C20696D616765-
  4327 00001943 3A2000             
  4328 00001946 0D0A496E76616C6964-     err_notkernel	db CR, LF, 'Invalid or corrupt kernel image.', CR, LF, 0
  4329 0000194F 206F7220636F727275-
  4330 00001958 7074206B65726E656C-
  4331 00001961 20696D6167652E0D0A-
  4332 0000196A 00                 
  4333 0000196B 497420617070656172-     err_not386	db 'It appears your computer uses a 286 or lower CPU.'
  4334 00001974 7320796F757220636F-
  4335 0000197D 6D7075746572207573-
  4336 00001986 657320612032383620-
  4337 0000198F 6F72206C6F77657220-
  4338 00001998 4350552E           
  4339 0000199C 0D0A                    		db CR, LF
  4340 0000199E 596F752063616E6E6F-     		db 'You cannot run Linux unless you have a 386 or higher CPU'
  4341 000019A7 742072756E204C696E-
  4342 000019B0 757820756E6C657373-
  4343 000019B9 20796F752068617665-
  4344 000019C2 206120333836206F72-
  4345 000019CB 206869676865722043-
  4346 000019D4 5055               
  4347 000019D6 0D0A                    		db CR, LF
  4348 000019D8 696E20796F7572206D-     		db 'in your machine.  If you get this message in error, hold'
  4349 000019E1 616368696E652E2020-
  4350 000019EA 496620796F75206765-
  4351 000019F3 742074686973206D65-
  4352 000019FC 737361676520696E20-
  4353 00001A05 6572726F722C20686F-
  4354 00001A0E 6C64               
  4355 00001A10 0D0A                    		db CR, LF
  4356 00001A12 646F776E2074686520-     		db 'down the Ctrl key while booting, and I will take your'
  4357 00001A1B 4374726C206B657920-
  4358 00001A24 7768696C6520626F6F-
  4359 00001A2D 74696E672C20616E64-
  4360 00001A36 20492077696C6C2074-
  4361 00001A3F 616B6520796F7572   
  4362 00001A47 0D0A                    		db CR, LF
  4363 00001A49 776F726420666F7220-     		db 'word for it.', CR, LF, 0
  4364 00001A52 69742E0D0A00       
  4365 00001A58 497420617070656172-     err_noram	db 'It appears your computer has less than 512K of low ("DOS")'
  4366 00001A61 7320796F757220636F-
  4367 00001A6A 6D7075746572206861-
  4368 00001A73 73206C657373207468-
  4369 00001A7C 616E203531324B206F-
  4370 00001A85 66206C6F7720282244-
  4371 00001A8E 4F532229           
  4372 00001A92 0D0A                    		db CR, LF
  4373 00001A94 52414D2E20204C696E-     		db 'RAM.  Linux needs at least this amount to boot.  If you get'
  4374 00001A9D 7578206E6565647320-
  4375 00001AA6 6174206C6561737420-
  4376 00001AAF 7468697320616D6F75-
  4377 00001AB8 6E7420746F20626F6F-
  4378 00001AC1 742E2020496620796F-
  4379 00001ACA 7520676574         
  4380 00001ACF 0D0A                    		db CR, LF
  4381 00001AD1 74686973206D657373-     		db 'this message in error, hold down the Ctrl key while'
  4382 00001ADA 61676520696E206572-
  4383 00001AE3 726F722C20686F6C64-
  4384 00001AEC 20646F776E20746865-
  4385 00001AF5 204374726C206B6579-
  4386 00001AFE 207768696C65       
  4387 00001B04 0D0A                    		db CR, LF
  4388 00001B06 626F6F74696E672C20-     		db 'booting, and I will take your word for it.', CR, LF, 0
  4389 00001B0F 616E6420492077696C-
  4390 00001B18 6C2074616B6520796F-
  4391 00001B21 757220776F72642066-
  4392 00001B2A 6F722069742E0D0A00 
  4393 00001B33 556E6B6E6F776E206B-     err_badcfg      db 'Unknown keyword in syslinux.cfg.', CR, LF, 0
  4394 00001B3C 6579776F726420696E-
  4395 00001B45 207379736C696E7578-
  4396 00001B4E 2E6366672E0D0A00   
  4397 00001B56 4D697373696E672070-     err_noparm      db 'Missing parameter in syslinux.cfg.', CR, LF, 0
  4398 00001B5F 6172616D6574657220-
  4399 00001B68 696E207379736C696E-
  4400 00001B71 75782E6366672E0D0A-
  4401 00001B7A 00                 
  4402 00001B7B 0D0A436F756C64206E-     err_noinitrd    db CR, LF, 'Could not find ramdisk image: ', 0
  4403 00001B84 6F742066696E642072-
  4404 00001B8D 616D6469736B20696D-
  4405 00001B96 6167653A2000       
  4406 00001B9C 4E6F7420656E6F7567-     err_nohighmem   db 'Not enough memory to load specified kernel.', CR, LF, 0
  4407 00001BA5 68206D656D6F727920-
  4408 00001BAE 746F206C6F61642073-
  4409 00001BB7 706563696669656420-
  4410 00001BC0 6B65726E656C2E0D0A-
  4411 00001BC9 00                 
  4412 00001BCA 0D0A4B65726E656C20-     err_highload    db CR, LF, 'Kernel transfer failure.', CR, LF, 0
  4413 00001BD3 7472616E7366657220-
  4414 00001BDC 6661696C7572652E0D-
  4415 00001BE5 0A00               
  4416 00001BE7 43616E6E6F74206C6F-     err_oldkernel   db 'Cannot load a ramdisk with an old kernel image.'
  4417 00001BF0 616420612072616D64-
  4418 00001BF9 69736B207769746820-
  4419 00001C02 616E206F6C64206B65-
  4420 00001C0B 726E656C20696D6167-
  4421 00001C14 652E               
  4422 00001C16 0D0A00                                  db CR, LF, 0
  4423 00001C19 3A20617474656D7074-     err_notdos	db ': attempted DOS system call', CR, LF, 0
  4424 00001C22 656420444F53207379-
  4425 00001C2B 7374656D2063616C6C-
  4426 00001C34 0D0A00             
  4427 00001C37 434F4D424F4F542069-     err_comlarge	db 'COMBOOT image too large.', CR, LF, 0
  4428 00001C40 6D61676520746F6F20-
  4429 00001C49 6C617267652E0D0A00 
  4430 00001C52 496E76616C6964206F-     err_bootsec	db 'Invalid or corrupt boot sector image.', CR, LF, 0
  4431 00001C5B 7220636F7272757074-
  4432 00001C64 20626F6F7420736563-
  4433 00001C6D 746F7220696D616765-
  4434 00001C76 2E0D0A00           
  4435 00001C7A 0D0A41323020676174-     err_a20		db CR, LF, 'A20 gate not responding!', CR, LF, 0
  4436 00001C83 65206E6F7420726573-
  4437 00001C8C 706F6E64696E67210D-
  4438 00001C95 0A00               
  4439 00001C97 0D0A426F6F74206661-     err_bootfailed	db CR, LF, 'Boot failed: please change disks and press '
  4440 00001CA0 696C65643A20706C65-
  4441 00001CA9 617365206368616E67-
  4442 00001CB2 65206469736B732061-
  4443 00001CBB 6E6420707265737320 
  4444 00001CC4 61206B657920746F20-     		db 'a key to continue.', CR, LF, 0
  4445 00001CCD 636F6E74696E75652E-
  4446 00001CD6 0D0A00             
  4447 00001CD9 2072656164792E0D0A-     ready_msg	db ' ready.', CR, LF, 0
  4448 00001CE2 00                 
  4449 00001CE3 4C6F6164696E672000      loading_msg     db 'Loading ', 0
  4450 00001CEC 2E                      dotdot_msg      db '.'
  4451 00001CED 2E00                    dot_msg         db '.', 0
  4452 00001CEF 2061626F727465642E      aborted_msg	db ' aborted.'			; Fall through to crlf_msg!
  4453 00001CF8 0D0A00                  crlf_msg	db CR, LF, 0
  4454 00001CFB 0D0C00                  crff_msg	db CR, FF, 0
  4455 00001CFE 5359534C494E555843-     syslinux_cfg	db 'SYSLINUXCFG'
  4456 00001D07 4647               
  4457                                  ;
  4458                                  ; Command line options we'd like to take a look at
  4459                                  ;
  4460                                  ; mem= and vga= are handled as normal 32-bit integer values
  4461 00001D09 696E697472643D          initrd_cmd	db 'initrd='
  4462                                  initrd_cmd_len	equ 7
  4463                                  ;
  4464                                  ; Config file keyword table
  4465                                  ;
  4466                                  		align 2
  4467 00001D10 6170                    keywd_table	db 'ap' ; append
  4468 00001D12 6465                    		db 'de' ; default
  4469 00001D14 7469                    		db 'ti' ; timeout
  4470 00001D16 666F                    		db 'fo'	; font
  4471 00001D18 6B62                    		db 'kb' ; kbd
  4472 00001D1A 6469                    		db 'di' ; display
  4473 00001D1C 7072                    		db 'pr' ; prompt
  4474 00001D1E 6C61                    		db 'la' ; label
  4475 00001D20 696D                                    db 'im' ; implicit
  4476 00001D22 6B65                    		db 'ke' ; kernel
  4477 00001D24 7365                    		db 'se' ; serial
  4478 00001D26 6631                    		db 'f1' ; F1
  4479 00001D28 6632                    		db 'f2' ; F2
  4480 00001D2A 6633                    		db 'f3' ; F3
  4481 00001D2C 6634                    		db 'f4' ; F4
  4482 00001D2E 6635                    		db 'f5' ; F5
  4483 00001D30 6636                    		db 'f6' ; F6
  4484 00001D32 6637                    		db 'f7' ; F7
  4485 00001D34 6638                    		db 'f8' ; F8
  4486 00001D36 6639                    		db 'f9' ; F9
  4487 00001D38 6630                    		db 'f0' ; F10
  4488 00001D3A 0000                    		dw 0
  4489                                  ;
  4490                                  ; Extensions to search for (in *reverse* order).  Note that the last
  4491                                  ; (lexically first) entry in the table is a placeholder for the original
  4492                                  ; extension, needed for error messages.  The exten_table is shifted so
  4493                                  ; the table is 1-based; this is because a "loop" cx is used as index.
  4494                                  ;
  4495                                  exten_table:
  4496 00001D3C 00000000                OrigKernelExt:	dd 0			; Original extension
  4497 00001D40 434F4D00                		db 'COM',0		; COMBOOT (same as DOS)
  4498 00001D44 42532000                		db 'BS ',0		; Boot Sector 
  4499 00001D48 42535300                		db 'BSS',0		; Boot Sector (add superblock)
  4500 00001D4C 43425400                		db 'CBT',0		; COMBOOT (specific)
  4501                                  
  4502                                  exten_count	equ (($-exten_table) >> 2) - 1	; Number of alternates
  4503                                  ;
  4504                                  ; Misc initialized (data) variables
  4505                                  ;
  4506                                  %ifdef debug				; This code for debugging only
  4507                                  debug_magic	dw 0D00Dh		; Debug code sentinel
  4508                                  %endif
  4509 00001D50 0000                    AppendLen       dw 0                    ; Bytes in append= command
  4510 00001D52 0000                    KbdTimeOut      dw 0                    ; Keyboard timeout (if any)
  4511 00001D54 0000                    FKeyMap		dw 0			; Bitmap for F-keys loaded
  4512 00001D56 0090                    CmdLinePtr	dw cmd_line_here	; Command line advancing pointer
  4513                                  initrd_flag	equ $
  4514 00001D58 0000                    initrd_ptr	dw 0			; Initial ramdisk pointer/flag
  4515 00001D5A 0000                    VKernelCtr	dw 0			; Number of registered vkernels
  4516 00001D5C 0000                    ForcePrompt	dw 0			; Force prompt
  4517 00001D5E 0100                    AllowImplicit   dw 1                    ; Allow implicit kernels
  4518 00001D60 0000                    SerialPort	dw 0			; Serial port base (or 0 for no serial port)
  4519 00001D62 [170F][170F][220F]-     A20List		dw a20_dunno, a20_none, a20_bios, a20_kbc, a20_fast
  4520 00001D68 [340F][5A0F]       
  4521 00001D6C [E20F][E20F][B40F]-     A20DList	dw a20d_dunno, a20d_none, a20d_bios, a20d_kbc, a20d_fast
  4522 00001D72 [C50F][BD0F]       
  4523 00001D76 0000                    A20Type		dw A20_DUNNO		; A20 type unknown
  4524 00001D78 1000                    VGAFontSize	dw 16			; Defaults to 16 byte font
  4525 00001D7A 00                      UserFont	db 0			; Using a user-specified font
  4526 00001D7B 07                      ScrollAttribute	db 07h			; White on black (for text mode)
  4527                                  ;
  4528                                  ; Stuff for the command line; we do some trickery here with equ to avoid
  4529                                  ; tons of zeros appended to our file and wasting space
  4530                                  ;
  4531 00001D7C 6C696E757820617574-     linuxauto_cmd	db 'linux auto',0
  4532 00001D85 6F00               
  4533                                  linuxauto_len   equ $-linuxauto_cmd
  4534 00001D87 424F4F545F494D4147-     boot_image      db 'BOOT_IMAGE='
  4535 00001D90 453D               
  4536                                  boot_image_len  equ $-boot_image
  4537 00001D92 00<rept>                                align 4, db 0		; For the good of REP MOVSD
  4538                                  command_line	equ $
  4539                                  default_cmd	equ $+(max_cmd_len+2)
  4540                                  ldlinux_end	equ default_cmd+(max_cmd_len+1)
  4541                                  kern_cmd_len    equ ldlinux_end-command_line
  4542                                  ldlinux_len	equ ldlinux_end-ldlinux_magic
  4543                                  ;
  4544                                  ; Put the getcbuf right after the code, aligned on a sector boundary
  4545                                  ;
  4546                                  end_of_code	equ (ldlinux_end-bootsec)+7C00h
  4547                                  getcbuf		equ (end_of_code + 511) & 0FE00h
  4548                                  
  4549                                  ; VGA font buffer at the end of memory (so loading a font works even
  4550                                  ; in graphics mode.)
  4551                                  vgafontbuf	equ 0E000h
  4552                                  
  4553                                  ; This is a compile-time assert that we didn't run out of space
  4554                                  %if (getcbuf+trackbufsize) > vgafontbuf
  4555                                  %error "Out of memory, better reorganize something..."
  4556                                  %endif