flat assembler
Message board for the users of flat assembler.
![]() Goto page 1, 2 Next |
Author |
|
vid 26 May 2011, 18:11
In Pmode, your segment registers hold "selector" instead of segment_base/16. "selector" is index to "descriptor table". "Descriptor table" (global or local, GDT or LDT) is table of "Descriptors" located somewhere in memory. "Descriptor" is a structure that describes a segment. One of fields in descriptor is "segment base address".
So if for example DS contains selector 8, descriptor at index 8 in GDT has segment base address 1000h, then address "DS:20h" corresponds to linear address 1020h, address DS:0 corresponds to 1000h, etc. Last edited by vid on 26 May 2011, 19:46; edited 4 times in total |
|||
![]() |
|
ouadji 26 May 2011, 19:11
vid is absolutely right in his comment ... but just a small typo. (it's not to show off, really, but this typo hurts my eyes ![]() if segment selector = 8 then his index in GDT = 1 ![]() |
|||
![]() |
|
vid 26 May 2011, 19:43
yep, I was aware of that, I just simplified things a bit
|
|||
![]() |
|
ouadji 26 May 2011, 20:10
I Knew that! (of course) but I could not help myself ![]() |
|||
![]() |
|
vid 26 May 2011, 20:31
Sure, no problem
|
|||
![]() |
|
ouadji 26 May 2011, 20:39
Quote: can we multitasking in real mode? The multitasking is possible only in protected mode .. this is the first goal of protected mode. |
|||
![]() |
|
LocoDelAssembly 26 May 2011, 21:59
Although not advised because of what it was pointed out above, as long as the programs cooperate with the system integrity (keep memory accesses to their own areas only, don't access hardware directly, and don't access the interrupt vector table nor any other stuff that should be controlled by the OS), multitasking should work (even in preemptive mode).
|
|||
![]() |
|
ouadji 26 May 2011, 22:23
with these conditions multitasking is possible With DOS ![]() |
|||
![]() |
|
Dex4u 26 May 2011, 22:52
This is a demo of multi-tasking in realmode, that needs no OS, as it fits into boot sector of floppy.
It won the first 512byte compo, that we ran on the fasm forum. Code: ; ; ============== ; Nano OS v2.1 copyright by Viktor Peter Kovacs (KVP) ; ============== for the fasm 512 byte os contest of 2004 ; ; This is a demo os, written to show some os design ; methods, and to proove that it's possible to put ; a simple multitasking os into 512 bytes... ; ; ---- constants ---- TIMER_IRQN equ (8) ; hw. timer interrupt number IRQ_BIT equ (512) ; 'irq enable' bit in the flags register TS_FREE equ (0) ; task states TS_READY equ (1) TS_SEND equ (2) TS_RECV equ (3) TS_PUTC equ (4) TS_GETC equ (5) E_TIDLIMIT equ (0ffffh) ; error code for task resource limit error TID_NUM equ (8) ; maximal number of tasks allowed TID_STACK equ (512) ; default task stack size ; ---- startup code ---- start0: ; needed for compatibility jmp start1 nop start1: jmp 07c0h:start2 ; code segment alignement start2: cli mov ax, cs mov ds, ax mov es, ax mov ss, ax mov sp, stack_top cld mov di, _bss_start ; zero the bss mov cx, _bss_end-_bss_start xor ax, ax rep stosb push es ; change the irq vector table xor bx, bx mov es, bx mov ax, [es:TIMER_IRQN*4] mov [timer0l], ax mov ax, [es:TIMER_IRQN*4+2] mov [timer0h], ax mov ax, timer_irq mov [es:TIMER_IRQN*4], ax mov ax, cs mov [es:TIMER_IRQN*4+2], ax pop es mov cx, idle_task ; start idle task call sys_exec mov cx, prg1 ; start program 1 (rpc demo - data source) call sys_exec mov cx, prg3 ; start program 3 (hello world) call sys_exec mov ax, (TID_NUM-1)*2 ; setup and enable the scheduler mov [ctid], ax sti idle_task: jmp idle_task ; the idle task ; ---- kernel code ---- timer_irq: push bp ; save task context push di push si push dx push cx push bx push ax mov ax, [irqflg] ; kernel lock check or ax, ax jz timer_irq1 timer_irq0: pop ax ; restore task context pop bx pop cx pop dx pop si pop di pop bp db 0eah ; jmp far to old handler (for compatibility) timer0l dw 00000h timer0h dw 00000h timer_irq1: mov ax, 1 ; lock kernel mov [irqflg], ax mov bx, [ctid] mov ax, [tstate+bx] timer_cmd1: cmp ax, TS_SEND ; ipc message send (blocking ipc) jnz timer_cmd2 mov si, [msgtid+bx] mov ax, [tstate+si] cmp ax, TS_RECV jnz timer_next mov ax, [msgdat+bx] mov [msgdat+si], ax mov [msgtid+si], bx mov ax, TS_READY mov [tstate+si], ax jmp timer_cmd_ok timer_cmd2: cmp ax, TS_PUTC ; terminal write jnz timer_cmd3 mov ax, [msgdat+bx] call bios_putc jmp timer_cmd_ok timer_cmd3: cmp ax, TS_GETC ; terminal read jnz timer_next call bios_getc mov [msgdat+bx], ax or ax, ax jz timer_next timer_cmd_ok: ; resume task mov ax, TS_READY mov [tstate+bx], ax timer_next: ;; prints task states (see:TS_* constants; red=current task) ;; (used for testing, removed to save code space) ; push es ; mov ax, 0b800h ; mov es, ax ; xor di, di ; mov si, tstate ;debug_print: ; lodsw ; mov ah, 15 ; add al, '0' ; stosw ; cmp si, tstate+TID_NUM*2 ; jnz debug_print ; mov di, [ctid] ; inc di ; mov al, 12 ; stosb ; pop es timer_next0: mov bx, [ctid] ; hard realtime round robin scheduler mov [tstack+bx], sp timer_next1: add bx, 2 and bx, (TID_NUM-1)*2 mov [ctid], bx mov ax, [tstate+bx] cmp ax, TS_FREE jz timer_next1 mov sp, [tstack+bx] xor ax, ax ; unlock kernel mov [irqflg], ax jmp timer_irq0 ; ; <- ; ax : char ; bios_putc: ; device i/o function (called internally) push bp push bx mov ah, 00eh mov bx, 00007h int 010h cmp al, 13 jnz bios_putc1 mov al, 10 int 010h bios_putc1: pop bx pop bp ret ; ; -> ; ax : char (0=no char) ; bios_getc: ; device i/o function (called internally) mov ax, 00100h int 016h jnz bios_getc1 xor ax, ax ret bios_getc1: mov ax, 00000h int 016h xor ah, ah ret ; ---- standard library ---- ; ; EXEC: Starts a new task ; ; <- ; cx : code offset ; (ax, si) ; -> ; bx : new tid (E_TIDLIMIT=out of task slots) ; sys_exec: pushf ; task table resource lock cli xor bx, bx sys_exec1: mov ax, [tstate+bx] ; looks for a free task slot cmp ax, TS_FREE jz sys_exec2 add bx, 2 cmp bx, TID_NUM*2 jnz sys_exec1 mov bx, E_TIDLIMIT ; return error code popf ret sys_exec2: mov dx, bx mov dh, dl xor dl, dl mov si, tstacks+TID_STACK-10*2 ; allocate task stack add si, dx mov [tstack+bx], si mov [si+7*2], cx ; set task startup context (cs:ip,flg) mov ax, cs mov [si+8*2], ax pushf pop ax or ax, IRQ_BIT mov [si+9*2], ax mov ax, TS_READY mov [tstate+bx], ax ; activate new task shr bx, 1 popf ; release task table lock ret ; ; EXIT: Exits a task ; sys_exit: mov bx, [ctid] mov ax, TS_FREE mov [tstate+bx], ax jmp $ ; ; SEND: Sends an ipc message ; ; <- ; ax : msg ; bx : dst ; (cx, bp) ; sys_send: shl bx, 1 mov cx, TS_SEND sys_send0: mov bp, [ctid] mov [msgdat+bp], ax mov [msgtid+bp], bx mov [tstate+bp], cx sys_send1: mov ax, [tstate+bp] cmp ax, TS_READY jnz sys_send1 ret ; ; RECV: Receives an ipc message ; ; -> ; ax : msg ; bx : dst ; (cx, bp) ; sys_recv: mov cx, TS_RECV sys_recv0: mov bp, [ctid] mov [tstate+bp], cx sys_recv1: mov ax, [tstate+bp] cmp ax, TS_READY jnz sys_recv1 mov ax, [msgdat+bp] mov bx, [msgtid+bp] shr bx, 1 ret ; ; PUTC: Outputs a character to the console ; ; <- ; ax : chr ; (bx, cx, bp) ; sys_putc: mov cx, TS_PUTC jmp sys_send0 ; ; GETC: Inputs a character from the console ; ; (bx, cx, bp) ; -> ; ax : chr (0=no char) ; sys_getc: mov cx, TS_GETC jmp sys_recv0 ; ---- application code ---- ;; prg1 v1.0 ;prg1: ; call sys_getc ; or ax, ax ; jz prg1 ; cmp al, 'H' ; je prg1_1 ; call sys_putc ; jmp prg1 ;prg1_1: ; mov cx, prg2 ; call sys_exec ; jmp prg1 ; ; prg1 v2.0 ; -on startup, starts a listerner task ; -gets a character from the console and sends it via ipc ; -on the 'H' key, starts a new 'hello world' process ; prg1: mov cx, prg2 call sys_exec mov di, bx prg1_0: call sys_getc or ax, ax jz prg1_0 cmp al, 'H' je prg1_1 mov bx, di call sys_send jmp prg1_0 prg1_1: mov cx, prg3 call sys_exec jmp prg1_0 ; ; prg2 v1.0 ; -waits for incoming messages via ipc ; -prints the message content on the console ; prg2: call sys_recv call sys_putc jmp prg2 ; ; hello world v1.1 ; -prints the text 'Hello World!' on the console ; -exits on completition ; prg3: mov si, prg3_str_hello prg3_1: lodsb or al, al jz prg3_3 call sys_putc jmp prg3_1 prg3_3: call sys_exit prg3_str_hello db 'Hello World!',13,0 ; ---- boot flags ---- rb 510-$ dw 0aa55h ; ---- boot stack ---- rb 512 stack_top: _bss_start: ; uninitialized data area (cleared to 0 on start) ; ---- kernel data ---- irqflg rw 1 ; kernel lock ctid rw 1 ; current task tstate rw TID_NUM ; task states tstack rw TID_NUM ; task stack pointers msgtid rw TID_NUM ; message destination task ids msgdat rw TID_NUM ; message data ; ---- application data ---- ; ---- task stacks ---- rb (512*4)-$ tstacks: rb (TID_STACK*TID_NUM) _bss_end: |
|||
![]() |
|
LocoDelAssembly 26 May 2011, 23:04
Yep, and in fact TSRs provide some sort of multitasking (I think that even there were some MOD players capable of playing music in the background)
Also, I couldn't find reliable sources actually, but didn't Windows 1.0 and 2.0 work under 8086? |
|||
![]() |
|
ouadji 26 May 2011, 23:18
nice piece of code Dex4u ! |
|||
![]() |
|
Dex4u 26 May 2011, 23:44
ouadji wrote:
You can get most of the entry's here: http://board.flatassembler.net/topic.php?p=98270#98270 |
|||
![]() |
|
christiandy 27 May 2011, 04:43
vid wrote: In Pmode, your segment registers hold "selector" instead of segment_base/16. "selector" is index to "descriptor table". "Descriptor table" (global or local, GDT or LDT) is table of "Descriptors" located somewhere in memory. "Descriptor" is a structure that describes a segment. One of fields in descriptor is "segment base address". Thanks all for replying. Can you give me an example like how to access memory 1fffffff ? |
|||
![]() |
|
neville 27 May 2011, 09:20
christiandy wrote: Can you give me an example like how to access memory 1fffffff ? Code: push 0 pop ds mov al,[1fffffffh] Its that easy if you set up unreal mode or flat real mode first. You don't need pmode. _________________ FAMOS - the first memory operating system |
|||
![]() |
|
vid 27 May 2011, 09:48
Quote: Its that easy if you set up unreal mode or flat real mode first. You don't need pmode. Or doing things "the right way", you need to create descriptor with base address 0, load selector of that descriptor to DS, and then use "ds:1fffffffh". As for format of descriptor structure, you really should read CPU manuals, it's bit too messy to explain here quickly. |
|||
![]() |
|
Mike Gonta 27 May 2011, 09:56
neville wrote:
Code: mov al,[1fffffffh] Last edited by Mike Gonta on 11 Feb 2012, 14:10; edited 1 time in total |
|||
![]() |
|
vid 27 May 2011, 10:34
guys, question was about accessing RAM in protected mode, not about accessing RAM in whatever esoteric mode you find easiest to use.
|
|||
![]() |
|
Mike Gonta 27 May 2011, 18:18
vid wrote: guys, question was about accessing RAM in protected mode, not about accessing RAM in whatever esoteric mode you find easiest to use. You'll notice that in real mode the questions are not about real mode. It's there, you just use it. You don't have to mess with the A20, remap the PIC, build an IDT and stuff a bunch of registers. All of which is necessary but not OS. The BIOS takes care of it. You'll notice that in protected mode the questions are about protected mode. It's not there, you can't just use it. You have to mess with the A20, remap the PIC, build an IDT and stuff a bunch of registers. All of which is necessary but not OS. |
|||
![]() |
|
Dex4u 27 May 2011, 18:27
Basic boot to pmode
Code: ;************************************ ; By Dex ; Assemble with fasm ; c:\fasm pmode.asm pmode.bin ; org 0x7C00 use16 ;**************************** ; Realmode startup code. ;**************************** start: xor ax,ax mov ds,ax mov es,ax mov ss,ax mov sp,0x7C00 ;**************************** ; A20 ;**************************** cli mov al,255 out 0xa1,al out 0x21,al l.5: in al,0x64 test al,2 jnz l.5 mov al,0xD1 out 0x64,al l.6: in al,0x64 test al,2 jnz l.6 mov al,0xDF out 0x60,al mov cx,14h l.7: out 0edh,ax loop l.7 ;***************************** ; Small delay. ;***************************** mov ecx,0xffff A20_delay: nop nop loop A20_delay ;***************************** ; Setting up, to enter pmode. ;***************************** lgdt [gdtr] mov eax, cr0 or al,0x1 mov cr0,eax jmp 0x10: protected ;***************************** ; Pmode. Last edited by Dex4u on 29 May 2011, 00:00; edited 6 times in total |
|||
![]() |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.