flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Issues with NOS kernel

Author
Thread Post new topic Reply to topic
nkeck72



Joined: 28 May 2015
Posts: 83
Location: 0000:7C00
nkeck72
I have had a problem for a while now concerning the NOS kernel. Everything inits OK, but when the prompt appears for a user to enter commands, only one char is displayed. Then, when you press Return, the system hangs... and I don't see why. Boot record and Kernel init/load codes seem OK.

Bootsector code:
Code:
use16
org 7C00h       
mov ax, 9ch mov ss, ax
mov sp, 4096d
mov ax, 7C0h
mov ds, ax      
mov ah, 02h
mov dx, 0000h   
int 10h
;----------------------------------------       
loadup:

        mov ah, 00h
        mov dl, 00h
        int 13h
        jc  reset_err
        ;; Clear the screen
        mov ah, 00h
        mov al, 03h
        int 10h

kernel_load:
        ;; Load the filesystem into RAM
        mov ah, 02h
        mov al, 01h
        mov ch, 00h
        mov dh, 00h
        mov cl, 02h
        mov dl, 00h
        mov bx, 2000h
        mov es, bx
        mov bx, 0000h
        int 13h
        jc  int13_err
        ;; Read kernel CHS and length from RAM
        mov ch, [es:bx]
        inc bx
        mov dh, [es:bx]
        inc bx
        mov cl, [es:bx]
        inc bx
        mov al, [es:bx]
        cmp al, 0FFh
        je  non_sys_disk
        mov ah, 02h
        mov dl, 00h
        mov bx, 1000h
        mov es, bx
        mov bx, 0000h
        int 13h
        jc  int13_err
        ;; jump to the kernel
        jmp 1000h:0000h
stop:
        cli
        hlt
        jmp stop
non_sys_disk:
        ;; A non-system disk is being booted from
        mov ah, 0Eh
        mov al, 'F'
        int 10h
        mov al, 'S'
        int 10h
        mov al, 'B'
        int 10h
        mov al, 20h
        int 10h
        mov al, 'E'
        int 10h
        mov al, 'R'
        int 10h
        int 10h                 ;Char should still be in AL
        jmp stop
int13_err:
        mov ah, 0Eh
        mov al, 'I'
        int 10h
        mov al, '1'
        int 10h
        mov al, '3'
        int 10h
        mov al, 20h
        int 10h
        mov al, 'E'
        int 10h
        mov al, 'R'
        int 10h
        int 10h                 ;Again, char should still be in AL
        jmp stop
reset_err:
        mov ah, 0Eh
        mov al, 'R'
        int 10h
        mov al, 'S'
        int 10h
        mov al, 'T'
        int 10h
        mov al, 20h
        int 10h
        mov al, 'E'
        int 10h
        mov al, 'R'
        int 10h
        int 10h

;---------------------------------------- 
; Fit this in the MBR and add boot signature
times 510-($-$$) db 0
dw 0xAA55
                                                                   

Kernel code:
Code:
        use16
disp_check:
        ;; Check the disply for proper operation
        mov ah, 09h
        mov al, '#'
        mov cx, 0FFFFh
        int 10h
        mov ah, 86h
        mov cx, 000Fh
        mov dx, 4240h
        int 15h
        mov ah, 09h
        mov al, ' '
        mov cx, 0FFFFh
        int 10h
        xor ax, ax
        mov bx, ax
        mov cx, ax
        mov dx, ax
init_kernel:
        ;; Display 'NOS 1.0.4' message
        mov ah, 0Eh
        mov al, 'N'
        int 10h
        mov al, 'O'
        int 10h
        mov al, 'S'
        int 10h
        mov al, 20h
        int 10h
        mov al, '1'
        int 10h
        mov al, '.'
        int 10h
        mov al, '0'
        int 10h
        mov al, '.'
        int 10h
        mov al, '4'
        int 10h
        call print_enter
        ;; Here we want to overwrite the MBR code and use it for the stack.
        mov bx, 0000h
        mov es, bx
        mov bx, 7C00h
        call clear_mbr
        mov ax, 0000h
        mov ss, ax
        mov es, ax
        mov ax, 7C00h
        mov sp, ax
        xor ax, ax
        xor bx, bx
        ;; Begin init of kernel (display prompt, prep mem, etc.)
        ;; Begin by setting ES to 0000, and it will be used for program segments
        mov es, bx
        ;; Display the prompt in a loop, for now not interpreting the commands
        ;; using RAM locations 1000:1000-1000:10FF for command line entered
        mov bx, 1000h
        push cx
        mov cx, 1000h
        mov ds, cx
        pop cx
