NewOS revisited, applied patch 1916: now evaluates the extended BIOS
RAM size call. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6984 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -25,11 +25,12 @@
|
|||||||
; ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
; ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
; /*
|
; /*
|
||||||
; ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
; ** Copyright 2004, The OpenBeOS Team. All rights reserved.
|
||||||
|
; ** Distributed under the terms of the OpenBeOS License.
|
||||||
|
; **
|
||||||
|
; ** Copyright 2001-2004, Travis Geiselbrecht. All rights reserved.
|
||||||
; ** Distributed under the terms of the NewOS License.
|
; ** Distributed under the terms of the NewOS License.
|
||||||
; */
|
; **
|
||||||
|
|
||||||
; /*
|
|
||||||
; ** Reviewed, documented and some minor modifications and bug-fixes
|
; ** Reviewed, documented and some minor modifications and bug-fixes
|
||||||
; ** applied by Michael Noisternig on 2001-09-02.
|
; ** applied by Michael Noisternig on 2001-09-02.
|
||||||
; */
|
; */
|
||||||
@@ -89,15 +90,17 @@ unreal:
|
|||||||
sti
|
sti
|
||||||
mov si,loadmsg
|
mov si,loadmsg
|
||||||
call print
|
call print
|
||||||
dec cx ; TK: one sector is already read as second part of boot block
|
|
||||||
call load_floppy ; read remaining sectors at address edi
|
call load_floppy ; read remaining sectors at address edi
|
||||||
call disable_floppy_motor
|
call disable_floppy_motor
|
||||||
mov si,okmsg
|
mov si,okmsg
|
||||||
call print
|
call print
|
||||||
cli
|
cli
|
||||||
|
|
||||||
|
; uncomment the next two lines to enable the VESA mode switch
|
||||||
; call enable_vesa
|
; call enable_vesa
|
||||||
mov [in_vesa],al
|
; mov [in_vesa],al
|
||||||
|
|
||||||
|
call find_mem_size_real
|
||||||
|
|
||||||
mov ebx,[dword 0x100074] ; load dword at rel. address 0x74 from read-destination-buffer
|
mov ebx,[dword 0x100074] ; load dword at rel. address 0x74 from read-destination-buffer
|
||||||
add ebx,0x101000 ; for stage2 entry
|
add ebx,0x101000 ; for stage2 entry
|
||||||
@@ -111,7 +114,7 @@ unreal:
|
|||||||
jmp dword 0x8:code32 ; flush prefetch queue
|
jmp dword 0x8:code32 ; flush prefetch queue
|
||||||
code32:
|
code32:
|
||||||
BITS 32
|
BITS 32
|
||||||
mov ax,0x10 ; load descriptor 2 in all segment selectors (except cs)
|
mov ax,0x10 ; load descriptor 2 in all segment selectors (except cs)
|
||||||
mov ds,ax
|
mov ds,ax
|
||||||
mov es,ax
|
mov es,ax
|
||||||
mov fs,ax
|
mov fs,ax
|
||||||
@@ -120,38 +123,39 @@ BITS 32
|
|||||||
mov ebp,0x10000
|
mov ebp,0x10000
|
||||||
mov esp,ebp
|
mov esp,ebp
|
||||||
|
|
||||||
mov eax,[vesa_info]
|
mov eax,[vesa_info] ; set up arguments for _start()
|
||||||
push eax
|
push eax
|
||||||
|
|
||||||
xor eax,eax
|
xor eax,eax
|
||||||
mov al,[in_vesa]
|
mov al,[in_vesa]
|
||||||
push eax
|
push eax
|
||||||
|
|
||||||
call find_mem_size
|
xor eax,eax
|
||||||
|
mov al,[ext_mem_count]
|
||||||
push eax
|
push eax
|
||||||
|
|
||||||
call ebx ; jump to stage2 entry
|
cmp al, 0x0
|
||||||
inf:jmp short inf
|
je probe_mem
|
||||||
|
|
||||||
; find memory size by testing
|
mov eax,[ext_mem_info]
|
||||||
; OUT: eax = memory size
|
push eax
|
||||||
find_mem_size:
|
|
||||||
mov eax,0x31323738 ; test value
|
xor eax,eax ; argument mem_size is loaded
|
||||||
mov esi,0x100ff0 ; start above conventional mem + HMA = 1 MB + 1024 Byte
|
push eax ; with zero
|
||||||
_fms_loop:
|
|
||||||
mov edx,[esi] ; read value
|
jmp call_stage2
|
||||||
mov [esi],eax ; write test value
|
|
||||||
mov ecx,[esi] ; read it again
|
probe_mem:
|
||||||
mov [esi],edx ; write back old value
|
xor eax,eax ; argument ext_mem_info is
|
||||||
cmp ecx,eax
|
push eax ; loaded with zero
|
||||||
jnz _fms_loop_out ; read value != test value -> above mem limit
|
|
||||||
add esi,0x1000 ; test next page (4 K)
|
call find_mem_size_probe
|
||||||
jmp short _fms_loop
|
push eax
|
||||||
_fms_loop_out:
|
; falls through
|
||||||
mov eax,esi
|
|
||||||
sub eax,0x1000
|
call_stage2:
|
||||||
add eax,byte +0x10
|
call ebx ; jump to stage2 entry
|
||||||
ret
|
inf:jmp short inf
|
||||||
|
|
||||||
BITS 16
|
BITS 16
|
||||||
; read sectors into memory
|
; read sectors into memory
|
||||||
@@ -276,13 +280,64 @@ gdt:
|
|||||||
|
|
||||||
retrycnt db 3
|
retrycnt db 3
|
||||||
in_vesa db 0
|
in_vesa db 0
|
||||||
vesa_info dw 0
|
vesa_info dd 0
|
||||||
|
ext_mem_info dd 0
|
||||||
|
ext_mem_count db 0
|
||||||
|
|
||||||
times 510-($-$$) db 0 ; filler for boot sector
|
times 510-($-$$) db 0 ; filler for boot sector
|
||||||
dw 0xaa55 ; magic number for boot sector
|
dw 0xaa55 ; magic number for boot sector
|
||||||
|
|
||||||
; Starting here is the second sector of the boot code
|
; Starting here is the second sector of the boot code
|
||||||
|
|
||||||
|
BITS 32
|
||||||
|
; find memory size by testing
|
||||||
|
; OUT: eax = memory size
|
||||||
|
find_mem_size_probe:
|
||||||
|
mov eax,0x31323738 ; test value
|
||||||
|
mov esi,0x100ff0 ; start above conventional mem + HMA = 1 MB + 1024 Byte
|
||||||
|
_fms_loop:
|
||||||
|
mov edx,[esi] ; read value
|
||||||
|
mov [esi],eax ; write test value
|
||||||
|
mov ecx,[esi] ; read it again
|
||||||
|
mov [esi],edx ; write back old value
|
||||||
|
cmp ecx,eax
|
||||||
|
jnz _fms_loop_out ; read value != test value -> above mem limit
|
||||||
|
add esi,0x1000 ; test next page (4 K)
|
||||||
|
jmp short _fms_loop
|
||||||
|
_fms_loop_out:
|
||||||
|
mov eax,esi
|
||||||
|
sub eax,0x1000
|
||||||
|
add eax,byte +0x10
|
||||||
|
ret
|
||||||
|
|
||||||
|
BITS 16
|
||||||
|
find_mem_size_real:
|
||||||
|
; use int 0x15, EAX=0xe820 to test for memory
|
||||||
|
; assumes es is null
|
||||||
|
|
||||||
|
mov ebx,0
|
||||||
|
mov edi,0x7000 ; the extended memory structures will go at 0x7000
|
||||||
|
mov [ext_mem_info],edi
|
||||||
|
|
||||||
|
find_mem_next:
|
||||||
|
mov eax,0xe820
|
||||||
|
mov edx,'PAMS' ; 'SMAP' in the correct order
|
||||||
|
mov ecx,0x20
|
||||||
|
|
||||||
|
int 0x15
|
||||||
|
jc done_mem_real ; if carry is set, it wasn't supported
|
||||||
|
|
||||||
|
inc byte [ext_mem_count] ; increment the count of the number
|
||||||
|
|
||||||
|
cmp ebx,0x0 ; test if we're done
|
||||||
|
je done_mem_real
|
||||||
|
|
||||||
|
add edi,0x20 ; increment the buffer by 0x20
|
||||||
|
jmp find_mem_next
|
||||||
|
|
||||||
|
done_mem_real:
|
||||||
|
ret
|
||||||
|
|
||||||
; fool around with vesa mode
|
; fool around with vesa mode
|
||||||
enable_vesa:
|
enable_vesa:
|
||||||
; put the VBEInfo struct at 0x30000
|
; put the VBEInfo struct at 0x30000
|
||||||
@@ -325,6 +380,7 @@ mode_loop:
|
|||||||
test ax,0x1 ; test the supported bit
|
test ax,0x1 ; test the supported bit
|
||||||
jz next_mode
|
jz next_mode
|
||||||
test ax,0x08 ; test the linear frame mode bit
|
test ax,0x08 ; test the linear frame mode bit
|
||||||
|
jz next_mode
|
||||||
mov ax,[es:di+18]
|
mov ax,[es:di+18]
|
||||||
cmp ax,VESA_X_TARGET ; x
|
cmp ax,VESA_X_TARGET ; x
|
||||||
jne next_mode
|
jne next_mode
|
||||||
|
|||||||
Binary file not shown.
@@ -25,11 +25,19 @@ const unsigned kBSSSize = 0x9000;
|
|||||||
# define MESSAGE(x)
|
# define MESSAGE(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// memory structure returned by int 0x15, ax 0xe820
|
||||||
|
typedef struct ext_memory {
|
||||||
|
uint64 base_addr;
|
||||||
|
uint64 length;
|
||||||
|
uint64 type;
|
||||||
|
uint64 filler;
|
||||||
|
} ext_memory;
|
||||||
|
|
||||||
// we're running out of the first 'file' contained in the bootdir, which is
|
// we're running out of the first 'file' contained in the bootdir, which is
|
||||||
// a set of binaries and data packed back to back, described by an array
|
// a set of binaries and data packed back to back, described by an array
|
||||||
// of boot_entry structures at the beginning. The load address is fixed.
|
// of boot_entry structures at the beginning. The load address is fixed.
|
||||||
#define BOOTDIR_ADDR 0x100000
|
#define BOOTDIR_ADDR 0x100000
|
||||||
static const boot_entry *bootdir = (boot_entry*)BOOTDIR_ADDR;
|
static const boot_entry *bootdir = (boot_entry *)BOOTDIR_ADDR;
|
||||||
|
|
||||||
// stick the kernel arguments in a pseudo-random page that will be mapped
|
// stick the kernel arguments in a pseudo-random page that will be mapped
|
||||||
// at least during the call into the kernel. The kernel should copy the
|
// at least during the call into the kernel. The kernel should copy the
|
||||||
@@ -37,7 +45,7 @@ static const boot_entry *bootdir = (boot_entry*)BOOTDIR_ADDR;
|
|||||||
static kernel_args *ka = (kernel_args *)0x20000;
|
static kernel_args *ka = (kernel_args *)0x20000;
|
||||||
|
|
||||||
// needed for message
|
// needed for message
|
||||||
static uint16 *kScreenBase = (unsigned short*) 0xb8000;
|
static uint16 *kScreenBase = (uint16 *)0xb8000;
|
||||||
static uint32 screenOffset = 0;
|
static uint32 screenOffset = 0;
|
||||||
|
|
||||||
unsigned int cv_factor = 0;
|
unsigned int cv_factor = 0;
|
||||||
@@ -50,6 +58,7 @@ static uint32 *pgdir = 0;
|
|||||||
static uint32 *pgtable = 0;
|
static uint32 *pgtable = 0;
|
||||||
|
|
||||||
// function decls for this module
|
// function decls for this module
|
||||||
|
static void sort_addr_range(addr_range *range, int count);
|
||||||
static void calculate_cpu_conversion_factor(void);
|
static void calculate_cpu_conversion_factor(void);
|
||||||
static void load_elf_image(void *data, uint32 *next_paddr, addr_range *ar0,
|
static void load_elf_image(void *data, uint32 *next_paddr, addr_range *ar0,
|
||||||
addr_range *ar1, uint32 *start_addr, addr_range *dynamic_section);
|
addr_range *ar1, uint32 *start_addr, addr_range *dynamic_section);
|
||||||
@@ -58,6 +67,9 @@ static void mmu_map_page(uint32 vaddr, uint32 paddr);
|
|||||||
static int check_cpu(void);
|
static int check_cpu(void);
|
||||||
|
|
||||||
|
|
||||||
|
extern void _start(uint32 memSize, ext_memory *extMemoryBlock, uint32 extMemoryCount,
|
||||||
|
int in_vesa, uint32 vesa_ptr);
|
||||||
|
|
||||||
/* called by the stage1 bootloader.
|
/* called by the stage1 bootloader.
|
||||||
* State:
|
* State:
|
||||||
* 32-bit
|
* 32-bit
|
||||||
@@ -67,7 +79,8 @@ static int check_cpu(void);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
_start(uint32 mem, int in_vesa, uint32 vesa_ptr)
|
_start(uint32 memSize, ext_memory *extMemoryBlock, uint32 extMemoryCount,
|
||||||
|
int in_vesa, uint32 vesa_ptr)
|
||||||
{
|
{
|
||||||
uint32 *idt;
|
uint32 *idt;
|
||||||
segment_descriptor *gdt;
|
segment_descriptor *gdt;
|
||||||
@@ -82,7 +95,8 @@ _start(uint32 mem, int in_vesa, uint32 vesa_ptr)
|
|||||||
clearscreen();
|
clearscreen();
|
||||||
|
|
||||||
dprintf("stage2 bootloader entry.\n");
|
dprintf("stage2 bootloader entry.\n");
|
||||||
dprintf("memsize = 0x%x, in_vesa %d, vesa_ptr 0x%x\n", mem, in_vesa, vesa_ptr);
|
dprintf("args: memsize 0x%x, emem_block %p, emem_count %d, in_vesa %d, vesa = %p\n",
|
||||||
|
memSize, extMemoryBlock, extMemoryCount, in_vesa, vesa_ptr);
|
||||||
|
|
||||||
// verify we can run on this cpu
|
// verify we can run on this cpu
|
||||||
if (check_cpu() < 0) {
|
if (check_cpu() < 0) {
|
||||||
@@ -95,6 +109,16 @@ _start(uint32 mem, int in_vesa, uint32 vesa_ptr)
|
|||||||
for (;;);
|
for (;;);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extMemoryCount > 0) {
|
||||||
|
uint32 i;
|
||||||
|
|
||||||
|
dprintf("extended memory info (from 0xe820):\n");
|
||||||
|
for (i = 0; i < extMemoryCount; i++) {
|
||||||
|
dprintf(" base 0x%Lx, len 0x%Lx, type %Ld\n",
|
||||||
|
extMemoryBlock[i].base_addr, extMemoryBlock[i].length, extMemoryBlock[i].type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// calculate the conversion factor that translates rdtsc time to real microseconds
|
// calculate the conversion factor that translates rdtsc time to real microseconds
|
||||||
calculate_cpu_conversion_factor();
|
calculate_cpu_conversion_factor();
|
||||||
|
|
||||||
@@ -234,18 +258,96 @@ _start(uint32 mem, int in_vesa, uint32 vesa_ptr)
|
|||||||
ka->arch_args.vir_pgdir = next_vaddr;
|
ka->arch_args.vir_pgdir = next_vaddr;
|
||||||
next_vaddr += PAGE_SIZE;
|
next_vaddr += PAGE_SIZE;
|
||||||
|
|
||||||
// save the kernel args
|
// mark memory that we know is used
|
||||||
ka->arch_args.system_time_cv_factor = cv_factor;
|
|
||||||
ka->physical_memory_range[0].start = 0;
|
|
||||||
ka->physical_memory_range[0].size = mem;
|
|
||||||
ka->num_physical_memory_ranges = 1;
|
|
||||||
ka->str = NULL;
|
|
||||||
ka->physical_allocated_range[0].start = BOOTDIR_ADDR;
|
ka->physical_allocated_range[0].start = BOOTDIR_ADDR;
|
||||||
ka->physical_allocated_range[0].size = next_paddr - BOOTDIR_ADDR;
|
ka->physical_allocated_range[0].size = next_paddr - BOOTDIR_ADDR;
|
||||||
ka->num_physical_allocated_ranges = 1;
|
ka->num_physical_allocated_ranges = 1;
|
||||||
|
|
||||||
|
// figure out the memory map
|
||||||
|
if (extMemoryCount > 0) {
|
||||||
|
uint32 i;
|
||||||
|
|
||||||
|
ka->num_physical_memory_ranges = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < extMemoryCount; i++) {
|
||||||
|
if (extMemoryBlock[i].type == 1) {
|
||||||
|
// round everything up to page boundaries, exclusive of pages it partially occupies
|
||||||
|
extMemoryBlock[i].length -= (extMemoryBlock[i].base_addr % PAGE_SIZE)
|
||||||
|
? (PAGE_SIZE - (extMemoryBlock[i].base_addr % PAGE_SIZE)) : 0;
|
||||||
|
extMemoryBlock[i].base_addr = ROUNDUP(extMemoryBlock[i].base_addr, PAGE_SIZE);
|
||||||
|
extMemoryBlock[i].length = ROUNDOWN(extMemoryBlock[i].length, PAGE_SIZE);
|
||||||
|
|
||||||
|
// this is mem we can use
|
||||||
|
if (ka->num_physical_memory_ranges == 0) {
|
||||||
|
ka->physical_memory_range[0].start = (addr_t)extMemoryBlock[i].base_addr;
|
||||||
|
ka->physical_memory_range[0].size = (addr_t)extMemoryBlock[i].length;
|
||||||
|
ka->num_physical_memory_ranges++;
|
||||||
|
} else {
|
||||||
|
// we might have to extend the previous hole
|
||||||
|
addr_t previous_end = ka->physical_memory_range[ka->num_physical_memory_ranges - 1].start
|
||||||
|
+ ka->physical_memory_range[ka->num_physical_memory_ranges - 1].size;
|
||||||
|
|
||||||
|
if (previous_end <= extMemoryBlock[i].base_addr
|
||||||
|
&& ((extMemoryBlock[i].base_addr - previous_end) < 0x100000)) {
|
||||||
|
// extend the previous buffer
|
||||||
|
ka->physical_memory_range[ka->num_physical_memory_ranges - 1].size +=
|
||||||
|
(extMemoryBlock[i].base_addr - previous_end) +
|
||||||
|
extMemoryBlock[i].length;
|
||||||
|
|
||||||
|
// mark the gap between the two allocated ranges in use
|
||||||
|
ka->physical_allocated_range[ka->num_physical_allocated_ranges].start = previous_end;
|
||||||
|
ka->physical_allocated_range[ka->num_physical_allocated_ranges].size = extMemoryBlock[i].base_addr - previous_end;
|
||||||
|
ka->num_physical_allocated_ranges++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we dont have an extended map, assume memory is contiguously mapped at 0x0
|
||||||
|
ka->physical_memory_range[0].start = 0;
|
||||||
|
ka->physical_memory_range[0].size = memSize;
|
||||||
|
ka->num_physical_memory_ranges = 1;
|
||||||
|
|
||||||
|
// mark the bios area allocated
|
||||||
|
ka->physical_allocated_range[ka->num_physical_allocated_ranges].start = 0x9f000; // 640k - 1 page
|
||||||
|
ka->physical_allocated_range[ka->num_physical_allocated_ranges].size = 0x61000;
|
||||||
|
ka->num_physical_allocated_ranges++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// save the memory we've virtually allocated (for the kernel and other stuff)
|
||||||
ka->virtual_allocated_range[0].start = KERNEL_BASE;
|
ka->virtual_allocated_range[0].start = KERNEL_BASE;
|
||||||
ka->virtual_allocated_range[0].size = next_vaddr - KERNEL_BASE;
|
ka->virtual_allocated_range[0].size = next_vaddr - KERNEL_BASE;
|
||||||
ka->num_virtual_allocated_ranges = 1;
|
ka->num_virtual_allocated_ranges = 1;
|
||||||
|
|
||||||
|
// sort the address ranges
|
||||||
|
sort_addr_range(ka->physical_memory_range, ka->num_physical_memory_ranges);
|
||||||
|
sort_addr_range(ka->physical_allocated_range, ka->num_physical_allocated_ranges);
|
||||||
|
sort_addr_range(ka->virtual_allocated_range, ka->num_virtual_allocated_ranges);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
dprintf("phys memory ranges:\n");
|
||||||
|
for (i = 0; i < ka->num_physical_memory_ranges; i++) {
|
||||||
|
dprintf(" base 0x%08lx, length 0x%08lx\n", ka->physical_memory_range[i].start, ka->physical_memory_range[i].size);
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("allocated phys memory ranges:\n");
|
||||||
|
for (i = 0; i < ka->num_physical_allocated_ranges; i++) {
|
||||||
|
dprintf(" base 0x%08lx, length 0x%08lx\n", ka->physical_allocated_range[i].start, ka->physical_allocated_range[i].size);
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("allocated virt memory ranges:\n");
|
||||||
|
for (i = 0; i < ka->num_virtual_allocated_ranges; i++) {
|
||||||
|
dprintf(" base 0x%08lx, length 0x%08lx\n", ka->virtual_allocated_range[i].start, ka->virtual_allocated_range[i].size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// save the kernel args
|
||||||
|
ka->arch_args.system_time_cv_factor = cv_factor;
|
||||||
|
ka->str = NULL;
|
||||||
ka->arch_args.page_hole = 0xffc00000;
|
ka->arch_args.page_hole = 0xffc00000;
|
||||||
ka->num_cpus = 1;
|
ka->num_cpus = 1;
|
||||||
#if 0
|
#if 0
|
||||||
@@ -491,6 +593,27 @@ sleep(uint64 time)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
sort_addr_range(addr_range *range, int count)
|
||||||
|
{
|
||||||
|
addr_range tempRange;
|
||||||
|
bool done;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
do {
|
||||||
|
done = true;
|
||||||
|
for (i = 1; i < count; i++) {
|
||||||
|
if (range[i].start < range[i - 1].start) {
|
||||||
|
done = false;
|
||||||
|
memcpy(&tempRange, &range[i], sizeof(addr_range));
|
||||||
|
memcpy(&range[i], &range[i - 1], sizeof(addr_range));
|
||||||
|
memcpy(&range[i - 1], &tempRange, sizeof(addr_range));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (!done);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define outb(value,port) \
|
#define outb(value,port) \
|
||||||
asm("outb %%al,%%dx"::"a" (value),"d" (port))
|
asm("outb %%al,%%dx"::"a" (value),"d" (port))
|
||||||
|
|
||||||
@@ -687,10 +810,12 @@ static void
|
|||||||
scrup()
|
scrup()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memcpy(kScreenBase, kScreenBase + SCREEN_WIDTH,
|
memcpy(kScreenBase, kScreenBase + SCREEN_WIDTH,
|
||||||
SCREEN_WIDTH * SCREEN_HEIGHT * 2 - SCREEN_WIDTH * 2);
|
SCREEN_WIDTH * SCREEN_HEIGHT * 2 - SCREEN_WIDTH * 2);
|
||||||
screenOffset = (SCREEN_HEIGHT - 1) * SCREEN_WIDTH;
|
screenOffset = (SCREEN_HEIGHT - 1) * SCREEN_WIDTH;
|
||||||
for(i=0; i<SCREEN_WIDTH; i++)
|
|
||||||
|
for (i = 0; i < SCREEN_WIDTH; i++)
|
||||||
kScreenBase[screenOffset + i] = 0x0720;
|
kScreenBase[screenOffset + i] = 0x0720;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -720,7 +845,7 @@ dprintf(const char *fmt, ...)
|
|||||||
char temp[256];
|
char temp[256];
|
||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
ret = vsprintf(temp,fmt,args);
|
ret = vsprintf(temp, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
kputs(temp);
|
kputs(temp);
|
||||||
|
|||||||
Reference in New Issue
Block a user