Minix1.5/tools/menu1.s
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