beep_init:
        ;; Show that the kernel has been loaded by beeping the PC speaker
        mov cx, 1000d
        call startsound
        mov ah, 86h
        mov cx, 000Fh
        mov dx, 4240h
        int 15h
        call stopsound
prompt_loop:
        mov ah, 0Eh
        mov al, 0Dh
        int 10h
        mov al, '>'
        int 10h
        mov al, 20h
        int 10h
        mov ah, 00h
        int 16h
        cmp al, 08h
        je  print_backspace
        cmp al, 0Dh
        jne prompt_2
        jmp interpret_cmd
prompt_2:       
        mov ah, 0Eh
        int 10h                 ;Char is already in AL
        mov [ds:bx], al
        mov ah, 03h
        int 10h
        mov ah, 02h
        inc dl
        int 10h
        cmp bx, 10FFh
        jne prompt_3
        call interpret_cmd
prompt_3:
        inc bx
        jmp prompt_loop
clear_mbr:
        cmp bx, 7E00h
        jne clr_loop
        ret
clr_loop:
        mov dl, 00h
        mov [es:bx], dl
        inc bx
        jmp clear_mbr
interpret_cmd:
        mov ah, 0Eh
        mov al, 0Dh
        int 10h
        mov ah, 03h
        int 10h
        mov ah, 02h
        inc dl
        mov dh, 00h
        int 10h
        ;; interpretation code goes here
        mov bx, 1000h
clear_loop:     
        ;; reset the pointer and clear everything up to 1000:10FF
        cmp bx, 1100h
        jne clear_cmd
        jmp prompt_loop
clear_cmd:      
        mov bx, 1000h
        mov dl, 00h
        mov [ds:bx], dl
        inc bx
        jmp clear_loop
print_backspace:
        mov ah, 03h
        int 10h
        mov ah, 02h
        dec dl
        int 10h
        mov ah, 09h
        mov al, 20h
        int 10h
        jmp prompt_loop
startsound:                     ;Not my own software bit, got this function
                                ;edaboard.com
        ;; CX=Frequency in Hertz. Destroys AX and DX.
        cmp cx, 014h
        jb  startsound_done     ;Call stopsound
        in  al, 61h
        or  al, 003h
        dec ax
        out 061h, al            ;Turn and gate on; turn timer off
        mov dx, 00012h          ;High word of 1193180
        mov ax, 034DCh          ;Low word of 1193180
        div cx
        mov dx, ax
        mov al, 0B6h
        pushf
        cli                     ;!!!
        out 043h, al
        mov al, dl
        out 042h, al
        mov al, dh
        out 042h, al
        popf
        in  al, 061h
        or  al, 003h
        out 61h, al
startsound_done:
        ret
stopsound:                      ;Destroys AL. Again, not my own code in this routine. From edaboard.com.
        in  al, 061h
        and al, 0FCh
        out 061h, al
        ret
print_enter:
        mov ah, 03h
        int 10h
        mov ah, 02h
        inc dh
        mov dl, 00h
        int 10h
        ret
;; Set to two blocks
times 1020-($-$$) db 0
    

FSB (or filesystem block):
Code:
 ;; This is a simple FSB (Filesystem block) for NOS on a 1.44MB floppy disk.

        ;; CHS for Kernel start
        db 00h
        db 00h
        db 03h
        ;; Length of kernel in blocks (0FFh here means no kernel on disk)
        db 02h
        ;; free blocks
        dw 2876d
        ;; total blocks
        dw 2880d
        ;; file fields go here
        times 511-($-$$) db 00h
        db 0FFh                        

Disk structure:
Code:
file 'myos.img'      ;Bootsector
        file 'fsb.img'       ;FSB
        db 0FFh              ;These bytes indicate system file
        db 80h
        file 'kernel.img'    ;Kernel
        times 1474560-($-$$) db 0      

_________________
It may look hard, but it won't take long if you take it one byte at a time.

NOS: www.github.com/nkeck720/nos
Post 12 Sep 2015, 15:36
View user's profile Send private message Visit poster's website Reply with quote
Trinitek



Joined: 06 Nov 2011
Posts: 257
Trinitek
Are your segment registers set correctly?
Post 16 Sep 2015, 01:37
View user's profile Send private message Reply with quote
nkeck72



Joined: 28 May 2015
Posts: 83
Location: 0000:7C00
nkeck72
At the command prompt, the segs are:
SS=0000 (SP=7C00) DS=1000 CS=1000 ES=0000 (to be set later)

_________________
It may look hard, but it won't take long if you take it one byte at a time.

