]> pd.if.org Git - mmurtl/commitdiff
autocommit for file dated 1994-12-31 09:56:04
authorRichard Burgess <>
Sat, 31 Dec 1994 09:56:04 +0000 (09:56 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Mon, 17 Oct 2016 14:03:47 +0000 (14:03 +0000)
mscode16/bootcode/bootblok.asm [new file with mode: 0644]

diff --git a/mscode16/bootcode/bootblok.asm b/mscode16/bootcode/bootblok.asm
new file mode 100644 (file)
index 0000000..1334aeb
--- /dev/null
@@ -0,0 +1,336 @@
+.386P\r
+;This boot sector is STUFFed to the gills to do a single\r
+;stage boot of the MMURTL OS which is about 160K stored as\r
+;a loadable image beginning at cluster 2 on the disk. The OS must\r
+;be stored contiguously in each of the following logical sectors.\r
+;The actual number of sectors is stored in the data param nOSSectors.\r
+\r
+CSEG    SEGMENT WORD 'Code' USE16\r
+        ASSUME CS:CSEG, DS:CSEG, ES:Nothing\r
+\r
+ORG     0h\r
+\r
+       JMP SHORT Bootup\r
+       NOP\r
+\r
+;This 59 byte structure follows the 3 jump bytes above\r
+;and is found on all MS-DOS FAT compatible\r
+;disks. This contains additional information about the file system\r
+;on this disk that the operating needs to know. The boot sector code also\r
+;needs some of this information if this is a bootable disk.\r
+\r
+Herald          DB   'MURTL1.0'\r
+nBytesPerSect   DW   0200h             ;nBytes/Sector\r
+nSectPerClstr   DB   01h               ;Sect/Cluster\r
+nRsvdSect       DW   0001h             ;Resvd sectors\r
+nFATS           DB   02                        ;nFATs\r
+nRootDirEnts    DW   00E0h             ;Root Dir entries max\r
+nTotalSectors   DW   0B40h             ;nTotal Sectors (0 = <32Mb)\r
+bMedia          DB   0F0h              ;media desc. (worthless)\r
+nSectPerFAT     DW   0009h             ;nSect in FAT\r
+nSectPerTrack   DW   0012h             ;nSectors/track\r
+nHeads          DW   0002h             ;nHeads\r
+nHidden         DD   00000000h ;nHidden Sectors (first whole track on HD)\r
+nTotalSect32    DD   00000000h ;nTotalSectors if > 32Mb\r
+bBootDrive             DB   00h                ;Drive boot sector came from\r
+ResvdByte      DB   00h                ;Used for temp storage of Sector to Read\r
+ExtBootSig     DB   29h                ; Ext Boot Signature (always 29h)\r
+nOSSectors             DW   0140h      ; (140 sectors max) Was Volume ID number\r
+ResvdWord              DW   0000h\r
+Volname                DB   'RICH       '      ;11 bytes for volume name\r
+FatType                DB   'FAT12   '         ;8 bytes for FAT name (Type)\r
+\r
+\r
+;The following are pointers to my IDT and GDT after my OS loads\r
+; and are not part of the above boot sector structure.\r
+\r
+IDTptr          DW 7FFh                 ;LIMIT 256 IDT Slots\r
+                   DD 0000h                ;BASE (Linear)\r
+\r
+GDTptr          DW 17FFh                ;LIMIT 768 slots\r
+                DD 0800h                ;BASE (Linear)\r
+\r
+;This is where we jump from those first 3 bytes\r
+\r
+BootUp:\r
+\r
+;Boot blocks first instruction starts here after initial jump from beginning\r
+    CLI                                        ;Clear interrupts\r
+\r
+       ;Stick the stack at 98000h (an arbitrary location)\r
+\r
+    MOV  AX,9000h\r
+    MOV  SS, AX\r
+       MOV  SP, 8000h\r
+\r
+;Move this boot sector UP to 90000h Linear.\r
+\r
+       MOV  AX, 09000h\r
+       MOV  ES, AX\r
+       XOR  DI, DI\r
+       MOV      AX, 7C0h\r
+       MOV  DS, AX\r
+       XOR  SI, SI\r
+       MOV  CX, 512\r
+    REP  MOVSB\r
+\r
+       ; Now we jump UP to where we moved it.\r
+\r
+       MOV AX, 09000h          ;Segment\r
+       PUSH AX\r
+       MOV AX, 6Fh                     ;Offset to new location\r
+       PUSH AX\r
+       RETF\r
+\r
+; Now set DS equal to ES which is 9000h\r
+       PUSH ES\r
+       POP  DS\r
+       MOV CX, nSectPerTrack\r
+\r
+       XOR AX, AX\r
+       MOV DS, AX\r
+    MOV  BX, 0078h        ;Int 1E FDC Params!\r
+    LDS  SI, DS:[BX]\r
+\r
+    MOV  BYTE PTR [SI+4], CL\r
+       MOV  BYTE PTR [SI+9], 0Fh\r
+\r
+       PUSH ES\r
+       POP DS\r
+       PUSH DS\r
+\r
+    STI\r
+\r
+       MOV DL, bBootDrive              ;Required for Disk System Reset\r
+       XOR AX, AX\r
+\r
+    INT  13h                           ;Reset Disk Controller (DL has drive num)\r
+    JC   SHORT BadBoot         ;Reset failed...\r
+\r
+       POP DS\r
+\r
+    ;The controller is reset, now let's read some stuff!!\r
+       ;We are gonna skip checking to see if the first file\r
+       ;really IS the OS. We need the space for other code.\r
+\r
+    MOV  SI, OFFSET MsgLoad\r
+    CALL PutChars\r
+\r
+       ;What we do now is calcualte our way to the third cluster\r
+       ;on the disk and read in the total number of OS sectors in\r
+       ;logical sector order. (3rd cluster is really the first allocated\r
+       ; cluster because first 2 are unused).\r
+       ;The layout of the Disk is:\r
+       ;       Boot Sector (at logical sector 0)\r
+       ;   Hidden Sectors (optional)\r
+       ;       FATS (1 or more)\r
+       ;   Additional Reserved sectors (optional)\r
+       ;       Root Directory (n Sectors long)\r
+\r
+       XOR AX, AX\r
+    MOV  AL, nFATS\r
+    MUL  WORD PTR nSectPerFAT\r
+    ADD  AX, WORD PTR nHidden  ;\r
+    ADC  DX, WORD PTR nHidden+2\r
+    ADD  AX, nRsvdSect\r
+       MOV  CX, AX                             ;Save in CX\r
+\r
+       ;CX now has a Word that contains the sector of the Root\r
+\r
+       ;Calculate the size of the root directory and skip past it\r
+       ;to the first allocated sectors (this is where the OS or\r
+       ;stage one of the a two stage loader should be).\r
+\r
+    MOV  AX,0020h                      ;Size of Dir Entry\r
+    MUL  WORD PTR nRootDirEnts\r
+    MOV  BX, nBytesPerSect\r
+    DIV  BX\r
+       ADD  AX, CX\r
+\r
+       ;AX is at sector for cluster 0, but cluster 0 and 1 don't exist\r
+       ;so we are really at cluster 2 like we want to be.\r
+\r
+    MOV  CX, nOSSectors        ;Number of OS sectors to read\r
+       JMP SHORT ContinueBoot\r
+\r
+;Bad boot goes here and displays a message then\r
+;waits for a key to reboot (or tries to) via int 19h\r
+\r
+BadBoot:\r
+    MOV  SI, OFFSET MsgBadDisk\r
+    CALL PutChars\r
+\r
+    XOR  AX,AX\r
+    INT  16h           ;Wait for keystroke\r
+    INT  19h        ;Sys Reboot\r
+\r
+PutChars:\r
+    LODSB\r
+    OR   AL,AL\r
+    JZ   SHORT Done\r
+    MOV  AH, 0Eh\r
+    MOV  BX,0007\r
+    INT  10h\r
+    JMP  SHORT PutChars\r
+Done:\r
+       RETN\r
+\r
+ContinueBoot:\r
+    MOV  BX, 06000h    ;This is segment where we load the OS.\r
+    MOV  ES, BX\r
+\r
+NextSector:\r
+    PUSH AX\r
+    PUSH CX\r
+    PUSH DX\r
+       PUSH ES\r
+\r
+       XOR BX, BX\r
+\r
+; Read a logical sector to ES:BX\r
+; AX has Logical Sector Number\r
+;\r
+       MOV  SI, nSectPerTrack\r
+    DIV  SI                                    ;Divide LogicalSect by nSectPerTrack\r
+    INC  DL                                    ;Sector numbering begins at 1 (not 0)\r
+    MOV  ResvdByte, DL                 ;Sector to read\r
+    XOR  DX, DX                                ;Logical Track left in AX\r
+    DIV  WORD PTR nHeads       ;Leaves Head in DL, Cyl in AX\r
+       MOV  DH, bBootDrive\r
+       XCHG DL, DH                             ;Head to DH, Drive to DL\r
+       MOV  CX, AX                             ;Cyl into CX\r
+       XCHG CL, CH                             ;Low 8 bits of Cyl to CH, Hi 2 bits to CL\r
+       SHL  CL, 6                              ;  shifted to bits 6 and 7\r
+       OR   CL, BYTE PTR ResvdByte     ;OR with Sector number\r
+       MOV  AL, 1                              ;Number of sectors\r
+    MOV  AH, 2                         ;Read\r
+    INT  13h                           ;Read that sucker!\r
+    JC   SHORT BadBoot\r
+\r
+    MOV  SI, OFFSET MsgDot\r
+    CALL PutChars\r
+\r
+    POP  ES\r
+    POP  DX\r
+    POP  CX\r
+    POP  AX\r
+\r
+       MOV  BX, ES\r
+       ADD  BX, 20h    ;512 bytes for segment\r
+       MOV  ES, BX\r
+       INC  AX                 ;Next Sector\r
+    LOOP NextSector\r
+\r
+       ;At this point we have the OS loaded in a contigous section\r
+       ;from 60000 linear up to about 80000 linear.\r
+       ;Now we disable interrupts, turn on the A20 line, move\r
+       ;it down to address 0, set protected mode and JUMP!\r
+\r
+       CLI\r
+       XOR CX,CX\r
+IBEmm0:\r
+       IN AL,64h\r
+       TEST AL,02h\r
+       LOOPNZ IBEmm0\r
+       MOV AL,0D1h\r
+       OUT 64h,AL\r
+       XOR CX,CX\r
+IBEmm1:\r
+       IN AL,64h\r
+       TEST AL,02h\r
+       LOOPNZ IBEmm1\r
+       MOV AL,0DFh\r
+       OUT 60h,AL\r
+       XOR CX,CX\r
+IBEmm2:\r
+       IN AL,64h\r
+       TEST AL,02h\r
+       LOOPNZ IBEmm2\r
+\r
+       ;A20 line should be ON Now\r
+       ;So move the OS\r
+\r
+       ; Set up our new DS to where we moved the data\r
+       ; We must do this before each 32K load cause we use DS */\r
+\r
+       MOV DX, 8000h\r
+\r
+       ; Move 64K data chunk from linear 60000h to linear 0\r
+\r
+       MOV BX, 06000h\r
+       MOV DS, BX\r
+       XOR SI, SI\r
+       XOR AX, AX\r
+       MOV ES,AX\r
+       XOR DI,DI\r
+       MOV CX, DX\r
+       CLD                     ;\r
+       REP MOVSW                               ;WORD move\r
+\r
+       ; Move first 64K code chunk from linear 70000h to 10000h\r
+\r
+       MOV BX, 07000h\r
+       MOV DS, BX\r
+       XOR SI, SI\r
+       MOV AX,1000h\r
+       MOV ES,AX\r
+       XOR DI,DI\r
+       MOV CX, DX\r
+       REP MOVSW                               ;WORD move\r
+\r
+       ; Move last code (32K) from linear 80000h to 18000h\r
+\r
+       MOV DS, DX                              ;DX is 8000h anyway\r
+       XOR SI, SI\r
+       MOV AX,2000h\r
+       MOV ES,AX\r
+       XOR DI,DI\r
+       MOV CX, DX\r
+       REP MOVSB                               ;BYTE move\r
+\r
+       MOV BX, 9000h\r
+       MOV DS, BX\r
+\r
+       XOR EDX, EDX\r
+       MOV DL, bBootDrive              ;OS can find bootdrive in DL on entry\r
+\r
+       LIDT FWORD PTR IDTptr\r
+       LGDT FWORD PTR GDTptr\r
+\r
+       MOV EAX,CR0\r
+       OR AL,1\r
+       MOV CR0,EAX\r
+       JMP $+2\r
+       NOP\r
+       NOP\r
+\r
+    MOV BX, 10h\r
+       MOV DS,BX\r
+       MOV ES,BX\r
+       MOV FS,BX\r
+       MOV GS,BX\r
+       MOV SS,BX\r
+\r
+       ;We define a far jump with 48 bit pointer manually\r
+\r
+       DB 66h\r
+       DB 67h\r
+       DB 0EAh\r
+       DD 10000h\r
+       DW 8h\r
+\r
+MsgNone     DB '                                '\r
+MsgBadDisk  DB 0Dh, 0Ah, 'Bad Boot Disk!', 00h\r
+MsgLoad     DB 0Dh, 0Ah, 'Loading MMURTL', 00h\r
+MsgDot      DB '.', 00h\r
+\r
+BootSig   DW 0AA5Fh\r
+\r
+CSEG    ENDS\r
+        END\r
+\r
+;Character Message stuff to save for troubleshooting\r
+;      MOV BX, 0B800h\r
+;      MOV ES, BX\r
+;      XOR BX,BX\r
+;      MOV WORD PTR ES:[BX], 4730h\r