Special Feature: ColorForth Commentary
ColorForth: BOOT.ASM
NOTICE: This is a work in progress. Parts of my commentary are still very rough. However, I have it up on the web because even in this rough form it may be useful to ColorForth enthusiasts. Expect the contents of these files to change frequently.
Boot-sector tables
; floppy boot segment org 0 ; actually 7c00 start: jmp start0 nop db 'cmcf 1.0' dw 512 ; bytes/sector db 1 ; sector/cluster dw 1 ; sector reserved db 2 ; fats dw 16*14 ; root directory entries dw 80*2*18 ; sectors db 0f0h ; media dw 9 ; sectors/fat dw 18 ; sectors/track dw 2 ; heads dd 0 ; hidden sectors dd 80*2*18 ; sectors again db 0 ; drive ; db 0 ; db 29h ; signature ; dd 44444444h ; serial ; db 'color forth'; label ; db ' ' ;............................................................................. ; Refs -- start: loc, relocate, nc_, xy_, fov_, sps, last, octal
command db 0 db 0 ; head, drive cylinder db 0 db 0 ; head db 1 ; sector db 2 ; 512 bytes/sector db 18 ; sectors/track db 1bh ; gap db 0ffh align 4 nc: dd 9 ; forth+icons+blocks 24-161 ; Number of cylinders ;............................................................................. ; Refs: ; -- command: cmd, dma ; -- cylinder: cold, spin, flop ; -- nc: cold, nc_
[Dissect bitfields in this GDT -- privilege level, start address, granularity, segment size, etc.]
gdt: dw 17h dd offset gdt0 align 8 gdt0: dw 0, 0, 0, 0 dw 0ffffh, 0, 9a00h, 0cfh ; code dw 0ffffh, 0, 9200h, 0cfh ; data ;............................................................................. ; Refs: ; -- gdt: relocate ; -- gdt0: gdt
Booting the system
; 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 start0: mov eax, 4f02h ; video mode org $-2 mov ebx, vesa ; hp*vp rgb: 565 org $-2 int 10h cli xor ax, ax ; move code to 0 mov bx, ax mov ebx, cs mov ds, ebx mov es, eax mov di, ax mov si, ax call $+5 ; where are we? ip+4*cs org $-2 loc: pop esi sub esi, offset loc-offset start org $-2 mov ecx, 512/4 org $-2 rep movsw ; jmp 0:relocate db 0eah dw offset relocate-offset start, 0 ;............................................................................. ; Refs: ; -- start0: start ; -- loc: loc
relocate: ; this code is executed from 0 mov ds, eax ; lgdt fword ptr gdt db 0fh, 1, 16h dw offset gdt-offset start mov al, 1 mov cr0, eax ; jmp 8:protected db 0eah dw offset protected-offset start, 8 protected: ; now in protected 32-bit mode mov al, 10h mov ds, eax mov es, eax mov ss, eax mov esp, gods xor ecx, ecx ;............................................................................. ; Refs: ; -- relocate: loc ; -- protected: relocate
a20: mov al, 0d1h out 64h, al @@: in al, 64h and al, 2 jnz @b mov al, 4bh out 60h, al call dma shl ebx, 4 add esi, ebx cmp dword ptr [esi], 44444444h ; boot? jnz cold mov cx, 63*100h-80h ; nope rep movsd mov esi, godd jmp start2 cold: call sense_ jns cold mov esi, godd xor edi, edi ; cylinder 0 on top of address 0 mov cl, byte ptr nc @@: push ecx call read inc cylinder pop ecx loop @b start2: call stop jmp start1 ;............................................................................. ; Refs: ; -- a20: none ; -- cold: cold, a20 ; -- start2: a20
Floppy driver
us equ 1000/6 ms equ 1000*us ;............................................................................. ; Refs: ; -- us: ms, (delay) ; -- ms: spin
spin: ;[Refs: flop] mov cl, 1ch call onoff ; mov dx, 3f2h ; out dx, al @@: call sense_ jns @b mov cylinder, 0 ; calibrate mov al, 7 mov cl, 2 call cmd mov ecx, 500*ms @@: loop @b cmdi: ;[Refs: cmdi, seekf] call sense_ js cmdi ret ready: ;[Refs: cmd1, sense_, read, write, readyf] ;call delay mov dx, 3f4h @@: in al, dx out 0e1h, al shl al, 1 jnc @b lea edx, [edx+1] ret transfer: ;[Refs: read, write] mov cl, 9 cmd: ;[Refs: sense_, dma, seekf, spin] lea edx, command mov [edx], al cmd0: ;[Refs: cmdf] push esi mov esi, edx cmd1: ;[Refs: cmd1] call ready jns @f in al, dx jmp cmd1 @@: lodsb out dx, al out 0e1h, al loop cmd1 pop esi ;delay: ;[Refs: seekf, ready] ; mov eax, us ;@@: dec eax ; jnz @b ret sense_: ;[Refs: seek, cold, spin, cmdi] mov al, 8 mov ecx, 1 call cmd @@: call ready jns @b in al, dx out 0e1h, al and al, al ; cmp al, 80h ret seek: ;[Refs: seek, dma, read, write, seekf] call sense_ jns seek ret stop: ;[Refs: start2, forth2] mov cl, 0ch ; motor off onoff: ;[Refs: spin] dup_ mov al, cl mov dx, 3f2h out dx, al out 0e1h, al drop ret dma: ;[Refs: a20] mov word ptr command+1, 3a2h ; l2 s6 u32 ms (e 2) mov al, 3 ; timing mov cl, 3 call cmd mov word ptr command+1, 7000h ; +seek -fifo -poll mov al, 13h ; configure mov cl, 4 call cmd mov dword ptr command, ecx ; 0 ret read: ;[Refs: cold, readf] call seek mov al, 0e6h ; read normal data call transfer mov cx, 18*2*512 @@: call ready in al, dx out 0e1h, al stosb next @b ret write: ;[Refs: writef] call seek mov al, 0c5h ; write data call transfer mov cx, 18*2*512 @@: call ready lodsb out dx, al out 0e1h, al next @b ret org 1feh ; mark boot sector dw 0aa55h dd 44444444h ; mark color.com flop: ;[Refs: readf, writef, seekf] mov cylinder, al ; c-cx dup_ mov dx, 3f2h in al, dx out 0e1h, al test al, 10h jnz @f jmp spin @@: ret readf: ;"read" ;[Refs: forth2] call flop ; ac-ac push edi mov edi, [esi+4] shl edi, 2 call read pop edi readf1: ;[Refs: writef] drop inc eax add dword ptr [esi], 1200h ret writef: ;"write" ;[Refs: forth2] call flop ; ac-ac push esi mov esi, [esi+4] shl esi, 2 call write pop esi jmp readf1 seekf: ;"seek" ;[Refs: forth2] call flop ; c-c ; call delay call seek mov al, 0fh mov cl, 3 call cmd call cmdi drop ret cmdf: ;"command" ;[Refs: forth2] mov ecx, eax ; an drop lea edx, [eax*4] call cmd0 drop ret readyf: ;"ready" ;[Refs: forth2] dup_ call ready drop ret
Check the index for other entries.