NOS: www.github.com/nkeck720/nos


Last edited by nkeck72 on 16 Sep 2015, 11:19; edited 3 times in total
Post 16 Sep 2015, 01:43
View user's profile Send private message Visit poster's website Reply with quote
nkeck72



Joined: 28 May 2015
Posts: 83
Location: 0000:7C00
nkeck72
SP may change later of course as pushes and pulls are executed
Post 16 Sep 2015, 01:44
View user's profile Send private message Visit poster's website Reply with quote
nkeck72



Joined: 28 May 2015
Posts: 83
Location: 0000:7C00
nkeck72
Try getting IMAGE.IMG from https://sourceforge.net/p/nosanopensourcefasmos/code
(This isnt a link to use with git clone)

Put it in Bochs or VBox and you will see what I mean.
Post 16 Sep 2015, 02:21
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17667
Location: In your JS exploiting you and your system
revolution
nkeck72 wrote:
Code:
;...
non_sys_disk:
        ;; A non-system disk is being booted from
        mov ah, 0Eh
        mov al, 'F'
        int 10h
        mov al, 'S'
        int 10h
        mov al, 'B'
        int 10h
        mov al, 20h
        int 10h
        mov al, 'E'
        int 10h
        mov al, 'R'
        int 10h
        int 10h                 ;Char should still be in AL
        jmp stop
int13_err:
        mov ah, 0Eh
        mov al, 'I'
        int 10h
        mov al, '1'
        int 10h
        mov al, '3'
        int 10h
        mov al, 20h
        int 10h
        mov al, 'E'
        int 10h
        mov al, 'R'
        int 10h
        int 10h                 ;Again, char should still be in AL
        jmp stop
reset_err:
        mov ah, 0Eh
        mov al, 'R'
        int 10h
        mov al, 'S'
        int 10h
        mov al, 'T'
        int 10h
        mov al, 20h
        int 10h
        mov al, 'E'
        int 10h
        mov al, 'R'
        int 10h
        int 10h
;...
init_kernel:
        ;; Display 'NOS 1.0.4' message
        mov ah, 0Eh
        mov al, 'N'
        int 10h
        mov al, 'O'
        int 10h
        mov al, 'S'
        int 10h
        mov al, 20h
        int 10h
        mov al, '1'
        int 10h
        mov al, '.'
        int 10h
        mov al, '0'
        int 10h
        mov al, '.'
        int 10h
        mov al, '4'
        int 10h
;...    
Did you consider using a print subroutine? Seems a bit inefficient like this; both in terms of byte count (maybe unimportant here) and programmer typing requirements (always important IMO).
Post 16 Sep 2015, 14:26
View user's profile Send private message Visit poster's website Reply with quote
nkeck72



Joined: 28 May 2015
Posts: 83
Location: 0000:7C00
nkeck72
I tried using an INT 21 routine of my own but it stopped working after some OS structure changes, and it is currently under further development.

_________________
It may look hard, but it won't take long if you take it one byte at a time.

NOS: www.github.com/nkeck720/nos
Post 16 Sep 2015, 19:44
View user's profile Send private message Visit poster's website Reply with quote
SeproMan



Joined: 11 Oct 2009
Posts: 60
Location: Belgium
SeproMan
I see (at least) 5 problems with your program.

1. When you setup the SS:SP in the kernal you allow extra instructions between both these MOV's. This is very dangerous because for a small period the stackpointer will point to anywhere! The next code will be better.
Code:
        mov ax, 0000h 
        mov bx, 7C00h 
        mov ss, ax
        mov sp, bx 
    


2. To pad your kernal for having 2 sectors you wrote "times 1020-($-$$) db 0"
Since nothing follows you should use 1024 here.

3. You use the BX register to address the buffer at 1000h:1000h but are forgetting that BH is also used by the BIOS teletype function. Better use SI or DI. Now you output to a page 16 (BH=10h)

4. At PROMPT_3 you jump back to PROMPT_LOOP and thus you erase whatever character you already typed! Maybe you meant to INC DH instead of INC DL a few lines higher in the code?

5. Your CLEAR_LOOP and CLEAR_CMD will crash the computer because you keep setting the BX register to 1000h within the loop itself!!!

_________________
Real Address Mode.
Post 20 Sep 2015, 17:28
View user's profile Send private message Reply with quote
nkeck72



Joined: 28 May 2015
Posts: 83
Location: 0000:7C00
nkeck72
I think I need to add more comments to my code, eh?
Thank you sooo much, SeproMan! Will edit this and push the changes. If there are any other issues, PLEASE let me know!
Post 20 Sep 2015, 18:15
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.