Benjamin David Lunt wrote:
> Okay. Here are the results of the compo.
...
I started with 365 byte and Ben found it didn't even pass the test.
so I removed one bug and some bytes too and came up with 318 byte.
this version passed the test even it had another silly bug.
After fixing this one I had only 295 byte.
Then I adapted my code to the test and cheated with 276 bytes.
Ok, here is my final variant with a few more comments.
It's written in pure hex and exported to a FAT-file.
disassembled with NASM (mine show my personal syntax),
and I tried to not produce linewraps with comments here.
feel free to ask any question or just pick on it :)
__
wolfgang
M:\DIV_TOOL\NASM9838>ndisasmw d:com\entry.bin (281 byte)
000 FC cld
001 666A00 o32 push byte +0x0 ;push four Zero bytes
004 1F pop ds
005 17 pop ss
006 8CDC mov sp,ds ;ds=ss=sp=0
008 1E push ds ;esp=0_fffe, [sp]=0
009 BBAA55 mov bx,0x55aa
00C B441 mov ah,0x41
00E CD13 int 0x13
010 BEEE7C mov si,0x7cf3 ;error text and my base
013 7206 jc 0x1b
015 81FB55AA cmp bx,0xaa55 ;'NOT BX' trick isn't shorter
019 740C jz 0x27
01B 5B pop bx ;zero as demanded
01C AC lodsb
01D 3C4C cmp al,0x4c ;who said ASCII-Z?
01F 74FC jz 0x1d ;freeze on the "L"
021 B40E mov ah,0xe
023 CD10 int 0x10
025 EBF5 jmp short 0x1c
027 BBBE7D mov bx,0x7dbe ;find active partition
02A 0A27 or ah,[bx] ;AH was 0x41 from above
02C 7805 js 0x33
02E 80C310 add bl,0x10
031 EBF7 jmp short 0x2a
033 8B4708 mov ax,[bx+0x8] ;volume-start LBA
036 1E push ds ;
037 50 push ax ;prepared for popad: eax
038 6668EFBEADDE push dword 0xdeadbeef ;ecx
03E B600 mov dh,0x0
040 1E push ds
041 52 push dx ;edx
042 666804030201 push dword 0x1020304 ;ebx
048 8854F6 mov [si-0xa],dl ;[7cf3-0a=7ce9] BIOS Drv#
04B E88300 call 0xd6 ;load sectors AX..to 0:7e00
04E B108 mov cl,0x8 ;prepare for popad (CH=0 from call)
050 1E push ds ;ebp,(esp),esi,edi all zero.
051 E2FD loop 0x50
053 03470E add ax,[bx+0xe] ;add boot-sectors
056 8EE0 mov fs,ax ;FS aka FAT-Start here
058 807F3A36 cmp byte [bx+0x3a],0x36 ;FAT12 or 16
05C 7407 jz 0x65 ;skip if 16
05E FE4CA8 dec byte [si-0x58] ;[7cf3-58=7c9b]
;=nibbles per entry
061 C644B60F mov byte [si-0x4a],0xf ;[7cf3-4a=7ca9]
;=EOC-mask highbyte
065 8A4F0D mov cl,[bx+0xd] ;sectors per cluster
068 884CC3 mov [si-0x3d],cl ;[7cf3-3d=7cb6]
06B 034716 add ax,[bx+0x16] ;sectors per FAT
06E FE4F10 dec byte [bx+0x10] ;add as many as reported
071 75F8 jnz 0x6b
073 8BE8 mov bp,ax ;BP = AX = rootstart
075 8B7F11 mov di,[bx+11] ;root-entries
078 C1EF04 shr di,0x4 ;root-size (sectors)
07B 03EF add bp,di ;BP = BR+FATs+Root = Datastart
;----------------------------
;before I had something like:
;
;075 mov cx,[bx+11]
;078 test cl,0xf
;07B jz 0x80
;07D add cx,0x10
;080 shr cx,0x4
;083 add bp,cx
;
;but I never saw any nonzero low-nibble values for root-entries.
;
;and I cheated in the 276 byte version with:
;075 add bp,0x0e ;figured as Ben's root-size standard :)
;----------------------------
07D 56 push si
07E E85500 call 0xd6 ;load root sectors to 0:7e00
081 8BFB mov di,bx ;instead of push/pop di, see 0C2
083 BE097D mov si,0x7d0e ;ptr to: "LOADER .SYS"
086 B10B mov cl,0xb ;CH=0 from above
088 F3A6 repe cmpsb ;find entry
08A 7405 jz 0x91
08c 83C320 add bx,byte +0x20
08F EBF0 jmp short 0x81
091 5E pop si
092 8B471A mov ax,[bx+0x1a] ;get cluster (ignore size)
095 8904 mov [si],ax ;save a copy
097 31DB xor bx,bx ;init destination-ptr
;LOOP:
099 6BF804 imul di,ax,byte +0x4 ;[7c9b] become 3 if FAT12
09C 8CE0 mov ax,fs ;ax=FAT-start, di=nibble_offset
;-------------------------------
;in previous trials I had:;
;
;099 B504 mov ch,0x4 ;CL=0 from above and below
; 6BC004 imul ax,ax,byte +0x4 ;3 or 4 [nibbles/entry]
; 31D2 xor dx,dx
; F7F1 div cx ;(1024 nibbles/sector)
; 8BFA mov di,dx ;di= nibble offset
; 8CE2 mov dx,fs ;
; 03C2 add ax,dx ;ax=FATsector+FATstart
;
;but then found that this isn't required and
:I can keep DX as EOC-mark within the loop.
;-------------------------------
09E 53 push bx
09F E83400 call 0xd6 ;load FAT-sectors to 0:7e00
0A2 D1EF shr di,1 ;nibble to byte, remember Carry
0A4 8B01 mov ax,[bx+di] ;get FAT-entry
0A6 5B pop bx
;------
; you may ask why I have the call above within the loop.
; the FAT-import from my OS loads only a few FAT-sectors
; at a time and calculate the LBA from Cluster-Nr.
; This way I avoid to load the whole FAT into RAM which
; would be required for far distant fragments.
; All because a whole FAT32 copy will be quite large.
;------
0A7 BAFFFF mov dx,0xffff ;[7ca9] EOC become '0FFF' if FAT12
0AA 7303 jnc 0xaf ;odd? (never odd if FAT16)
0AC C1E804 shr ax,0x4 ;
0AF 21D0 and ax,dx ;mask it
0B1 8704 xchg ax,[si] ;save entry, get cluster
0B3 48 dec ax ; cluster-Nr.
0B4 48 dec ax ; -2
0B5 B101 mov cl,0x1 ; * [7cb6] sectors per cluster
0B7 F6E1 mul cl ;
0B9 03C5 add ax,bp ; + 1st_data
0BB 680030 push word 0x3000
0BE 07 pop es ;es=3000
0BF E81C00 call 0xde ;load one cluster to ES:BX
0C2 80C702 add bh,0x2 ;adjust for next cluster
0C5 E2FB loop 0xc2 ;add di,0200 was one byte more
;so I swapped bx and di usage
0C7 8B04 mov ax,[si] ;get recent FATentry
0C9 3BC2 cmp ax,dx ;cmp with EOC
0CB 72CC jc 0x99 ;repeat if <EOC
0CD 6661 popad ;set all regs as demanded
0CF 06 push es ;is 0x3000 from last call
0D0 1F pop ds
0D1 06 push es
0D2 17 pop ss
0D3 06 push es
0D4 57 push di ;di became 0 from popad
0D5 CB retf
0D6 B90200 mov cx,0x4 ;load 2K to 0:7e00
;-----
; I could have used 0x007f instead of 4, but my always
; present concern about speed and my maniac needs for
; avoiding redundant actions made it even pass the test
; with a 2 here.
;-----
0D9 BB007E mov bx,0x7e00
0DC 1E push ds
0DD 07 pop es ;es=0
0DE 60 pusha ;load CL-sectors to ES:BX
0DF 1E push ds ;0
0E0 1E push ds ;0
0E1 1E push ds ;0
0E2 50 push ax ;LBA
0E3 06 push es ;seg
0E4 53 push bx ;offset
0E5 51 push cx ;count (CH must be 0)
0E6 6A10 push byte +0x10 ;size of struct
0E8 B280 mov dl,0x80 ;[7ce9] BIOS drv-Nr.
0EA 8BF4 mov si,sp ;works because SS=DS=0
0EC B442 mov ah,0x42
0EE CD13 int 0x13
0F0 61 popa ;add SP,16
0F1 61 popa ;restore all
0F2 C3 ret
;text data:
0F3 4E 6F 20 44 69 73 6B 20 53 65 72 76 69
100 63 65 73 20 41 76 61 69 6C 61 62 6C 65 2E
10E 4C 4F
110 41 44 45 52 20 20 53 59 53
119 ...free
---------------