flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > Need help with unreal mode code |
Author |
|
DJ Mauretto 31 Jul 2008, 18:10
Hello
Code: in al, 0x92 ;Enable A20 or al, 0x02 out 0x92, al Note that fast A20 it's not a default setting on pc ,usually you must set it through the chipset , try to enable A20 through keyboard ports. Reset PC = 99% of the times Wrong Address _________________ Nil Volentibus Arduum |
|||
31 Jul 2008, 18:10 |
|
NEOAethyr 31 Jul 2008, 19:34
Code: Enable_A20_Slow: in al, 0x64 ;Keyboard Controller Status or al, 0x03 ;Enable The A20, Ensure The CPU Is Not Reset mov bl, al out 0xEB, al ;newiodelay mov al, 0xD1 ;Keyboard Controller Command Write ? out 0x64, al out 0xEB, al ;newiodelay mov al, bl out 0x60, al ret Enable_A20_Fast: in al, 0x92 and al, 0xFE ;Clear The CPU Reset Bit or al, 0x02 ;Set The A20 Bit out 0xEB, al ;newiodelay out 0x92, al ret Those look allright? I'm assuming I should call these sometime after I actually call the unreal mode function and safely ret from it. I don't normally use delays, but I figuered why not I guess. That newiodelay is a macro used in award bios'es. They used to do something else but I've can't remember what it was. I am using an ami bios for testing at the moment though..., so I dn if I should be doing that... I didn't add support for checking to see if the A20 was infact allready enabled or failed to change. If I'm testing, or if I'm on some specific platform or something, I could get stuck in conditional jmp loop thing if it never changes. I'll make myself some disable functions in a little bit. Btw, I found that the hardlock with calling the unreal mode function after bootsector was just my error. I was including the asm file in my bootsector, I was testing after the bootsector...(I had it working in the bootsector allready) After moving the include to the main src file away from the bootsector it fixed that. Now it reset the pc every time I run it lol, like it allways does... I think I need to work with the stack segment and pointer too, but I have to take care with those. I really need to restore them exactly to where they were before so if I'm running in rom, I can exit back to the bios where it can do the dmi pooling(not nessary...) and IPL loader(kinda nessary lol..., I still want it). Update: Here's the rest of the A20 stuff and a macro for the delay. (Edit: had to do some fixups with this code, found some info and had to look up other info to make sure I was doign it right, I think it's good now, a20 wise) (I'll have to make myself a Function called Enable A20, one that scans for the availibility of the fast A20 and stuff like that maybe, I dn yet) Code: macro New_IO_Delay { out 0xEB, al ;Award BIOS newiodelay } Enable_A20_Slow: mov al, 0xD0 ;Read Controller Status out 0x64, al New_IO_Delay in al, 0x60 ;Controller Status or al, 0x03 ;Enable The A20, Ensure The CPU Is Not Reset mov bl, al New_IO_Delay mov al, 0xD1 ;Write Controller Status out 0x64, al New_IO_Delay mov al, bl out 0x60, al ret Disable_A20_Slow: mov al, 0xD0 ;Read Controller Status out 0x64, al New_IO_Delay in al, 0x60 ;Controller Status or al, 0x01 ;Ensure The CPU Is Not Reset and al, 0xFD ;Clear The A20 Bit mov bl, al New_IO_Delay mov al, 0xD1 ;Write Controller Status out 0x64, al New_IO_Delay mov al, bl out 0x60, al ret Enable_A20_Fast: in al, 0x92 and al, 0xFE ;Clear The CPU Reset Bit or al, 0x02 ;Set The A20 Bit New_IO_Delay out 0x92, al ret Disable_A20_Fast: in al, 0x92 and al, 0xFC ;Clear The CPU Reset Bit And A20 Bit New_IO_Delay out 0x92, al ret |
|||
31 Jul 2008, 19:34 |
|
DJ Mauretto 01 Aug 2008, 09:03
Hi
I don't have time to look at your source, there are many example in this section about A20 , try to debug your code printing to the screen some numbers every statment to search your bug , or insert wait to understand where your code is buggy. _________________ Nil Volentibus Arduum |
|||
01 Aug 2008, 09:03 |
|
NEOAethyr 01 Aug 2008, 14:39
I put together a stand alone program to test the mode switch functionality.
It may look long, maybe messy, and lame. I thaught there was no reason to post src that compiles into diff outputs types. I'll step through it real quick. I called it unreal.asm, so I'll be using that as an example. Cmd prompt commands: fasm unreal.asm unreal.ima I'm running it with virtual pc because I can duplicate the same probs that I have both in rom and in real dos. "Boot Sector Entry Point" This is the org of the floppy and where the pragram 1st starts. It then jumps to the bootsector init. "BS_Init:" Boot Sector Init The bootsector init 1st copies 64k-512b of drive0(floppy) to segment 0x1000, and offset 0x0100 (like a com file, to sim a com file from dos, it works for some programs too, I've tested a little before...). That code maybe a hassle to read through if you're not looking to obtain it . The disk reading code I mean. Just know that it indeed works well enough for a floppy. And if I did the job right (not totally optimized probably though), then it should work completely with ECHS limits(Allmost 8gigs), just with a 64k transfer limit because it's baised on a bios irq. I know for a fact it's workign quite well on the floppy because I've used it to transfer over 900k from the floppy into memory with 100% accuracy (a 24bit bmp). It uses a 32bit lba offset scheme, however like I said before it's limited to ECHS limits if the bios in ? that supplies the irq has support for ECHS... Otherwise it would be limited to 500m or something, like back in the old days with some 486's. And it is somewhat reliable. So you can ignore it, I just include it so I have a full example and demo of the probs at hand. call BS_Unreal_Mode mov eax, 0x000B8000 ; note 32 bit offset mov word [fs:eax], 0x0F01 ; attrib/char of smiley Here is has the option to test the unreal mode code from the bootsector. This works. ;BS_Init_Loop: ;mov cx, 0xFFFF ;loop BS_Init_Loop An inf to test for probs related to the bootsector, it "could" be reloacted to a diff spot in the bootsaector if needed... push word 0x1000 ;Segment push word 0x0100 ;Offset retf ;pop cs:ip It's commented I think , it effectivally jumps to the code that was loaded from the disk a bit ago. So now in this example, we'll be relocating cs to 0x1000, and ip to 0x0100. That's the position of "Entry Point" times (65536-($-$$)) db 0x00 org 0x0100 jmp Init Some hack work, a new org, and the jump to init. Making it act as if it were loaded from a command prompt. I'm positioning the main code 64k from the start of the floppy image. I just felt like doing it this way when I original wrote it, I'm still fine with it. "Init:" The main program init. call Unreal_Mode <-- This fails mov al, "1" mov ah, 0x0E dw 0x10CD This never happens if unreal mode was called from the main program section. It does work if it was called not though. mov eax, 0x000B8004 ; note 32 bit offset mov word [fs:eax], 0x0F01 ; attrib/char of smiley mov al, "2" mov ah, 0x0E dw 0x10CD mov eax, 0x000B8008 ; note 32 bit offset mov word [fs:eax], 0x0F01 ; attrib/char of smiley Init_Loop_2: mov cx, 0xFFFF loop Init_Loop_2 More test code, and an inf loop to see the final results. All of that test code works if I called unreal from just the bootsector. It never runs if I call unreal from the main program. Does'nt matter if I call it from both the bootsector and the main program, it still won't get past the 2nd call of unreal mode from within the main program segment. Under the main program functions, ther is a function called "Unreal_Mode:". In there you'll see this: Init_Loop: ;Dies after this... mov cx, 0xFFFF loop Init_Loop Just as the comment says. mov ax, 0x0010 ;Load Descriptor ;mov ds, ax ;Automaticly happens anyways ;mov es, ax mov fs, ax ;mov gs, ax ;mov ss, ax This kills my main program code if I call it from there. But the very same code byte for byte under BS_Unreal_Mode in the boot sector works^^. Now unreal called from the bootsector does work. And it's still working after I've switched code segments(changed my program running location). Both the int13 disk access and the simple bios print char irq access are not screwing with the code and resetting the limits, or causing me any probs. But I can't say for sure I won't run across anything that would, I know I actually have too, just have'nt spent the time to figuer what it was (No example in this code)... So if I played it safe from a bootsector, I could probably get by. Watching and paying close attention after every new function I put into the program I could get by if... Well, that's the thing, I can't be stuck with just a bootsector function. If it causes dos probs, I don't really care as much. But it messes up while in rom(real rom), causing me resets just like dos... And this example I'm posting, it resets just the same if I call it as if I wasn't a bootsector. I sometimes need working examples in order to figuer things out. However in the case of switching to protected mode and back, I haven't found one that's done the trick well enough to beable to be called anywhere from within a real mode env. I'm not to worried about access rights and limits, I want all access (as much as protected limits provide memory access wise), and full rights. I'm sure I won't have to worry much if I reset the limits once before booting anything, if anything I could learn and how redo the limits. But I don't think I'll have a prob, I can boot nt if I've allready setup unreal mode. I probably can't setup memtest or stuff that checks for it, I dn, still. Like i said, I could allways redo the limits before pop'ing the stack back into the code that called my program, bios(bootsector and rom), dos, etc. Oh btw,. the footer algo is off because of the main entry ptr section org. And also note that I don't have to do a thign with the A20 gate with virtual pc, so I can't say for sure anything about the current a20 functions. I don't need them in the example, if virtual pc is used (microsoft emu, it's allright..., never tried bochs). ... Offtopic like. Ther code that's in the macro New_IO_Delay. I dn, like i meantioned in an above post, if it's safe or not for all bios types. I only know award is safe. Anyways, if one where to use that macro now that I think about it, and have enough functions that used it. One could comment out the code in the macro or replace it with nop's depending on the situation (static offsets or compiled offsets). It's kinda useful as a macro now that I think about it if you tend to work with the instruction alot... Onestly I don't think you need i/o delays these days... I've never had any probs removing delays and having it still work fine(well I have ran across some, but they were fixable by aligning output a little when I'm doing large transfers). And yes I allways write my irq's out that way in plain word hex format... It's that same for me as if I were to put 0x in front of a hex # instead of using h at the end of it. It's just comment practice to me, even if it may seem odd :\, it's just something I do. Here's the code I put together as an example: Code: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Unreal ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Macros ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; macro New_IO_Delay { out 0xEB, al ;Award BIOS newiodelay } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Boot Sector Entry Point ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 0x7C00 ;Floppy jmp BS_Init ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Boot Sector Defines ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; align 8 ;Pseudo Descriptor Alignment times 6 db 0x90 BS_GDT_PD: dw ((BS_GDT_End - BS_GDT) - 1) ;GDT Table Limit In Bytes (8 Bytes * # Of Descriptors - 1 Byte) dd BS_GDT ;GDT Base Address align 8 ;GDT Alignment BS_GDT: BS_GDT_Descriptor_NULL: ;NULL Descriptor dd 0x00000000 dd 0x00000000 BS_GDT_Descriptor_Data_20: ;20 Bit Descriptor db 0xFF, 0xFF ;Segment Limit Bits 00-15 db 0x00, 0x00, 0x00 ;Segment Base Address Bits 00-23 db 10010010b ;Segment Type, Descriptor Type, Descriptor Privilege Level, Segment Present db 00001111b ;Segment Limit Bits 16-19, Scratch, Reserved, Segment Size, Granularity db 0x00 ;Segment Base Address Bits 24-31 BS_GDT_Descriptor_Data_32: ;32 Bit Descriptor db 0xFF, 0xFF ;Segment Limit Bits 00-15 db 0x00, 0x00, 0x00 ;Segment Base Address Bits 00-23 db 10010010b ;Segment Type, Descriptor Type, Descriptor Privilege Level, Segment Present db 11001111b ;Segment Limit Bits 16-19, Scratch, Reserved, Segment Size, Granularity db 0x00 ;Segment Base Address Bits 24-31 BS_GDT_End: BS_Disk_Offset dd 0x00000000 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Boot Sector Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BS_Get_Entry_Point: ;Out: AX = Entry Point Offset (ORG) call $+0x0003 ;push ip pop ax ;mov ax, ip sub ax, $-0x0001 ret BS_Ret_Function: ret BS_Delay: dec ecx cmp ecx, 0x00000000 je BS_Ret_Function jmp BS_Delay BS_Read_Disk: ;IN: BS_Disk_Offset = LBA Offset(Min = 1), CL = Tranfer Size - Limited To 64k(0x80), DL = Drive, ES:BX = Buffer push cx ;Transfer Size call BS_Read_Disk_Sector cmp cl, 0x01 je BS_Read_Disk_Error pop cx ;Transfer Size call BS_Get_Entry_Point mov si, BS_Disk_Offset add di, ax inc dword [cs:di] ;LBA Offset add bx, 0x0200 ;Buffer Offset dec cl cmp cl, 0x00 je BS_Ret_Function jmp BS_Read_Disk BS_Read_Disk_Error: jmp BS_Exit ;Temp Code ret BS_Read_Disk_Sector: call BS_Get_Entry_Point mov si, BS_Disk_Offset add si, ax mov eax, [cs:si] call BS_LBA2CHS ;Convert LBA to CHS mov ah, 0x02 ;Function: Read Sectors mov al, 0x01 ;# Of Sectors To Read push bx dw 0x13CD jc BS_Read_Disk_Sector_Error mov cl, 0x00 ;No Error pop bx ;Buffer Offset ret BS_Read_Disk_Sector_Error: mov cl, 0x01 ;Error pop bx ;Buffer Offset ret BS_LBA2CHS: ;IN: EAX = 32bit LBA Offset (2tb limit, far beyond the 8gig limit of ECHS, but limited by ECHS...) push bx ;Buffer Offset push dx ;Drive push eax shr eax, 0x00000010 mov dx, ax pop eax mov bx, 0x0012 ;Sectors Per Track div bx mov cl, dl inc cl ;Sector push eax shr eax, 0x00000010 mov dx, ax pop eax mov bx, 0x0002 ;Heads Per Cylinder div bx mov ch, al ;Cylinder and ah, 0xFC shl ah, 0x06 or cl, ah mov dh, dl ;Head pop bx mov dl, bl ;Drive pop bx ;Buffer Offset ret BS_Unreal_Mode: push ds ;push es ;push fs ;push gs ;push ss cli ;Disable Interrupts mov al, 0x80 ;Disable Non-Maskable Interrupts out 0x70, al xor ax, ax mov ds, ax lgdt [BS_GDT_PD] mov eax, cr0 ;Protected Mode or al, 0x01 mov cr0, eax ;push cs ;push $+2 ;retf ;Clear cs and cache mov ax, 0x0010 ;Load Descriptor ;mov ds, ax ;Automaticly happens anyways ;mov es, ax mov fs, ax ;mov gs, ax ;mov ss, ax mov eax, cr0 ;Unreal Mode and al, 0xFE mov cr0, eax ;push cs ;push $+2 ;retf ;Clear cs and cache ;pop ss ;pop gs ;pop fs ;pop es pop ds mov al, 0x00 ;Enable Non-Maskable Interrupts out 0x70, al sti ;Enable Interrupts ret BS_Enable_A20_Slow: mov al, 0xD0 ;Read Controller Status out 0x64, al New_IO_Delay in al, 0x60 ;Controller Status or al, 0x03 ;Enable The A20, Ensure The CPU Is Not Reset mov bl, al New_IO_Delay mov al, 0xD1 ;Write Controller Status out 0x64, al New_IO_Delay mov al, bl out 0x60, al ret BS_Disable_A20_Slow: mov al, 0xD0 ;Read Controller Status out 0x64, al New_IO_Delay in al, 0x60 ;Controller Status or al, 0x01 ;Ensure The CPU Is Not Reset and al, 0xFD ;Clear The A20 Bit mov bl, al New_IO_Delay mov al, 0xD1 ;Write Controller Status out 0x64, al New_IO_Delay mov al, bl out 0x60, al ret BS_Enable_A20_Fast: in al, 0x92 and al, 0xFE ;Clear The CPU Reset Bit or al, 0x02 ;Set The A20 Bit New_IO_Delay out 0x92, al ret BS_Disable_A20_Fast: in al, 0x92 and al, 0xFC ;Clear The CPU Reset Bit And A20 Bit New_IO_Delay out 0x92, al ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Boot Sector Init ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BS_Init: push word 0x1000 ;Buffer Segment pop es mov bx, 0x0100 ;Buffer Offset mov dl, 0x00 ;Drive call BS_Get_Entry_Point mov di, BS_Disk_Offset add di, ax mov dword [cs:di], 0x00000080 mov cl, 0x7F call BS_Read_Disk ;call BS_Unreal_Mode ;call BS_Enable_A20_Fast mov eax, 0x000B8000 ; note 32 bit offset mov word [fs:eax], 0x0F01 ; attrib/char of smiley ;BS_Init_Loop: ;mov cx, 0xFFFF ;loop BS_Init_Loop push word 0x1000 ;Segment push word 0x0100 ;Offset retf ;pop cs:ip ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Boot Sector Exit ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BS_Exit: mov al, "E" mov ah, 0x0E dw 0x10CD mov al, "r" mov ah, 0x0E dw 0x10CD mov al, "r" mov ah, 0x0E dw 0x10CD mov al, "o" mov ah, 0x0E dw 0x10CD mov al, "r" mov ah, 0x0E dw 0x10CD BS_Exit_Loop: jmp BS_Exit_Loop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Boot Sector Footer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; times (510-($-$$)) db 0x00 ;Floppy Boot Sector dw 0xAA55 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Entry Point ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; times (65536-($-$$)) db 0x00 org 0x0100 jmp Init ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Defines ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; align 8 ;Pseudo Descriptor Alignment times 6 db 0x90 GDT_PD: dw ((GDT_End - GDT) - 1) ;GDT Table Limit In Bytes (8 Bytes * # Of Descriptors - 1 Byte) dd GDT ;GDT Base Address align 8 ;GDT Alignment GDT: GDT_Descriptor_NULL: ;NULL Descriptor dd 0x00000000 dd 0x00000000 GDT_Descriptor_Data_20: ;20 Bit Descriptor db 0xFF, 0xFF ;Segment Limit Bits 00-15 db 0x00, 0x00, 0x00 ;Segment Base Address Bits 00-23 db 10010010b ;Segment Type, Descriptor Type, Descriptor Privilege Level, Segment Present db 00001111b ;Segment Limit Bits 16-19, Scratch, Reserved, Segment Size, Granularity db 0x00 ;Segment Base Address Bits 24-31 GDT_Descriptor_Data_32: ;32 Bit Descriptor db 0xFF, 0xFF ;Segment Limit Bits 00-15 db 0x00, 0x00, 0x00 ;Segment Base Address Bits 00-23 db 10010010b ;Segment Type, Descriptor Type, Descriptor Privilege Level, Segment Present db 11001111b ;Segment Limit Bits 16-19, Scratch, Reserved, Segment Size, Granularity db 0x00 ;Segment Base Address Bits 24-31 GDT_End: Disk_Offset dd 0x00000000 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Get_Entry_Point: ;Out: AX = Entry Point Offset (ORG) call $+0x0003 ;push ip pop ax ;mov ax, ip sub ax, $-0x0001 ret Ret_Function: ret Delay: dec ecx cmp ecx, 0x00000000 je BS_Ret_Function jmp BS_Delay Read_Disk: ;IN: BS_Disk_Offset = LBA Offset(Min = 1), CL = Tranfer Size - Limited To 64k(0x80), DL = Drive, ES:BX = Buffer push cx ;Transfer Size call BS_Read_Disk_Sector cmp cl, 0x01 je BS_Read_Disk_Error pop cx ;Transfer Size call BS_Get_Entry_Point mov si, BS_Disk_Offset add di, ax inc dword [cs:di] ;LBA Offset add bx, 0x0200 ;Buffer Offset dec cl cmp cl, 0x00 je BS_Ret_Function jmp BS_Read_Disk Read_Disk_Error: jmp BS_Exit ;Temp Code ret Read_Disk_Sector: call BS_Get_Entry_Point mov si, BS_Disk_Offset add si, ax mov eax, [cs:si] call BS_LBA2CHS ;Convert LBA to CHS mov ah, 0x02 ;Function: Read Sectors mov al, 0x01 ;# Of Sectors To Read push bx dw 0x13CD jc BS_Read_Disk_Sector_Error mov cl, 0x00 ;No Error pop bx ;Buffer Offset ret Read_Disk_Sector_Error: mov cl, 0x01 ;Error pop bx ;Buffer Offset ret LBA2CHS: ;IN: EAX = 32bit LBA Offset (2tb limit, far beyond the 8gig limit of ECHS, but limited by ECHS...) push bx ;Buffer Offset push dx ;Drive push eax shr eax, 0x00000010 mov dx, ax pop eax mov bx, 0x0012 ;Sectors Per Track div bx mov cl, dl inc cl ;Sector push eax shr eax, 0x00000010 mov dx, ax pop eax mov bx, 0x0002 ;Heads Per Cylinder div bx mov ch, al ;Cylinder and ah, 0xFC shl ah, 0x06 or cl, ah mov dh, dl ;Head pop bx mov dl, bl ;Drive pop bx ;Buffer Offset ret Unreal_Mode: push ds ;push es ;push fs ;push gs ;push ss cli ;Disable Interrupts mov al, 0x80 ;Disable Non-Maskable Interrupts out 0x70, al xor ax, ax mov ds, ax lgdt [GDT_PD] mov eax, cr0 ;Protected Mode or al, 0x01 mov cr0, eax ;push cs ;push $+2 ;retf ;Clear cs and cache Init_Loop: ;Dies after this... mov cx, 0xFFFF loop Init_Loop mov ax, 0x0010 ;Load Descriptor ;mov ds, ax ;Automaticly happens anyways ;mov es, ax mov fs, ax ;mov gs, ax ;mov ss, ax mov eax, cr0 ;Unreal Mode and al, 0xFE mov cr0, eax ;push cs ;push $+2 ;retf ;Clear cs and cache ;pop ss ;pop gs ;pop fs ;pop es pop ds mov al, 0x00 ;Enable Non-Maskable Interrupts out 0x70, al sti ;Enable Interrupts ret Enable_A20_Slow: mov al, 0xD0 ;Read Controller Status out 0x64, al New_IO_Delay in al, 0x60 ;Controller Status or al, 0x03 ;Enable The A20, Ensure The CPU Is Not Reset mov bl, al New_IO_Delay mov al, 0xD1 ;Write Controller Status out 0x64, al New_IO_Delay mov al, bl out 0x60, al ret Disable_A20_Slow: mov al, 0xD0 ;Read Controller Status out 0x64, al New_IO_Delay in al, 0x60 ;Controller Status or al, 0x01 ;Ensure The CPU Is Not Reset and al, 0xFD ;Clear The A20 Bit mov bl, al New_IO_Delay mov al, 0xD1 ;Write Controller Status out 0x64, al New_IO_Delay mov al, bl out 0x60, al ret Enable_A20_Fast: in al, 0x92 and al, 0xFE ;Clear The CPU Reset Bit or al, 0x02 ;Set The A20 Bit New_IO_Delay out 0x92, al ret Disable_A20_Fast: in al, 0x92 and al, 0xFC ;Clear The CPU Reset Bit And A20 Bit New_IO_Delay out 0x92, al ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Init ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Init: call Unreal_Mode mov al, "1" mov ah, 0x0E dw 0x10CD mov eax, 0x000B8004 ; note 32 bit offset mov word [fs:eax], 0x0F01 ; attrib/char of smiley mov al, "2" mov ah, 0x0E dw 0x10CD mov eax, 0x000B8008 ; note 32 bit offset mov word [fs:eax], 0x0F01 ; attrib/char of smiley Init_Loop_2: mov cx, 0xFFFF loop Init_Loop_2 jmp Exit ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Exit ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Exit: ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Footer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; times (1409024-($-$$)) db 0x00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|||
01 Aug 2008, 14:39 |
|
NEOAethyr 02 Aug 2008, 17:21
Double post, sorry.
Just an update... I've been testing my main program code with this more. In virtual pc, as a floppy. I was checking it a little under unreal mode. I figuered out linear frame buffer access, simple as adding a 0x4xxx the mode #. I have'nt figuered out how to get the address automatically, I thaught it would of been ModeInfoBlock_PhysBasePtr. mov ebx, 0xF7FFFF00 ;Sis LFB Offset That's what I got, and I was able to fill the screen with this . Which is a start. I can't go straight lfb, I want to beable to compile a com file, and use it in windows, unless I could use lfb in windows... Anyways I'll have some fun redo'ing a ton of code for linear fb, and then making sure that banking can still run. It's gotta be in a flashable state where I can really test it (if I re-wrote the whole thing I'de run it as a network rom so I could toggle it on or off with the cmos/bios menu just to be safe, incase it didn't work). But for sure, I can boot windows right out of my debug rom floppy. It boots automatically if the program exe's and then ret's from it's boot loader / ipl. A soft reset essentually. And windows boots with unreal mode pre-setup no ?'s asked. Not that windows will probably reset all of that, still, my point is that windows can't tell the diff between unreal and real. I still can't run unreal mode after the boot sector, but I can still get access to the full amount of mem if I setup it up before it. I do not know the entry point of the floppy's boot sector. My program's, or demo's is entry ptr of whatever I choose, right now 0x00010000 I think. My program's rom entry point is usually 0x000D4000 (depends on other rom modules too). Again my floppy's boot sector ptr, ??? I could find out though. @DJ Mauretto, I think it's related to some address too now. Stack maybe, irq's, ... What else? My main program works fine, I know inside and out pretty much. My demo should be fine too, floppy disk access wise (would need and update to access hardrives) and etc. My irq's are running fine after I run it from the bootsector. So is my stack. So maybe something related to the offset of with the unreal mode function... Like the lgdtr instruction? I thaught about that a long time ago. And I tried to pass along the entry point inside my unreal mode set function. Where I could add my entrypoint value of the gdt table offset, and pass that along as a register with the [] brackets like I usually do. The compiler gives me an error. I figuered the instruction was a type of one that was relative to the offset of the instruction it's self and not the actual define or lable. But maybe..., I just thaught of something, all instrunctions of that type are bound to a max of one byte of distance to the lable, 8bit offset, 255 max offset. I don't know if that instruction is able to read lables from a longer distance or not. I mean if it's an instruction that's effected by org, then I've got a prob right there... Then maybe I could get it to work in rom, but I dn about dos... Because I've tried before as a standerd com file and just the unreal mode+ test, with no special org detecting code. I dn why I put the get entry point function into the example though but that's what I'm using to figuer out where I am while in program. Example: call Get_Entry_Point mov bx, Some_Memoy_Value_In_CS add bx, ax ;this right here fixes the offset of the memory value to the correct one mov ebx, [cs:bx] ;this right here is the 32bit value of "Some_Memory_Value_In_CS" That's how I've been getting around in shadow ram. Instead of copying the contents to a diff location of ram starting a preset org. I'm fine with using it at the moment because I can stay at that location and still be there after windows 2003 has run(starting in rom). It has come in handy, even though it makes my program bloat. I've learn to deal with it and from time to time, optimize and reduces the programs code size. So when I pass along a value form memory, or even pass along an offset. I must beable to change that value before it's passed to an irq, or etc. I'm gonna try some stuff... lgdt [cs:bx] [bx], compiles, oh crap, I must of never tried with [bx]... oops. I'll try it a little later on today and see if that fixes the code . That's probably a prob lol... Edit: 08/03/08 Throughout yesterday I messed around a little and found that I could run unreal mode after the bootsector. But the results are strange. My code is'nt on this system, I swapped over all of the networking to a 2nd machine last night too... Anyways, I shortend the unrealmode function. With the same gdt as the above previous examples, I load descriptor fs with 0x0010(table 2). Then on the one after the boot sector, I MUST load it with 0x0000. Ex: xor ax, ax mov fs, ax It runs though. And with the 0'ed one(one after bootsector), I can't blindly find 0xB8000 addy. But both match offsets at the vesa lfb, of 0xF8000000 (was a wierd addy before...) (now it's exactly as windows says it is in the device manager). Also, the mode info ptr for the lfb addy is partially working. I know all of my vesa and defines for it work. So getting the value from the info blocks are np. It's really odd. I use the mode info blocks ptr for lfb, and I'm allowed to copy to the 1st bank of the screen, but nothing else. But why in the heck am I getting the banked addy.... I dn if it's the same as the real one or not. I'll have to figuer it out. What I'm concerned about is that fact that offset 0x000B8000 is'nt working the way it should after I switch cpu modes after I've exited the boot block. In a little bit I'm gonna get back on my other machine and check it out. I'm gonna see if a com file will restart dos, or if it will behave now, with a vesa lfb inf loop. I'll try in real dos too, and then make sure my main code is ok enough for rom, and make a menu entry for a demo of it, again, unreal mode then a vesa fill screen using lfb inf loop. That lgdt [cs:bx], and a diff desc selector on the 2nd switch is what I did to get it working. I don't think it's 100% right though, but I'm gonna try to figuer it out. I mean, if it's not reseting at all anymore, then I can use it to dump address info to the screen, then I can figuer some stuff out maybe... |
|||
02 Aug 2008, 17:21 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.