# Floppy boot segment .org 0# actually 7c00 start: jmp start0 nop .ascii "cmcf 1.0" .word 512# bytes/sector .byte 1# sector/cluster .word 1# sector reserved .byte 2# FATs .word 16 * 14# root directory entries .word 80 * 2 * 18# sectors .byte 0x0F0# media .word 9# sectors/FAT .word 18# sectors/track .word 2# heads .int 0# hidden sectors .int 80 * 2 * 18# sectors again .byte 0# drive # db 0 # db 29h ; signature # dd 44444444h ; serial # db 'COLOR FORTH' ; label # db ' ' command:.byte 0 .byte 0# head, drive cylinder: .byte 0 .byte 0# head .byte 1# sector .byte 2# 512 bytes/sector .byte 18# sectors/track .byte 0x1b# gap .byte 0x0ff .balign 4 nc: .int 9# Forth+Icons+blocks 24-161 gdt: .word 0x17 .int gdt0 .balign 8 gdt0: .word 0, 0, 0, 0 .word 0x0FFFF, 0, 0x9A00, 0x0CF# code .word 0x0FFFF, 0, 0x9200, 0x0CF# data # Code is compiled in Protected 32-bit mode. # Hence org $-2 to fix 16-bit words # and 4 hand-assembled instructions. # and EAX and AX exchanged # This code is in Real 16-bit mode .code16 start0: mov $0x7c00, %ax mov %ax, %es mov $512, %di mov $0x4F01, %ax mov $vesa, %cx int $0x10 mov $0x4F02, %ax# Video mode mov $vesa, %bx# hp*vp rgb: 565 int $0x10 mov %es:42(%di), %bp shl $16, %ebp mov %es:40(%di), %bp cli xor %eax, %eax# Move code to 0 mov %eax, %ebx mov %cs, %bx mov %bx, %ds mov %ax, %es movl %eax, %edi movl %eax, %esi call loc# Where are we? IP+4*CS loc: pop %si sub $loc - start, %si mov $512 / 4, %cx rep movsl jmp $0, $relocate relocate:# This code is executed from 0 mov %ax, %ds lgdt gdt movb $1, %al movl %eax, %cr0 jmp $8, $protected .code32 protected:# Now in Protected 32-bit mode movb $0x10, %al mov %eax, %ds mov %eax, %es mov %eax, %ss movl $gods, %esp # setup return stack xorl %ecx, %ecx a20: movb $0x0d1, %al outb %al, $0x64 0: inb $0x64, %al andb $2, %al jnz 0b movb $0x4b, %al outb %al, $0x60 cold: movl $godd, %esi call spin call dma xorl %edi, %edi# Cylinder 0 on top of Address 0 call read incb cylinder movb nc, %cl 0: pushl %ecx call read popl %ecx loop 0b call stop start2: jmp start1 stop: movb $0x0c, %cl# Motor off onoff: DUP_ movb %cl, %al movw $0x3f2, %dx out %al, %dx outb %al, $0x0e1 DROP ret .equ ms, 1000 * 1000 / 4 spin: movb $0x1c, %cl # tll call onoff movl $400 * ms, %ecx # (c4a) 0: loop 0b # movb %cl, cylinder # calibrate ; (c4a) movb $7, %al # recalibrate command movb $2, %cl jmp cmdi ready: movl $0x3F4, %edx 0: in %dx, %al OUTb %al, $0x0E1 # tll ; (c4a) shlb $1, %al jnc 0b leal 1(%edx), %edx ret cmd: pushl %esi lea command, %esi# (c4a) movb %al, (%esi) 0: call ready jns cmd0 in %dx, %al # discard input OUTb %al, $0x0E1# tll ; (c4a) jmp 0b cmd0: lodsb out %al, %dx # write command pushl %ecx# (c4a) movl $0x001e, %ecx# (c4a) cmd1: outb %al, $0x0e1# (c4a) loop cmd1# (c4a) popl %ecx# (c4a) loop 0b popl %esi ret sense_: movb $8, %al # sense interrupt status command movb $1, %cl call cmd call ready in %dx, %al OUTb %al, $0x0E1# tll ; (c4a) cmpb $0x80, %al ret seek: outb %al, $0x0b 0: call sense_ jnz 0b movb $0x0F, %al movb $3, %cl cmdi: call cmd 0: call sense_ jz 0b ret dma: movw $0x2a1, command + 1# 2 6 16 ms (e 2) movb $3, %al# timing movb $3, %cl call cmd movw $0, command + 1 movl $buffer * 4, %eax outb %al, $4 movb %ah, %al outb %al, $4 shrl $16, %eax outb %al, $0x81 movl $512 * 18 * 2 - 1, %eax# DMA 2 outb %al, $5 movb %ah, %al outb %al, $5 movb $0x0b, %al outb %al, $0x0f ret transfer: movb $9, %cl call cmd incb cylinder 0: call ready jns 0b ret read: movb $0x16, %al# Read DMA 2 call seek movb $0x0e6, %al call transfer pushl %esi movl $buffer * 4, %esi movl $512 * 18 * 2 / 4, %ecx rep movsl popl %esi ret .org 0x1FE# End boot sector .byte 0x55, 0x0AA write: movl $buffer * 4, %edi movl $512 * 18 * 2 / 4, %ecx rep movsl movb $0x1a, %al# Write DMA 2 call seek movb $0x0c5, %al jmp transfer flop: movb %al, cylinder# c-cx DUP_ movw $0x3f2, %dx in %dx, %al outb %al, $0x0e1 testb $0x10, %al jnz 0f jmp spin 0: ret readf: call flop# ac-ac pushl %edi movl 4(%esi), %edi shll $2, %edi call read popl %edi readf1: DROP incl %eax addl $0x1200, (%esi) ret writef: call flop# ac-ac pushl %esi movl 4(%esi), %esi shll $2, %esi call write popl %esi jmp readf1