.define begtext, begdata, begbss .data begdata: .asciz "(null)" .bss begbss: BOOTOFF = 0x7C00 LOADSEG = 0x1000 BUFFER = 0x0600 PENTRYSIZE = 16 DSKBASE = 120 DSKPARSIZE = 11 SECTORS = 4 a_flags = 2 a_text = 8 a_data = 12 a_bss = 16 a_total = 24 A_SEP = 0x20 .extern _cseg, _dseg, _runsize, _edata, _end .extern _device, _dskpars, _heads, _sectors .extern _eqscancode .extern _rem_part .text begtext: .extern _boot, _printk jmpi boot, LOADSEG+3 .space 11 jmpi boot, LOADSEG+2 boot: mov ax, #LOADSEG mov ds, ax movb al, a_flags testb al, #A_SEP jnz sepID comID: xor ax, ax xchg ax, a_text add a_data, ax sepID: mov ax, a_total and ax, #0xFFFE mov a_total, ax cli mov sp, ax mov ax, a_text movb cl, #4 shr ax, cl mov cx, cs add ax, cx mov ds, ax mov ss, ax sti push es mov es, ax cld xor ax, ax mov di, #_edata mov cx, #_end sub cx, di shr cx, #1 rep stow xorb dh, dh mov _device, dx mov _rem_part+0, si pop _rem_part+2 mov _cseg, cs mov _dseg, ds push ds mov ax, #LOADSEG mov ds, ax mov ax, a_total+0 mov dx, a_total+2 add ax, a_text+0 adc dx, a_text+2 pop ds mov _runsize+0, ax mov _runsize+2, dx call _boot .define _exit, __exit, _main .define _reboot _exit: __exit: _main: _reboot: mov ax, #any_key push ax call _printk call _getchar int 0x19 .data any_key: .asciz "\nHit any key to reboot\n" .text .define _raw_copy _raw_copy: mov bx, sp push si push di mov cx, 10(bx) les di, 2(bx) lds si, 6(bx) shr cx, #1 jb bytecopy rep movw j copydone bytecopy: rcl cx, #1 rep movb copydone: mov ax, ss mov ds, ax mov es, ax pop di pop si ret .define _raw_clear _raw_clear: mov bx, sp push di les di, 2(bx) xor ax, ax mov cx, 6(bx) shr cx, #1 jb byteclear rep stow j cleardone byteclear: rcl cx, #1 rep stob cleardone: mov ax, ds mov es, ax pop di ret .define _get_word, _put_word _get_word: mov bx, sp push ds lds bx, 2(bx) mov ax, (bx) pop ds ret _put_word: mov bx, sp push ds mov ax, 6(bx) lds bx, 2(bx) mov (bx), ax pop ds ret .define _relocate _relocate: pop bx mov ax, cs sub ax, _cseg mov dx, ds sub dx, ax mov ds, dx mov es, dx mov ss, dx mov _dseg, dx push _cseg push bx reti .data .align 2 break: .word _end .text .define _brk, __brk, _sbrk, __sbrk _brk: __brk: xor ax, ax j sbrk _sbrk: __sbrk: mov ax, break sbrk: push ax mov bx, sp add ax, 4(bx) mov break, ax lea dx, -1024(bx) cmp dx, ax jb heaperr lea dx, -4096(bx) cmp dx, ax jae plenty mov ax, #memwarn push ax call _printk pop ax movb memwarn, #0 plenty: pop ax ret heaperr: mov ax, #chmem push ax mov ax, #nomem push ax call _printk call _reboot .data nomem: .asciz "\nOut of%s" memwarn: .ascii "\nLow on" chmem: .asciz " memory, use chmem to increase the heap\n" .text .define _dev_geometry _dev_geometry: movb dl, _device cmpb dl, #0x80 jae winchester floppy: int 0x11 testb al, #0x01 jz geoerr shl ax, #1 shl ax, #1 andb ah, #0x03 cmpb dl, ah ja geoerr movb dh, #2 movb _heads, dh mov bx, #_dskpars movb cl, SECTORS(bx) movb _sectors, cl xor ax, ax mov es, ax seg es mov DSKBASE+0, bx seg es mov DSKBASE+2, ds j geoboth winchester: movb ah, #0x08 int 0x13 jb geoerr andb cl, #0x3F movb _sectors, cl incb dh movb _heads, dh geoboth: mov ax, #1 push ax movb al, cl mulb dh mov secspcyl, ax geodone: push ds pop es pop ax ret geoerr: xor ax, ax push ax j geodone .bss secspcyl: .zerow 1 .text .define _readsectors, _writesectors _writesectors: push bp mov bp, sp movb 13(bp), #3 j rwsec _readsectors: push bp mov bp, sp movb 13(bp), #2 rwsec: push di push es les bx, 4(bp) mov di, #3 cmpb _device, #0x80 jb nohd mov di, #1 nohd: cmpb 12(bp), #0 jz done more: mov ax, 8(bp) mov dx, 10(bp) div secspcyl xchg ax, dx movb ch, dl divb _sectors xorb dl, dl shr dx, #1 shr dx, #1 orb dl, ah movb cl, dl incb cl movb dh, al movb dl, _device movb al, _sectors subb al, ah cmpb al, 12(bp) jbe doit movb al, 12(bp) doit: movb ah, 13(bp) push ax int 0x13 pop cx jb ioerr movb al, cl addb bh, al addb bh, al add 8(bp), ax adc 10(bp), #0 subb 12(bp), al jnz more done: call wheel xorb ah, ah j finish ioerr: dec di jl finish xorb ah, ah int 0x13 jae more finish: movb al, ah xorb ah, ah pop es pop di pop bp ret .define _getchar, _peekchar _peekchar: movb ah, #1 int 0x16 jnz getc xor ax, ax ret _getchar: movb ah, #0 int 0x16 getc: cmpb al, #0x3D jnz noeq movb _eqscancode, ah noeq: cmpb al, #0x0D jnz nocr movb al, #0x0A nocr: xorb ah, ah ret .define _putchar, _putc, _putk _putchar: _putc: _putk: mov bx, sp movb al, 2(bx) testb al, al jz nulch cmpb al, #0x0A jnz putc cmpb wdirty, #0 jz nodirt movb al, #0x20 call putc nodirt: movb al, #0x0D call putc movb al, #0x0A putc: movb ah, #14 mov bx, #0x0001 int 0x10 movb wdirty, #0 nulch: ret wheel: push si mov si, gp lodb call putc movb al, #0x08 call putc cmp si, #glyphs+4 jne wmore mov si, #glyphs wmore: mov gp, si incb wdirty pop si ret .data .align 2 gp: .word glyphs glyphs: .ascii "|/-\\" wdirty: .byte 0 .text .define _reset_video, _set_cursor _reset_video: mov bx, sp movb al, #7 cmp 2(bx), #0 jz clear movb al, #3 clear: xorb ah, ah int 0x10 xor dx, dx j setcur _set_cursor: mov bx, sp movb dl, 2(bx) movb dh, 4(bx) setcur: xorb bh, bh movb ah, #0x02 int 0x10 ret .define _get_tick _get_tick: xorb ah, ah int 0x1A mov ax, dx mov dx, cx ret .define _get_video .define _get_ext_memsize .define _get_low_memsize .define _get_processor _get_video: mov ax, #0x1A00 int 0x10 cmpb al, #0x1A jnz no_dc mov ax, #2 cmpb bl, #5 jz got_video inc ax cmpb bl, #4 jz got_video inc ax cmpb bl, #7 jz got_video inc ax cmpb bl, #8 jz got_video no_dc: movb ah, #0x12 movb bl, #0x10 int 0x10 cmpb bl, #0x10 jz no_ega mov ax, #2 cmpb bh, #1 jz got_video inc ax j got_video no_ega: int 0x11 and ax, #0x30 sub ax, #0x30 jz got_video mov ax, #1 got_video: ret _get_ext_memsize: call _get_processor cmp ax, #186 jbe no_ext movb ah, #0x88 clc int 0x15 jnb got_ext_memsize no_ext: sub ax, ax got_ext_memsize: ret _get_low_memsize: int 0x12 ret o32 = 0x66 _get_processor: push bp mov bp, sp push sp pop ax cmp ax, sp jz new_processor mov cx, #0x0120 shlb ch, cl mov ax, #86 jz got_processor mov ax, #186 j got_processor new_processor: sub sp, #6 .byte 0x0F add -6(bp), ax cmpb -1(bp), #0 mov ax, #286 jnz got_processor and sp, #0xFFFC .byte o32 pushf pop ax pop dx mov bx, ax mov cx, dx xor dx, #0x0004 push dx push ax .byte o32 popf .byte o32 pushf pop ax pop dx push cx push bx .byte o32 popf xor dx, cx test dx, #0x0004 mov ax, #386 jz got_processor mov ax, #486 got_processor: mov sp, bp pop bp ret .define _bootstrap _bootstrap: mov bx, sp movb dl, 2(bx) lds si, 4(bx) xor ax, ax mov es, ax mov di, #BUFFER mov cx, #PENTRYSIZE rep movb mov si, #BUFFER mov ds, ax cli mov ss, ax mov sp, #BOOTOFF sti jmpi BOOTOFF, 0 stop_motor: mov dx, #0x03F2 movb al, #0x0C out ret .define _minix86 _minix86: call stop_motor mov bp, sp mov ax, #0x100 mov si, 6(bp) mov di, ds mov cx, 8(bp) push cx push si mov ds, 4(bp) mov es, 4(bp) cli mov (bp), #0 jmpi @(bp) .define _minix386 _minix386: call stop_motor mov bp, sp mov di, ds mov si, #gdt mov bx, #gdt_desc call set_base mov di, 4(bp) xor si, si mov bx, #ds_desc call set_base mov di, ss xor si, si mov bx, #ss_desc call set_base mov di, 2(bp) xor si, si mov bx, #cs_desc call set_base xor ax, ax push ax push 8(bp) push ax push 6(bp) mov si, #gdt xor bx, bx movb ah, #0x89 cli pushf push 2(bp) push bx mov ds, bx jmpi @4*0x15 set_base: mov 2(bx), di mov cx, #4 seg2abs: shl 2(bx), #1 rclb 4(bx), #1 loop seg2abs add 2(bx), si adcb 4(bx), #0 ret .data .align 2 UNSET = 0 gdt: null_desc: .word 0x0000, 0x0000 .byte 0x00, 0x00, 0x00, 0x00 gdt_desc: .word 8*8-1, UNSET .byte UNSET, 0x00, 0x00, 0x00 idt_desc: .word 0x0000, 0x0000 .byte 0x00, 0x00, 0x00, 0x00 ds_desc: .word 0xFFFF, UNSET .byte UNSET, 0x92, 0xCF, 0x00 es_desc: .word 0xFFFF, 0x0000 .byte 0x00, 0x92, 0xCF, 0x00 ss_desc: .word 0xFFFF, UNSET .byte UNSET, 0x92, 0x40, 0x00 cs_desc: .word 0xFFFF, UNSET .byte UNSET, 0x9A, 0xCF, 0x00 bios_desc: .word UNSET, UNSET .byte UNSET, UNSET, UNSET, UNSET