STACKSIZE = 8192 .globl _main, _exit, _edata, _end, _putc, _getc, _reset_diskette, _diskio .globl csv, cret, begtext, begdata, begbss .globl _cylsiz, _tracksiz, _drive, _boot_parameters .text begtext: start: mov dx,bx | bootblok puts # sectors/track in bx xor ax,ax mov bx,#_edata | prepare to clear bss mov cx,#_end sub cx,bx sar cx,*1 st.1: mov (bx),ax | clear bss add bx,#2 loop st.1 mov _tracksiz,dx | dx (was bx) is # sectors/track add dx,dx mov _cylsiz,dx | # sectors/cylinder mov sp,#kerstack+STACKSIZE call _main mov bx,ax | put scan code for '=' in bx sub ax,ax | ax == 0 to show new boot (was scan code) mov si,#_boot_parameters | pointer to boot parameters in di:si mov di,ds mov cx,#10 | sizeof structure in cx | next 'cli' and setting up segs is redundant | and the segments are wrong for sep I&D cli mov dx,#0x60 mov ds,dx mov es,dx mov ss,dx jmpi 0,0x60 | jmp to kernel _exit: mov bx,_tracksiz jmp start _putc: xor ax,ax call csv movb al,4(bp) | al contains char to be printed movb ah,#14 | 14 = print char movb bl,*1 | foreground color push bp | not preserved int 0x10 | call BIOS VIDEO_IO pop bp jmp cret _getc: xorb ah,ah int 0x16 ret _reset_diskette: xor ax,ax call csv push es | not preserved int 0x13 | call BIOS DISKETTE_IO pop es jmp cret | handle diskio(RW, sector_number, buffer, sector_count) call | Do not issue a BIOS call that crosses a track boundary _diskio: xor ax,ax call csv mov tmp1,#0 | tmp1 = # sectors actually transferred mov di,10(bp) | di = # sectors to transfer mov tmp2,di | di = # sectors to transfer d0: mov ax,6(bp) | ax = sector number to start at xor dx,dx | dx:ax is dividend div _cylsiz | ax = cylinder, dx = sector within cylinder movb cl,ah | cl = hi-order bits of cylinder rorb cl,#1 | BIOS expects hi bits in a funny place rorb cl,#1 | ditto movb ch,al | cx = sector # in BIOS format mov ax,dx | ax = sector offset within cylinder xor dx,dx | dx:ax is dividend div _tracksiz | ax = head, dx = sector movb dh,al | dh = head orb cl,dl | cl = 2 high-order cyl bits || sector incb cl | BIOS counts sectors starting at 1 movb dl,_drive | dl = drive code (0-3 or 0x80 - 0x81) mov bx,8(bp) | bx = address of buffer movb al,cl | al = sector # addb al,10(bp) | compute last sector decb al | al = last sector to transfer cmpb al,_tracksiz | see if last sector is on next track jle d1 | jump if last sector is on this track mov 10(bp),#1 | transfer 1 sector at a time d1: movb ah,4(bp) | ah = READING or WRITING addb ah,*2 | BIOS codes are 2 and 3, not 0 and 1 movb al,10(bp) | al = # sectors to transfer mov tmp,ax | al is # sectors to read/write push es | BIOS ruins es int 0x13 | issue BIOS call pop es | restore es cmpb ah,*0 | ah != 0 means BIOS detected error jne d2 | exit with error mov ax,tmp | fetch count of sectors transferred xorb ah,ah | count is in ax add tmp1,ax | tmp1 accumulates sectors transferred mov si,tmp1 | are we done yet? cmp si,tmp2 | ditto je d2 | jump if done inc 6(bp) | next time around, start 1 sector higher add 8(bp),#0x200 | move up in buffer by 512 bytes jmp d0 d2: jmp cret csv: pop bx push bp mov bp,sp push di push si sub sp,ax jmp (bx) cret: lea sp,*-4(bp) pop si pop di pop bp ret .data begdata: tmp: .word 0 tmp1: .word 0 tmp2: .word 0 .bss begbss: kerstack: .zerow STACKSIZE/2 | kernel stack